MapServer 5.4.0
MapServer 5.4.0
Release 5.4.0
CONTENTS
1 2
About An Introduction to MapServer 2.1 MapServer Overview . . . . . . . . . 2.2 Anatomy of a MapServer Application 2.3 Installation and Requirements . . . . 2.4 Introduction to the Maple . . . . . . 2.5 Making the Site Your Own . . . . . . 2.6 Enhancing your site . . . . . . . . . 2.7 How do I get Help? . . . . . . . . . .
3 5 5 6 8 14 22 23 25 27 27 27 28 28 29 29 30 31 31 39 46 52 57 60 65 65 68 73 74 75 76 78 82 85 91
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
MapServer Tutorial 3.1 Tutorial Timeframe . . . . . . . . . . . . . . . 3.2 Tutorial Data . . . . . . . . . . . . . . . . . . 3.3 Before Using the Tutorial . . . . . . . . . . . 3.4 Windows, UNIX/Linux Issues . . . . . . . . . 3.5 Other Resources . . . . . . . . . . . . . . . . 3.6 Section 1: Static Maps and the MapFile . . . . 3.7 Section 2: CGI variables and the User Interface Installation 4.1 Compiling on Unix . . . . . . 4.2 Compiling on Win32 . . . . . 4.3 PHP MapScript Installation . 4.4 .NET MapScript Compilation 4.5 IIS Setup for MapServer . . . 4.6 Oracle Installation . . . . . . Maple 5.1 CLASS . . 5.2 Expressions 5.3 FEATURE 5.4 FONTSET 5.5 INCLUDE 5.6 GRID . . . 5.7 JOIN . . . 5.8 LABEL . . 5.9 LAYER . . 5.10 LEGEND .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
5.11 5.12 5.13 5.14 5.15 5.16 5.17 5.18 5.19 5.20 5.21 5.22 5.23 5.24 6
MAP . . . . . . . . . . . . . . . . . . . . . . . . . OUTPUTFORMAT . . . . . . . . . . . . . . . . . PROJECTION . . . . . . . . . . . . . . . . . . . . QUERYMAP . . . . . . . . . . . . . . . . . . . . . REFERENCE . . . . . . . . . . . . . . . . . . . . SCALEBAR . . . . . . . . . . . . . . . . . . . . . STYLE . . . . . . . . . . . . . . . . . . . . . . . . SYMBOL . . . . . . . . . . . . . . . . . . . . . . Cartographic Symbol Construction with MapServer Symbology Examples . . . . . . . . . . . . . . . . Templating . . . . . . . . . . . . . . . . . . . . . . Variable Substitution . . . . . . . . . . . . . . . . . WEB . . . . . . . . . . . . . . . . . . . . . . . . . Notes . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
92 95 98 99 99 100 101 103 105 126 129 137 137 138 141 141 142 178 222 224 227 230 232
MapScript 6.1 Introduction . . . . . . . . . . . . . 6.2 SWIG MapScript API Reference . . 6.3 PHP MapScript . . . . . . . . . . . . 6.4 Python MapScript Appendix . . . . . 6.5 Python MapScript Image Generation 6.6 Maple Manipulation . . . . . . . . 6.7 Querying . . . . . . . . . . . . . . . 6.8 MapScript Variables . . . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
Data Input 239 7.1 Vector Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 7.2 Raster Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296 Output Generation 8.1 AGG Rendering Specics . . . . 8.2 AntiAliasing with MapServer . . 8.3 Dynamic Charting . . . . . . . . 8.4 Flash Output . . . . . . . . . . . 8.5 HTML Legends with MapServer 8.6 HTML Imagemaps . . . . . . . . 8.7 PDF Output . . . . . . . . . . . . 8.8 SVG . . . . . . . . . . . . . . . 8.9 Tile Mode . . . . . . . . . . . . 309 309 312 315 319 325 333 336 341 348 353 353 374 381 386 393 403 406 413 423 434 439 451 459
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
OGC Support and Conguration 9.1 WMS Server . . . . . . . . . . . . . . 9.2 WMS Client . . . . . . . . . . . . . . 9.3 WMS Time . . . . . . . . . . . . . . . 9.4 Map Context . . . . . . . . . . . . . . 9.5 WFS Server . . . . . . . . . . . . . . 9.6 WFS Client . . . . . . . . . . . . . . . 9.7 WFS Filter Encoding . . . . . . . . . . 9.8 SLD . . . . . . . . . . . . . . . . . . . 9.9 WCS Server . . . . . . . . . . . . . . 9.10 WCS Use Cases . . . . . . . . . . . . 9.11 SOS Server . . . . . . . . . . . . . . . 9.12 MapScript Wrappers for WxS Services
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
10 Optimization ii
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
459 461 463 464 467 471 471 471 473 473 475 476 477 479 480 484 484 487 487 488 488 489 493 495 497 497 498 499 499 501 501 501 502 503 508 514 672 673
11 Utilities 11.1 legend . . . . . 11.2 msencrypt . . . 11.3 scalebar . . . . . 11.4 shp2img . . . . 11.5 shptree . . . . . 11.6 shptreevis . . . . 11.7 sortshp . . . . . 11.8 sym2img . . . . 11.9 tile4ms . . . . . 11.10 Batch Scripting . 11.11 File Management 12 CGI 12.1 12.2 12.3 12.4 12.5 12.6
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
MapServer CGI Introduction . mapserv . . . . . . . . . . . . Map Context Files . . . . . . MapServer CGI Controls . . . Run-time Substitution . . . . A Simple CGI Wrapper Script
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
13 Community Activities 13.1 IRC . . . . . . . . . . . . . . 13.2 Mailing Lists . . . . . . . . . 13.3 MapServer Wiki Pages . . . . 13.4 MapServer Service Providers
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
14 Development 14.1 Sponsors . . . . . . . . . . . . . . 14.2 Bug Submission . . . . . . . . . . 14.3 Subversion . . . . . . . . . . . . . 14.4 Documentation Development Guide 14.5 Testing . . . . . . . . . . . . . . . 14.6 Request for Comments . . . . . . . 14.7 Maple Editing . . . . . . . . . . . 14.8 External Links . . . . . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
15 Download 675 15.1 Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 675 15.2 Binaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 675 16 Glossary 17 Errors 17.1 drawEPP(): EPPL7 support is not available . . 17.2 loadMapInternal(): Given map extent is invalid 17.3 msSaveImageGD(): Unable to access le . . . 17.4 msLoadMap(): Failed to open map le . . . . 17.5 msQueryByPoint: search returned no results . 677 681 681 681 682 683 683
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
iii
17.6 17.7 17.8 17.9 17.10 17.11 17.12 17.13 17.14 18 FAQ 18.1 18.2 18.3 18.4 18.5 18.6 18.7 18.8 18.9 18.10 18.11 18.12 18.13 18.14 18.15 18.16 18.17 18.18 18.19 18.20 18.21 18.22 18.23 18.24 18.25
msLoadFontset(): Error opening fontset . . . . . . . . . . . . . . . . . . . . . . msGetLabelSize(): Requested font not found . . . . . . . . . . . . . . . . . . . loadLayer(): Unknown identier. Maximum number of classes reached . . . . . msReturnPage(): Web application error. Malformed template name . . . . . . . Unable to load dll (MapScript) . . . . . . . . . . . . . . . . . . . . . . . . . . . msProcessProjection(): Projection library error.major axis or radius = 0 not given msProcessProjection(): no options found in init le . . . . . . . . . . . . . . . msProcessProjection(): No such le or directory . . . . . . . . . . . . . . . . . msQueryByPoint: search returned no results . . . . . . . . . . . . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
683 684 684 684 685 685 686 686 686 689 689 689 689 689 689 691 691 691 692 692 692 692 692 693 693 694 694 695 696 696 697 698 698 699 699 701 703 705 707
Where is the MapServer log le? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . What books are available about MapServer? . . . . . . . . . . . . . . . . . . . . . . . . . . How do I compile MapServer for Windows? . . . . . . . . . . . . . . . . . . . . . . . . . . What do MapServer version numbers mean? . . . . . . . . . . . . . . . . . . . . . . . . . . Is MapServer Thread-safe? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . What does STATUS mean in a LAYER? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . How can I make my maps run faster? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . What does Polyline mean in MapServer? . . . . . . . . . . . . . . . . . . . . . . . . . . . . What is MapScript? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Does MapServer support reverse geocoding? . . . . . . . . . . . . . . . . . . . . . . . . . . Does MapServer support geocoding? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . How do I set line width in my maps? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Why do my JPEG input images look crappy via MapServer? . . . . . . . . . . . . . . . . . . Which image format should I use? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Why doesnt PIL (Python Imaging Library) open my PNGs? . . . . . . . . . . . . . . . . . . Why do my symbols look poor in JPEG output? . . . . . . . . . . . . . . . . . . . . . . . . How do I add a copyright notice on the corner of my map? . . . . . . . . . . . . . . . . . . . How do I have a polygon that has both a ll and an outline with a width? . . . . . . . . . . . How can I create simple antialiased line features? . . . . . . . . . . . . . . . . . . . . . . . . Which OGC Specications does MapServer support? . . . . . . . . . . . . . . . . . . . . . . Why does my requested WMS layer not align correctly? . . . . . . . . . . . . . . . . . . . . When I do a GetCapabilities, why does my browser want to download mapserv.exe/mapserv? Why do my WMS GetMap requests return exception using MapServer 5.0? . . . . . . . . . . Where do I nd my EPSG code? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . How can I reproject my data using ogr2ogr? . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
iv
Note: The entire documentation is also available as a single PDF document Table 1: Quick Links An Introduction to MapServer MapScript OGC Support and Conguration Development Index Installation Data Input Optimization Glossary About Maple Output Generation Utilities Errors Community Activities
CONTENTS
CONTENTS
CHAPTER
ONE
ABOUT
MapServer is an Open Source geographic data rendering engine written in C. Beyond browsing GIS data, MapServer allows you create geographic image maps, that is, maps that can direct users to content. For example, the Minnesota DNR Recreation Compass provides users with more than 10,000 web pages, reports and maps via a single application. The same application serves as a map engine for other portions of the site, providing spatial context where needed. MapServer was originally developed by the University of Minnesota (UMN) ForNet project in cooperation with NASA, and the Minnesota Department of Natural Resources (MNDNR). Later it was hosted by the TerraSIP project, a NASA sponsored project between the UMN and a consortium of land management interests. MapServer is now a project of OSGeo, and is maintained by a growing number of developers (nearing 20) from around the world. It is supported by a diverse group of organizations that fund enhancements and maintenance, and administered within OSGeo by the MapServer Project Steering Committee made up of developers and other contributors. Advanced cartographic output Scale dependent feature drawing and application execution Feature labeling including label collision mediation Fully customizable, template driven output TrueType fonts Map element automation (scalebar, reference map, and legend) Thematic mapping using logical- or regular expression-based classes Support for popular scripting and development environments PHP, Python, Perl, Ruby, Java, and .NET Cross-platform support Linux, Windows, Mac OS X, Solaris, and more Support of numerous Open Geospatial Consortium (OGC) standards WMS (client/server), non-transactional WFS (client/server), WMC, WCS, Filter Encoding, SLD, GML, SOS, OM A multitude of raster and vector data formats TIFF/GeoTIFF, EPPL7, and many others via GDAL ESRI shaples, PostGIS, ESRI ArcSDE, Oracle Spatial, MySQL and many others via OGR Map projection support On-the-y map projection with 1000s of projections through the Proj.4 library
Chapter 1. About
CHAPTER
TWO
AN INTRODUCTION TO MAPSERVER
Revision $Revision: 8478 $ Date $Date: 2009-01-29 11:54:42 -0800 (Thu, 29 Jan 2009) $ Author Jeff McKenna Contact jmckenna at gatewaygeomatics.com Author David Fawcett Contact david.fawcett at moea.state.mn.us Author Howard Butler Contact hobu.inc at gmail.com
Contents An Introduction to MapServer MapServer Overview Anatomy of a MapServer Application Installation and Requirements Introduction to the Maple Making the Site Your Own Enhancing your site How do I get Help?
high quality rendering fully customizable application output many ready-to-use Open Source application environments In its most basic form, MapServer is a CGI program that sits inactive on your Web server. When a request is sent to MapServer, it uses information passed in the request URL and the Maple to create an image of the requested map. The request may also return images for legends, scale bars, reference maps, and values passed as CGI variables. See Also: The Glossary contains an overview of many of the jargon terms in this document. MapServer can be extended and customized through MapScript or templating. It can be built to support many different vector and raster input data formats, and it can generate a multitude of output formats. Most pre-compiled MapServer distributions contain most all of its features. See Also: Compiling on Unix and Compiling on Win32 Note: MapScript provides a scripting interface for MapServer for the construction of Web and stand-alone applications. MapScript can used independently of CGI MapServer, and it is a loadable module that adds MapServer capability to your favorite scripting language. MapScript currently exists in PHP, Perl, Python, Ruby, Tcl, Java, and .NET avors. This guide will not explicitly discuss MapScript, check out the MapScript Reference for more information.
Template File - controls how the maps and legends output by MapServer will appear in the browser. By referencing MapServer CGI variables in the template html, you allow MapServer to populate them with values related to the current state of your application (e.g. map image name, reference image name, map extent, etc.) as it creates the html page for the browser to read. The template also determines how the user can interact with the MapServer application (browse, zoom, pan, query). See Also: Templating MapServer CGI - The binary or executable le that receives requests and returns images, data, etc. It sits in the cgi-bin or scripts directory of the http server. The Web server user must have execute rights for the directory that it sits in, and for security reasons, it should not be in the web root. By default, this program is called mapserv HTTP Server - serves up the html pages when hit by the users browser. You need a working HTTP (Web) server, such as Apache or Microsoft Internet Information Server, on the machine on which you are installing MapServer.
Note: Express contains options for higher-level packages such as MapServer, GRASS, and uDig. Advanced gives you full access to choosing commandline tools and applications for MapServer that are not included in the Express install 4. Select packages to install
Note: Click on the Default text beside the higher-level packages (such as Web) to install all of Webs subpackages, or click on the Skip text beside the sub-package (such as MapServer) to install that package and all of its dependencies. 5. Let the installer fetch the packages.
10
6. Run the apache-install.bat script to install the Apache Service. Note: You must run this script under the OSGeo4W Shell. This is usually available as a shortcut on your desktop Note: A apache-uninstall.bat script is also available to remove the Apache service installation. 7. Start Apache from the OSGeo4W shell and navigate to http://127.0.0.1
apache-restart.bat
11
12
13
2.3.4 Skills
In addition to learning how the different components of a MapServer application work together and learning Map File syntax, building a basic application requires some conceptual understanding and prociency in several skill areas. You need to be able to create or at least modify HTML pages and understand how HTML forms work. Since the primary purpose of a MapServer application is to create maps, you will also need to understand the basics of geographic data and likely, map projections. As your applications get more complex, skills in SQL, DHTML/Javascript, Java, databases, expressions, compiling, and scripting may be very useful.
Note: Comments in a maple are specied with a # character MapServer parses maples from top to bottom, therefore layers at the end of the maple will be drawn last (meaning they will be displayed on top of other layers) Using relative paths is always recommended Paths should be quoted (single or double quotes are accepted)
14
EXTENT is the output extent in the units of the output map SIZE is the width and height of the map image in pixels IMAGECOLOR is the default image background color
15
DATA b a t h _ m a p s e r v e r . t i f END
See Also: Raster Data Vector Layers Vector layers of TYPE point, line, or polygon can be displayed. The following example shows how to display only lines from a TYPE polygon layer, using the OUTLINECOLOR parameter:
LAYER NAME "world_poly" DATA shapefile/countries_area.shp STATUS ON TYPE POLYGON CLASS NAME The World STYLE OUTLINECOLOR 0 0 0 END END END # layer
16
2.4.4 SYMBOLs
can be dened directly in the maple, or in a separate le 2.4. Introduction to the Maple 17
the separate le method must use the SYMBOLSET parameter in the MAP object:
MAP NAME EXTENT SIZE IMAGECOLOR SYMBOLSET END "sample" -180 -90 180 90 # Geographic 800 400 128 128 255 "../etc/symbols.txt"
See Also: Cartographic Symbol Construction with MapServer, Symbology Examples, and SYMBOL
2.4.5 LABEL
dened within a LAYER object the LABELITEM parameters in the LAYER object can be used to label by a specic column in the data refer to a FONTSET le, that is set in the MAP object, that contains a reference to the available font names An example LABEL object that references one of the above fonts might look like:
LABEL FONT "sans-bold" TYPE truetype SIZE 10 POSITION LC PARTIALS FALSE COLOR 100 100 100 OUTLINECOLOR 242 236 230 END # label
18
19
Figure 2.6: Rendered Bluemarble image with skier symbol and a label
20
2. Regular expressions
(EXPRESSION /^9|^10/)
3. Logical expressions
([POPULATION] > 50000 AND [LANGUAGE] eq FRENCH)
Note: Logical expressions should be avoided wherever possible as they are very costly in terms of drawing time. See Also: Expressions
2.4.7 INCLUDE
Added to MapServer 4.10, any part of the maple can now be stored in a separate le and added to the main maple using the INCLUDE parameter. The lename to be included can have any extension, and it is always relative to the main .map le. Here are some potential uses: LAYER s can be stored in les and included to any number of applications STYLE s can also be stored and included in multiple applications The following is an example of using maple includes to include a layer denition in a separate le: If shadedrelief.lay contains:
LAYER NAME STATUS TYPE DATA END shadedrelief ON RASTER GLOBALeb3colshade.jpg
The following is an example of a maple where all LAYER s are in separate .lay les, and all other objects (WEB, REFERENCE, SCALEBAR, etc.) are stored in a .ref le:
21
NAME "base" # # include reference objects # INCLUDE "../templates/template.ref" # # Start of layer definitions # INCLUDE "../layers/usa/usa_outline.lay" INCLUDE "../layers/canada/base/1m/provinces.lay" INCLUDE "../layers/canada/base/1m/roads_atlas_of_canada_1m.lay" INCLUDE "../layers/canada/base/1m/roads_atlas_of_canada_1m_shields.lay" INCLUDE "../layers/canada/base/1m/populated_places.lay" END # Map File
Warning: Maples must end with the .map extension or MapServer will not recognize them. Include les can have any extension you want, however. See Also: INCLUDE
You can also send a HTTP request directly to the MapServer CGI program without passing any conguration variables (e.g. http://your.domain.name/cgi-bin/ms4/mapserv.exe). If you receive the message, No query information to decode. QUERY_STRING not set., your installation is working.
22
2.5.4 Projections
Because the earth is round and your monitor (or paper map) is at, distortions will occur when you display geographic data in a two-dimensional image. Projections allow you to represent geographic data on a at surface. In doing so, some of the original properties (e.g. area, direction, distance, scale or conformity)of the data will be distorted. Different projections excel at accurately portraying different properties. A good primer on map projections can be found at the University of Colorado. With MapServer, if you keep all of your spatial data sets in the same projection (or unprojected Latitude and Longitude), you do not need to include any projection info in your Map File. In building your rst MapServer application, this simplication is recommended. On-the-y projection can be accomplished when MapServer is compiled with Proj.4 support. Instructions on how to enable Proj.4 support on Windows can be found on the Wiki.
23
by passing query denition information to MapServer in the URL (or form post). Mode=itemquery returns a single result, and mode=itemnquery returns multiple result sets. The request must also include a QLAYER, which identies the layer to be queried, and a QSTRING which contains the query string. Optionally, QITEM, can be used in conjunction with QSTRING to dene the eld to be queried. Attribute queries only apply within the EXTENT set in the map le.
2.6.4 Interfaces
See: OpenLayers http://openlayers.org
24
2.7.3 IRC
MapServer users and developers can be found on Internet Relay Chat. The channel is #mapserver on irc.freenode.net.
2.7.4 Gallery
See examples of existing MapServer applications.
2.7.5 Tutorial
Perry Nacionales built a great Tutorial on how to build a MapServer application. You are invited to extend the collection of examples if you see cases that are missing.
2.7.7 Books
Web Mapping Illustrated , a new book by Tyler Mitchell that describes well and provides real-world examples for the use of Web mapping concepts, Open Source GIS software, MapServer, Web services, and PostGIS. Mapping Hacks , by Schuyler Erle, Rich Gibson, and Jo Walsh, creatively demonstrates digital mapping tools and concepts. MapServer only appears in a handful of the 100 hacks, but many more are useful for concepts and inspiration. Beginning MapServer: Opensource GIS Development , by Bill Kropla, is a new book focusing on MapServer. So new, I havent seen it yet. According to the publisher, it covers installation and conguration, basic MapServer topics and features, incorporation of dynamic data, advanced topics, MapScript, and the creation of an actual application.
25
26
CHAPTER
THREE
MAPSERVER TUTORIAL
Author Pericles S. Nacionales Contact pnaciona at gmail.com Author Jeff McKenna Contact jmckenna at gatewaygeomatics.com Revision $Revision: 8577 $ Date $Date: 2009-02-18 11:38:50 -0500 (Wed, 18 Feb 2009) $ This tutorial was designed to give new users a quick (relatively speaking) introduction to the concepts behind MapServer. It is arranged into four sections with each section having one or more examples and increasing in complexity. Users can jump to any section at any time although it is recommended that absolute beginners work on the rst three sections sequentially. Section one focuses on basic MapServer conguration concepts such as layer and class ordering, using vector and raster data, projections and labeling. Section two provides examples on how to use HTML templates to create a simple interface for an interactive web mapping application. Section three introduces the use of HTML templates to provide a query interface. Finally, section four introduces some advanced user interface concepts.
27
or:
SHAPEPATH "C:\data\projects\tutorial\data".
Notice that either slash or backslash works in Windows. The usual backslash may work well for you if you want to make a distinction between virtual (as in URLs or web addresses) and local paths in your map le. However, if you plan to move your application to UNIX at some point, youll have the tedious task of switching all backslashes to slashes. While were on the subject of paths, keep in mind that paths in maples are typically relative to the systems root directory: the slash (/) in UNIX or some drive letter (C:) in Windows. This is true except when specically asked to enter a URL or when referencing a URL. When working with HTML template les, paths are relative to the web servers root directory. i.e., /tutorial/ is relative to http://demo.mapserver.org/. Please read http://www.alistapart.com/stories/slashforward/ for a few insights on URLs. 28 Chapter 3. MapServer Tutorial
3.4.2 Executable
Another issue is that UNIX executable les dont require a .EXE or .COM extensions, but they do in Windows. If you are using Windows, append .exe to all instances of /cgi-bin/mapserv or /cgi-bin/mapserv50 to make it /cgibin/mapserv.exe or /cgi-bin/mapserv50.exe.
We can display the same shapele repeatedly. We can display the polygon attributes on one LAYER and and the line attrib Example 1.2 - A map with two layers And we can select which parts of the shapele to display. We do this using the CLASS object... Example 1.3 - Using classes to make a useful map We can also label our maps... Example 1.4 - Labeling layers and label layers Example 1.5
Or add raster data such as satellite images, aerial photographs, or shaded reliefs... Adding a raster layer
We can reproject our data from just about any projection to just about any... Yeah, check it out! Example 1.6 - Projection/Reprojection And we can use layers from other map servers on the internet (as long as they are WMS servers)... Example 1.7 - Adding a WMS layer MapServer can output to various formats such as PDF and GeoTIFF. format
MapServer not only generates static maps, it can also create interactive maps... example1-9
29
3.7.2 Examples
So, lets build an interactive interface for our application... Users of a web mapping application should be able to pan and zoom on the map: Example 2.1 - Pan and Zoom Controls They also should be able to turn on and off layers on a map: Example 2.2 - Layer Control A map should always include a scalebar. Example 2.3 - Adding a Scalebar If users are to navigate through the map, a reference map should be provided: Example 2.4 - Adding a Reference Map The map should include a legend. Example 2.5- Adding a Legend
Begin tutorial
30
CHAPTER
FOUR
INSTALLATION
4.1 Compiling on Unix
Author J.F. Doyon Contact jdoyon at nrcan.gc.ca Author Howard Butler Contact hobu.inc at gmail.com Revision $Revision: 8463 $ Date $Date: 2009-01-28 07:37:36 -0800 (Wed, 28 Jan 2009) $
Table of Contents Compiling on Unix Introduction Obtaining the necessary software libgd Anti-Grain Geometry Support OGC Support Spatial Warehousing Compiling Installation
4.1.1 Introduction
The University of Minnesotas MapServer is an open-source and freely available map rendering engine for the web. Due to its open-source nature, it can be compiled on a wide variety of platforms and operating systems. We will focus on how to obtain, compile and install MapServer on UNIX-like platforms. You might also check the MapServerCompilation wiki page for additional information.
You can also get the latest MapServer source code from Subversion. Required External Libraries libpng: libpng should be on your system by default. 1.2.12 is the current release with security patches, although versions all the way back to 1.2.7 should work. freetype: Version 2.x or above is required by GD. GD: libgd is used by MapServer for rendering images. Version 2.0.28 or greater required. Version 2.0.29 or later is required to use curved (following) labels, and version 2.0.34 is required for antialiasing (1 pixel wide lines/outlines). zlib: Zlib should be on your system by default. 1.2.1 is the current release with security patches. Highly Recommended Libraries libproj: libproj provides projection support for MapServer. Version 4.4.6 or greater is required. libcurl: libcurl is the foundation of OGC (WFS/WMS/WCS) client and server support. Version 7.10 or greater is required OGR: OGR provides access to at least 18 different vector formats. GDAL: GDAL provides access to at least 42 different raster formats. AGG: AGG (Anti-Grain Geometry) is an optional dependency to enable high quality antialiased output for vector data. Currently versions 2.4 and 2.5 are identical featurewise, and only vary in their licence (2.4 is BSD, 2.5 is GPL) Optional External Libraries libtiff: libtiff provides TIFF (Tagged Image File Format) reading support to MapServer. libgeotiff libgeotiff provides support to read GeoTIFF les (TIFF les with geographic referencing). libjpeg: libjpeg allows MapServer to render images in JPEG format. A sufcient version should be installed by default on your system. Version 6b is the current version and dates back to 1998. GEOS: GEOS allows MapServer to do spatial predicate and algebra operations (within, touches, etc & union, difference, intersection). Requires version 4.10 or greater. libxml: libxml is required to use OGC SOS support in MapServer (versions 4.10 and greater). SDE Client Library: The client libraries for your platform should be part of the ArcSDE media kit. They are not publicly available for download. Oracle Spatial OCI: The client libraries for your platform are available for download from Oracles website. Ideally, your client library matches the database you are querying from, but this is not a hard requirement. libpq: libpq is required to support the use of PostGIS geometries within the PostgreSQL database. Ideally, your client library matches the database you are querying from. pdib (lite): PDFlib Lite is the Open Source version of PDFlib that allows MapServer to produce PDF output. Version 4.0.3 or greater is required. libming: libming provides Macromedia Flash output to MapServer. Version 0.2a is required. Later versions are not known to work. 32 Chapter 4. Installation
4.1.3 libgd
There are a number of issues that you should be aware of when using GD in combination with MapServer. Minimum libgd versions MapServer aggressively takes advantage of new features and bug xes in the latest versions of libgd. The minimum required version to run MapServer is 2.0.29. Upgrading to at least 2.0.34 is advised as it includes an important bug x for antialiased lines. Congure should detect which version of libgd you have installed, but you can quickly check yourself by issuing the following command:
gdlib-config --version
libiconv If you intend to use international character sets, your version of libgd must be compiled against the GNU iconv libraries. If you are using a pre-packaged version, it is very likely that this is the case. To check for yourself, issue the following command and look for -liconv in the output:
gdlib-config --libs
Pre-packaged/system libraries If you intend to use your systems libgd, ensure that you have the development package also installed so MapServer can nd and use the appropriate headers. MacOSX A useful FAQ on for libgd on OSX is available at http://www.libgd.org/DOC_INSTALL_OSX FreeType support The GD you compile MapServer against MUST be compiled against the FreeType library in order to use TrueType fonts. MapServer no longer uses its own interface to FreeType, using it through GD instead. When you run your congure script, look for the following output:
using GD ( -DUSE_GD_GIF -DUSE_GD_PNG -DUSE_GD_JPEG -DUSE_GD_WBMP -DUSE_GD_TTF -DGD_HAS_GDIMAGEGIFPTR) from system libs.
If your GD is built against FreeType, you will see either -DUSE_GD_TTF (Or -DUSE_GD_FT for Freetype 2.x) part. If its missing, you will need to recompile your GD to make sure you include FreeType support. See the GD documentation for more information. Also note that the congure script looks for the FreeType library separately as well, generating output looking somewhat like this:
checking where FreeType is installed... checking for FT_Init_FreeType in -lfreetype... yes using libfreetype -lfreetype from system libs.
33
Even though you have FreeType installed on your system and the congure script nds it, does NOT mean you will have TrueType font support. GD MUST be compiled against FreeType either way. 1px Anti-Aliasing and segfaults Versions of libgd earlier than 2.0.34 contain a one very signicant bug and will always cause a segfault if you attempt to do one pixel wide antialiasing. You can manually patch older gds, or better yet upgrade to at least GD 2.0.34. In gd.c, function gdImageSetAAPixelColor() change:
int dr,dg,db,p,r,g,b; p = gdImageGetPixel(im,x,y);
to
int dr,dg,db,p,r,g,b; if (!gdImageBoundsSafeMacro (im, x, y)) return; p = gdImageGetPixel(im,x,y);
More detail about this patch (if you need any) was described by Steve Lime in a post to mapserver-users. Curved label support ANGLE FOLLOW, a new feature that allows MapServer to draw curved labels about a linear feature like a road, requires libgd 2.0.29 and TrueType font support. Congure should autodetect if you have a sufcient libgd and TrueType support to be able to use this feature.
WMS Server
Support for this specication is automatically enabled when you include PROJ.4 support. (with-proj) You can check this yourself by looking for the following in your congure output:
checking whether we should include WMS support... OGC WMS compatibility enabled (-DUSE_WMS).
34
Chapter 4. Installation
If, for some reason you DONT want WMS support, you can force it off by passing without-wms to your congure script. More information on using this feature is available in the WMS Server HOWTO available on the MapServer website.
WMS Client
Cascading is also supported. This allows mapserver to transparently fetch remote layers over WMS, basically acting like a client, and combine them with other layers to generate the nal map. In order to enable this feature, you will need to pass the with-wmsclient option to the congure script. MapServer will automatically look for libcurl, which is also required. To verify that the WMS Client feature is enabled, check the output from the congure script:
checking whether we should include WMS Client Connections support... OGC WMS Client Connections enabled (-DUSE_WMS_LYR).
Note that this feature is disabled by default, you have to specically request it. More information on using this feature is available in the WMS Client HOWTO available on the MapServer website. WFS support
WFS Server
Support for this specication is enabled by passing the congure script the with-wfs option. OGR and PROJ.4 support is required. You can check this yourself by looking for the following in your congure output:
checking whether we should include WFS Server support... OGC WFS Server support enabled (-DUSE_WFS_SVR).
Note that this feature is disabled by default, you have to specically request it. More information on using this feature is available in the WFS Server HOWTO available on the MapServer website.
WFS Client
MapServer can also act as a WFS client. This effectively means that MapServer reads its data from a remote servers WFS output and renders it into a map, just like it would when reading data from a shapele. In order to enable this feature, you will need to make sure you include OGR (Built with Xerces support) and PROJ.4 support, and pass the with-wfsclient option to your congure script. MapServer will automatically look for libcurl, which is also required. To verify that the WFS Client feature is enabled, check the output from the congure script:
checking whether we should include WFS Client Connections support... OGC WFS Client Connections enabled (-DUSE_WFS_LYR).
Note that this feature is disabled by default, you have to specically request it. More information on using this feature is available in the WFS Client HOWTO available on the MapServer website.
35
ArcSDE MapServer allows you to use SDE as a data source both for geometry and attributes. In order to achieve this, you must have the SDE client librairies at your disposition, and have them installed on the machine running MapServer. In order to enable SDE support in MapServer, you have to compile it with two options specied:
--with-sde=/opt/sdeexe90 --with-sde-version=90
Oracle Spatial Oracles Spatial Warehousing cartridge is also supported by MapServer. In order to connect to it, you will need to compile MapServer against the Oracle libraries by passing the with-oraclespatial argument to your congure script. You will very likely need an ORACLE_HOME environment variable set to have it congure things correctly.
--with-oraclespatial=/opt/oracle
4.1.7 Compiling
First prepare the ground by making sure all of your required and/or recommended libraries are installed before attempting to compile MapServer. This will make your life much less complicated ;). Here is the order that I usually use: 1. Compile GD. This often means acquiring libjpeg, libpng, zlib, and freetype before actually compiling the library. You shouldnt have too much trouble nding binaries of the libraries that GD requires, and often, they will already be installed with your system. On unix, Ive had very little luck nding pre-compiled binaries of the required GD library. See libgd section for notes about patching libgd if you plan to use antialiasing. 2. Compile GDAL/OGR. Describing how to compile GDAL/OGR is beyond the scope of this document. If you have requirements for lots of different formats, make sure to install those libraries rst. I often nd that building up a GDAL/OGR library often takes as long as compiling MapServer itself! 36 Chapter 4. Installation
3. Compile Proj.4. Proj.4 is a straight-forward congure/make/make install library. 4. Compile libcurl. libcurl is a straight-forward congure/make/make install library. 5. Compile/install optional libraries. These might include SDE, PostGIS, Oracle Spatial, AGG, Ming, PDFlib, or MyGIS. Mix and match as you need them. 6. Unpack the MapServer tarball and cd into the mapserver directory:
[user@host user]$ tar -zxvf mapserver-X.Y.Z.tar.gz
7. Congure your environment using congure. I often place my congure command in its own le and changes its mode to be executable (+x) to save typing and have a record of how MapServer was congured.
./configure --with-sde=/usr/sde/sdeexe90 \ --with-sde-version=90 \ --with-ogr=/usr/local/bin/gdal-config \ --with-gdal=/usr/local/bin/gdal-config \ --with-httpd=/usr/sbin/httpd \ --with-wfsclient \ --with-wmsclient \ --enable-debug \ --with-curl-config=/usr/bin/curl-config \ --with-proj=/usr/local \ --with-tiff \ --with-gd=/usr/local/ \ --with-jpeg \ --with-freetype=/usr/ \ --with-oraclespatial=/usr/oracle \ --with-threads \ --with-wcs \ --with-postgis=/usr/local/database/bin/pg_config \ --with-libiconv=/usr \ # new in 4.8 --with-geos=/usr/local/bin/geos-config \ # new in 4.8 --with-libiconv=/usr \ # new in 4.8 --with-xml2-config=/usr/bin/xml2-config \ # new in 4.10 --with-sos \ # new in 4.10 --with-agg=/path/to/agg-2.4
8. Now that you have congured your build options and selected all the libraries you wish mapserver to use, youre ready to compile the source code into an executable. This is actually quite simple, just execute make:
[user@host mapserver]$ make
9. There is no make install step in the installation of MapServer. The output of the compilation of MapServer is a binary executable that you can use in a CGI execution environment. To make sure all went well, look for the le called mapserv
[user@host mapserver]$ ls -al mapserv -rwxr-xr-x 1 user user 351177 Dec 21 11:38 mapserv
37
[user@host mapserver]$ ./mapserv This script can only be used to decode form results and should be initiated as a CGI process via a httpd server. [user@host mapserver]$
The message above is perfectly normal, and means exactly what it says. If you get anything else, something went terribly wrong.
4.1.8 Installation
MapServer binary The MapServer program itself consists of only one le, the mapserv binary executable. This is a CGI executable, meant to be called and run by your web server. In this section, we will assume you are running Apache under its default directory structure in /usr/local/apache. You may need to have privileges to edit your httpd.conf (the main apache conguration le), or have someone (such as your webmaster) help you with the conguration details. The main goal is to get the mapserv binary installed in a publicly accessible directory that is congured to run CGI programs and scripts.
File permissions
The most common problem one is likely to encounter when attempting to install the binary are permissions issues: You do not have write permissions into your web servers CGI Directory. Ask your webmaster to install the le for you. The web server gives you a 403 Permission denied error. Make sure the user the web server runs as (usually nobody) has execute permission on the binary executable. Making the le world executable is perfectly ne and safe:
[user@host cgi-bin]$ chmod o+x mapserv
Apache errors
You may receive a few different type of errors as well if your web server conguration isnt right:
38
Chapter 4. Installation
500 Internal server error: This is a fairly generic error message. All it basically tells you is that the web server was unsuccessful in running the program. You will have to consult the web servers error log to nd out more, and may need to enlist the help of your webmaster/system administrator. Where to go once youve got it compiled The An Introduction to MapServer document provides excellent coverage of getting started with MapServer.
Table of Contents Compiling on Win32 Introduction Compiling Set up a Project Directory Download MapServer Source Code and Supporting Libraries The MapServer source code Set Compilation Options Compile the Libraries Compile MapServer Compiling MapServer with PostGIS support Common Compiling Errors Installation Other Helpful Information Acknowledgements
4.2.1 Introduction
This document provides a simple set of compilation procedures for MapServer on Win32 platforms. If youve made it this far, chances are you already know about MapServer and are at least tempted to try compiling it for yourself. Pre-compiled binaries for MapServer are available from a variety of sources. Refer to Windows. Building MapServer for win32 platforms can be a daunting task, so if existing binaries are sufcient for your needs, it is strongly advised that they be used in preference to trying to build everything from source. However, there can be a variety of reasons to want to build MapServer from source on win32. Reasons include the need to enable specic options, to build with alternate versions of support libraries (such as GDAL), the desire for MapScript support not part of the core builds, the need to debug and x bugs or even to implement new features in 4.2. Compiling on Win32 39
MapServer. To make it easy for users and developers, Ive made a list of steps to compile MapServer. Background information is provided in each step, along with examples. Each example is a continuation of the previous one and in the end will produce the MapServer DLL (libmap.dll), the CGI program (the mapserv.exe), and utility programs. Warning: This document may refer to older library versions. You may want to try to use more recent library versions for your build.
4.2.2 Compiling
If you are new to Windows programming, please follow this document carefully. The compilation steps are fairly simple but Ive added a few blurbs in each step to help you understand how MapServer compiles. For the more experienced programmers, perhaps reading the README.Win32 that accompanies the MapServer source code would be more useful. For those who are antsy, compiling MapServer involves download and unpacking the source codes, editing the make les, and invoking Microsofts Visual C++ compiler from the command prompt. The resulting mapserv.exe is the CGI program that installs in the cgi-bin directory of your web server. For those who are willing to take the time, the compilation steps follow.
To go to that directory:
C:\Users> cd \Projects C:\Projects>
From the projects directory, you can extract the source codes for MapServer and its libraries. Now youre ready to download the source codes.
If you look down later in the le, you can see that once PROJ is enabled, MapServer will be linked with proj_i.lib, the PROJ.4 stub library, meaning that MapServer will be using the PROJ.DLL as opposed to statically linking in PROJ.4. 1. Uncomment the WMS option.
# Use this flag to compile with WMS Server support. # To find out more about the OpenGIS Web Map Server Specification go to # http://www.opengis.org/ WMS=-DUSE_WMS_SVR
1. Update to use GD. Heres what it should look like in our example.
GD_DIR=c:/projects/gdwin32 GD_LIB=$(GD_DIR)/bgd.lib
Note: As distributed the GDWin32 binary build does not include the bgd.lib stub library. It is necessary to run the makemsvcimport.bat script in the gdwin32 directory rst. D. Make sure the regex path is set correctly. In order for the delete command in the nmake /f makele.vc clean target to work properly it is necessary to use backslashes in the REGEX_DIR denition.
42
Chapter 4. Installation
# # # # # #
REGEX Libary VC++ does not include the REGEX library... so we must provide our one. The following definitions will try to build GNU regex-0.12 located in the regex-0.12 sub-directory. If it was not included in the source distribution, then you can get it from:
# ftp://ftp.gnu.org/pub/gnu/regex/regex-0.12.tar.gz # Provide the full path to the REGEX project directory # You do not need this library if you are compiling for PHP mapscript. # In that case the PHP regex library will be used instead !IFNDEF PHP REGEX_DIR=c:\projects\regex-0.12 !ENDIF
This creates a static library, libcurl.lib, to which you compile against. Versions newer than version 7.10.x should be compiled as dynamic library. This is accomplished using the command:
nmake /f makefile.vc6 CFG=release-dll
You will then need to edit MapServers nmake.opt to replace the CURL_LIB variable with this line:
CURL_LIB = $(CURL_DIR)/lib/libcurl_imp.lib
43
Now issue the command: nmake /f Makele.vc and wait for it to nish compiling. If it compiles successfully, you should get mapserver.lib, libmap.dll, mapserv.exe, and other .EXE les. Thats it for the compilation process. If you run into problems, read section 4 about compiling errors. You can also ask for help from the helpful folks in the MapServer-dev e-mail list.
6. Dene the following in the nmake.opt for MapServer: POSTGIS =-DUSE_POSTGIS POSTGIS_DIR =c:/projects/postgresql-8.0.1/src 7. nmake /f makele.vc 8. dont forget to copy libpq.dll (from C:projectspostgresql-8.0.1srcinterfaceslibpqrelease) into a location where MapServer can nd it.
This occurs if you have not properly dened the path and other environment variables required to use MS VisualC++ from the command shell. Invoke the VCVARS32.BAT script, usually with the command C:Program FilesMicrosoft Visual StudioVC98binvcvars32.bat or something similar if visual studio was installed in an alternate location. To test if VC++ is available, just type nmake or cl in the command shell and ensure it is found. Regex Build Problems.
regex.obj : error LNK2001: unresolved external symbol _printchar libmap.dll : fatal error LNK1120: 1 unresolved externals NMAKE : fatal error U1077: link : return code 0x460 Stop.
This occurs if you use the stock regex-0.12 we referenced. I work around this by commenting out the extern statement for the printchar() function, and replacing it with a stub implementation in regex-0.12regex.c.
//extern void printchar (); void printchar( int i ) {}
44
Chapter 4. Installation
If you are using the pre-built GD binaries, you still need to run the makemsvcimport.bat script in the gdwin32 directory to create a VC++ compatible stub library (bgd.lib).
4.2.11 Installation
The le we are most interested in is mapserv.exe. The other executable les are the MapServer utility programs. See Also: MapServer Utilities to learn more about these utilities. To test that the CGI program is working, type mapserv.exe at the command prompt. You should see the following message:
This script can only be used to decode form results and should be initiated as a CGI process via a httpd server.
You may instead get a popup indicating that a DLL (such as bgd.dll) is missing. You will need to copy all the required DLLs (ie. bgd.dll, and proj.dll) to the same directory as the mapserv.exe program. Now type mapserv -v at the command prompt to get this message:
MapServer version 4.4.0-beta3 OUTPUT=GIF OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER INPUT=SHAPEFILE DEBUG=MSDEBUG
This tells us what data formats and other options are supported by mapserv.exe. Assuming you have your web server set up, copy mapserv.exe, libmap.dll, bgd.dll, proj.dll and any other required DLLs to the cgi-bin directory. You are now ready to download the demo application and try out your own MapServer CGI program. If you wish, you can also create a directory to store the utility programs. Id suggest making a subdirectory called bin under the directory projects and copy the executables to that subdirectory. You might nd these programs useful as you develop MapServer applications.
4.2.13 Acknowledgements
Thanks to Assefa Yewondwossen for providing the Makele.vc. I would not have been able to write this HOWTO without that le.
45
Thanks to Bart van den Eijnden for the libcurl and PostGIS compilation info. Thanks to the Steve Lime for developing MapServer and to the many developers who contribute time and effort in order to keep the MapServer project successful.
Table of Contents PHP MapScript Installation Introduction Obtaining, Compiling, and Installing PHP and the PHP/MapScript Module FAQ / Common Problems
4.3.1 Introduction
The PHP/MapScript module is a PHP dynamically loadable module that makes MapServers MapScript functions and classes available in a PHP environment. The original version of MapScript (in Perl) uses SWIG, but since SWIG does not support the PHP language, the module has to be maintained separately and may not always be in sync with the Perl version. The PHP module was developed by DM Solutions Group and is currently maintained by Mapgears. This document assumes that you are already familiar with certain aspects of your operating system: For Unix/Linux users, a familiarity with the build environment, notably make. For Windows users, some compilation skills if you dont have ready access to a pre-compiled installation and need to compile your own copy of MapServer with the PHP/MapScript module. Which version of PHP is supported? PHP MapScript was originally developed for PHP-3.0.14 but after MapServer 3.5 support for PHP3 has been dropped and as of the last update of this document, PHP 4.3.11 or more recent was required (PHP5 is well supported). The best combinations of MapScript and PHP versions are: MapScript 4.10 with PHP 5.2.1 and up MapScript 4.10 with PHP 4.4.6 and up
46
Chapter 4. Installation
How to Get More Information on the PHP/MapScript Module for MapServer For a list of all classes, properties, and methods available in the module see the PHP MapScript reference document. More information on the PHP/MapScript module can be found on the PHP/MapScript page on MapTools.org. The MapServer Wiki also has PHP/MapScript build and installation notes and some php code snippets. Questions regarding the module should be forwarded to the MapServer mailing list.
4.3.2 Obtaining, Compiling, and Installing PHP and the PHP/MapScript Module
Download PHP and PHP/MapScript The PHP source or the Win32 binaries can be obtained from the PHP web site. Once you have veried that PHP is installed and is running, you need to get the latest MapServer source and compile MapServer and the PHP module. Setting Up PHP on Your Server Unix Check if you have PHP already installed (several Linux distributions have it built in). If not, see the PHP manuals Installation on Unix systems section. Windows MS4W (MapServer For Windows) is a package that contains Apache, PHP, and PHP/MapScript ready to use in a simple ziple. Several Open Source applications are also available for use in MS4W. Windows users can follow steps in the Installing Apache, PHP and MySQL on Windows tutorial to install Apache and PHP manually on their system. Window users running PWS/IIS can follow php.nets howto for installing PHP for PWS/IIS 3, PWS 4 or newer, and IIS 4 or newer. Note: When setting up PHP on Windows, make sure that PHP is congured as a CGI and not as an Apache module because php_mapscript.dll is not thread-safe and does not work as an Apache module (See the Example Steps of a Full Windows Installation section of this document). Build/Install the PHP/MapScript Module Building on a Linux Box NOTE: For UNIX users, see the README.CONFIGURE le in the MapServer source, or see the Compiling on Unix HowTo. The main MapServer congure script will automatically setup the main makele to compile php_mapscript.so if you pass the with-php=DIR argument to the congure script. Copy the php_mapscript.so library to your PHP extensions directory, and then use the dl() function to load the module at the beginning of your PHP scripts. See also the PHP function extension_loaded() to check whether an extension is already loaded. 4.3. PHP MapScript Installation 47
The le mapscript/php3/examples/phpinfo_mapscript.phtml will test that the php_mapscript module is properly installed and can be loaded. If you get an error from PHP complaining that it cannot load the library, then make sure that you recompiled and reinstalled PHP with support for dynamic libraries. On RedHat 5.x and 6.x, this means adding -rdynamic to the CLDFLAGS in the main PHP3 Makele after running ./congure Also make sure all directories in the path to the location of php_mapscript.so are at least r-x for the HTTPd user (usually nobody), otherwise dl() may complain that it cannot nd the le even if its there. Building on Windows For Windows users, it is recommended to look for a precompiled binary for your PHP version on the MapServer download page or on MapTools.org. If for some reason you really need to compile your own Windows binary then see the README.WIN32 le in the MapServer source (good luck!). Installing PHP/MapScript Simply copy the le php4_mapscript.dll to your PHP4 extensions directory (pathto/php/extensions) Using phpinfo() To verify that PHP and PHP/MapScript were installed properly, create a .php le containing the following code and try to access it through your web server:
<HTML> <BODY> <?php if (PHP_OS == "WINNT" || PHP_OS == "WIN32") { dl("php_mapscript.dll"); } else { dl("php_mapscript.so"); } phpinfo(); ?> </BODY> </HTML>
If PHP and PHP/MapScript were installed properly, several tables should be displayed on your page, and MapScript should be listed in the Extensions table. Example Steps of a Full Windows Installation Using MS4W (MapServer for Windows) 1. Download the latest MS4W base package. 2. Extract the les in the archive to the root of one of your drives (e.g. C:/ or D:/). 3. Double-click the le /ms4w/apache-install.bat to install and start the Apache Web server.
48
Chapter 4. Installation
4. In a web browser goto http://127.0.0.1. You should see an MS4W opening page. You are now running PHP, PHP/MapScript, and Apache. 5. You can now optionally install other applications that are pre-congured for MS4W, which are located on the MS4W download page. Manual Installation Using Apache Server 1. Download the Apache Web Server and extract it to the root of a directory (eg. D:/Apache). 2. Download PHP4 and extract it to your Apache folder (eg. D:/Apache/PHP4). 3. Create a temp directory to store MapServer created GIFs. NOTE: This directory is specied in the IMAGEPATH parameter of the WEB Object in the Maple reference. For this example we will call the temp directory ms_tmp (eg. E:/tmp/ms_tmp). 4. Locate the le httpd.conf in the conf directory of Apache, and open it in a text viewer (eg. TextPad, Emacs, Notepad). In the Alias section of this le, add aliases to the ms_tmp folder and any other folder you require (for this example we will use the msapps folder):
Alias Alias /ms_tmp/ /msapps/ "path/to/ms_tmp/" "path/to/msapps/"
In the ScriptAlias section of this le, add an alias for the PHP4 folder.
ScriptAlias /cgi-php4/ "pathto/apache/php4/"
In the AddType section of this le, add a type for php4 les.
AddType application/x-httpd-php4 .php
In the Action section of this le, add an action for the php.exe le.
Action application/x-httpd-php4 "/cgi-php4/php.exe"
5. Copy the le php4.ini-dist located in your Apache/php4 directory and paste it into your WindowsNT folder (eg. c:/winnt), and then rename this le to php.ini in your WindowsNT folder. 6. If you want specic extensions loaded by default, open the php.ini le in a text viewer and uncomment the appropriate extension. 7. Place the le php_mapscript.dll into your Apache/php4/extensions folder. Installation Using Microsofts IIS (please see the IIS Setup for MapServer document for uptodate steps) 1. Install IIS if required (see the IIS 4.0 installation procedure). 2. Install PHP and PHP/MapScript (see above). 3. Open the Internet Service Manager (eg. C/WINNT/system32/inetsrv/inetmgr.exe). 4. Select the Default web site and create a virtual directory (right click, select New/Virtual directory). For this example we will call the directory msapps. 5. In the Alias eld enter msapps and click Next.
49
6. Enter the path to the root of your application (eg. c:/msapps) and click Next. 7. Set the directory permissions and click Finish. 8. Select the msapps virtual directory previously created and open the directory property sheets (by right clicking and selecting properties) and then click on the Virtual directory tab. 9. Click on the Conguration button and then click the App Mapping tab. 10. Click Add and in the Executable box type: path/to/php4/php.exe %s %s. You MUST have the %s %s on the end, PHP will not function properly if you fail to do this. In the Extension box, type the le name extension to be associated with your PHP scripts. Usual extensions needed to be associated are phtml and php. You must repeat this step for each extension. 11. Create a temp directory in Explorer to store MapServer created GIFs. Note: This directory is specied in the IMAGEPATH parameter of the WEB Object in the Maple. For this example we will call the temp directory ms_tmp (eg. C:/tmp/ms_tmp). 12. Open the Internet Service Manager again. 13. Select the Default web site and create a virtual directory called ms_tmp (right click, select New/Virtual directory). Set the path to the ms_tmp directory (eg. C:/tmp/ms_tmp) . The directory permissions should at least be set to Read/Write Access.
Q Where can I nd sample scripts? A Some examples are included in directory mapserver/mapscript/php3/examples/ in the MapServer source distribution. A good one to get started is test_draw_map.phtml: its a very simple script that just draws a map, legend and scalebar in an HTML page. A good intermediate example is the PHP MapScript By Example guide (note that this document was created for an earlier MapServer version but the code might be still useful). The next example is the GMap demo. You can download the whole source and data les from the MapTools.org download page. Questions About Installation Q How can I tell that the module is properly installed on my server? A Create a le called phpinfo.phtml with the following contents:
50
Chapter 4. Installation
<?php ?>
dl("php_mapscript.so"); phpinfo();
Make sure you replace the php_mapscript.so with the name under which you installed it, it could be php_mapscript_46.so on Unix, or php_mapscript_46.dll on Windows You can then try the second test page mapserver/mapscript/php3/examples/test_draw_map.phtml. This page simply opens a MapServer .map le and inserts its map, legend, and scalebar in an HTML page. Modify the page to access one of your own MapServer .map les, and if you get the expected result, then everything is probably working ne.
Q I try to display my .phtml or .php page in my browser but the page is shown as it would it Notepad. A The problem is that your PHP installation does not recognize .phtml as a PHP le extension. Assuming youre using PHP4 under Apache then you need to add the following line with the other PHP-related AddType lines in the httpd.conf:
AddType application/x-httpd-php .phtml
For a more detailed explanation, see the Example Steps of a Full Windows Installation section of this document.
Q I installed the PROJ.4, GDAL, or one of the support libraries on my system, it is recognized by MapServers congure as a system lib but at runtime I get an error: libproj.so.0: No such le or directory. A You are probably running a RedHat Linux system if this happened to you. This happens because the libraries install themselves under /usr/local/lib but this directory is not part of the runtime library path by default on your system. (Im still surprised that congure picked proj.4 as a system lib since its not in the systems lib path...probably something magic in autoconf that well have to look into) There are a couple of possible solutions: 1. Add a setenv LD_LIBRARY_PATH to your httpd.conf to contain that directory 2. Edit /etc/ld.so.conf to add /usr/local/lib, and then run /sbin/ldcong. This will permanently add /usr/local/lib to your systems runtime lib path. 3. Congure MapServer with the following options:
--with-proj=/usr/local --enable-runpath
and the /usr/local/lib directory will be hardcoded in the exe and .so les I (Daniel Morissette) personally prefer option #2 because it is permanent and applies to everything running on your system.
Q Does PHP/MapScript have to be setup as a CGI? If so, why? A Yes, please see the PHP/MapScript CGI page in the MapServer Wiki for details.
51
Q I have compiled PHP as a CGI and when PHP tries to load the php_mapscript.so, I get an undened symbol: _register_list_destructors error. Whats wrong? A Your PHP CGI executable is probably not linked to support loading shared libraries. The MapServer congure script must have given you a message about a ag to add to the PHP Makele to enable shared libs. Edit the main PHP Makele and add -rdynamic to the LDFLAGS at the top of the Makele, then relink your PHP executable. Note: The actual parameter to add to LDFLAGS may vary depending on the system youre running on. On Linux it is -rdynamic, and on *BSD it is -export-dynamic.
Q What are the best combinations of MapScript and PHP versions? A The best combinations are: MapScript 4.10 with PHP 5.2.1 and up MapScript 4.10 with PHP 4.4.6 and up
Q I am dynamically loading gd.so and php_mapscript.so and running into problems, why? A The source of the problems could be a mismatch of GD versions. The PHP GD module compiles its own version of libgd, and if the GD library is loaded before the mapscript library, mapscript will use the php-specic version. Wherever possible you should use a gd.so built with the same GD as PHPMapScript. A workaround is to load the php_mapscript module before the GD module.
4.4.1 Compilation
Before compiling C# MapScript you should compile MapServer with the options for your requirements. For more information about the compilation of MapServer please see Win32 Compilation and Installation Guide. It is highly recommended to minimize the library dependency of your application, so when compiling MapServer enable only the features really needed. To compile the C# binding SWIG 1.3.31 or later is required. Warning: This document may refer to older library versions. You may want to try to use more recent library versions for your build.
52
Chapter 4. Installation
Win32 compilation targeting the MS.NET framework 1.1 You should compile MapServer, MapScript and all of the subsequent libraries using Visual Studio 2003. Download and uncompress the latest SWIGWIN package that contains the precompiled swig.exe Open the Visual Studio .NET 2003 Command Prompt and step into the /mapscript/csharp directory. Edit makele.vc and set the SWIG variable to the location of your swig.exe Use
nmake -f makefile.vc
to compile mapscript.dll and mapscript_csharp.dll. Win32 compilation targeting the MS.NET framework 2.0 You should compile MapServer, MapScript and all of the subsequent libraries using Visual Studio 2005. Download and uncompress the latest SWIGWIN package that contains the precompiled swig.exe Open the Visual Studio 2005 Command Prompt and step into the /mapscript/csharp directory Edit makele.vc and set the SWIG variable to the location of your swig.exe. Use
nmake -f makefile.vc
to compile mapscript.dll and mapscript_csharp.dll. Win32 compilation targeting the MONO framework Before the compilation you should download and install the recent mono Win32 setup package (eg. mono-1.1.13.2gtksharp-2.8.1-win32-1.exe) Edit makele.vc and set the CSC variable to the location of your mcs.exe. Alternatively you can dene
MONO = YES
in your nmake.opt le. You should use the same compiler for compiling MapScript as the compiler has been used for the MapServer compilation. To compile MapScript open the Command Prompt supplied with your compiler and use
nmake -f makefile.vc
to compile mapscript.dll and mapscript_csharp.dll. Alternative compilation methods on Windows Beginning from MapServer 4.8.3 you can invoke the C# compilation from the MapServer directory by uncommenting DOT_NET in nmake.opt
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # .NET/C# MapScript # ---------------------------------------------------------------------# .NET will of course only work with MSVC 7.0 and 7.1. Also note that # you will definitely want USE_THREAD defined.
53
for making the compilation an copying the targets into a common output directory. Testing the compilation For testing the compilation and the runtime environment you can use
nmake -f makefile.vc test
within the csharp directory for starting the sample applications compiled previously. Before making the test the location of the corresponding libraries should be included in the system PATH. Linux compilation targeting the MONO framework Before the compilation you should download and install the recent mono Linux package. Some distributions have precompiled binaries to install, but for using the latest version you might want to compile and install it from the source. Download and uncompress the latest SWIG release. You should probably compile it from the source if pre-compiled binaries are not available for your platform. Before compiling MapScript, MapServer should be congured and compiled. Beginning from MapServer 4.8.2 during conguration the mapscript/csharp/Makele will be created according to the conguration options. Edit this le and set the SWIG and CSC for the corresponding executable pathes if the les could not be accessed by default. To compile at a console step into the /mapscript/csharp directory use.
make
to compile libmapscript.so and mapscript_csharp.dll. For testing the compilation and the runtime environment you can use
make test
for starting the sample applications compiled previously. OSX compilation targeting the MONO framework Beginning from 4.10.0 the csharp/Makele supports the OSX builds. Before making the build the recent MONO package should be installed on the system. Before compiling MapScript, MapServer should be congured and compiled. Beginning from MapServer 4.8.2 during conguration the mapscript/csharp/Makele will be created according to the conguration options. Edit this le and set the SWIG and CSC for the corresponding executable pathes if the les could not be accessed by default. To compile at a console step into the /mapscript/csharp directory use
54
Chapter 4. Installation
make
to compile libmapscript.dylib and mapscript_csharp.dll. For testing the compilation and the runtime environment you can use
make test
for starting the sample applications compiled previously. To run the applications mapscript_csharp.dll.cong is needed along with the mapscript_csharp.dll le. This le is created during the make process
4.4.2 Installation
The les required for your application should be manually installed. It is highly recommended to copy the les into the same folder as the executable resides.
<?xml version="1.0" encoding="utf-8"?> <assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion <assemblyIdentity name="drawmap.exe" version="1.0.0.0" type="win32" /> <dependency> <dependentAssembly asmv2:dependencyType="install" asmv2:codebase="Microsoft.VC80.CRT.manifest" asmv2: <assemblyIdentity name="Microsoft.VC80.CRT" version="8.0.50608.0" publicKeyToken="1fc8b3b9a1e18e3b" p <hash xmlns="urn:schemas-microsoft-com:asm.v2"> <dsig:Transforms> <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" /> </dsig:Transforms> <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /> <dsig:DigestValue>UMOlhUBGeKRrrg9DaaPNgyhRjyM=</dsig:DigestValue> </hash> </dependentAssembly> </dependency> </assembly>
This will inform the CLR that your exe depends on the CRT and the proper assembly wrapper is to be used. If you are using the IDE the manifest le could be pregenerated by adding a reference to Microsoft.VC80.CRT.manifest within the /Microsoft Visual Studio 8/VC/redist/x86/Microsoft.VC80.CRT directory. Manifests for the dll-s must be embedded as a resource According to the windows makele the MapScript compilation target (mapscript.dll) is linked with the /MD option. In this case the VS2005 linker will generate a manifest le containing the unmanaged assembly dependency. The sample contents of the manifest le are:
55
<?xml version=1.0 encoding=UTF-8 standalone=yes?> <assembly xmlns=urn:schemas-microsoft-com:asm.v1 manifestVersion=1.0> <dependency> <dependentAssembly> <assemblyIdentity type=win32 name=Microsoft.VC80.CRT version=8.0.50608.0 processorArchitecture= </dependentAssembly> </dependency> </assembly>
Like previously mentioned if you are creating a windows application the common language runtime will search for a manifest le for the application. The name of the manifest le should be the same as the executable append and end with the .manifest extension. However if the host process is not controlled by you (like web mapping applications using aspnet_wp.exe as the host process) you will not be certain if the host process (.exe) will have a manifest containing a reference to the CRT wrapper. In this case you may have to embed the manifest into the dll as a resource using the mt tool like:
mt /manifest mapscript.dll.manifest /outputresource:mapscript.dll;#2
the common language runtime will search for the embedded resource and load the CRT assembly properly. Normally it is enough to load the CRT with the root dll (mapscript.dll), but it is not harmful embedding the manifest into the dependent libraries as well. Issue with regex and Visual Studio 2005 When compiling with Microsoft Visual Studio 2005 variable name collision may occur between regex.c and crtdefs.h. For more details see: http://trac.osgeo.org/mapserver/ticket/1651 C# MapScript library name mapping with MONO Using the MapScript interface created by the SWIG interface generator the communication between the C# wrapper classes (mapscript_csharp.dll) and the C code (mapscript.dll) takes place using platform invoke like:
[DllImport("mapscript", EntryPoint="CSharp_new_mapObj")] public static extern IntPtr new_mapObj(string jarg1);
The DllImport declaration contains the library name, however to transform the library name into a le name is platform dependent. On Windows the library name is simply appended with the .dll extension (mapscript.dll). On the Unix systems the library le name normally starts with the lib prex and appended with the .so extension (libmapscript.so). Mapping of the library name may be manually controlled using a dll.cong le. This simply maps the library le the DllImport is looking for to its unix equivalent. The le normally contains the following information (mapscript_csharp.dll.cong):
<configuration> <dllmap dll="mapscript" target="libmapscript.so" /> </configuration>
56
Chapter 4. Installation
The le should be placed along with the corresponding mapscript_csharp.dll le, and created by default during the make process. For more information see: http://trac.osgeo.org/mapserver/ticket/1596 http://www.mono-project.com/Interop_with_Native_Libraries Localization issues with MONO/Linux According to http://trac.osgeo.org/mapserver/ticket/1762 MapServer may not operate equally well on different locale settings. Especially when the decimal separator is other than . inside the locale of the process may cause parse errors when the maple contains oat numbers. Since the MONO process takes over the locale settings of the environment it is worth considering to set the default locale to C of the host process, like:
LC_ALL=C mono ./drawmap.exe ../../tests/test.map test_csharp.png
57
Table of Contents IIS Setup for MapServer Base conguration Php.ini le Internet Services Manager Under the tree for your new website - add virtual directories for Test PHP Maples for IIS Conguration les:
Some help on how to set up MapServer/Chameleon/PhpPgAdmin on Microsoft IIS (v5.0). Contains note on changes to the php.ini le and necessary changes to the MapServer maples. Please contribute or make changes as required.
4.5.2 Php.ini le
session.save_path (absolute path to your tmp directory) extension_dir (relative path to your php/extensions directory) cgi.force_redirect = 0</li> enable the pg_sql extension (php_pgsql.dll) (for Postgresql)
58
Chapter 4. Installation
Local Path: c:\ms4w\Apache\htdocs Read access + whatever else you need Execute Permissions: Scripts only Conguration button - App Mappings (Add extensions .php and .phtml, Executable is c:\ms4w\Apache\cgi-bin\php.exe,select All verbs, Script Engine, and check that le exists<br> Documents Tab Add index.phtml and index.html
Directory Security Tab Anonymous access amd authentication control Select Anonymous access and the edit button should indicate the IUSR_account Server Extensions Tab Enable authoring is selected and client scripting says Javascript
4.5.4 Under the tree for your new website - add virtual directories for
cgi-bin Under Properties, virtual directory tab Local Path should point to c:\ms4w\apache\cgi-bin. Select Read. Execute Permissions should say scripts and executables ms_tmp Under Properties, virtual directory tab Local Path should point to c:\ms4w\tmp\ms_tmp. Select Read, Write. Execute Permissions should say scripts only. This is where temporary images are written to so in the File system Security tab (use windows explorer), the c:\ms4w\tmp\ms_tmp directory should have permissions set for the Internet Guest Account (Read and execute, Read, Write, List Folder Contents). tmp Under Properties, virtual directory tab Local Path should point to c:\ms4w\tmp. Select Read, Write. Execute Permissions should say scripts only. This is where chameleon writes sessions to so in the File system Security tab (use windows explorer), the c:\ms4w\tmp directory should have permissions set for the Internet Guest Accounnt (Read and execute, Read, Write, List Folder Contents). chameleon Under Properties, virtual directory tab Local Path should point to C:\ms4w\apps\chameleon\htdocs. Select Read. Execute Permissions should say scripts only. Under the Chameleon tree, you can add virtual directories for admin (c:\ms4w\apps\chameleon\admin\htdocs), samples (c:\ms4w\apps\chameleon\samples\htdocs), cwc2 (c:\ms4w\apps\chameleon\cwc2\htdocs) phppgadmin If using postgresql/postgis, under Properties, virtual directory tab Local Path should point to C:\ms4w\Apache\htdocs\phpPgAdmin. Select Read, Write. Execute Permissions should say scripts and executables. Under Documents - add index.php. Note: We had to unzip the phppgadmin package into this directory in order to get phppgadmin to show us the login page at http://yourserver/phppgadmin/index.php. You might want additional security on this directory. gmap Good for testing purposes. Remember to change your maples as discussed in Maples for IIS below. Under Properties, virtual directory tab Local Path should point to C:\ms4w\apps\gmap\htdocs. Select Read. Execute Permissions should say scripts only.
59
Table of Contents Oracle Installation Preface System Assumptions Compile MapServer Set Environment Variables
60
Chapter 4. Installation
4.6.1 Preface
This document explains the whole conguration needed to get the connect between MapServer CGI and an Oracle database server on a linux (Ubuntu) box. The aim of this document is just to put a lot of googled knowledge in ONE place. Hopefully it will preserve many of people spending analog amount of time than I did! This manual was written, because I spent several days googling around to get my UMN having access to an oracle database. Im NOT an oracle expert, so the aim of this document is just to put a lot of googled knowledge in ONE place. Hopefully it will preserve many of people spending analog amount of time than I did! (Or: If you have the choice: Try PostGIS ;-)) Before we start, some basic knowledge, I didnt know before: MapServer can access oracle spatial as well as geodata from any oracle locator installation! Oracle locator comes with every oracle instance, there is no need for an extra license. There is no need for further installation of any packages beside oracle/oracle OCI
It is important that you know the NAME of the datasource, in this example this is MY_ORACLE and will be used further on. Done that, youre ne using User/Password@MY_ORACLE in your maple to connect to the oracle database. But rst we have to do some more stuff.
61
$ echo export ORACLE_HOME=/path/to/oracle/home >> /etc/profile # **(e.g. ORACLE_HOME=/app/oracle/ora10g) $ echo export ORACLE_BASE=path/to/oracle >> /etc/profile # **(e.g. ORACLE_HOME=/app/oracle) $ echo export ORACLE_SID=MY_ORACLE >> /etc/profile $ echo export LD_LIBRARY_PATH=path/to/oracle/home/lib >> /etc/profile # **(e.g. ORACLE_HOME=/app/oracle/ora10g/lib)
The command comes silent, so there is no system output if you didnt mistype anything! Setting the Apache Environment Sometimes it is confusing WHERE to set WHAT in the splitted apache2.conf-les. In the folder /etc/apache2/sites_available you nd your sites-le. If you did not do sth. Special e.g. installing virtual hosts, the le is named default. In this le, the apache cgi-directory is dened. Our le looks like this:
ScriptAlias /cgi-bin/ /var/www/cgi-bin/ <Directory "/var/www/cgi-bin"> AllowOverride None Options ExecCGI -MultiViews +SymLinksIfOwnerMatch Order allow,deny
62
Chapter 4. Installation
In this le, the local apache environment variables must be set. We did it within a location-block like this:
<Location "/cgi-bin/"> SetEnv ORACLE_HOME "/path/to/oracle/home" </Location></p>
Where /cgi-bin/ in the opening location block refers to the script alias /cgi-bin/ and the TNS_ADMIN directory point to the location of the tnsnames.ora le. Then restart apache:
$ /etc/init.d/apache2 force-reload
Create maple Before we start creating our maple ensure that you have a your access data (User/Password) and that you know the Oracle SRID, which could be different from the proj-EPSG! The data access parameters: CONNECTIONTYPE oraclespatial CONNECTION user/password@MY_ORACLE DATA GEOM FROM MY_LAYER USING SRID 82032 [...] Where: GEOM is the name of the geometry column MY_LAYER the name of the table 82032 is equivalent to the EPSG code 31468 (German projection system) Testing & Error handling So you are ne now. Load the maple in your application and try it. If everything goes well: Great, if not, possibly this ugly error-emssage occurs (this one cmae by querying MapServer through the WMS interface as a GetMap-request):
<ServiceExceptionReport version="1.0.1"> <ServiceException> msDrawMap(): Image handling error. Failed to draw layer named test1. msOracleSpatialLayerOpen(): OracleSpatial error. Cannot create OCI Handlers. Connection failure. Check the connection string. Error: . </ServiceException> </ServiceExceptionReport>
This points us towards, that there might be a problem with the connection to the database. First of all, lets check, if the maple is all right. Therefore we use the MapServer utility program shp2img. Lets assume you are in the directory, where you compiled MapServer and run shp2img: 4.6. Oracle Installation 63
If not, this possibly points you towards any error in your maple or in the way to access the data directly. In this case, take a look at Oracle Spatial. If there is a problem with your oracle connect, the same message as above (MsDrawMap() ...) occurs. Check your maple syntax and/or the environment settings for Oracle. For Debian/Ubuntu its worth also checking the le /etc/environment and test-wise to add the system variables comparable to System Variables If the output is OK, you may have a look at the generated image (output.png). Then your problem reduces to the access of apache to oracle home directory. Carefully check your apache conguration. Please note, that the apache.cong le differs in several linux-distributions. For this paper we talk about Ubuntu, which should be the same as Debian.
64
Chapter 4. Installation
CHAPTER
FIVE
MAPFILE
Author Steve Lime Contact steve.lime at dnr.state.mn.us Author Jeff McKenna Contact jmckenna at gatewaygeomatics.com Author Jean-Franois Doyon Contact jdoyon at ccrs.nrcan.gc.ca The Maple is the heart of MapServer. It denes the relationships between objects, points MapServer to where data are located and denes how things are to be drawn. There are some important concepts that you must understand before you can reliably use maples to congure MapServer. First is the concept of a LAYER. A layer is the combination of data plus styling. Data, in the form of attributes plus geometry, are given styling using CLASS and STYLE directives. See Also: An Introduction to MapServer for An Introduction to the Maple
5.1 CLASS
BACKGROUNDCOLOR [r] [g] [b] Color to use for non-transparent symbols. COLOR [r] [g] [b] Color to use for drawing features.
DEBUG [on|off] Enables debugging of the class object. Verbose output is generated and sent to the standard error output (STDERR) or the MapServer logle if one is set using the LOG parameter in the WEB object. See Also: MS RFC 28: Redesign of LOG/DEBUG output mechanisms
EXPRESSION [string] Four types of expressions are now supported to dene class membership. String comparisons, regular expressions, simple logical expressions, and string functions. If no expression is given, then all features are said to belong to this class. String comparisons are case sensitive and are the fastest to evaluate. No special delimiters are necessary although string must be quoted if they contain special characters. (As a matter of good habit, it is recommended you quote all strings).
65
Regular expressions function just like previous versions of MapServer. However, you must now delimit a regular expression using /regex/. No quotes should be used. Logical expressions allow you to build fairly complex tests based on one or more attributes and therefore are only available with shapeles. Logical expressions are delimited by parentheses (expression). Attribute names are delimited by square brackets [ATTRIBUTE]. These names are case sensitive and must match the items in the shapele. For example: EXPRESSION ([POPULATION] > 50000 AND [LANGUAGE] eq FRENCH) ... The following logical operators are supported: =,>,<,<=,>=,=,or,and,lt,gt,ge,le,eq,ne. As you might expect this level of complexity is slower to process. One string function exists: length(). This obviously computes the length of a string. An example follows:
EXPRESSION (length([NAME_E]) < 8)
String comparisons and regular expressions work from the classitem dened at the layer level. You may mix expression types within the different classes of a layer.
GROUP [string] Allows for grouping of classes. It is only used when a CLASSGROUP at the LAYER level is set. If the CLASSGROUP parameter is set, only classes that have the same group name would be considered at rendering time. An example of a layer with grouped classes might contain:
LAYER ... CLASSGROUP "group1" ... CLASS NAME "name1" GROUP "group1" ... END CLASS NAME "name2" GROUP "group2" ... END CLASS NAME "name3" GROUP "group1" ... END ... END # layer
KEYIMAGE [lename] Full lename of the legend image for the CLASS. This image is used when building a legend (or requesting a legend icon via MapScript or the CGI application). LABEL Signals the start of a LABEL object.
MAXSCALEDENOM [double] Maximum scale at which this CLASS is drawn. Scale is given as the denominator of the actual scale fraction, for example for a map at a scale of 1:24,000 use 24000. Implemented in MapServer 5.0, to replace the deprecated MAXSCALE parameter. See Also: Map Scale
66
Chapter 5. Maple
MAXSCALE [double] - deprecated Since MapServer 5.0 the proper parameter to use is MAXSCALEDENOM instead. The deprecated MAXSCALE is the maximum scale at which this CLASS is drawn. Scale is given as the denominator of the actual scale fraction, for example for a map at a scale of 1:24,000 use 24000. MAXSIZE [integer] Maximum size in pixels to draw a symbol. Default is 50.
MINSCALEDENOM [double] Minimum scale at which this CLASS is drawn. Scale is given as the denominator of the actual scale fraction, for example for a map at a scale of 1:24,000 use 24000. Implemented in MapServer 5.0, to replace the deprecated MINSCALE parameter. See Also: Map Scale MINSCALE [double] - deprecated Since MapServer 5.0 the proper parameter to use is MINSCALEDENOM instead. The deprecated MINSCALE is the minimum scale at which this CLASS is drawn. Scale is given as the denominator of the actual scale fraction, for example for a map at a scale of 1:24,000 use 24000. MINSIZE [integer] Minimum size in pixels to draw a symbol. Default is 0. NAME [string] Name to use in legends for this class. If not set class wont show up in legend. OUTLINECOLOR [r] [g] [b] Color to use for outlining polygons and certain marker symbols. Line symbols do not support outline colors. SIZE [integer] Height, in pixels, of the symbol/pattern to be used. Only useful with scalable symbols. For vector (and ellipse) symbol types the default size is based on the range of Y values in the POINTS dening the symbol. For pixmaps, the default is the vertical size of the image. Default size is 1 for TTF symbols. STATUS [on|off] Sets the current display status of the class. Default turns the class on. STYLE Signals the start of a STYLE object. A class can contain multiple styles. SYMBOL [integer|string|lename] The symbol name or number to use for all features if attribute tables are not used. The number is the index of the symbol in the symbol le, starting at 1, the 5th symbol in the le is therefore symbol number 5. You can also give your symbols names using the NAME keyword in the symbol denition le, and use those to refer to them. Default is 0, which results in a single pixel, single width line, or solid polygon ll, depending on layer type. You can also specify a gif or png lename. The path is relative to the location of the maple. TEMPLATE [lename] Template le or URL to use in presenting query results to the user. See Templating for more info. TEXT [string] Static text to label features in this class with. This overrides values obtained from the LABELTIEM. The string may be given as an expression delimited using the ()s. This allows you to concatenate multiple attributes into a single label. For example: ([FIRSTNAME],[LASTNAME]). You can also stack 2 symbols to achieve interesting effects. You dene the second symbol, which effectively sits on top of the symbol normally dened above. See Cartographic Symbol Construction with MapServer for more information. The following parameters allow you to dene the symbol, and they are equivalent to their non-overlay counterparts: OVERLAYBACKGROUNDCOLOR OVERLAYCOLOR OVERLAYOUTLINECOLOR
5.1. CLASS
67
5.2 Expressions
Author Dirk Tilger Contact dirk at MIRIUP.DE Author Umberto Nicoletti Contact umberto.nicoletti at gmail.com Revision $Revision: 8295 $ Date $Date: 2008-12-26 21:08:04 -0800 (Fri, 26 Dec 2008) $ Last Updated 2007/07/09
5.2.1 Introduction
As of version 4.6.1, expressions are used in two places. Theyre used to lter layers for specic records in the dataset and theyre used in CLASS EXPRESSIONs to specify to which items this CLASS does apply to.
68
Chapter 5. Maple
ltering a LAYER, both FILTERITEM and FILTER must be set. FILTERITEM is set to the attribute name. FILTER is set to the value for comparison. The same rule applies to CLASSITEM and EXPRESSION in the CLASS object. Example for a simple string comparison lter
FILTER "2005" FILTERITEM "year"
would match all records that have the attribute year set to 2005. The rendered map would appear as if the dataset would only contain those items that have the year set to 2005. Similarly, a classication for the items matched above would be done by setting the CLASSITEM in the layer and the EXPRESSION in the class
LAYER NAME "example" CLASSITEM "year" ... CLASS NAME "year-2005" EXPRESSION "2005" ... END END
For a reason explained later on the values for both CLASSITEM and FILTERITEM should start neither with an / nor with a ( character. Regular expression comparison Regular expressions are a standard text pattern matching mechanism from the UNIX world. The functionality of regular expression matching is provided by the operating system on UNIX systems and therefore slightly operating system dependent. However their minimum set of features are those dened by the POSIX standard. The documentation of the particular regular expression library is usually in the regex manual page (man regex). Regular expression with MapServer work similarly to string comparison, but allow more complex operation. They are slower than pure string comparisons, but might be still faster than logical expression. As with the string comparison use regular expressions, a FILTERITEM or a CLASSITEM has to dened, respectively. A regular expression typically consists of characters with special meanings and characters that are interpreted as they are. Alphanumeric characters (A-Z, a-z and 0-9) are taken as they are. Characters with special means are: . will match a single character [ and ] are used for grouping. For example [A-Z] would match the characters A,B,C,...,X,Y,Z. {, }, and * are used to specify how often something should match. ^ matches the beginning, $ matches the end of the value. The backslash \ is used to take away the special meaning. For example $ would match the dollar sign. The following LAYER conguration would have all records rendered on the map that have hotel in the attribute named placename
5.2. Expressions
69
Note: The regular expression is case-sensitive, thus records having Hotel in them would not have matched. Example: Match records that have a value for the current century (as of 2005 ;) in the attribute year
FILTERITEM "year" FILTER /^20[0-9][0-9]/
Example: Match all the records that are either purely numerical or empty
FILTER /^[0-9]*$/
Note: If you experience frequently segmentation faults when working with MapServer and regular expressions, it might be that your current working environment is linked against more than one regular expression library. This can happen when MapServer is linked with components that bring their own copy, like the Apache httpd or PHP. In these cases the author has made best experiences with making all those components using the regular expression library of the operating system (i.e. the one in libc). That involved editing the build les of some of the components, however.
( String1 < String2 ) ( String1 lt String2 ) ... will become true when String1 is lexicographically smaller than String2 ( String1 > String2 ) ( String1 gt String2 ) ... will become true when String1 is lexicographically larger than String2. ( String1 <= String2 ) ( String1 le String2 ) ... will become true when String1 is not lexicographically larger than String2 ( String1 >= String2 ) ( String1 ge String2 ) ... will become true when String1 is not lexicographically smaller than String2. ( String1 IN token1,token2,...,tokenN ) ... will become true when String1 is in equal one of the given tokens. Note: The separator for those tokens is the comma. That means that you must not add unnecessary white space to the list and that you cannot compare to tokens that have a comma in it. ( String1 =~ /regexp/ ) ... will become true, when String1 matches the regular expression regexp. This operation is identical to the regular expression matching described earlier. String operations that return string values There is only one operation for strings that returns a string value: String1 + String2 ... will return String1String2, thus the two string concatenated to each other. Arithmetic expressions returning logical values The basic element for the arithmetic operation is the number. There are some purely arithmetic operations that are returning numbers as their value. They will be covered in the next section. ( n1 eq n2 ) ( n1 == n2 ) ( n1 = n2 ) ... will become true when both numbers are equal. ( n1 != n2 ) ( n1 ne n2 ) ... will become true when both numbers are not equal. ( n1 < n2 ) ( n1 lt n2 ) ... will become true when n1 is smaller than n2 ( n1 > n2 ) ( n1 gt n2 ) ... will become true when n1 is larger than n2. ( n1 <= n2 ) ( n1 le n2 ) ... will become true when n1 is smaller or equal n2 ( n1 >= n2 ) ( n1 ge n2 ) ... will become true when n1 is larger or equal n2. ( n1 IN number1,number2,...,numberN ) ... will become true when n1 is equal to one of the given numbers. Arithmetic expression returning a number As stated in the previous section, MapServer can do purely numerical operations with numbers. n1 + n2 ... will become the sum of n1 and n2 n1 - n2 ... will become n2 subtracted from n1 5.2. Expressions 71
n1 * n2 ... will become n1 multiplicated with n2 n1 / n2> ... will become n1 divided by n2 -n1 ... will become n1 with negated sign n1 ^ n2 ... will become n1 by a power of n2 length ( String1 ) ... will become the number of characters of String1 Note: When the numerical operations above are used like logical operations, the following rule applies: values equal to zero will be taken as false and everything else will be true. That means the expression :: ( 6 + 5 ) ... would evaluate as true, but
( 5 - 5 ) ...
would evaluate as false. Temporal expressions MapServer uses an internal time type to do comparison. To convert a keys value into this time type it will check the list below from the top down if the specied time matches and if so, it will do the conversion. YYYY-MM-DDTHH:MM:SSZ (Z and T being the characters itself)</i> YYYY-MM-DDTHH:MM:SS (T being the character itself)</i> YYYY-MM-DD HH:MM:SS YYYY-MM-DDTHH:MM (T being the character itself)</i> YYYY-MM-DD HH:MM YYYY-MM-DDTHH (T being the character itself)</i> YYYY-MM-DD HH YYYY-MM-DD YYYY-MM YYYY THH:MM:SSZ (Z and T being the characters itself)</i> THH:MM:SS For temporal values obtained this way, the following operations are supported: ( n1 eq n2 ) ( n1 == n2 ) ( n1 = n2 ) ... will become true when both times are equal. ( t1 != t2 ) ( t1 ne t2 ) ... will become true when both times are not equal. ( t1 < t2 ) ( t1 lt t2 ) ... will become true when t1 is earlier than t2 ( t1 > t2 ) ( t1 gt t2 ) ... will become true when t1 is later than t2. ( t1 <= t2 ) ( t1 le t2 ) ... will become true when t1 is earlier or same t2 ( n1 >= n2 ) ( n1 ge n2 ) ... will become true when t1 is later or same t2. 72 Chapter 5. Maple
How the attributes are referenced To make a meaningful use of the expressions above, we need to get the attribute values into the expressions. That is done by enclosing the attribute key into square brackets, like this: [KEY]. Then before the expression is evaluated every occurrence of [KEY] will be replaced by the value for attribute KEY. Example: how a simple string comparison would be evaluated. The lter is set to:
FILTER ( "[BUILDING_NAME]" == "National Museum" )
There is a attribute BUILDING_NAME and its value is National Government Building. Thus the expression actually evaluated is...
"National Government Building" == "National Museum" )
...and as such should be false. Some layers do not really come with metadata. For raster layers for example special attributes have been dened that can be used for classication: [PIXEL] ... will become the pixel value as number [RED], [GREEN], [BLUE] ... will become the color value for the red, green and blue component in the pixel value, respectively. Quotes escaping in strings Note: Quotes escaping is not supported in MapServer versions lower than 5.0. Starting with MapServer 5.0, if your dataset contains double-quotes, you can use a C-like escape sequence in the expression string. For example if your key NAME has the value National hero statue you could write the FILTER expression as follows:
FILTER ( "[NAME]" == "National \"hero\" statue" ) ...
5.3 FEATURE
POINTS A set of xy pairs terminated with an END, for example:
POINTS 1 1 50 50 1 50 1 1 END
Note: POLYGON/POLYLINE layers POINTS must start and end with the same point (i.e. close the feature). ITEMS Comma separated list of the feature attributes:
ITEMS "value1;value2;value3"
5.3. FEATURE
73
Note: Specifying the same number of items is recommended for each features of the same layer. The item names should be specied as a PROCESSING option of the layer. TEXT [string] String to use for labeling this feature. WKT [string] A geometry expressed in OpenGIS Well Known Text geometry format. This feature is only supported if MapServer is built with OGR or GEOS support.
WKT "POLYGON((500 500, 3500 500, 3500 2500, 500 2500, 500 500))" WKT "POINT(2000 2500)"
Note: Inline features should be dened as their own layers in the maple. If another CONNECTIONTYPE is specied in the same layer, MapServer will always use the inline features to draw the layer and ignore the other CONNECTIONTYPEs.
5.4 FONTSET
Author Kari Guerts Author Jeff McKenna Contact jmckenna at gatewaygeomatics.com Revision $Revision: 8295 $ Date $Date: 2008-12-26 21:08:04 -0800 (Fri, 26 Dec 2008) $ Last Updated 2008/10/08
5.4.1 Format
The format is very simple. Each line contains 2 items: an alias and the name/path of the font separated by white space. The alias is simply the name you refer to the font as in your Maple (eg. times-bold). The name is the actual name of the TrueType le. If not full path then it is interpreted as relative to the location of the fontset. Heres the fontset I use (the font.list le and all .ttf les are stored in the same sub-directory). Note: Aliases are case sensitive. Excellent reference information about the TrueType format and online font resources is available from the FreeType.
arial arial-bold arial-italic arial-bold-italic arial_black comic_sans comic_sans-bold courier courier-bold arial.ttf arialbd.ttf ariali.ttf arialbi.ttf ariblk.ttf comic.ttf comicbd.ttf cour.ttf courbd.ttf
74
Chapter 5. Maple
courier-italic courier-bold-italic georgia georgia-bold georgia-italic georgia-bold-italic impact monotype.com recreation_symbols times times-bold times-italic times-bold-italic trebuchet_ms trebuchet_ms-bold trebuchet_ms-italic trebuchet_ms-bold-italic verdana verdana-bold verdana-italic verdana-bold-italic
couri.ttf courbi.ttf georgia.ttf georgiab.ttf georgiai.ttf georgiaz.ttf impact.ttf monotype.ttf recreate.ttf times.ttf timesbd.ttf timesi.ttf timesbi.ttf trebuc.ttf trebucbd.ttf trebucit.ttf trebucbi.ttf verdana.ttf verdanab.ttf verdanai.ttf verdanaz.ttf
5.5 INCLUDE
When this directive is encountered parsing switches to the included le immediately. As a result the included le can be comprised of any valid maple syntax. For example:
INCLUDE myLayer.map
Performance does not seem to be seriously impacted with limited use, however in high performance instances you may want to use includes in a pre-processing step to build a production maple. The C pre-processor can also be used (albeit with a different syntax) and is far more powerful.
5.5.1 Notes
Supported in versions 4.10 and higher. The name of the le to be included MUST be quoted (single or double quotes). Includes may be nested, up to 5 deep. File location can be given as a full path to the le, or (in MapServer >= 4.10.1) as a path relative to the maple. Debugging can be problematic because: 1. the le an error occurs in does not get output to the user 2. the line number counter is not reset for each le. Here is one possible error that is thrown when the include le cannot be found:
msyylex(): Unable to access file. Error opening included file "parks_include.map"
5.5. INCLUDE
75
5.5.2 Example
MAP NAME "include_mapfile" EXTENT 0 0 500 500 SIZE 250 250 INCLUDE "test_include_symbols.map" INCLUDE "test_include_layer.map" END
5.6 GRID
LABELFORMAT [DD|DDMM|DDMMSS|C format string] Format of the label. DD for degrees, DDMM for degrees minutes, and DDMMSS for degrees, minutes, seconds. A C-style formatting string is also allowed, such as %g to show decimal degrees with a degree symbol. The default is decimal display of whatever SRS youre rendering the GRID with. MINARCS [double] The minimum number of arcs to draw. Increase this parameter to get more lines. Optional.
76
Chapter 5. Maple
MAXARCS [double] The maximum number of arcs to draw. Decrease this parameter to get fewer lines. Optional. MININTERVAL [double] The minimum number of intervals to try to use. The distance between the grid lines, in the units of the grids coordinate system. Optional. MAXINTERVAL [double] The maximum number of intervals to try to use. The distance between the grid lines, in the units of the grids coordinate system. Optional. MINSUBDIVIDE [double] The minimum number of segments to use when rendering an arc. If the lines should be very curved, use this to smooth the lines by adding more segments. Optional. MAXSUBDIVIDE [double] The maximum number of segments to use when rendering an arc. If the graticule should be very straight, use this to minimize the number of points for faster rendering. Optional, default 256. The following is an example of a GRID object in use:
LAYER NAME "grid" METADATA "DESCRIPTION" "Grid" END TYPE LINE STATUS ON CLASS NAME "Graticule" COLOR 0 0 0 LABEL COLOR 255 0 0 FONT "fritqat" TYPE truetype SIZE 8 POSITION AUTO PARTIALS FALSE BUFFER 5 OUTLINECOLOR 255 255 255 END END PROJECTION "init=epsg:4326" END GRID LABELFORMAT "DDMM" # LABELFORMAT %g # dec degrees with symbol MAXARCS 10 MAXINTERVAL 10 MAXSUBDIVIDE 2 # LABELFORMAT %7.0f m # nice if a projected SRS used # MININTERVAL 20000 # MAXSUBDIVIDE 2 END END # Layer
5.6. GRID
77
5.7 JOIN
5.7.1 Description
Joins are dened within a LAYER object. It is important to understand that JOINs are ONLY available once a query has been processed. You cannot use joins to affect the look of a map. The primary purpose is to enable lookup tables for coded data (e.g. 1 => Forest) but there are other possible uses.
CONNECTIONTYPE [string] Type of connection (not required for DBF or CSV joins). The following is an example for PostgreSQL:
CONNECTIONTYPE ogr
FROM [item] Join item in the dataset. This is case sensitive. NAME [string] Unique name for this join. Required. TABLE [lename|tablename] For le-based joins this is the name of XBase or comma delimited le (relative to the location of the maple) to join TO. For PostgreSQL and MySQL support this is the name of the PostgreSQL/MySQL table to join TO. TEMPLATE [lename] Template to use with one-to-many joins. The template is processed once for each record and can only contain substitutions for items in the joined table. Refer to the column in the joined table in your template like [joinname_columnname], where joinname is the NAME specied for the JOIN object. TO [item] Join item in the table to be joined. This is case sensitive. TYPE [ONE-TO-ONE|ONE-TO-MANY] The type of join. Default is one-to-one.
78
Chapter 5. Maple
LAYER NAME "prov_bound" TYPE POLYGON STATUS DEFAULT DATA "prov.shp" CLASS NAME "Province" STYLE OUTLINECOLOR 120 120 120 COLOR 255 255 0 END END TEMPLATE "../htdocs/cgi-query-templates/prov.html" HEADER "../htdocs/cgi-query-templates/prov-header.html" FOOTER "../htdocs/cgi-query-templates/footer.html" JOIN NAME "test" TABLE "../data/lookup.dbf" FROM "ID" TO "IDENT" TYPE ONE-TO-ONE END END # layer
Ogrinfo
>ogrinfo lookup.dbf lookup -summary INFO: Open of lookup.dbf using driver ESRI Shapefile successful. Layer name: lookup Geometry: None Feature Count: 12 Layer SRS WKT: (unknown) IDENT: Integer (2.0) VAL: Integer (2.0)
>ogrinfo prov.shp prov -summary INFO: Open of prov.shp using driver ESRI Shapefile successful. Layer name: prov Geometry: Polygon Feature Count: 12 Extent: (-2340603.750000, -719746.062500) - (3009430.500000, 3836605.250000) Layer SRS WKT: (unknown) NAME: String (30.0) ID: Integer (2.0)
5.7. JOIN
79
Template
<tr bgcolor="#EFEFEF"><td align="left">[NAME]</td><td align="left">[test_VAL]</td></tr>
Ogrinfo
>ogrinfo -ro PG:"host=127.0.0.1 port=5432 user=postgres password=postgre dbname=join" lookup -summary INFO: Open of PG:host=127.0.0.1 port=5432 user=postgres password=postgres dbname=join using driver PostgreSQL successful. Layer name: lookup Geometry: Unknown (any) Feature Count: 12 Layer SRS WKT: (unknown) ident: Integer (0.0) val: Integer (0.0)
80
Chapter 5. Maple
Template
<tr bgcolor="#EFEFEF"><td align="left">[NAME]</td><td align="left">[test_val]</td></tr>
Note: When testing with MapServer 4.10.0 on Windows this postgresql join caused a mapserv.exe crash. However when testing this with a MapServer build > 4.10.0 the crash did not occur.
5.7. JOIN
81
Ogrinfo
>ogrinfo lookup.csv lookup -summary INFO: Open of lookup.csv using driver CSV successful. Layer name: lookup Geometry: None Feature Count: 12 Layer SRS WKT: (unknown) IDENT: String (0.0) VAL: String (0.0)
Template
<tr bgcolor="#EFEFEF"><td align="left">[NAME]</td><td align="left">[test_VAL]</td></tr>
5.8 LABEL
ALIGN [left|center|right] Since version 5.4 . Species text alignment for multiline labels (see WRAP) Note that the alignment algorithm is far from precise, so dont expect fabulous results (especially for right alignment) if youre not using a xed width font. ANGLE [double|auto|follow|attribute] Angle, given in degrees, to draw the label.
AUTO allows MapServer to compute the angle. Valid for LINE layers only. FOLLOW was introduced in version 4.10 and tells MapServer to compute a curved label for appropriate linear features (see MS RFC 11: Support for Curved Labels for specics). [Attribute] was introduced in version 5.0, to specify the item name in the attribute table to use for angle values. The hard brackets [] are required. For example, if your shapeles DBF has a eld named MYANGLE that holds angle values for each record, your LABEL object might contain:
LABEL COLOR 150 150 150 OUTLINECOLOR 255 255 255 FONT s a n s TYPE truetype SIZE 6 ANGLE [ M Y ANGLE] POSITION AUTO PARTIALS FALSE END
The associated RFC document for this feature is MS RFC 19: Style & Label attribute binding.
ANTIALIAS [true|false] Should text be antialiased? Note that this requires more available colors, decreases drawing performance, and results in slightly larger output images. BACKGROUNDCOLOR [r] [g] [b] Color to draw a background rectangle (i.e. billboard). Off by default. BACKGROUNDSHADOWCOLOR [r] [g] [b] Color to draw a background rectangle (i.e. billboard) shadow. Off by default. 82 Chapter 5. Maple
BACKGROUNDSHADOWSIZE [x][y] How far should the background rectangle be offset? Default is 1. BUFFER [integer] Padding, in pixels, around labels. Useful for maintaining spacing around text to enhance readability. Available only for cached labels. Default is 0. COLOR [r] [g] [b] | [attribute] Color to draw text with.
[Attribute] was introduced in version 5.0, to specify the item name in the attribute table to use for color values. The hard brackets [] are required. For example, if your shapeles DBF has a eld named MYCOLOR that holds color values for each record, your LABEL object might contain:
LABEL COLOR [ M Y COLOR] OUTLINECOLOR 255 255 255 FONT s a n s TYPE truetype SIZE 6 POSITION AUTO PARTIALS FALSE END
The associated RFC document for this feature is MS RFC 19: Style & Label attribute binding. ENCODING [string] Supported encoding format to be used for labels. If the format is not supported, the label will not be drawn. Requires the iconv library (present on most systems). The library is always detected if present on the system, but if not the label will not be drawn. Required for displaying international characters in MapServer. http://www.foss4g.org/FOSS4G/MAPSERVER/mpsnf-i18n-en.html. FONT [name] Font alias (as dened in the FONTSET) to use for labeling. FORCE [true|false] Forces labels for a particular class on, regardless of collisions. Available only for cached labels. Default is false. MAXLENGTH [integer] Introduced in mapserver 5.4, this keyword interacts with the WRAP keyword so that line breaks only occur after the dened number of characters Table 5.1: Interaction with WRAP keyword wrap = char no wrap maxlength = 0 always wrap at the WRAP character no processing maxlength > 0 newline at the rst WRAP character after MAXLENGTH characters skip label if it contains more than MAXLENGTH characters maxlength < 0 hard wrap (always break at exactly MAXLENGTH characters) hard wrap (always break at exactly MAXLENGTH characters) More information can be found at:
The associated RFC document for this feature is MS RFC 40: Support Label Text Transformations. MAXSIZE [integer] Maximum font size to use when scaling text (pixels). Default is 256. MINDISTANCE [integer] Minimum distance between duplicate labels. Given in pixels. MINFEATURESIZE [integer|auto] Minimum size a feature must be to be labeled. Given in pixels. For line data the overall length of the displayed line is used, for polygons features the smallest dimension of the bounding box is used. Auto keyword tells MapServer to only label features that are larger than their corresponding label. Available for cached labels only. MINSIZE [integer] Minimum font size to use when scaling text (pixels). Default is 4. OFFSET [x][y] Offset values for labels, relative to the lower left hand corner of the label and the label point. Given in pixels. In the case of rotated text specify the values as if all labels are horizontal and any rotation will be compensated for. 5.8. LABEL 83
[Attribute] was introduced in version 5.0, to specify the item name in the attribute table to use for color values. The hard brackets [] are required. For example, if your shapeles DBF has a eld named MYOUTCOLOR that holds color values for each record, your LABEL object might contain:
LABEL COLOR 150 150 150 OUTLINECOLOR [ M Y O U T COLOR] FONT s a n s TYPE truetype SIZE 6 POSITION AUTO PARTIALS FALSE END
The associated RFC document for this feature is MS RFC 19: Style & Label attribute binding. OUTLINEWIDTH [integer] Width of the outline if OUTLINECOLOR has been set. Defaults to 1. Currently only the AGG renderer supports values greater than 1, and renders these as a halo effect: recommended values are 3 or 5. PARTIALS [true|false] Can text run off the edge of the map? Default is true. POSITION [ul|uc|ur|cl|cc|cr|ll|lc|lr|auto] Position of the label relative to the labeling point (layers only). First letter is Y position, second letter is X position. Auto tells MapServer to calculate a label position that will not interfere with other labels. With points, MapServer selects from the 8 outer positions (i.e. excluding cc). With polygons, MapServer selects from cc (added in MapServer 5.4), uc, lc, cl and cr as possible positions. With lines, it only uses lc or uc, until it nds a position that doesnt collide with labels that have already been drawn. If all positions cause a conict, then the label is not drawn (Unless the labels FORCE a parameter is set to true). Auto placement is only available with cached labels. PRIORITY [integer]|[item_name] The priority parameter (added in v5.0) takes an integer value between 1 (lowest) and 10 (highest). The default value is 1. It is also possible to bind the priority to an attribute (item_name) using square brackets around the [item_name]. e.g. PRIORITY [someattribute] Labels are stored in the label cache and rendered in order of priority, with the highest priority levels rendered rst. Specifying an out of range PRIORITY value inside a map le will result in a parsing error. An out of range value set via MapScript or coming from a shape attribute will be clamped to the min/max values at rendering time. There is no expected impact on performance for using label priorities. SHADOWCOLOR [r] [g] [b] Color of drop shadow. SHADOWSIZE [x][y] Shadow offset in pixels. SIZE [integer]|[tiny|small|medium|large|giant]|[attribute] Text size. Use integer to give the size in pixels of your TrueType font based label, or any of the other 5 listed keywords to bitmap fonts. [Attribute] was introduced in version 5.0, to specify the item name in the attribute table to use for size values. The hard brackets [] are required. For example, if your shapeles DBF has a eld named MYSIZE that holds size values for each record, your LABEL object might contain:
LABEL COLOR 150 150 150 OUTLINECOLOR 255 255 255 FONT s a n s TYPE truetype SIZE [ M Y SIZE] POSITION AUTO PARTIALS FALSE END
84
Chapter 5. Maple
The associated RFC document for this feature is MS RFC 19: Style & Label attribute binding. TYPE [bitmap|truetype] Type of font to use. Generally bitmap fonts are faster to draw then TrueType fonts. However, TrueType fonts are scalable and available in a variety of faces. Be sure to set the FONT parameter if you select TrueType. WRAP [character] Character that represents an end-of-line condition in label text, thus resulting in a multi-line label. Interacts with MAXLENGTH for conditional line wrapping after a given number of characters
5.9 LAYER
CLASS Signals the start of a CLASS object. Inside a layer, only a single class will be used for the rendering of a feature. Each feature is tested against each class in the order in which they are dened in the maple. The rst class that matches the its min/max scale constraints and its EXPRESSION check for the current feature will be used for rendering. CLASSITEM [attribute] Item name in attribute table to use for class lookups. CLASSGROUP [string] Specify the classs group that would be considered at rendering time. The CLASS objects GROUP parameter must be used in combination with CLASSGROUP. CONNECTION [string] Database connection string to retrieve remote data. An SDE connection string consists of a hostname, instance name, database name, username and password separated by commas. A PostGIS connection string is basically a regular PostgreSQL connection string, it takes the form of user=nobody password=****** dbname=dbname host=localhost port=5432 An Oracle connection string: user/pass[@db] See Also: See Vector Data for specic connection information for various data sources. CONNECTIONTYPE [local|sde|ogr|postgis|oraclespatial|wms] Type of connection. Default is local. See additional documentation for any other type. See Also: See Vector Data for specic connection information for various data sources. DATA [lename]|[sde parameters][postgis table/column][oracle table/column] Full lename of the spatial data to process. No le extension is necessary for shapeles. Can be specied relative to the SHAPEPATH option from the Map Object. If this is an SDE layer, the parameter should include the name of the layer as well as the geometry column, i.e. mylayer,shape,myversion. If this is a PostGIS layer, the parameter should be in the form of <columnname> from <tablename>, where columnname is the name of the column containing the geometry objects and tablename is the name of the table from which the geometry data will be read. For Oracle, use shape FROM table or shape FROM (SELECT statement) or even more complex Oracle compliant queries! Note that there are important performance impacts when using spatial subqueries however. Try using MapServers FILTER whenever possible instead. You can also see the SQL submitted by forcing an error, for instance by submitting a DATA parameter you know wont work, using for example a bad column name. See Also: See Vector Data for specic connection information for various data sources. 5.9. LAYER 85
DEBUG [off|on|0|1|2|3|4|5] Enables debugging of a layer in the current map. Debugging with MapServer versions >= 5.0: Verbose output is generated and sent to the standard error output (STDERR) or the MapServer errorle if one is set using the MS_ERRORFILE environment variable. You can set the environment variable by using the CONFIG parameter at the MAP level of the maple, such as:
CONFIG "MS_ERRORFILE" "/ms4w/tmp/ms_error.txt"
You can also set the environment variable in Apache by adding the following to your httpd.conf:
SetEnv MS_ERRORFILE "/ms4w/tmp/ms_error.txt"
Once the environment variable is set, the DEBUG maple parameter can be used to control the level of debugging output. Here is a description of the possible DEBUG values: DEBUG O or OFF - only msSetError() calls are logged to MS_ERRORFILE. No msDebug() output at all. This is the default and corresponds to the original behavior of MS_ERRORFILE in MapServer 4.x DEBUG 1 or ON - includes all output from DEBUG 0 plus msDebug() warnings about common pitfalls, failed assertions or non-fatal error situations (e.g. missing or invalid values for some parameters, missing shapeles in tileindex, timeout error from remote WMS/WFS servers, etc.) DEBUG 2 - includes all output from DEBUG 1 plus notices and timing information useful for tuning maples and applications DEBUG 3 - all of DEBUG 2 plus some debug output useful in troubleshooting problems such as WMS connection URLs being called, database connection calls, etc. This is the recommended level for debugging maples. DEBUG 4 - DEBUG 3 plus even more details... DEBUG 5 - DEBUG 4 plus any msDebug() output that might be more useful to the developers than to the users. You can also set the debug level by using the MS_DEBUGLEVEL environment variable. The DEBUG setting can also be specied for the entire map, by setting the DEBUG parameter in the MAP object. For more details on this debugging mechanism, please see MS RFC 28: Redesign of LOG/DEBUG output mechanisms. Debugging with MapServer versions < 5: Verbose output is generated and sent to the standard error output (STDERR) or the MapServer logle if one is set using the LOG parameter in the WEB object. Apache users will see timing details for drawing in Apaches error_log le. Requires MapServer to be built with the DEBUG=MSDEBUG option (with-debug congure option). DUMP [true|false] Switch to allow MapServer to return data in GML format. Useful when used with WMS GetFeatureInfo operations. false by default. EXTENT [minx] [miny] [maxx] [maxy] The spatial extent of the data. In most cases you will not need to specify this, but it can be used to avoid the speed cost of having MapServer compute the extents of the data. An application can also possibly use this value to override the extents of the map. FEATURE Signals the start of a FEATURE object. FILTER [string] This parameter allows for data specic attribute ltering that is done at the same time spatial ltering is done, but before any CLASS expressions are evaluated. For OGR and shapeles the string is simply a mapserver regular expression. For spatial databases the string is a SQL WHERE clause that is valid with respect to the underlying database. For example: FILTER type=road and size <2 86 Chapter 5. Maple
FILTERITEM [attribute] Item to use with simple FILTER expressions. OGR and shapeles only. FOOTER [lename] Template to use after a layers set of results have been sent. Multiresult query modes only. GRID Signals the start of a GRID object. GROUP [name] Name of a group that this layer belongs to. The group name can then be reference as a regular layer name in the template les, allowing to do things like turning on and off a group of layers at once. HEADER [lename] Template to use before a layers set of results have been sent. Multiresult query modes only. JOIN Signals the start of a JOIN object. LABELANGLEITEM [attribute] (As of MapServer 5.0 this parameter is no longer available. Please see the LABEL objects ANGLE parameter) For MapServer versions < 5.0, this is the item name in attribute table to use for class annotation angles. Values should be in degrees. Deprecated since version 5.0. LABELCACHE [on|off] Species whether labels should be drawn as the features for this layer are drawn, or whether they should be cached and drawn after all layers have been drawn. Default is on. Label overlap removal, auto placement etc... are only available when the label cache is active. LABELITEM [attribute] Item name in attribute table to use for class annotation (i.e. labeling).
LABELMAXSCALEDENOM [double] Maximum scale at which this LAYER is labeled. Scale is given as the denominator of the actual scale fraction, for example for a map at a scale of 1:24,000 use 24000. Implemented in MapServer 5.0, to replace the deprecated LABELMAXSCALE parameter. See Also: Map Scale LABELMAXSCALE [double] - deprecated Since MapServer 5.0 the proper parameter to use is LABELMAXSCALEDENOM instead. The deprecated LABELMAXSCALE is the maximum scale at which this LAYER is labeled. Scale is given as the denominator of the actual scale fraction, for example for a map at a scale of 1:24,000 use 24000. Deprecated since version 5.0.
LABELMINSCALEDENOM [double] Minimum scale at which this LAYER is labeled. Scale is given as the denominator of the actual scale fraction, for example for a map at a scale of 1:24,000 use 24000. Implemented in MapServer 5.0, to replace the deprecated LABELMINSCALE parameter. See Also: Map Scale LABELMINSCALE [double] - deprecated Since MapServer 5.0 the proper parameter to use is LABELMINSCALEDENOM instead. The deprecated LABELMINSCALE is the minimum scale at which this LAYER is labeled. Scale is given as the denominator of the actual scale fraction, for example for a map at a scale of 1:24,000 use 24000. Deprecated since version 5.0. LABELREQUIRES [expression] Sets context for labeling this layer, for example:
LABELREQUIRES "![orthoquads]"
means that this layer would NOT be labeled if a layer named orthoquads is on. The expression consists of a boolean expression based on the status of other layers, each [layer name] substring is replaced by a 0 or a 1 depending on that layers STATUS and then evaluated as normal. Logical operators AND and OR can be used.
5.9. LAYER
87
LABELSIZEITEM [attribute] (As of MapServer 5.0 this parameter is no longer available. Please see the LABEL objects SIZE parameter) For MapServer versions < 5.0, this is the item name in attribute table to use for class annotation sizes. Values should be in pixels. Deprecated since version 5.0. MAXFEATURES [integer] Species the number of features that should be drawn for this layer in the CURRENT window. Has some interesting uses with annotation and with sorted data (i.e. lakes by area).
MAXSCALEDENOM [double] Maximum scale at which this LAYER is drawn. Scale is given as the denominator of the actual scale fraction, for example for a map at a scale of 1:24,000 use 24000. Implemented in MapServer 5.0, to replace the deprecated MAXSCALE parameter. See Also: Map Scale MAXSCALE [double] - deprecated Since MapServer 5.0 the proper parameter to use is MAXSCALEDENOM instead. The deprecated MAXSCALE is the maximum scale at which this LAYER is drawn. Scale is given as the denominator of the actual scale fraction, for example for a map at a scale of 1:24,000 use 24000. Deprecated since version 5.0. METADATA This keyword allows for arbitrary data to be stored as name value pairs. This is used with OGC WMS to dene things such as layer title. It can also allow more exibility in creating templates, as anything you put in here will be accessible via template tags. Example:
METADATA title "My layer title" a u t h or "Me!" END
MINSCALEDENOM [double] Minimum scale at which this LAYER is drawn. Scale is given as the denominator of the actual scale fraction, for example for a map at a scale of 1:24,000 use 24000. Implemented in MapServer 5.0, to replace the deprecated MINSCALE parameter. See Also: Map Scale MINSCALE [double] - deprecated Since MapServer 5.0 the proper parameter to use is MINSCALEDENOM instead. The deprecated MINSCALE is the minimum scale at which this LAYER is drawn. Scale is given as the denominator of the actual scale fraction, for example for a map at a scale of 1:24,000 use 24000. Deprecated since version 5.0. NAME [string] Short name for this layer. Limit is 20 characters. This name is the link between the maple and web interfaces that refer to this name. They must be identical. The name should be unique, unless one layer replaces another at different scales. Use the GROUP option to associate layers with each other. OFFSITE [r] [g] [b] Sets the color index to treat as transparent for raster layers. OPACITY [integer|alpha] Sets the opacity level (or the inability to see through the layer) of all classed pixels for a given layer. The value can either be an integer in the range (0-100) or the named symbol ALPHA. A value of 100 is opaque and 0 is fully transparent. Implemented in MapServer 5.0, to replace the deprecated TRANSPARENCY parameter. The ALPHA symbol directs the MapServer rendering code to honor the indexed or alpha transparency of pixmap symbols used to style a layer. This is only needed in the case of RGB output formats, and should be used only when necessary as it is expensive to render transparent pixmap symbols onto an RGB map image. 88 Chapter 5. Maple
POSTLABELCACHE [true|false] Tells MapServer to render this layer after all labels in the cache have been drawn. Useful for adding neatlines and similar elements. Default is false.
PROCESSING [string] Passes a processing directive to be used with this layer. The supported processing directives vary by layer type, and the underlying driver that processes them. Attributes Directive - The ITEMS processing option allows to specify the name of attributes for inline layers or specify the subset of the attributes to be used by the layer, such as:
PROCESSING "ITEMS=itemname1,itemname2,itemname3"
Connection Pooling Directive - This is where you can enable connection pooling for certain layer layer types. Connection pooling will allow MapServer to share the handle to an open database or layer connection throughout a single map draw process. Additionally, if you have FastCGI enabled, the connection handle will stay open indenitely, or according to the options specied in the FastCGI conguration. Oracle Spatial, ArcSDE, OGR and PostGIS/PostgreSQL currently support this approach.
PROCESSING "CLOSE_CONNECTION=DEFER"
OGR Styles Directive - This directive can be used for obtaining label styles through MapScript. For more information see the MapServers OGR document.
PROCESSING "GETSHAPE_STYLE_ITEMS=all"
Raster Directives - All raster processing options are described in Raster Data. Here we see the SCALE and BANDs directives used to autoscale raster data and alter the band mapping.
PROCESSING "SCALE=AUTO" PROCESSING "BANDS=3,2,1"
PROJECTION Signals the start of a PROJECTION object. REQUIRES [expression] Sets context for displaying this layer (see LABELREQUIRES). SIZEUNITS [pixels|feet|inches|kilometers|meters|miles| Sets the unit of CLASS object SIZE values (default is pixels). Useful for simulating buffering. STATUS [on|off|default] Sets the current status of the layer. Often modied by MapServer itself. Default turns the layer on permanently. Note: In CGI mode, layers with STATUS DEFAULT cannot be turned off using normal mechanisms. It is recommended to set layers to STATUS DEFAULT while debugging a problem, but set them back to ON/OFF in normal use. Note: For WMS, layers in the server maple with STATUS DEFAULT are always sent to the client. STYLEITEM [attribute] Item to use for feature specic styling. This is very experimental and OGR only at the moment.
SYMBOLSCALEDENOM [double] The scale at which symbols and/or text appear full size. This allows for dynamic scaling of objects based on the scale of the map. If not set then this layer will always appear at the same size. Scaling only takes place within the limits of MINSIZE and MAXSIZE as described above. Scale is given as the denominator of the actual scale fraction, for example for a map at a scale of 1:24,000 use 24000. Implemented in MapServer 5.0, to replace the deprecated SYMBOLSCALE parameter. See Also: Map Scale
5.9. LAYER
89
SYMBOLSCALE [double] - deprecated Since MapServer 5.0 the proper parameter to use is SYMBOLSCALEDENOM instead. The deprecated SYMBOLSCALE is the scale at which symbols and/or text appear full size. This allows for dynamic scaling of objects based on the scale of the map. If not set then this layer will always appear at the same size. Scaling only takes place within the limits of MINSIZE and MAXSIZE as described above. Scale is given as the denominator of the actual scale fraction, for example for a map at a scale of 1:24,000 use 24000. Deprecated since version 5.0. TEMPLATE [le|url] Used as a global alternative to CLASS TEMPLATE. TILEINDEX [lename|layername] Name of the tileindex le or layer. A tileindex is similar to an ArcInfo library index. The tileindex contains polygon features for each tile. The item that contains the location of the tiled data is given using the TILEITEM parameter. When a le is used as the tileindex for shapele or raster layers, the tileindex should be a shapele. For CONNECTIONTYPE OGR layers, any OGR supported datasource can be a tileindex. Normally the location should contain the path to the tile le relative to the shapepath, not relative to the tileindex itself. If the DATA parameter contains a value then it is added to the end of the location. When a tileindex layer is used, it works similarly to directly referring to a le, but any supported feature source can be used (ie. postgres, oracle). Note: All les in the tileindex should have the same coordinate system, and for vector les the same set of attributes in the same order. TILEITEM [attribute] Item that contains the location of an individual tile, default is location. TOLERANCE [double] Sensitivity for point based queries (i.e. via mouse and/or map coordinates). Given in TOLERANCEUNITS. If the layer is a POINT or a LINE, the default is 3. For all other layer types, the default is 0. To restrict polygon searches so that the point must occur in the polygon set the tolerance to zero. TOLERANCEUNITS [pixels|feet|inches|kilometers|meters|miles|dd] Units of the TOLERANCE value. Default is pixels. TRANSPARENCY [integer|alpha] - deprecated Since MapServer 5.0 the proper parameter to use is OPACITY. The deprecated TRANSPARENCY parameter sets the transparency level of all classed pixels for a given layer. The value can either be an integer in the range (0-100) or the named symbol ALPHA. Although this parameter is named transparency, the integer values actually parameterize layer opacity. A value of 100 is opaque and 0 is fully transparent. The ALPHA symbol directs the MapServer rendering code to honor the indexed or alpha transparency of pixmap symbols used to style a layer. This is only needed in the case of RGB output formats, and should be used only when necessary as it is expensive to render transparent pixmap symbols onto an RGB map image. Deprecated since version 5.0. See Also: OPACITY TRANSFORM [true|false ul|uc|ur|lc|cc|lr|ll|lc|lr] Tells MapServer whether or not a particular layer needs to be transformed from some coordinate system to image coordinates. Default is true. This allows you to create shapeles in image/graphics coordinates and therefore have features that will always be displayed in the same location on every map. Ideal for placing logos or text in maps. Remember that the graphics coordinate system has an origin in the upper left hand corner of the image, contrary to most map coordinate systems. Version 4.10 introduces the ability to dene features with coordinates given in pixels (or percentages, see UNITS), most often inline features, relative to something other than the UL corner of an image. That is what TRANSFORM FALSE means. By setting an alternative origin it allows you to anchor something like a copyright statement to another portion of the image in a way that is independent of image size. TYPE [point|line|polygon|circle|annotation|raster|query|chart] Species how the data should be drawn. Need not be the same as the shapele type. For example, a polygon shapele may be drawn as a point layer, but a point shapele may not be drawn as a polygon layer. Common sense rules. Annotation means that a label point will be calculated for the features, but the feature itself will not be drawn although a marker symbol can be 90 Chapter 5. Maple
optionally drawn. this allows for advanced labeling like numbered highway shields. Points are labeled at that point. Polygons are labeled rst using a centroid, and if that doesnt fall in the polygon a scanline approach is used to guarantee the label falls within the feature. Lines are labeled at the middle of the longest arc in the visible portion of the line. Query only means the layer can be queried but not drawn. In order to differentiate between POLYGONs and POLYLINEs (which do not exist as a type), simply respectively use or omit the COLOR keyword when classifying. If you use it, its a polygon with a ll color, otherwise its a polyline with only an OUTLINECOLOR. A circle must be dened by a a minimum bounding rectangle. That is, two points that dene the smallest square that can contain it. These two points are the two opposite corners of said box. The following is an example using inline points to draw a circle:
LAYER NAME inline_circles TYPE CIRCLE STATUS ON FEATURE POINTS 74.01 -53.8 110.7 -22.16 END END CLASS STYLE COLOR 0 0 255 END END END
See Also: For CHART layers, see the Dynamic Charting HowTo. UNITS [feet|inches|kilometers|meters|miles|dd|pixels|percentages] Units of the layer. Percentages was added in MapServer 4.10 and is mostly geared for inline features.
5.10 LEGEND
The size of the legend image is NOT known prior to creation so be careful not to hard-code width and height in the <IMG> tag in the template le. IMAGECOLOR [r] [g] [b] Color to initialize the legend with (i.e. the background). INTERLACE [on|off] Default is [on]. This keyword is now deprecated in favor of using the FORMATOPTION INTERLACE=ON line in the OUTPUTFORMAT declaration. Deprecated since version 4.6. LABEL Signals the start of a LABEL object OUTLINECOLOR [r] [g] [b] Color to use for outlining symbol key boxes. POSITION [ul|uc|ur|ll|lc|lr] Where to place an embedded legend in the map. Default is lr. KEYSIZE [x][y] Size of symbol key boxes in pixels. Default is 20 by 10. KEYSPACING [x][y] Spacing between symbol key boxes ([y]) and labels ([x]) in pixels. Default is 5 by 5. POSTLABELCACHE [true|false] Tells MapServer to render this legend after all labels in the cache have been drawn. Useful for adding neatlines and similar elements. Default is false. 5.10. LEGEND 91
STATUS [on|off|embed] Is the legend image to be created. TEMPLATE [lename] HTML legend template le. See Also: HTML Legends with MapServer TRANSPARENT [on|off] Should the background color for the legend be transparent. This ag is now deprecated in favor of declaring transparency within OUTPUTFORMAT declarations. Default is off. Deprecated since version 4.6.
5.11 MAP
ANGLE [double] Angle, given in degrees, to rotate the map. Default is 0. The rendered map will rotate in a clockwise direction. The following are important notes: Requires a PROJECTION object specied at the MAP level and for each LAYER object (even if all layers are in the same projection). Requires MapScript (SWIG, PHP MapScript). Does not work with CGI mode. If using the LABEL objects ANGLE or the LAYER objects LABELANGLEITEM parameters as well, these parameters are relative to the maps orientation (i.e. they are computed after the MAP objects ANGLE). For example, if you have specied an ANGLE for the map of 45, and then have a layer LABELANGLEITEM value of 45, the resulting label will not appear rotated (because the resulting map is rotated clockwise 45 degrees and the label is rotated counter-clockwise 45 degrees). More information can be found on the MapRotation Wiki Page.
CONFIG [key] [value] This can be used to specify several values at run-time, for both MapServer and GDAL/OGR libraries. Developers: values will be passed on to CPLSetCongOption(). Details on GDAL/OGR options are found in their associated driver documentation pages (GDAL/OGR). The following options are available specically for MapServer: CGI_CONTEXT_URL [value] The CONFIG parameter can be used to enable loading a map context from a URL. See the Map Context HowTo for more info. MS_ENCRYPTION_KEY [lename] The CONFIG parameter can be used to specify an encryption key that is used with MapServers msencypt utility. MS_ERRORFILE [lename] The CONFIG parameter can be used to write MapServer errors to a le (as of MapServer 5.0). A full path (absolute reference) is required, including the lename. For more on this see the DEBUG parameter below. MS_NONSQUARE [yes|no] The CONFIG parameter can be used to allow non-square WMS requests. MS_PROJ_LIB [path] The CONFIG parameter can be used to dene the location of your EPSG les. For more info see the PROJ_LIB parameter below. ON_MISSING_DATA [FAIL|LOG|IGNORE] The CONFIG parameter can be used to tell MapServer how to handle missing data in tile indexes (as of MapServer 5.3-dev, r8015). Previous MapServer versions required a compile-time switch (IGNORE_MISSING_DATA), but this is no longer required. FAIL This will cause MapServer to throw an error and exit (to crash, in other words) on a missing le in a tile index. This is the default.
CONFIG "ON_MISSING_DATA" "FAIL"
LOG This will cause MapServer to log the error message for a missing le in a tile index, and continue with the map creation. Note: DEBUG parameter and CONFIG MS_ERRORFILE need to be set for logging to occur, so please see the DEBUG parameter below for more information. 92 Chapter 5. Maple
IGNORE This will cause MapServer to not report or log any errors for missing les, and map creation will occur normally.
CONFIG "ON_MISSING_DATA" "IGNORE"
PROJ_LIB [path] The CONFIG parameter can be used to dene the location of your EPSG les for the Proj.4 library. Setting the [key] to PROJ_LIB and the [value] to the location of your EPSG les will force PROJ.4 to use this value. Using CONFIG allows you to avoid setting environment variables to point to your PROJ_LIB directory. Here are some examples: 1. Unix
CONFIG "PROJ_LIB" "/usr/local/share/proj/"
2. Windows
CONFIG "PROJ_LIB" "C:/somedir/proj/nad/"
DATAPATTERN [regular expression] This denes a regular expression to be applied to requests to change DATA parameters via URL requests (i.e. map_layername_data=...). If a pattern doesnt exist then web users cant monkey with support les via URLs. This allows you to isolate one application from another if you desire, with the default operation being very conservative. See also TEMPLATEPATTERN. DEBUG [off|on|0|1|2|3|4|5] Enables debugging of all of the layers in the current map. Debugging with MapServer versions >= 5.0: Verbose output is generated and sent to the standard error output (STDERR) or the MapServer errorle if one is set using the MS_ERRORFILE environment variable. You can set the environment variable by using the CONFIG parameter at the MAP level of the maple, such as:
CONFIG "MS_ERRORFILE" "/ms4w/tmp/ms_error.txt"
You can also set the environment variable in Apache by adding the following to your httpd.conf:
SetEnv MS_ERRORFILE "/ms4w/tmp/ms_error.txt"
Once the environment variable is set, the DEBUG maple parameter can be used to control the level of debugging output. Here is a description of the possible DEBUG values: DEBUG O or OFF - only msSetError() calls are logged to MS_ERRORFILE. No msDebug() output at all. This is the default and corresponds to the original behavior of MS_ERRORFILE in MapServer 4.x DEBUG 1 or ON - includes all output from DEBUG 0 plus msDebug() warnings about common pitfalls, failed assertions or non-fatal error situations (e.g. missing or invalid values for some parameters, missing shapeles in tileindex, timeout error from remote WMS/WFS servers, etc.) DEBUG 2 - includes all output from DEBUG 1 plus notices and timing information useful for tuning maples and applications DEBUG 3 - all of DEBUG 2 plus some debug output useful in troubleshooting problems such as WMS connection URLs being called, database connection calls, etc. This is the recommended level for debugging maples. DEBUG 4 - DEBUG 3 plus even more details... DEBUG 5 - DEBUG 4 plus any msDebug() output that might be more useful to the developers than to the users.
5.11. MAP
93
You can also set the debug level by using the MS_DEBUGLEVEL environment variable. The DEBUG setting can also be specied for a layer, by setting the DEBUG parameter in the LAYER object. For more details on this debugging mechanism, please see MS RFC 28: Redesign of LOG/DEBUG output mechanisms. Debugging with MapServer versions < 5: Verbose output is generated and sent to the standard error output (STDERR) or the MapServer logle if one is set using the LOG parameter in the WEB object. Apache users will see timing details for drawing in Apaches error_log le. Requires MapServer to be built with the DEBUG=MSDEBUG option (with-debug congure option). EXTENT [minx] [miny] [maxx] [maxy] The spatial extent of the map to be created. In most cases you will need to specify this, although MapServer can sometimes (expensively) calculate one if it is not specied. FONTSET [lename] Filename of fontset le to use. Can be a path relative to the maple, or a full path. IMAGECOLOR [r] [g] [b] Color to initialize the map with (i.e. background color). When transparency is enabled (TRANSPARENT ON) for the typical case of 8-bit pseudocolored map generation, this color will be marked as transparent in the output le palette. Any other map components drawn in this color will also be transparent, so for map generation with transparency it is best to use an otherwise unused color as the background color. IMAGEQUALITY [int] Deprecated Use FORMATOPTION QUALITY=n in the OUTPUTFORMAT declaration to specify compression quality for JPEG output. Deprecated since version 4.6. IMAGETYPE [gif|png|jpeg|wbmp|gtiff|swf|userdened] Output format to generate. See details in the OUTPUTFORMAT section for available formats. The name here must match the NAME of a user dened or internally generated OUTPUTFORMAT section. INTERLACE [on|off] Deprecated Use FORMATOPTION INTERLACE=ON in the OUTPUTFORMAT declaration to specify if the output images should be interlaced. Deprecated since version 4.6. LAYER Signals the start of a LAYER object. LEGEND Signals the start of a LEGEND object. MAXSIZE [integer] Sets the maximum size of the map image. This will override the default value. For example, setting this to 2048 means that you can have up to 2048 pixels in both dimensions (i.e. max of 2048x2048). NAME [name] Prex attached to map, scalebar and legend GIF lenames created using this maple. It should be kept short. PROJECTION Signals the start of a PROJECTION object. QUERYMAP Signals the start of a QUERYMAP object. REFERENCE Signals the start of a REFERENCE MAP object. RESOLUTION [int] Sets the pixels per inch for output, only affects scale computations and nothing else, default is 72.
SCALEDENOM [double] Computed scale of the map. Set most often by the application. Scale is given as the denominator of the actual scale fraction, for example for a map at a scale of 1:24,000 use 24000. Implemented in MapServer 5.0, to replace the deprecated SCALE parameter. See Also: Map Scale
94
Chapter 5. Maple
SCALE [double] - deprecated Since MapServer 5.0 the proper parameter to use is SCALEDENOM instead. The deprecated SCALE is the computed scale of the map. Set most often by the application. Scale is given as the denominator of the actual scale fraction, for example for a map at a scale of 1:24,000 use 24000. Deprecated since version 5.0. SCALEBAR Signals the start of a SCALEBAR object. SHAPEPATH [lename] Path to the directory holding the shapeles or tiles. There can be further subdirectories under SHAPEPATH. SIZE [x][y] Size in pixels of the output image (i.e. the map). STATUS [on|off] Is the map active? Sometimes you may wish to turn this off to use only the reference map or scale bar. SYMBOLSET [lename] Filename of the symbolset to use. Can be a path relative to the maple, or a full path. SYMBOL Signals the start of a SYMBOL object. TEMPLATEPATTERN [regular expression] This denes a regular expression to be applied to requests to change TEMPLATE parameters via URL requests (i.e. map_layername_template=...). If a pattern doesnt exist then web users cant monkey with support les via URLs. This allows you to isolate one application from another if you desire, with the default operation being very conservative. See also DATAPATTERN. TRANSPARENT [on|off] Use FORMATOPTION TRANSPARENT=ON in the OUTPUTFORMAT declaration to specify if the output images should be transparent. Deprecated since version 4.6. UNITS [feet|inches|kilometers|meters|miles|dd] Units of the map coordinates. Used for scalebar and scale computations. WEB Signals the start of a WEB object.
5.12 OUTPUTFORMAT
A map le may have zero, one or more OUTPUTFORMAT object declarations, dening available output formats supported including formats like PNG, GIF, JPEG, GeoTIFF and Flash (SWF). If OUTPUTFORMAT sections declarations are not found in the map le, the following implicit declarations will be made. Only those for which support is compiled in will actually be available. The GeoTIFF depends on building with GDAL support, and the Flash (SWF) depends on compiling with support for the MING library.
OUTPUTFORMAT NAME a g g p n g 24 DRIVER AGG/PNG MIMETYPE "image/png" IMAGEMODE RGB EXTENSION "png" END OUTPUTFORMAT NAME gif DRIVER "GD/GIF" MIMETYPE "image/gif" IMAGEMODE PC256 EXTENSION "gif" END OUTPUTFORMAT NAME png
5.12. OUTPUTFORMAT
95
DRIVER "GD/PNG" MIMETYPE "image/png" IMAGEMODE PC256 EXTENSION "png" END OUTPUTFORMAT NAME jpeg DRIVER "GD/JPEG" MIMETYPE "image/jpeg" IMAGEMODE RGB EXTENSION "jpg" END OUTPUTFORMAT NAME wbmp DRIVER "GD/WBMP" MIMETYPE "image/wbmp" IMAGEMODE PC256 EXTENSION "wbmp" END OUTPUTFORMAT NAME swf DRIVER "SWF" MIMETYPE "application/x-shockwave-flash" EXTENSION "swf" IMAGEMODE PC256 FORMATOPTION "OUTPUT_MOVIE=SINGLE" END OUTPUTFORMAT NAME GTiff DRIVER "GDAL/GTiff" MIMETYPE "image/tiff" IMAGEMODE RGB EXTENSION "tif" END
NAME [name] The name to use use in the IMAGETYPE keyword of the map le to select this output format.(optional) DRIVER [name] The name of the driver to use to generate this output format. Some driver names include the denition of the format if the driver supports multiple formats. For AGG, the possbile driver names are AGG/PNG and AGG/JPEG. For GD the possible driver names are GD/Gif, GD/PNG, GD/WBMP and GD/JPEG. For ash the driver is just called SWF. For output through GDAL the GDAL shortname for the format is appended, such as GDAL/GTiff. Note that PNG, JPEG and GIF output can be generated with either GDAL or GD (GD is generally more efcient).(mandatory) IMAGEMODE [PC256/RGB/RGBA/INT16/FLOAT32] Selects the imaging mode in which the output is generated. Does matter for non-raster formats like Flash. Not all formats support all combinations. For instance GD/GIF supports only PC256. (optional) PC256: Produced a pseudocolored result with up to 256 colors in the palette (traditional MapServer mode) RGB: Render in 24bit Red/Green/Blue mode. Supports all colors but does not support transparency. RGBA: Render in 32bit Red/Green/Blue/Alpha mode. Supports all colors, and alpha based transparency. All features are rendered against an initially transparent background. BYTE: Render raw 8bit pixel values (no presentation). Only works for RASTER layers (through GDAL) and WMS layers currently.
96
Chapter 5. Maple
INT16: Render raw 16bit signed pixel values (no presentation). Only works for RASTER layers (through GDAL) and WMS layers currently. FLOAT32: Render raw 32bit oating point pixel values (no presentation). Only works for RASTER layers (through GDAL) and WMS layers currently. MIMETYPE [type] Provide the mime type to be used when returning results over the web. (optional) EXTENSION [type] Provide the extension to use when creating les of this type. (optional) TRANSPARENT [ON/OFF] Indicates whether transparency should be enabled for this format. Note that transparency does not work for IMAGEMODE RGB output. Not all formats support transparency (optional). When transparency is enabled for the typical case of 8-bit pseudocolored map generation, the IMAGECOLOR color will be marked as transparent in the output le palette. Any other map components drawn in this color will also be transparent, so for map generation with transparency it is best to use an otherwise unused color as the background color. FORMATOPTION [option] Provides a driver or format specic option. Zero or more FORMATOPTION statement may be present within a OUTPUTFORMAT declaration. (optional) GD/JPEG: The QUALITY=n option may be used to set the quality of jpeg produced (value from 0-100). GD/PNG: The INTERLACE=[ON/OFF] option may be used to turn interlacing on or off. GD/GIF: The INTERLACE=[ON/OFF] option may be used to turn interlacing on or off. GDAL/GTiff: Supports the TILED=YES, BLOCKXSIZE=n, BLOCKYSIZE=n, INTERLEAVE=[PIXEL/BAND] and COMPRESS=[NONE,PACKBITS,JPEG,LZW,DEFLATE] format specic options. GDAL/*: All FORMATOPTIONs are passed onto the GDAL create function. Options supported by GDAL are described in the detailed documentation for each GDAL format GD/PNG and AGG/PNG both support quantizing from 24/32 bits to 8bits, in order to reduce the nal image size (and therefore save bandwidth) (see also http://trac.osgeo.org/mapserver/ticket/2436#comment:4 for strategies when applying these options): QUANTIZE_FORCE=on used to reduce an RGB or RGBA image into an 8bit (or less) paletted images. The colors used in the palette are selected to best t the actual colors in the RGB image (RGBA quantization was introduced in mapserver 5.2, and requires the enable-experimental-png ag to be used when conguring) QUANTIZE_COLORS=256 used to specify the number of colors to be used when applying quantization. Maximum value is 256. Specifying anything between 17 and 255 is probably a waste of quality as each pixel is still encoded with a full byte. Specifying a value under 16 will produce tiny images, but severly degraded. QUANTIZE_NEW=on used to force using a slower but higher quality quantization algorithm for RGB images. The default behavior is to use a fast but crude quantization algorithm, that usually results in duplicate entries in the palette, and visible artifacts when tiling. PALETTE_FORCE=on is used to reduce image depth with a predened palette. This option is incompatible with the previous quantization options. PALETTE=/path/to/palette.txt is used to dene the absolute path where palette colors can be found. This le must contain 256 entries of r,g,b triplets for RGB imagemodes, or r,g,b,a quadruplets for RGBA imagemodes. The expected format is one triplet (or quadruplet) per line, each value separated by commas, and each triplet/quadruplet on a single line. If less than 256 triplets are found in the le, 256-n remaining colors will be computed by quantization.
5.12. OUTPUTFORMAT
97
5.13 PROJECTION
To set up projections you must dene two projection objects: one for the output image (in the MAP object) and one for each layer (in the LAYER objects) to be projected. MapServer relies on the Proj.4 library for projections. Projection objects therefore consist of a series of PROJ.4 keywords, which are either specied within the object directly or referred to in an EPSG le. An EPSG le is a lookup le containing projection parameters, and is part of the PROJ.4 library. The following two examples both dene the same projection (UTM zone 15, NAD83), but use 2 different methods: Example 1: Inline Projection Parameters
PROJECTION "proj=utm" "ellps=GRS80" "datum=NAD83" "zone=15" "units=m" "north" "no_defs" END
Note: This refers to an EPSG lookup le that contains a 26915 code with the full projection parameters. epsg in this instance is case-sensitive because it is referring to a le name. If your le system is case-sensitive, this must be lower case, or MapServer (Proj.4 actually) will complain about not being able to nd this le. Note: See http://spatialreference.org/ref/epsg/26915 for more information on this coordinate system. The next two examples both display how to possibly dene unprojected lat/longs (geographic): Example 3: Inline Projection Parameters
PROJECTION "proj=latlong" "ellps=WGS84" "datum=WGS84" END
MAP-level projection) then you must dene PROJECTION objects for those layers, to tell MapServer what projections they are in. If you specify a MAP-level projection, and then only one other LAYER projection object, MapServer will assume that all of the other layers are in the specied MAP-level projection. Always refer to the EPSG le in lowercase, because it is a lowercase lename and on Linux/Unix systems this parameter is case sensitive.
5.14 QUERYMAP
COLOR [r] [g] [b] Color in which features are highlighted. Default is yellow. SIZE [x][y] Size of the map in pixels. Defaults to the size dened in the map object. STATUS [on|off] Is the query map to be drawn? STYLE [normal|hilite|selected] Sets how selected features are to be handled. Layers not queried are drawn as usual. Normal: Draws all features according to the settings for that layer. Hilite: Draws selected features using COLOR. Non-selected features are drawn normally. Selected: draws only the selected features normally.
5.15 REFERENCE
Three types of reference maps are supported. The most common would be one showing the extent of a map in an interactive interface. It is also possible to request reference maps as part of a query. Point queries will generate an image with a marker (see below) placed at the query point. Region based queries will depict the extent of the area of interest. Finally, feature based queries will display the selection feature(s) used. COLOR [r] [g] [b] Color in which the reference box is drawn. Set any component to -1 for no ll. Default is red. EXTENT [minx][miny][maxx][maxy] The spatial extent of the base reference image. IMAGE [lename] Full lename of the base reference image. Must be a GIF image. MARKER [integer|string] Denes a symbol (from the symbol le) to use when the box becomes too small (see MINBOXSIZE and MAXBOXSIZE below). Uses a crosshair by default. MARKERSIZE [integer] Denes the size of the symbol to use instead of a box (see MARKER above). MINBOXSIZE [integer] If box is smaller than MINBOXSIZE (use box width or height) then use the symbol dened by MARKER and MARKERSIZE.
5.14. QUERYMAP
99
MAXBOXSIZE [integer] If box is greater than MAXBOXSIZE (use box width or height) then draw nothing (Often the whole map gets covered when zoomed way out and its perfectly obvious where you are). OUTLINECOLOR [r] [g] [b] Color to use for outlining the reference box. Set any component to -1 for no outline. SIZE [x][y] Size, in pixels, of the base reference image. STATUS [on|off] Is the reference map to be created? Default it off.
5.16 SCALEBAR
Scalebars currently do not make use of TrueType fonts. The size of the scalebar image is NOT known prior to rendering, so be careful not to hard-code width and height in the <IMG> tag in the template le. Future versions will make the image size available. ALIGN [left|center|right] Denes how the scalebar is aligned within the scalebar image. Default is center. Available in versions 5.2 and higher. New in version 5.2. BACKGROUNDCOLOR [r] [g] [b] Color to use for scalebar background, not the image background. COLOR [r] [g] [b] Color to use for drawing all features if attribute tables are not used. IMAGECOLOR [r] [g] [b] Color to initialize the scalebar with (i.e. background). INTERLACE [true|false] Should output images be interlaced? Default is [on]. This keyword is now deprecated in favour of using the FORMATOPTION INTERLACE=ON line in the OUTPUTFORMAT declaration. Deprecated since version 4.6. INTERVALS [integer] Number of intervals to break the scalebar into. Default is 4. LABEL Signals the start of a LABEL object OUTLINECOLOR [r] [g] [b] Color to use for outlining individual intervals. Set any component to -1 for no outline which is the default. POSITION [ul|uc|ur|ll|lc|lr] Where to place an embedded scalebar in the image. Default is lr. POSTLABELCACHE [true|false] For use with embedded scalebars only. Tells the MapServer to embed the scalebar after all labels in the cache have been drawn. Default is false. SIZE [x][y] Size in pixels of the scalebar. Labeling is not taken into account. STATUS [on|off|embed] Is the scalebar image to be created, and if so should it be embedded into the image? Default is off. (Please note that embedding scalebars require that you dene a markerset. In essence the scalebar becomes a custom marker that is handled just like any other annotation.) STYLE [integer] Chooses the scalebar style. Valid styles are 0 and 1. TRANSPARENT [on|off] Should the background color for the scalebar be transparent. This ag is now deprecated in favor of declaring transparency within OUTPUTFORMAT declarations. Default is off. Deprecated since version 4.6. UNITS [feet|inches|kilometers|meters|miles] Output scalebar units, default is miles. Used in conjunction with the maps units to develop the actual graphic. Note that decimal degrees are not valid scalebar units.
100
Chapter 5. Maple
5.17 STYLE
Style holds parameters for symbolization. Multiple styles may be applied within a class. This object is new in 4.0 and is intended to separate logic from looks. The nal intent is to have named styles (Not yet supported) that will be re-usable through the maple. This is the new, preferred way of dening the appearance of an object, notably a class. ANGLE [double|attribute|AUTO] Angle, given in degrees, to draw the line work. Default is 0. For symbols of Type HATCH, this is the angle of the hatched lines. For its use with hatched lines, see Example#8 in the symbology examples. [Attribute] was introduced in version 5.0, to specify the item name in the attribute table to use for angle values. The hard brackets [] are required. For example, if your shapeles DBF has a eld named MYANGLE that holds angle values for each record, your STYLE object for hatched lines might contain:
STYLE SYMBOL hatch-test COLOR 255 0 0 ANGLE [ M Y ANGLE] SIZE 4 WIDTH 3 END
The associated RFC document for this feature is MS RFC 19: Style & Label attribute binding. The AUTO keyword was added in version 5.4, and currently only applies when coupled with the GEOMTRANSFORM keyword. ANGLEITEM [string] this parameter was removed in MapServer 5.0. You should use the ANGLE [attribute] parameter instead. For MapServer versions <5, this is the attribute/eld that stores the angle to be used in rendering. Angle is given in degrees with 0 meaning no rotation. ANTIALIAS [true|false] Should TrueType fonts and Cartoline symbols be antialiased. BACKGROUNDCOLOR [r] [g] [b] Color to use for non-transparent symbols. COLOR [r] [g] [b] | [attribute] Color to use for drawing features. [Attribute] was introduced in version 5.0, to specify the item name in the attribute table to use for color values. The hard brackets [] are required. For example, if your shapeles DBF has a eld named MYCOLOR that holds color values for each record, your STYLE object for might contain:
STYLE COLOR [ M Y COLOR] OUTLINECOLOR 150 150 150 END
The associated RFC document for this feature is MS RFC 19: Style & Label attribute binding. GEOMTRANSFORM [start|end|vertices|bbox] 5.17. STYLE 101
Used to indicate that the current feature will be transformed before the actual style is applied. Only applies to versions from 5.4 bbox: uses the current style for rendering the bounding box of the underlying geometry start and end: uses the current style to render a marker on the rst or last vertex of the current geometry. When used with ANGLE AUTO, this can be used to render arrowheads or tails on line segments. vertices: uses the current style for rendering a marker on the intermediate vertices of the underlying geometry. When used with ANGLE AUTO, the marker is oriented by the half angle formed by the two adjacent line segments. MAXSIZE [integer] Maximum size in pixels to draw a symbol. Default is 50. MINSIZE [integer] Minimum size in pixels to draw a symbol. Default is 0. MINWIDTH [integer] Minimum width in pixels to draw the line work. OFFSET [x][y] Offset values for shadows, hollow symbols, etc ... OPACITY [integer] Opacity to draw the current style (applies to 5.2+, AGG Rendering Specics only, does not apply to pixmap symbols) OUTLINECOLOR [r] [g] [b] | [attribute] Color to use for outlining polygons and certain marker symbols. Line symbols do not support outline colors. [Attribute] was introduced in version 5.0, to specify the item name in the attribute table to use for color values. The hard brackets [] are required. For example, if your shapeles DBF has a eld named MYOUTCOLOR that holds color values for each record, your STYLE object for might contain:
STYLE COLOR 255 0 0 OUTLINECOLOR [ M Y O U T COLOR] END
The associated RFC document for this feature is MS RFC 19: Style & Label attribute binding. SIZE [integer|attribute] Height, in layer SIZEUNITS, of the symbol/pattern to be used. Only useful with scalable symbols. Default is 1. For symbols of Type HATCH, the SIZE is the distance between hatched lines. For its use with hatched lines, see Example#8 in the symbology examples. [Attribute] was introduced in version 5.0, to specify the item name in the attribute table to use for size values. The hard brackets [] are required. For example, if your shapeles DBF has a eld named MYSIZE that holds size values for each record, your STYLE object for hatched lines might contain:
STYLE SYMBOL hatch-test COLOR 255 0 0 ANGLE 45 SIZE [ M Y SIZE] WIDTH 3 END
The associated RFC document for this feature is MS RFC 19: Style & Label attribute binding.
102
Chapter 5. Maple
Starting from version 5.4, the value can also be a fractional value (and not only integer). Note that currently only the AGG renderer can correctly render fractional widths. SIZEITEM [string] this parameter was removed in MapServer 5.0. You should use the SIZE [attribute] parameter instead. For MapServer versions <5, this is the attribute/eld that stores the size to be used in rendering. Value is given in pixels. SYMBOL [integer|string|lename] The symbol name or number to use for all features if attribute tables are not used. The number is the index of the symbol in the symbol le, starting at 1, the 5th symbol in the le is therefore symbol number 5. You can also give your symbols names using the NAME keyword in the symbol denition le, and use those to refer to them. Default is 0, which results in a single pixel, single width line, or solid polygon ll, depending on layer type. You can also specify a gif or png lename. The path is relative to the location of the maple. WIDTH [integer|attribute] Width refers to the thickness of line work drawn, in layer SIZEUNITS. Default is 1. For symbols of Type HATCH, the WIDTH is how thick the hatched lines are. For its use with hatched lines, see Example#8 in the symbology examples. Attribute binding was added in version 5.2 Starting from version 5.4, the value can also be a fractional value (and not only integer). Note that currently only the AGG renderer can correctly render fractional widths.
5.18 SYMBOL
Symbol denitions can be included within the main MapFile or, more commonly, in a separate le. Symbol denitions in a separate le are designated using the SYMBOLSET keyword, as part of the MAP Object. This recommended setup is ideal for re-using symbol denitions across multiple MapServer applications. There are 3 main types of symbols in MapServer: Markers, Shadesets, and Lines. Symbol 0 is always the degenerate case for a particular class of symbol. For points, symbol 0 is a single pixel, for shading (i.e. lled polygons) symbol 0 is a solid ll, and for lines, symbol 0 is a single pixel wide line. Symbol denitions contain no color information, colors are set within CLASS objects. For MapServer versions < 5 there is a maximum of 64 symbols per le. This can be changed by editing mapsymbol.h and changing the value of MS_MAXSYMBOLS at the top of the le. As of MapServer 5.0 there is no symbol limit. More information can be found in the Construction of Cartographic Symbols document.
ANTIALIAS [true|false] Should TrueType fonts be antialiased. CHARACTER [char] Character used to reference a particular TrueType font character. Youll need to gure out the mapping from the keyboard character to font character. FILLED [true|false] Sets the symbol to be lled with a user dened color (See the CLASS object). For marker symbols, if OUTLINECOLOR was specied then the symbol is outlined with it. 5.18. SYMBOL 103
FONT [string] Name of TrueType font to use as dened in the FONTSET. GAP [int] Given in pixels. This denes a distance between symbols for TrueType lines. As of MapServer 5.0 this also applies to PixMap symbols. When drawing the symbol along a line segment, a negative GAP will will add 180 degress to the angle. The TrueType and PixMap symbols are always oriented along the line. A GAP of 0 (the default value) will cause MapServer to use the symbol as a brush to draw the line. IMAGE [string] Image (GIF or PNG) to use as a marker or brush for type PIXMAP symbols. NAME [string] Alias for this font to be used in CLASS objects LINECAP [butt|round|square|triangle] Sets the line cap type for the cartoline symbol. Default is butt. Works with the CARTOLINE symbol only! LINEJOIN [round|miter|bevel] Sets the line join type for the cartoline symbol. Default is none - lines will not be joined . Works with the CARTOLINE symbol only! LINEJOINMAXSIZE [int] Sets the max length of the miter line join type. The value represents a coefcient which multiplies a current symbol size. Default is 3. Works with the CARTOLINE symbol only! PATTERN [num on] [num off] [num on] ... END Denes a dash style or pattern. Implemented in MapServer 5.0, to replace the deprecated STYLE parameter. POINTS [x y] [x y] ... END Signies the start of the denition of points that make up a vector symbol or that dene the x and y radius of an ellipse symbol. The end of this section is signied with the keyword END. Coordinates are given in pixels and dene the default size of the symbol before any scaling. You can create non-contiguous paths by inserting negative coordinates at the appropriate place. For ellipse symbols you provide a single point that denes the x and y radius of an ellipse. Circles are created when x and y are equal. Note: If a class using this symbol doesnt contain an explicit size, then the default symbol size will be based on the range of y values in the point coordinates. e.g. if the y coordinates of the points in the symbol range from 0 to 5, then the default size for this symbol will be assumed to be 5. STYLE [num on] [num off] [num on] ... END -deprecated Since MapServer 5.0 the proper parameter to use is PATTERN instead. The deprecated STYLE parameter denes a dash style or pattern. Deprecated since version 5.0. TRANSPARENT [color index] Sets a transparent color for the input GIF image for pixmap symbols, or determines whether all shade symbols should have a transparent background. For shade symbols it may be desirable to have background features show through a transparent hatching pattern, creating a more complex map. By default a symbols background is the same as the parent image (i.e. color 0). This is user congurable. TYPE [vector|ellipse|pixmap|truetype|simple|cartoline|hatch] shape of the symbol. vector: a simple drawing is used to dene the
ellipse: radius values in the x and y directions dene an ellipse. pixmap: a user supplied GIF image will be used as the symbol. truetype: TrueType font to use as dened in the FONTSET. cartoline: allows for different designs of line ends (mitered, rounded, beveled). More information can be found in the Cartographic Symbols document. hatch: produces hatched lines throughout the shape.
104
Chapter 5. Maple
Table of Contents Cartographic Symbol Construction with MapServer Abstract Introduction Using Cartographic Symbols in UMN MapServer Examples Current Problems / Open Issues
5.19.1 Abstract
This Document refers to the syntax of MAP and symbolles for MapServer 4.6. It is based upon the results of a project carried out at the University of Hannover, Institute of Landscape and Nature Conservation. It was initiated by Mr. Dipl. Ing. Roland Hachmann. Parts have been taken from a study carried through by Karsten Hoffmann, student of Geography and Cartography at the FU Berlin. In the context of a hands-on training in the company GraS GmbH Mr. Hoffman mainly dealed with the development of symbols. (Download study report in German) His degree dissertation will also concern this subject. At the end of this document you will nd a link to a paper discussing further development of the UMN MapServer software regarding the cartographic rendering capabilities. We will try to get around to also translating it to English asap. We welcome everybody who is interested in this subject to participate in the discussion. As a result of this discussion we want to put together a list with change requests and new requirements for UMN MapServer.
5.19.2 Introduction
Cartographic characters can be distinguished as point, line and area symbols. These symbols may vary depending on their special attributes (variables). Bertin (1974) created a clear and logical symbol scheme in which symbols can be varied referring to graphical variables. The following variables are used within MapServer: FORM, SIZE, PATTERN, COLOR and LIGHTNESS. Point and area symbols as well as text fonts (ttf) can additionally be displayed with a 1-pixel wide frame which we call OUTLINE. Multiple Rendering and Overlay Complex cartographic effects can be achieved by rendering the same vector data with different attributes, sizes and colors on top of each other. This is an easy workaround to creating complex signatures but obviously it will also reect on the performance of the application. Every rendering process of the same geometries will take up additional processor time. 5.19. Cartographic Symbol Construction with MapServer 105
As an example consider displaying a highway with a black border line, two yellow lanes and a red center line. You can achieve this by rendering the same highway geometry three times on top of each other. The lowest (in drawing order) is rendered as a broad black line with a width of 9 pixel. The second level lines are rendered in yellow color with a width of 7 pixel. The topmost layer is displayed as the red center line with a width of 3 pixel in size. That way each yellow colored lane will have a width of (7-1)/2 = 3 pixel. This can be a solution for many kinds of cartographic questions, a combination of different geometry types is also possible. First dene a polygon layer as TYPE LINE. It will frame the polygons with a line signature. On top of this include the same geometry a second time but now as TYPE POLYGON with a symbol lling the polygon. This way half of the underlying outline is covered by the polygon with the ll symbol. The clipping effect renders an asymmetric line symbol. To present the outline without clipping just reorder the layers and put the outline presentation on top of the layer with the ll symbol. Each step growing more complex, yet another way to construct asymmetric line signatures for framed faces is to tamper with the original geometries by buffering or clipping the original geometry such that the new objects lie inside the original polygons or grow over the borders. A new line symbol for these geometries can use the OFFSET parameter with the y-value set to -99. This is where current development stops short this functions has not been developed further. (Anybody need this feature?). Buffer areas may provide ideal geometry for ambitious cartography, this should be possible as soon as the GEOS library is implemented in MapServer. Until then using PostGIS helps to solve a lot of problems. Symbol Scaling There are two basically different ways to handle the display size of symbols and cartographic elements in a map at different scales. The size of cartographic objects is either set in screen pixel or in real world units. If the size is set in real world units (i.e. meters), then cartographic objects are scalable, they will shrink and grow together with the scale at which the map ist displayed. Object sizes in screen pixel will be displayed in the same size no matter at what scale the map is displayed. UMN MapServer implements the screen pixel size type for displaying cartographic elements. Additionally the size of cartographic elements can be tied to dened scales, such that the symbols grow and shrink with the scale. The involved parameters include SYMBOLSCALE, MINSIZE and MAXSIZE settings in the MAP le. All symbol and style denitions referenced in the following section are contained in the archive at the end of this document. The following gure shows the theoretical structure of cartographic symbols, which are also used in UMN MapServer: Figure1: Structure of Cartographic Symbols
106
Chapter 5. Maple
In a MapServer application symbol parameters are taken from the MAP and symbol le as follows: MAP le: The parameter TYPE denes the type of geometry (point, line or polygon) for each layer. The symbols are accordingly rendered as single points, along a line or area symbols. The denition of the color, brightness (through the color parameter), size and outline is set inside the STYLEsection of a CLASS-section by the parameters COLOR, SIZE and OUTLINECOLOR. Combining several basic elements to achieve a complex signature with several STYLEs inside one layer (observe the display order). Symbol le: Denition of form and pattern with TYPE, POINTS, IMAGE, FILLED, STYLE (meaning ll pattern) and GAP. The following gure shows the interaction of these elements and explains the conguration in the MAP and the SYMBOL le sections necessary for rendering cartographic symbols in the map: Figure2: Schema showing interaction of MAP and SYMBOL le
107
108
Chapter 5. Maple
Always observe that cartographic symbols depend a lot on the scale! So be careful with the interaction of content, symbols and scale when creating projects. All three parameters heavily interact and have to be coordinated to produce a good map. Symbols of TYPE VECTOR and ELLIPSE The TYPE VECTOR denes the form of a symbol by setting x- and y-values in a local caresian coordinate system with the origin at the upper left corner. Each symbol is parenthesized by the tags POINTS and END. The maximum number of points can be increased by changing the parameter MS_MAXVECTORPOINTS in the le mapsymbols.h. The current default is 100. Note that by setting the end point equal to the start point you obtain a closed form (polygon). To use the coordinates -99 -99 to break a line, the following point will not be connected by a line with the preceding one. When creating symbols of the TYPE VECTOR you should observe some style guidelines. Avoid downtilted lines in area symbols, as they will lead to heavy aliasing effects. Furthermore you should not go below a useful minimum size, which is relevant for all types of symbols. Keep in mind that the points in the local coordinate system are rendered as pixel images, thus only integer values make any sense. Every symbol of the TYPE VECTOR is rst rendered as a pixel image and then added to the geometry. This is the basic principle of the GD graphic kernel. PIXMAP symbols may be used directly for drawing. To create circles and ellipses use the TYPE ELLIPSE. These forms are created by setting the x and y values as the radius of the circle or ellipse inside POINTS and END. Construction of Point Symbols The following gure shows how to combine several basic elements to create a new point symbol. The combination is achieved by adding several STYLEs within one layer. Each basic element references one item of the SYMBOL le, which are centered and overlayed when rendered. Notice that the SIZE parameter in the STYLE section only refers to the width of the symbol (size in the y-direction). An edgewise rectangle will thus display smaller than a lying rectangle, although both have the same SIZE parameter. When combining several point elements on top of each other, they will not always be centered correctly. We have not found a regular rule yet. We can only recommend to set an even-numbered SIZE for combined elements. Combining elements with even and odd numbered SIZE parameters seem to have larger irregularities. Figure3: Construction of Point Symbols
109
Construction of Line Symbols For displaying line geometries most often a simple point symbol (lled circle / SYMBOL 0) is used. This point is painted for each pixel along the line, giving a continuous line with rounded ends. To create line patterns use the STYLE section of the SYMBOL le (do not confuse this with the STYLE-section of the CLASS object). Here you state how many pixel of the section shall be displayed and how many are left blank. This pattern will be repeated as many times as that pattern will t into the element. The following gure shows this effect. Unfortunately up to now no OFFSET (start gap) can be dened to create asymetric patterns. (anybody need this?) Figure4: Construction of Line Symbols
110
Chapter 5. Maple
When using the point character for rendering all line features with have rounded ends. This can be a desired effect or not, it gets more obvious the larger the width of line is set. Alternatively a rectangle can be used to generate a line. It can be enhanced with a STYLE-parameter to create line patterns (see below). Table 1. Creating a Symbol to Display Railways
111
CLASS-section from the Maple CLASS STYLE COLOR 102 102 102 SYMBOL point SIZE 4 END STYLE COLOR 255 255 255 SYMBOL rectangle-train SIZE 2 END END
Character from the Symbolle SYMBOL NAME point TYPE ELLIPSE POINTS 1 1 END FILLED TRUE END SYMBOL NAME rectangle-train TYPE VECTOR POINTS 0 0 0 0.6 1 0.6 1 0 0 0 END FILLED TRUE STYLE 8 12 8 12 END END
The STYLE parameter can be used for elements of the SYMBOL le with the TYPE VECTOR, ELLIPSE, CARTOLINE and PIXMAP. It will dene the number of intervals in which the symbol is rendered. This can be done using the GAP parameter with TRUETYPE symbols (see below). When combining of several symbols on a line, they will be positioned on the baseline which is dened by the geometry of the object in pixel coordinates. Again we face the problem of centering. In most cases MapServer corectly centers symbols. The combination of a line displayed in 6 pixel width and overlayed with 4 pixel width results in a line symbol with a 1 pixel border. If the cartographic symbol is to contain a centered line with a width of 1 pixel, then the SIZE parameters have to be reconguredfor example to 7 and a 5 pixel. As a rule of thumb only combine even numbered or odd numbered SIZE parameters (see above). In the STYLE section of the MAP le an OFFSET parameter can be set to shift symbols or characters in the x and y direction. Unfortunately the displacement is set relative to the map border, not the inclination of the line gemoetry (with the exception: OFFSET n -99). Therefore the iterated characters are all shifted in the same direction, independent of which direction the line takes (see Example 2). To generate asymmetrical line symbols apply -99 for the y value of the OFFSET. Then the x-value denes the distance from a parallel to the original geometry, for which the selected symbol is used (what a pity this wasnt documented anywhere!). Table 2: Use of the OFFSET parameter with line signatures
112
Chapter 5. Maple
CLASS SYMBOL STYLE NAME "circle" SIZE 1 TYPE ELLIPSE COLOR 0 0 0 POINTS END 1 1 STYLE END SYMBOL "circle" STYLE SIZE 7 1 10 1 10 COLOR 0 0 255 END OFFSET 8 -8 END END END
CLASS SYMBOL STYLE NAME "circle" SIZE 1 TYPE ELLIPSE COLOR 0 0 0 POINTS ANTIALIAS 1 1 END END STYLE STYLE SYMBOL "circle" 1 10 1 10 SIZE 12 END COLOR 0 0 255 END OFFSET -8 -99 ANTIALIAS TRUE END END
Area Symbols Areas (polygons) can be lled with elements of the SYMBOL le to create e.g. hatches and graticules. These are by default rendered without spacing one after the other in x and y direction and ll out the whole polygon. Simple line hatches (e.g. horizontal, vertical and diagonal) can be created by lling the polygon with a line symbol from the SYMBOL le (see example 5). The SIZE parameter in the STYLE section for line hatches only species the distance between the lines and not their width. Thus in these hatches all lines will always have a width of 1 pixel. Unfortunately there is no additional parameter to dene the line width (Anybody need this feature?). Notice that the SIZE parameter is interpreted by MapServer differently for horizontal and vertical lines. Vertical lines with a SIZE parameter of 8 pixel result in a distance of 8 pixel between the lines. Horizontal lines with the same SIZE parameter are instead renderes with a much smaller gap (see example 5). For creating cross hatches composed of vertical and horizontal lines the best method is to use a simple cross from the SYMBOL le. Polygons can also be lled with other POINT elements to obtain special patterns (e.g. with circles or triangles). Table 3: Construction of a cross hatch with different line distances
113
CLASS-Section from the Maple CLASS STYLE SYMBOL "line-vertical" SIZE 8 COLOR 255 102 51 OUTLINECOLOR 0 0 0 END STYLE SYMBOL "line-horizontal" SIZE 8 COLOR 204 102 51 OUTLINECOLOR 0 0 0 END END
Character from the Symbolle SYMBOL NAME "line-vertical" TYPE vector POINTS 0.5 0 0.5 1 END END SYMBOL NAME "line-horizontal" TYPE vector POINTS 0 0.5 1 0.5 END END
Signatures of TYPE PIXMAP Symbols of the TYPE PIXMAP are simply small raster images. The name of the raster images are specied in the SYMBOL le with the parameter IMAGE. MapServer supports the raster formats GIF and PNG. Observe the color depth of the images and avoid using 24 bit PNG symbols displayed in 8 bit mode as this may cause unexpected color leaps. When using raster images the color cannot be modied in the SMBOL le subsequently. But you can specify a color with the TRANPARENT parameter which will not be displayed - i.e. it will be transparent. As a result all underlying objects and colors are visible. The SIZE parameter denes the size of PIXMAP symbols when used as point symbols. Observe that the pixel structure will show when the SIZE grows too large. Prevent this from happening by setting a MAXSIZE parameter. When using PIXMAPS as line symbols or as ll symbols for polygons they will not be resized but are displayed in the original size. So the use of PIXMAP STYLE objects for signatures with a high need of scaling is rather limited. PIXMAP symbols are always rendered respective to the map border and will not follow the inclination of a line or polygon outline. Only truetype font symbols can follow an inclined line geometry, although with some defects (see below). To create more complex area symbols, e.g. with dened distances between single characters or hatches with broad lines, raster images are probably the most suitable objects. Depending on the desired pattern you have to generate the raster image with high precision using a graphic editor. To obtain a regular allocation of symbols with dened spacing you could use the raster image as shown in Figure1. Figure5: Raster image for a regular polygon symbol ll
114
Chapter 5. Maple
Instead of using circles you can use different characters. B denes the width and H the height of the raster image. For a regular arrangment of symbols in a 45 degree angle B = H. For symbols, which are regularly arranged in parallel and without offset between each other one centered symbol with same x and y distances to the imageborder is enough. A regular hatch with wider lines can be created by using the raster image in g. 2. To create a 45 degree hatch use:
B = H and x = y
When using the MapServer legend observe that each raster PIXMAP is displayed only once in the original size in the middle of the legend box. See the example below of some PIXMAP symbols, which can be used as area symbols with transparency. The raster images were created using FreeHand, nished with Photoshop and exported to PNG with special attention regarding the color palette. Observe that you have to specify a COLOR in the STYLE section of the CLASS to display raster
115
PIXMAPS although it has no inuence on the output and color of the image. Table 4: Construction of a horizontally arranged area symbol CLASS-Section from the Maple CLASS STYLE COLOR 255 255 0 END STYLE SYMBOL "in_the_star" COLOR 0 0 0 OUTLINECOLOR 0 0 0 END END Character from the Symbolle SYMBOL NAME "in_the_star" TYPE PIXMAP IMAGE "stern.png" TRANSPARENT 8 END
Table 5: Construction of a diagonally arranged area symbol CLASS-Section from the Maple CLASS STYLE SYMBOL "in_point1" COLOR 0 0 0 OUTLINECOLOR 0 0 0 END END Character from the Symbolle SYMBOL NAME "in_point1" TYPE PIXMAP IMAGE "flaeche1_1.png" TRANSPARENT 13 END
116
Chapter 5. Maple
CLASS-Section from the Maple CLASS STYLE COLOR 255 255 0 END STYLE SYMBOL "in_hatch" COLOR 0 0 0 OUTLINECOLOR 0 0 0 END END
Character from the Symbolle SYMBOL NAME "in_hatch" TYPE PIXMAP IMAGE "schraffur.png" TRANSPARENT 2 END
Signatures of TYPE CARTOLINE The TYPE Cartoline is not really an independent SYMBOL type or basic element but it is useful for creating line signatures. The advantage over the above types is the antialising of lines with any width. Conventional lines can only use antialising with a width of 1 pixel. This line type supports the ANTIALIAS parameter in the STYLE block of the CLASS denition just like the truetype fonts and symbols. Here you can also dene line patterns and offsets. The design of the line ends can be controled with the LINECAP parameter. The LINECAP value BUTT stopps the signature exactly at the end of the top line. Author of this features is Tomas Krecmer (tokr(a)tmapy.cz). If you have questions concerning this type of signature or suggestions for improvement please contact the author.
LINEJOIN
The different values for the parameter LINEJOIN have the following visual effects (see the following gure). Default is not set but do not specify the string not set, just omit the parameter LINEJOIN.
117
Miter follow line borders until they intersect, ll the resulting area. Round see above Bevel see above None Lines will not be connected but drawn with LINECAPP butt at the respective ends.
LINEJOINMAXSIZE
Specify the maximum length of m (only relevant for LINEJOIN type MITER). The value is a multiplication factor (default 3). The actual max length is calculated as follows:
m - current join size d - symbol size m_max = d * LINEJOINMAXSIZE
If current m > m_max then the connection length will be set to m_max. Signatures of TYPE TRUETYPE Finally you can use symbols from truetype fonts. The symbol settings are also dened in the SYMBOL le. Specify the ASCII number of the symbol to be used in the CHARACTER parameter. Add the ALIAS name of the font le to the parameter FONT as dened in the le fonts.list. Remember to set the FONTSET parameter in the MAP le to link the correct fonts.list le. With the parameter ANTIALIAS you dene whether to apply antialiasing to the symbols 118 Chapter 5. Maple
or characters. It is recommended to do this especially with more complex symbols and and whenever they dont t well into the raster matrix or show a visible pixel structure. Set a POSITION [ul|uc|ur|cl|cc|cr|ll|lc|lr] relative to the geometric origin of the geometry. In the STYLE section of the LAYER object it is possible to dene colors for true type symbols (as with signatures of the TYPE VECTOR). When using truetype chracters to render complex line symbols, you can dene the distance in pixel until the symbol is repeated by setting the GAP parmeter in the SYMBOL le. A more complicated pattern like the STYLE parameters for VECTOR, ELLIPSE or PIXMAP type symbols cannot be used not (Anybody need this feature?). The OFFSET parameter is currently not implemented yet. Truetype symbols follow the inclination of the accompanying line. When using asymmetrical symbols they unfortunately do not always follow the outside or the inside, left or right of a line but change. If possible symbols will always be displayed upside (which makes a lot of sense for string characters, what true type fonts basically are). On vertical lines symbols are rendered to the right or left side depending on the drawing direction of the line. If the line is drawn from bottom to top, the truetype symbol is displayed to the left, if the line is drawn from top to bottom, the symbol is displayed to the right (see table below). In left picture in the table the line is drawn clockwise and in the right picture drawn counterclockwise. Table 7: TrueType-character used on lines CLASS-Section from the Maple CLASS STYLE SYMBOL "T" SIZE 12 COLOR 0 0 255 END END Character from the Symbolle SYMBOL NAME "T" TYPE TRUETYPE FONT "arial" CHARACTER "T" ANTIALIAS TRUE GAP 10 END
To nd out the character number of a symbol use one of the following options: Use the software FontMap (Shareware, with free trial version for download, thanks Till!) Use the MS Windows truetype map Trial and Error :-) Please note that the numbering of the so-called symbol fonts starts at 61440! So if you want to use character T, you have to use 61440 + 84 = . (aint that a pain!!)
119
5.19.4 Examples
Find some examples to show different possibilities of the UMN MapServer for cartographical symbols of the vector based mapobjects (this is just a selection!): Basic Symbols
120
Chapter 5. Maple
121
Complex Symbols
122
Chapter 5. Maple
123
124
Chapter 5. Maple
CLASS-Section from the Maple CLASS STYLE SIZE 1 COLOR 0 0 0 END STYLE SYMBOL "cross2" SIZE 8 COLOR 204 153 0 OFFSET 1 -7 END END
Character from the Symbolle SYMBOL NAME "cross2" TYPE VECTOR POINTS 0 0 1 1 -99 -99 0 1 1 0 END STYLE 1 15 1 15 END END
Table9: Irregularities with line patterns CLASS-Section from the Maple CLASS STYLE SYMBOL "border2" SIZE 2 COLOR 255 0 0 END END Character from the Symbolle SYMBOL NAME "border2" TYPE VECTOR POINTS 0 0 1 0 1 0.8 0 0.8 0 0 END STYLE 10 6 1 6 END FILLED TRUE END
All symbols in this document were created with MAP les and SYMBOL les, which can be downloaded. If you want to use this MAP le please note, that your MapServer must at least be able to handle with 50 symbols. Otherwise you get an error while loading the SYMBOL les. I hope that this document will help you to present your data in a cartographically nice manner with the UMN MapServer and explains some basics and possibilities of the concept of the UMN MapServer as well as some weakness. It would be great to put together a cartographic symbols library for the prot of everyone. This especially concerns truetype-fonts, which were developed for some projects and contain some typical signatures for cartographic needs. 5.19. Cartographic Symbol Construction with MapServer 125
You can also view the discussion paper for the improvement of the MapServer Graphic-Kernel (sorry as yet German only).
Table of Contents Symbology Examples Example 1. Dashed Line Example 2. TrueType font marker symbol Example 3. Vector triangle marker symbol Example 4. Non-contiguous vector marker symbol (Cross) Example 5. Circle vector symbol Example 6. Downward diagonal ll Example 7. Dashed Cartoline symbol Example 8. Using the Symbol Type HATCH (new in 4.6)
The following example creates a dashed line with 10 pixels on, 5 off, 5 on, 10 off ...
The next example symbol is a star, used to represent the national capital, hence the name. The font name in dened in the FONTSET le. The code number 114 varies, you can use MS Windows character map to gure it out, or guestimate.
126
Chapter 5. Maple
TYPE TRUETYPE FONT g e o FILLED true ANTIALIAS true CHARACTER "r" END
The next example is fairly straight forward. Note that to have 3 sides you need 4 points, hence the rst and last points are identical.
The next example draws a cross, that is 2 lines (vectors) that are not connected end-to-end (Like the triangle in the previous example). The negative values separate the two.
The next example creates a simple lled circle. Using non-equal values for the point will give you an actual ellipse.
127
The next example creates a dashed line with 10 pixels on, 5 off,... The line will have butt caps and short miter joins. For layers with a scaled symbol (SYMBOLSCALE, MINSIZE, MAXSIZE, ...) the PATTERN will be resized to maintain symbol ratios.
Layer denition:
LAYER ... CLASS ... STYLE SYMBOL hatch-test COLOR 255 0 0 ANGLE 45 SIZE 10 WIDTH 3 END END END
128
Chapter 5. Maple
Other parameters available for HATCH are: ANGLEITEM, SIZEITEM, MINWIDTH, and MAXWIDTH.
5.21 Templating
Author Frank Koormann Contact frank.koormann at intevation.de Author Jeff McKenna Contact jmckenna at gatewaygeomatics.com Revision $Revision: 8278 $ Date $Date: 2008-12-23 13:34:31 -0800 (Tue, 23 Dec 2008) $ Last Updated 2008/07/18
5.21.1 Introduction
Templates are used: to dene the look of a MapServer CGI application interface and to present the results of a query. They guide the presentation of results, either a query or a map, to the user. Templates are almost always HTML les although they can also be a URL (e.g.. http://www.somewhere.com/[ATTRIBUTE]/info.html). URL templates can only be used with simple QUERY or ITEMQUERY results so many substitutions dened below are not available for them. Simple pan/zoom interfaces use a single template le while complicated queries often require many templates. Templates often use JavaScript to enhance the basic interface. Notes All CGI parameters can be referenced in template substitutions, MapServer specic parameters as well as user dened ones. In principle parameters are handed through by the MapServer 1:1. This feature is essential for implementing MapServer applications. The reference below only lists special template substitution strings which are needed to obtain information modied by the MapServer, e.g. a new scale, query results, etc. Template substitution strings are case sensitive. Attribute item substitutions must be the same case as the item names in the dbase le. ArcView and ArcInfo generally produce dbase les with item names that are all uppercase. Appropriate URL encoding (i.e. to +) is applied when templates are URLs. 5.21. Templating 129
Some substitutions are also available in escaped form (i.e. URL encoded). As an example this is needed when generating links within a template. This might pass the current mapextent to a new MapServer call. [mapext] is substituted by a space delimited set of lower left and upper right coordinates. This would break the URL. [mapext_esc] is substituted by a proper encoded set.
5.21.2 Format
Templates are simply HTML les or URL strings that contains special characters that are replaced by mapserv each time the template is processed. The simple substitution allows information such as active layers or the spatial extent to be passed from the user to mapserv and back again. Most often the new values are dumped into form variables that will be passed on again. The list of special characters and form variables is given below. HTML templates can include just about anything including JavaScript and Java calls. In HTML les, the attribute values can be inside quotes(). Writing attribute values inside quotes allows you to set special characters in value that you couldnt use normaly (ie: ],=, and space). To write a single quote in a attribute value, just use two quotes (). General [version] The MapServer version number. [id] Unique session id. The id can be passed in via a form but is more commonly generated by the software. In that case the id is a concatenation of UNIX time (or NT equivalent) and the process id. Unless youre getting more requests in a second than the system has process ids the id can be considered unique. ;-> [host] Hostname of the web server. [port] Port the web server is listening to. [post or get variable name], [post or get variable name_esc] The contents of any variables passed to the MapServer, whether they were used or not, can be echoed this way. One use might be to have the user set a map title or north arrow style in an interactive map composer. The system doesnt care about the values, but they might be real important in creating the nal output, e.g. if you specied a CGI parameter like myvalue=.... you can access this in the template le with [myvalue]. Also available as escaped version. [web_meta data key],[web_meta data key_esc] Web object meta data access (e.g [web_projection] Also available as escaped version. [errmsg], [errmsg_esc] Current error stack output. Various error messages are delimited by semi-colons. Also available as escaped version. File Reference [img] Path (relative to document root) of the new image, just the image name if IMAGE_URL is not set in the maple. In a map interface template, [img] is substituted with the path to the map image. In a query results template, it is substituted with the path to the querymap image (if a QUERYMAP object is dened in the Maple). [ref] Path (relative to document root) of the new reference image. [legend] Path (relative to document root) of new legend image rendered by the MapServer. Since version 3.5.1 a new HTML Legend template is provided by MapServer. If a template is dened in the Maple the [legend] string is replaced by the processed legend as. See the HTML Legends with MapServer for details. 130 Chapter 5. Maple
[scalebar] Path (relative to document root) of new scalebar image. [queryle] Path to the query le (if savequery was set as a CGI Parameter). [map] Path to the map le (if savemap was set as a CGI Parameter). Image Geometry [center] Computed image center in pixels. Useful for setting imgxy form variable when map sizes change. [center_x], [center_y] Computed image center X or Y coordinate in pixels. [mapsize], [mapsize_esc] Current image size in cols and rows (separated by spaces). Also available as escaped version. [mapwidth], [mapheight] Current image width or height. [scaledenom] Current image scale. The exact value is not appropriate for user information but essential for some applications. The value can be rounded e.g. using JavaScript or server side post processing. [scale] - deprecated Since MapServer 5.0 the proper parameter to use is [scaledenom] instead. The deprecated [scale] is the current image scale. The exact value is not appropriate for user information but essential for some applications. The value can be rounded e.g. using JavaScript or server side post processing. [cellsize] Size of an pixel in the current image in map units. Useful for distance measurement tools in user interfaces. Map Geometry [mapx], [mapy] X and Y coordinate of mouse click. [mapext], [mapext_esc] Full mapextent (separated by spaces). Also available as escaped version. (mapext_esc is deprecated in MapServer 5.2. You should use the escape= argument instead) The default template [mapext] returns coordinates in the format of: mixx miny maxx maxy Available arguments: escape= Escape the coordinates returned. Default is none. Valid values are: url Use URL escape codes to encode the coordinates returned. none Do not escape. expand= Expand the bounds of the extents by a specic value. Specied in map coordinates. For example, [mapext] might return:
123456 123456 567890 567890
format= Format of the coordinates. Default is $minx $miny $maxx $maxy. For example, to add commas to the coordinates you would use:
[mapext format="$minx,$miny,$maxx,$maxy"]
precision= The number of decimal places to output for coordinates (default is 0). [minx], [miny], [maxx], [maxy] Minimum / maximum X or Y coordinate of new map extent.
5.21. Templating
131
[dx], [dy] The differences of minimum / maximum X or Y coordinate of new map extent. Useful for creating cachable extents (i.e. 0 0 dx dy) with legends and scalebars [rawext], [rawext_esc] Raw mapextent, that is the extent before tting to a window size (separated by spaces). In cases where input came from imgbox (via Java or whatever) rawext refers to imgbox coordinates transformed to map units. Useful for spatial query building. Also available as escaped version. (rawext_esc is deprecated in MapServer 5.2. You should use the escape= argument instead) The default template [rawext] returns coordinates in the format of: mixx miny maxx maxy Available arguments: escape= Escape the coordinates returned. Default is none. Valid values are: url Use URL escape codes to encode the coordinates returned. none Do not escape. expand= Expand the bounds of the extents by a specic value. Specied in map coordinates. For example, [rawext] might return:
123456 123456 567890 567890
format= Format of the coordinates. Default is $minx $miny $maxx $maxy. For example, to add commas to the coordinates you would use:
[rawext format="$minx,$miny,$maxx,$maxy"]
precision= The number of decimal places to output for coordinates (default is 0). [rawminx], [rawminy], [rawmaxx], [rawmaxy] Minimum / maximum X or Y coordinate of a raw map/search extent. The following substitutions are only available if the MapServer was compiled with PROJ support and a PROJECTION is dened in the Maple. [maplon], [maplat] Longitude / latitude value of mouse click. Available only when projection enabled. [mapext_latlon], [mapext_latlon_esc] Full mapextent (separated by spaces). Available only when projection enabled. Also available as escaped version. (mapext_latlon_esc is deprecated in MapServer 5.2. You should use the escape= argument instead) The default template [mapext_latlon] returns coordinates in the format of: mixx miny maxx maxy Available arguments: escape= Escape the coordinates returned. Default is none. Valid values are: url Use URL escape codes to encode the coordinates returned. none Do not escape. expand= Expand the bounds of the extents by a specic value. Specied in map coordinates. For example, [mapext_latlon] might return:
123456 123456 567890 567890
132
Chapter 5. Maple
format= Format of the coordinates. Default is $minx $miny $maxx $maxy. For example, to add commas to the coordinates you would use:
[mapext_latlon format="$minx,$miny,$maxx,$maxy"]
precision= The number of decimal places to output for coordinates (default is 0). [minlon], [minlat], [maxlon] [maxlat] Minimum / maximum longitude or latitude value of mapextent. Available only when projection enabled. [refext], [refext_esc] Reference map extent (separated by spaces). This template has been added with version 4.6 on behalf of an enhancement request. See the thread in the MapServer ticket#1102 for potential use cases. Also available as escaped version. (refext_esc is deprecated in MapServer 5.2. You should use the escape= argument instead) The default template [refext] returns coordinates in the format of: mixx miny maxx maxy Available arguments: escape= Escape the coordinates returned. Default is none. Valid values are: url Use URL escape codes to encode the coordinates returned. none Do not escape. expand= Expand the bounds of the extents by a specic value. Specied in map coordinates. For example, [refext] might return:
123456 123456 567890 567890
format= Format of the coordinates. Default is $minx $miny $maxx $maxy. For example, to add commas to the coordinates you would use:
[refwext format="$minx,$miny,$maxx,$maxy"]
precision= The number of decimal places to output for coordinates (default is 0). Layer [layers] | [layers_esc] All active layers space delimited. Used for a POST request. Also available as escaped version. [toggle_layers] | [toggle_layers_esc] List of all layers that can be toggled, i.e. all layers dened in the Maple which status is currently not default. Also available as escaped version. [layername_check | select] Used for making layers persistent across a map creation session. String is replaced with the keyword checked, selected or if layername is on. Layername is the name of a layer as it appears in the Maple. Does not work for default layers. [layername_meta data key] Layer meta data access (e.g. [streets_build] the underscore is essential).
5.21. Templating
133
Zoom [zoom_minzoom to maxzoom_check|select] Used for making the zoom factor persistent. Zoom values can range from -25 to 25 by default. The string is replaced with the HTML keyword checked, selected or depending on the current zoom value. E.g. if the zoom is 12, a [zoom_12_select] is replaced with selected, while a [zoom_13_select] in the same HTML template le is not. [zoomdir_-1|0|1_check|select] Used for making the zoom direction persistent. Use check with a radio control or select with a selection list. See the demo for an example. The string is replaced with the HTML keyword checked, selected or depending on the current value of zoomdir. Query The following substitutions are only available when the template is processed as a result of a query. [shpext], [shpext_esc] Extent of current shape plus a 5 percent buffer. Available only when processing query results. The default template [shpext] returns coordinates in the format of: mixx miny maxx maxy Available arguments: escape= Escape the coordinates returned. Default is none. Valid values are: url Use URL escape codes to encode the coordinates returned. none Do not escape. expand= Expand the bounds of the extents by a specic value. Specied in map coordinates. For example, [shpext] might return:
123456 123456 567890 567890
format= Format of the coordinates. Default is $minx $miny $maxx $maxy. For example, to add commas to the coordinates you would use:
[shpext format="$minx,$miny,$maxx,$maxy"]
precision= The number of decimal places to output for coordinates (default is 0). [shpminx], [shpminy], [shpmaxx], [shpmaxy] Minimum / maximum X or Y coordinate of shape extent. Available only when processing query results. [shpmid] Middle of the extent of current shape. Available only when processing query results. [shpmidx], [shpmidy] X or Y coordinate of middle of the extent of the current shape. Available only when processing query results. [shpidx] Index value of the current shape. Available only when processing query results. [shpclass] Classindex value of the current shape. Available only when processing query results. [shpxy formatting options] The list of shape coordinates, with list formatting options, especially useful for SVG. The default template [shpxy] returns a comma separated list of space delimited of coordinates (i.e. x1 y1, x2 y2, x3 y3). Available only when processing query results. Available attributes (h = header, f=footer, s=separator): 134 Chapter 5. Maple
cs= Coordinate separator, default is comma (,). xh=, xf= Characters to put before and after the x coordinates (defaults are xh= and xf= ). yh= yf= Characters to put before and after the y coordinates (defaults are no characters). ph=, pf=, ps= Characters to put before and after and separators between feature parts (e.g. holes, defaults are no characters). sh=, sf= Characters to put before and after a feature (defaults are no characters) precision= The number of decimal places to output for coordinates (default is 0). proj= The output projection denition for the coordinates (default is none), a special value of image will convert to image coordinates. As a simple example:
[shpxy xh="(" yf=")"] will result in: (x1 y1),(x2 y2),(x3 y3)
[tileindex] Index value of the current tile. If no tiles used for the current shape this is replaced by -1. Available only when processing query results. [DBASE item name],[DBASE item name_esc],[DBASE item name_raw] Item name from the attribute table of a queried layer. Only attributes for the active query layers are accessible. Case must be the same as what is stored in the DBASE le. ArcView, for example, uses all caps for shapele eld names. Available only when processing query results. By default the attributes are encoded especially for HTML representation. In addition the escaped version (for use in URLs) as well as the raw data is available. [Join name_DBASE item name],[Join name_DBASE item name_esc], [Join name_DBASE item name_raw] One-to-one joins: First the join name (as specied in the Maple has to be given, second the tables elds can be accessed similar to the layers attribute data. Available only when processing query results. By default the attributes are encoded especially for HTML representation. In addition the escaped version (for use in URLs) as well as the raw data is available. [join_Join name] One-to-many joins: The more complex variant. If the join type is multiple (one-to-many) the template is replaced by the set of header, template le and footer specied in the Maple. [metadata_meta data key], [metadata_meta data key_esc] Queried data_projection] Also available as escaped version. For query modes that allow for multiple result sets, the following string substitutions are available. For FEATURESELECT and FEATURENSELECT modes the totals a re adjusted so as not to include the selection layer. The selection layer results ARE available for display to the user. [nr] Total number of results. Useful in web header and footers. Available only when processing query results. [nl] Number of layers returning results. Useful in web header and footers. Available only when processing query results. [nlr] Total number of results within the current layer. Useful in web header and footers. Available only when processing query results. [rn] Result number within all layers. Starts at 1. Useful in web header and footers. Available only when processing query results. [lrn] Result number within the current layer. Starts at 1. Useful in query templates. Available only when processing query results. [cl] Current layer name. Useful in layer headers and footers. Available only when processing query results. 5.21. Templating 135 layer meta data access (e.g [meta-
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/transitional.dtd"> <html> <head> <title>MapServer Template Sample</title> </head> <body> MapServer Template Sample<br> <!-- The central form the application is based on. --> <form method="GET" action="[program]"> <!-- CGI MapServer applications are server stateless in principle, all information must be "stored" in the client. This includes some basic settings as below. The example is based on the pan and zoom test suite: http://maps.dnr.state.mn.us/mapserver_demos/tests36/ <input type="hidden" name="map" value="[map]"> <input type="hidden" name="imgext" value="[mapext]"> <input type="hidden" name="imgxy" value="149.5 199.5"> <input type="hidden" name="program" value="[program]"> <input type="hidden" name="htmlroot" value="[htmlroot]"> <input type="hidden" name="map_web" value="[map_web]"> <!-- A table for minimal page formatting. --> <table border=0 cellpadding=5> <tr> <!-- First column: Map and scale bar --> <td align=center> <!-- The map --> <input type="image" name="img" src="[img]" style="border:0;width:300;height:400"> <br> <!-- The scale bar--> <img src="[scalebar]" alt="Scale Bar"> </td> <!-- Second column: Zoom direction, Legend and Reference --> <td valign=top> <!-- Zoom direction --> <b>Map Controls</b><br> Set your zoom option:<br> <select name="zoom" size="1"> <option value="2" [ z o o m _ 2 _ s e l e c t ] > Zoom in 2 times <option value="1" [ z o o m _ 1 _ s e l e c t ] > Recenter Map
-->
<option value="-2" [ z o o m _ - 2 _ s e l e c t ] > Zoom out 2 times </select> <br> <!-- Legend --> <b>Legend</b><br> <img src="[legend]" alt="Legend"><br><br><br><br>
136
Chapter 5. Maple
54 55 56 57 58 59 60 61 62 63 64 65
<!-- Reference map --> <input type="image" name="ref" src="[ref]" style="border:0;width:150;height:150"> </td> </tr> </table> </form> </body> </html>
Example 2. Handling temporary les You have a user based discovery application that generates shapeles and stores them in a users home directory on the server. The username comes from a cookie, the lename comes from a request parameter.
DATA "/home/%username%/tempshp/%filename%"
This feature is only available in the CGI version of MapServer through a maple pre-processor. If you are using MapScript, you will have to code the substitution logic into your application yourself (By writing your own preprocessor).
5.23 WEB
EMPTY [url] URL to forward users to if a query fails. If not dened the value for ERROR is used. ERROR [url] URL to forward users to if an error occurs. Ugly old MapServer error messages will appear if this is not dened FOOTER [lename] Template to use AFTER anything else is sent. Multiresult query modes only. HEADER [lename] Template to use BEFORE everything else has been sent. Multiresult query modes only. IMAGEPATH [path] Path to the temporary directory fro writing temporary les and images. Must be writable by the user the web server is running as. Must end with a / or depending on your platform. IMAGEURL [path] Base URL for IMAGEPATH. This is the URL that will take the web browser to IMAGEPATH to get the images. LOG [lename] File to log MapServer activity in. Must be writable by the user the web server is running as.
137
MAXSCALEDENOM [double] Maximum scale at which this interface is valid. When a user requests a map at a bigger scale, MapServer automatically returns the map at this scale. This effectively prevents user from zooming too far out. Scale is given as the denominator of the actual scale fraction, for example for a map at a scale of 1:24,000 use 24000. Implemented in MapServer 5.0, to replace the deprecated MAXSCALE parameter. Deprecated since version 5.0. MAXSCALE [double] - deprecated Since MapServer 5.0 the proper parameter to use is MAXSCALEDENOM instead. The deprecated MAXSCALE is the maximum scale at which this interface is valid. When a user requests a map at a bigger scale, MapServer automatically returns the map at this scale. This effectively prevents user from zooming too far out. Scale is given as the denominator of the actual scale fraction, for example for a map at a scale of 1:24,000 use 24000. See Also: Map scale MAXTEMPLATE [le|url] Template to be used if above the maximum scale for the app, useful for nesting apps. METADATA This keyword allows for arbitrary data to be stored as name value pairs. This is used with OGC WMS to dene things such as layer title. It can also allow more exibility in creating templates, as anything you put in here will be accessible via template tags. Example:
METADATA title "My layer title" a u t h or "Me!" END
MINSCALEDENOM [double] Minimum scale at which this interface is valid. When a user reqests a map at a smaller scale, MapServer automatically returns the map at this scale. This effectively prevents the user from zooming in too far. Scale is given as the denominator of the actual scale fraction, for example for a map at a scale of 1:24,000 use 24000. Implemented in MapServer 5.0, to replace the deprecated MINSCALE parameter. See Also: Map scale MINSCALE [double] - deprecated Since MapServer 5.0 the proper parameter to use is MINSCALEDENOM instead. The deprecated MINSCALE is the minimum scale at which this interface is valid. When a user reqests a map at a smaller scale, MapServer automatically returns the map at this scale. This effectively prevents the user from zooming in too far. Scale is given as the denominator of the actual scale fraction, for example for a map at a scale of 1:24,000 use 24000. Deprecated since version 5.0. MINTEMPLATE Template to be used if above the minimum scale for the app, useful for nesting apps. OUTPUTFORMAT [mime-type] Format of the query output. Default is text/html. This is experimental, the use of the OUTPUTFORMAT object is recommended instead. TEMPLATE [lename|url] Template le or URL to use in presenting the results to the user in an interactive mode (i.e. map generates map and so on ... )
5.24 Notes
The Maple is NOT case-sensitive. Strings containing non-alphanumeric characters or a MapServer keyword MUST be quoted. It is recommended to put ALL strings in double-quotes.
138
Chapter 5. Maple
For MapServer versions < 5, there was a default maximum of 200 layers per maple (there is no layer limit with MapServer >= 5). This can be changed by editing the map.h le to change the value of MS_MAXLAYERS to the desired number and recompiling. Here are other important default limits when using a MapServer version < 5: MAXCLASSES 250 (set in map.h) MAXSTYLES 5 (set in map.h) MAXSYMBOLS 64 (set in mapsymbol.h) MapServer versions >= 5 have no limits for classes, styles, symbols, or layers. File paths may be given as absolute paths, or as paths relative to the location of the maple. In addition, data les may be specied relative to the SHAPEPATH. The maple has a hierarchical structure, with the MAP object being the root. All other objects fall under this one. Comments are designated with a #. Attributes are named using the following syntax: [ATTRIBUTENAME] ... Note that the name of the attribute included between the square brackets IS CASE SENSITIVE. Generally ESRI generated shapeles have their attributes (.dbf column names) all in upper-case for instance, and for PostGIS, ALWAYS use lower-case. MapServer Regular Expressions are used through the operating systems C Library. For information on how to use and write Regular Expressions on your system, you should read the documentation provided with your C Library. On Linux, this is GLibC, and you can read man 7 regex ... This man page is also available on most UNIXs. Since these RegExs are POSIX compliant, they should be the same on Windows as well, so windows users can try searching the web for man 7 regex since man pages are available all over the web.
5.24. Notes
139
140
Chapter 5. Maple
CHAPTER
SIX
MAPSCRIPT
Release 5.4.0 Date May 28, 2009
6.1 Introduction
This is language agnostic documentation for the MapScript interface to MapServer generated by SWIG. This document is intended for developers and to serve as a reference for writers of more extensive, language specic documentation located at Maple
6.1.1 Appendices
Language-specic extensions are described in the following appendices Python Appendix
6.1.3 fooObj
A paragraph or two about class fooObj. fooObj Attributes attribute [type [access]] Concise description of the attribute. Attribute name are completely lower case. Multiple words are packed together like outlinecolor. Note that because of the way that mapscript is generated many confusing, meaningless, and even dangerous attributes are creeping into objects. See outputFormatObj.refcount for example. Until we get a grip on the structure members we are exposing to SWIG this problem will continue to grow. 141
fooObj Methods method(type mandatory_parameter [, type optional_parameter=default]) [type] Description of the method including elaboration on the method arguments, the methods actions, and returned values. Optional parameters and their default values are enclosed in brackets. Class method names are camel case with a leading lower case character like getExpressionString.
142
Chapter 6. MapScript
Contents SWIG MapScript API Reference Introduction * Appendices * Documentation Elements * fooObj * Additional Documentation MapScript Functions MapScript Classes * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * classObj colorObj errorObj fontSetObj hashTableObj imageObj intarray labelCacheMemberObj labelCacheObj labelObj layerObj legendObj lineObj mapObj markerCacheMemberObj outputFormatObj OWSRequest pointObj projectionObj rectObj referenceMapObj resultCacheMemberObj resultCacheObj scalebarObj shapeleObj shapeObj styleObj symbolObj symbolSetObj webObj
143
6.2.1 Introduction
This is language agnostic documentation for the mapscript interface to MapServer generated by SWIG. This document is intended for developers and to serve as a reference for writers of more extensive, language specic documentation in DocBook format for the MDP. Appendices Language-specic extensions are described in the following appendices Python MapScript Appendix Documentation Elements Classes will be documented in alphabetical order in the manner outlined below. Attributes and methods will be formatted as denition lists with the attribute or method as item, the type or return type as classier, and a concise description. To make the document as agnostic as possible, we refer to the following types: int, oat, and string. There are yet no mapscript methods that return arrays or sequences or accept array or sequence arguments. We will use the SWIG term immutable to indicate that an attributes value is read-only. fooObj A paragraph or two about class fooObj.
fooObj Attributes
attribute [type [access]] Concise description of the attribute. Attribute name are completely lower case. Multiple words are packed together like outlinecolor. Note that because of the way that mapscript is generated many confusing, meaningless, and even dangerous attributes are creeping into objects. See outputFormatObj.refcount for example. Until we get a grip on the structure members we are exposing to SWIG this problem will continue to grow.
fooObj Methods
method(type mandatory_parameter [, type optional_parameter=default]) [type] Description of the method including elaboration on the method arguments, the methods actions, and returned values. Optional parameters and their default values are enclosed in brackets. Class method names are camel case with a leading lower case character like getExpressionString. Additional Documentation Theres no point in duplicating the MapServer Maple Reference, which remains the primary reference for mapscript class attributes.
144
Chapter 6. MapScript
The other important associations for classObj are with styleObj, labelObj, and hashTableObj.
+-------+ 1 0..* +-------+ | Class | ---------> | Style | +-------+ +-------+ +-------+ 1 0..1 +-------+ | Class | ---------> | Label | +-------+ +-------+ +-------+ 1 1 +-----------+ | Class | ---------> | HashTable | +-------+ | -| | metadata | +-----------+
Multiple class styles are now supported in 4.1. See the styleObj section for details on use of multiple class styles. 6.2. SWIG MapScript API Reference 145
classObj Attributes
debug [int] MS_TRUE or MS_FALSE keyimage [string] TODO Not sure what this attribute is for label [labelObj immutable] Denition of class labeling layer [layerObj immutable] Reference to the parent layer maxscale [oat] The maximum scale at which class is drawn metadata [hashTableObj immutable] class metadata hash table. minscale [oat] The minimum scale at which class is drawn name [string] Unique within a layer numstyles [int] Number of styles for class. In the future, probably the 4.4 release, this attribute will be made immutable. status [int] MS_ON or MS_OFF. Draw features of this class or do not. template [string] Template for queries title [string] Text used for legend labeling type [int] The layer type of its parent layer
classObj Methods
new classObj( [ layerObj parent_layer=NULL ] ) [classObj] Create a new child classObj instance at the tail (highest index) of the class array of the parent_layer. A class can be created outside the context of a parent layer by omitting the single constructor argument. clone( ) [classObj] Return an independent copy of the class without a parent layer. createLegendIcon( mapObj map, layerObj layer, int width, int height ) [imageObj] Draw and return a new legend icon. drawLegendIcon( mapObj map, layerObj layer, int width, int height, imageObj image, int dstx, int dsty ) [int] Draw the legend icon onto image at dstx, dsty. Returns MS_SUCCESS or MS_FAILURE. getExpressionString() [string] Return a string representation of the expression enclosed in the quote characters appropriate to the expression type. getFirstMetaDataKey() [string] Returns the rst key in the metadata hash table. With getNextMetaDataKey(), provides an opaque iterator over keys. getMetaData( string key ) [string] Return the value of the classObj metadata at key. getNextMetaDataKey( string lastkey ) [string] Returns the next key in the metadata hash table or NULL if lastkey is the last valid key. If lastkey is NULL, returns the rst key of the metadata hash table. Note: getFirstMetaDataKey(), getMetaData(), and getNextMetaDataKey() are deprecated and will be removed in a future version. Replaced by direct metadata access, see hashTableObj. getStyle( int index ) [styleObj] Return a reference to the styleObj at index in the styles array. See the styleObj section for more details on multiple class styles. 146 Chapter 6. MapScript
getTextString() [string] Return a string representation of the text enclosed in the quote characters appropriate to the text expression type (logical or simple string). insertStyle( styleObj style [, int index=-1 ] ) [int] Insert a copy of style into the styles array at index index. Default is -1, or the end of the array. Returns the index at which the style was inserted. moveStyleDown( int index ) [int] Swap the styleObj at index with the styleObj index + 1. moveStyleUp( int index ) [int] Swap the styleObj at index with the styleObj index - 1. removeStyle( int index ) [styleObj] Remove the styleObj at index from the styles array and return a copy. setExpression( string expression ) [int] Set expression string where expression is a MapServer regular, logical or string expression. Returns MS_SUCCESS or MS_FAILUIRE. setMetaData( string key, string value ) [int] Insert value into the classObj metadata at key. Returns MS_SUCCESS or MS_FAILURE. Note: setMetaData() is deprecated and will be removed in a future version. Replaced by direct metadata access, see hashTableObj. setText( string text ) [int] Set text string where text is a MapServer text expression. Returns MS_SUCCESS or MS_FAILUIRE. Note: Older versions of MapScript (pre-4.8) featured the an undocumented setText() method that required a layerObj be passed as the rst argument. That argument was completely bogus and has been removed. colorObj Since the 4.0 release, MapServer colors are instances of colorObj. A colorObj may be a lone object or an attribute of other objects and have no other associations.
colorObj Attributes
blue [int] Blue component of color in range [0-255] green [int] Green component of color in range [0-255] red [int] Red component of color in range [0-255] pen [int] Dont mess with this unless you know what you are doing! Note: Because of the issue with pen, setting colors by individual components is unreliable. Best practice is to use setRGB(), setHex(), or assign to a new instance of colorObj().
colorObj Methods
new colorObj( [ int red=0, int green=0, int blue=0, int pens=-4 ] ) [colorObj] Create a new instance. The color arguments are optional. setRGB( int red, int green, int blue ) [int] Set all three RGB components. MS_FAILURE. Returns MS_SUCCESS or
setHex( string hexcolor ) [int] Set the color to values specied in case-independent hexadecimal notation. Calling setHex(#ffffff) assigns values of 255 to each color component. Returns MS_SUCCESS or MS_FAILURE. toHex() [string] Complement to setHex, returning a hexadecimal representation of the color components. 6.2. SWIG MapScript API Reference 147
errorObj This class allows inspection of the MapServer error stack. Only needed for the Perl module as the other language modules expose the error stack through exceptions.
errorObj Attributes
code [int] MapServer error code such as MS_IMGERR (1). message [string] Context-dependent error message. routine [string] MapServer function in which the error was set.
errorObj Methods
next [errorObj] Returns the next error in the stack or NULL if the end has been reached. fontSetObj A fontSetObj is always a fontset attribute of a mapObj.
fontSetObj Attributes
lename [string immutable] Path to the fontset le on disk. fonts [hashTableObj immutable] Mapping of fonts. numfonts [int immutable] Number of fonts in set.
fontSetObj Methods
None hashTableObj A hashTableObj is a very simple mapping of case-insensitive string keys to single string values. Map, Layer, and Class metadata have always been hash hables and now these are exposed directly. This is a limited hash that can contain no more than 41 values.
hashTableObj Attributes
numitems [int immutable] Number of hash items.
hashTableObj Methods
clear( ) [void] Empties the table of all items.
148
Chapter 6. MapScript
get( string key [, string default=NULL ] ) [string] Returns the value of the item by its key, or default if the key does not exist. nextKey( [string key=NULL] ) [string] Returns the name of the next key or NULL if there is no valid next key. If the input key is NULL, returns the rst key. remove( string key ) [int] Removes the hash item by its key. Returns MS_SUCCESS or MS_FAILURE. set( string key, string value ) [int] Sets a hash item. Returns MS_SUCCESS or MS_FAILURE. imageObj An image object is a wrapper for GD and GDAL images.
imageObj Attributes
format [outputFormatObj immutable] Image format. height [int immutable] Image height in pixels. imagepath [string immutable] If image is drawn by mapObj.draw(), this is the mapObjs web.imagepath. imageurl [string immutable] If image is drawn by mapObj.draw(), this is the mapObjs web.imageurl. renderer [int] MS_RENDER_WITH_GD, MS_RENDER_WITH_SWF, MS_RENDER_WITH_RAWDATA, MS_RENDER_WITH_PDF, or MS_RENDER_WITH_IMAGEMAP. Dont mess with this! size [int immutable] To access this attribute use the getSize method. Note: the getSize method is inefcient as it does a call to getBytes and then computes the size of the byte array. The bytearray is then immediately discarded. In most cases it is more efcient to call getBytes directly. width [int immutable] Image width in pixels.
imageObj Methods
new imageObj( int width, int height [, outputFormatObj format=NULL [, string lename=NULL ] ] ) [imageObj] Create new instance of imageObj. If lename is specied, an imageObj is created from the le and any specied width, height, and format parameters will be overridden by values of the image in lename. Otherwise, if format is specied an imageObj is created using that format. See the format attribute above for details. If lename is not specied, then width and height should be specied. getBytes() [binary data] Returns the image contents as a binary buffer. The exact form of this buffer will vary by mapscript language (eg. string in Python, byte[] array in Java and C#, unhandled in perl) getSize() [int] Resturns the size of the binary buffer representing the image buffer. Note: the getSize method is inefcient as it does a call to getBytes and then computes the size of the byte array. The byte array is then immediately discarded. In most cases it is more efcient to call getBytes directly. save( string lename [, mapObj parent_map=NULL ] ) [int] Save image to lename. The optional parent_map parameter must be specied if saving GeoTIFF images. write( [ FILE le=NULL ] ) [int] Write image data to an open le descriptor or, by default, to stdout. Returns MS_SUCCESS or MS_FAILURE. 6.2. SWIG MapScript API Reference 149
Note: This method is current enabled for Python and C# only. C# supports writing onto a Stream object. Usercontributed typemaps are needed for Perl, Ruby, and Java. Note: The free() method of imageObj has been deprecated. In MapServer revisions 4+ all instances of imageObj will be properly disposed of by the interpreters garabage collector. If the application cant wait for garabage collection, then the instance can simply be deleted or undefd. intarray An intarray is a utility class generated by SWIG useful for manipulating map layer drawing order. See mapObj::getLayersDrawingOrder for discussion of mapscript use and see http://www.swig.org/Doc1.3/Library.html#Library_nn5 for a complete reference.
intarray Attributes
None
intarray Methods
new intarray( int numitems ) [intarray] Returns a new instance of the specied length. labelCacheMemberObj An individual feature label. The labelCacheMemberObj class is associated with labelCacheObj.
+------------------+ 0..* 1 +------------+ | LabelCacheMember | <--------- | LabelCache | +------------------+ +------------+
labelCacheMemberObj Attributes
classindex [int immutable] Index of the class of the labeled feature. featuresize [oat immutable] TODO label [labelObj immutable] Copied from the class of the labeled feature. layerindex [int immutable] The index of the layer of the labeled feature. numstyles [int immutable] Number of styles as for the class of the labeled feature. point [pointObj immutable] Label point. poly [shapeObj immutable] Label bounding box. shapeindex [int immutable] Index within shapele of the labeled feature. status [int immutable] Has the label been drawn or not? styles [styleObj immutable] TODO this should be protected from SWIG. text [string immutable] Label text. tileindex [int immutable] Tileindex of the layer of the labeled feature. 150 Chapter 6. MapScript
labelCacheMemberObj Methods
None. Note: No real scripting control over labeling currently, but there may be some interesting new possibilities if users have control over labeling text, position, and status. labelCacheObj Set of a maps cached labels. Has no other existence other than as a labelcache attribute of a mapObj. Associated with labelCacheMemberObj and markerCacheMemberObj.
+------------+ 1 0..* +-------------------+ | LabelCache | ---------> | LabelCacheMember | +------------+ + ----------------- + | MarkerCacheMember | +-------------------+
labelCacheObj Attributes
cachesize [int immutable] TODO markercachesize [int immutable] TODO numlabels [int immutable] Number of label members. nummarkers [int immutable] Number of marker members.
labelCacheObj Methods
freeCache( ) [void] Free the labelcache. labelObj A labelObj is associated with a classObj, a scalebarObj, or a legendObj.
+-------+ 0..1 1 +----------+ | Label | <--------- | Class | +-------+ | -------- | | Scalebar | | -------- | | Legend | +----------+
labelObj Attributes
angle [oat] TODO antialias [int] MS_TRUE or MS_FALSE autoangle [int] MS_TRUE or MS_FALSE
151
autofollow [int] MS_TRUE or MS_FALSE. Tells mapserver to compute a curved label for appropriate linear features (see MS RFC 11: Support for Curved Labels for specics). autominfeaturesize: int MS_TRUE or MS_FALSE backgroundcolor [colorObj] Color of background rectangle or billboard. backgroundshadowcolor [colorObj] Color of background rectangle or billboard shadow. backgroundshadowsizex [int] Horizontal offset of drop shadow in pixels. backgroundshadowsizey [int] Vertical offset of drop shadow in pixels. buffer [int] Maybe this shouldve been named padding since thats what it is: padding in pixels around a label. color [colorObj] Foreground color. encoding [string] Supported encoding format to be used for labels. If the format is not supported, the label will not be drawn. Requires the iconv library (present on most systems). The library is always detected if present on the system, but if not the label will not be drawn. Required for displaying international characters in MapServer. More information can be found at: http://www.foss4g.org/FOSS4G/MAPSERVER/mpsnf-i18n-en.html. font [string] Name of TrueType font. force [int] MS_TRUE or MS_FALSE. maxsize [int] Maximum height in pixels for scaled labels. See symbolscale attribute of layerObj. mindistance [int] Minimum distance in pixels between duplicate labels. minfeaturesize [int] Features of this size of greater will be labeled. minsize [int] Minimum height in pixels. offsetx [int] Horizontal offset of label. offsety [int] Vertical offset of label. outlinecolor [colorObj] Color of one point outline. partials [int] MS_TRUE (default) or MS_FALSE. Whether or not labels can ow past the map edges. position [int] MS_UL, MS_UC, MS_UR, MS_CL, MS_CC, MS_CR, MS_LL, MS_LC, MS_LR, or MS_AUTO. shadowcolor [colorObj] Color of drop shadow. shadowsizex [int] Horizontal offset of drop shadow in pixels. shadowsizey [int] Vertical offset of drop shadow in pixels. size [int] Annotation height in pixels. type [int] MS_BITMAP or MS_TRUETYPE. wrap [string] Character on which legend text will be broken to make multi-line legends.
labelObj Methods
None
152
Chapter 6. MapScript
layerObj A layerObj is associated with mapObj. In the most recent revision, an intance of layerObj can exist outside of a mapObj.
+-------+ 0..* 0..1 +-----+ | Layer | <--------> | Map | +-------+ +-----+
and hashTableObj
+-------+ 1 1 +-----------+ | Layer | ---------> | HashTable | +-------+ | -| | metadata | +-----------+
layerObj Attributes
bandsitem [string] The attribute from the index le used to select the source raster band(s) to be used. Normally NULL for default bands processing. classitem [string] The attribute used to classify layer data. connection [string] Layer connection or DSN. connectiontype [int] See MS_CONNECTION_TYPE in mapserver.h for possible values. When setting the connection type setConnectionType() should be used in order to initialize the layer vtable properly. data [string] Layer data denition, values depend upon connectiontype. debug [int] Enable debugging of layer. MS_ON or MS_OFF (default). dump [int] Switch to allow mapserver to return data in GML format. MS_TRUE or MS_FALSE. Default is MS_FALSE. extent [rectObj] optional limiting extent for layer features. lteritem [string] Attribute dening lter. footer [string] TODO group [string] Name of a group of layers. header [string] TODO index [int immutable] Index of layer within parent maps layers array. labelangleitem [string] Attribute dening label angle. labelcache [int] MS_ON or MS_OFF. Default is MS_ON. labelitem [string] Attribute dening feature label text. 6.2. SWIG MapScript API Reference 153
labelmaxscale [oat] Maximum scale at which layer will be labeled. labelminscale [oat] Minimum scale at which layer will be labeled. labelrequires [string] Logical expression. labelsizeitem [string] Attribute dening label size. map [mapObj immutable] Reference to parent map. maxfeatures [int] Maximum number of layer features that will be drawn. For shapele data this means the rst N features where N = maxfeatures. maxscale [oat] Maximum scale at which layer will be drawn. metadata [hashTableObj immutable] Layer metadata. minscale [oat] Minimum scale at which layer will be drawn. name [string] Unique identier for layer. numclasses [int immutable] Number of layer classes. numitems [int immutable] Number of layer feature attributes (items). numjoins [int immutable] Number of layer joins. numprocessing [int immutable] Number of raster processing directives. offsite [colorObj] transparent pixel value for raster layers. postlabelcache [int] MS_TRUE or MS_FALSE. Default is MS_FALSE. requires [string] Logical expression. sizeunits [int] Units of class size values. MS_KILOMETERS, MS_DD or MS_PIXELS status [int] MS_ON, MS_OFF, or MS_DEFAULT. styleitem [string] Attribute dening styles. symbolscale [oat] Scale at which symbols are default size. template [string] Template le. Note that for historical reasons, the query attribute must be non-NULL for a layer to be queryable. tileindex [string] Layer index le for tiling support. tileitem [string] Attribute dening tile paths. tolerance [oat] Search buffer for point and line queries. toleranceunits [int] MS_INCHES, MS_FEET, MS_MILES, MS_METERS, MS_KILOMETERS, MS_DD or MS_PIXELS transform [int] Whether or not layer data is to be transformed to image units. MS_TRUE or MS_FALSE. Default is MS_TRUE. Case of MS_FALSE is for data that are in image coordinates such as annotation points. transparency [int] Layer opacity percentage in range [0, 100]. The special value of MS_GD_ALPHA (1000) indicates that the alpha transparency of pixmap symbols should be honored, and should be used only for layers that use RGBA pixmap symbols. type [int] See MS_LAYER_TYPE in mapserver.h. units [int] Units of the layer. See MS_UNITS in mapserver.h. 154 Chapter 6. MapScript MS_INCHES, MS_FEET, MS_MILES, MS_METERS,
layerObj Methods
new layerObj( [ mapObj parent_map=NULL ] ) [layerObj] Create a new layerObj in parent_map. The layer index of the new layerObj will be equal to the parent_map numlayers - 1. The parent_map arg is now optional and Layers can exist outside of a Map. addFeature( shapeObj shape ) [int] Add a new inline feature on a layer. Returns -1 on error. TODO: Is this similar to inline features in a maple? Does it work for any kind of layer or connection type? addProcessing( string directive ) [void] Adds a new processing directive line to a layer, similar to the PROCESSING directive in a map le. Processing directives supported are specic to the layer type and underlying renderer. applySLD( string sld, string stylelayer ) [int] Apply the SLD document to the layer object. The matching between the sld document and the layer will be done using the layers name. If a namedlayer argument is passed (argument is optional), the NamedLayer in the sld that matchs it will be used to style the layer. See SLD HOWTO for more information on the SLD support. applySLDURL( string sld, string stylelayer ) [int] Apply the SLD document pointed by the URL to the layer object. The matching between the sld document and the layer will be done using the layers name. If a namedlayer argument is passed (argument is optional), the NamedLayer in the sld that matchs it will be used to style the layer. See SLD HOWTO for more information on the SLD support. clearProcessing() [int] Clears the layers raster processing directives. Returns the subsequent number of directives, which will equal MS_SUCCESS if the directives have been cleared. clone() [layerObj] Return an independent copy of the layer with no parent map. close() [void] Close the underlying layer. Note: demote() is removed in MapServer 4.4 draw( mapObj map, imageObj image ) [int] Renders this layer into the target image, adding labels to the cache if required. Returns MS_SUCCESS or MS_FAILURE. TODO: Does the map need to be the map on which the layer is dened? I suspect so. drawQuery( mapObj map, imageObj image ) : Draw query map for a single layer into the target image. Returns MS_SUCCESS or MS_FAILURE. executeWFSGetFeature( layer ) [string] Executes a GetFeature request on a WFS layer and returns the name of the temporary GML le created. Returns an empty string on error. generateSLD() [void] Returns an SLD XML string based on all the classes found in the layers. getClass( int i ) [classObj] Fetch the requested class object. Returns NULL if the class index is out of the legal range. The numclasses eld contains the number of classes available, and the rst class is index 0. getExtent() [rectObj] Fetches the extents of the data in the layer. This normally requires a full read pass through the features of the layer and does not work for raster layers. getFeature( int shapeindex [, int tileindex=-1 ] ) [shapeObj] Return the layer feature at shapeindex and tileindex. getFilterString() [string] Returns the current lter expression. getFirstMetaDataKey() [string] Returns the rst key in the metadata hash table. With getNextMetaDataKey(), provides an opaque iterator over keys. getItem( int i ) [string] Returns the requested item. Items are attribute elds, and this method returns the item name (eld name). The numitems eld contains the number of items available, and the rst item is index zero.
155
getMetaData( string key ) [string] Return the value at key from the metadata hash table. getNextMetaDataKey( string lastkey ) [string] Returns the next key in the metadata hash table or NULL if lastkey is the last valid key. If lastkey is NULL, returns the rst key of the metadata hash table. Note: getFirstMetaDataKey(), getMetaData(), and getNextMetaDataKey() are deprecated and will be removed in a future version. Replaced by direct metadata access, see hashTableObj. getNumFeatures() [int] Returns the number of inline features in a layer. TODO: is this really only online features or will it return the number of non-inline features on a regular layer? getNumResults() [int] Returns the number of entries in the query result cache for this layer. getProcessing( int index) [string] Return the raster processing directive at index. getProjection( ) [string] Returns the PROJ.4 denition of the layers projection. getResult( int i ) [resultCacheMemberObj] Fetches the requested query result cache entry, or NULL if the index is outside the range of available results. This method would normally only be used after issuing a query operation. Note: getNumResults() and getResult() are deprecated in MapServer 4.4. Users should instead use the new querying API described in querying-HOWTO.txt. layerObj::getResults() is the entry point for the new API. getResults() [resultCacheObj] Returns a reference to layers result cache. Should be NULL prior to any query, or after a failed query or query with no results. getShape( shapeObj shape, int tileindex, int shapeindex ) [int] Get a shape from layer data. Note: getShape() is deprecated. Users should adopt getFeature() for new applications. getWMSFeatureInfoURL( mapObj map, int click_x, int click_y, int feature_count, string info_format ) [string] Return a WMS GetFeatureInfo URL (works only for WMS layers) clickX, clickY is the location of to query in pixel coordinates with (0,0) at the top left of the image. featureCount is the number of results to return. infoFormat is the format the format in which the result should be requested. Depends on remote servers capabilities. MapServer WMS servers support only MIME (and should support GML.1 soon). Returns and outputs a warning if layer is not a WMS layer or if it is not queriable. insertClass( classObj class [, int index=-1 ] ) [int] Insert a copy of the class into the layer at the requested index. Default index of -1 means insertion at the end of the array of classes. Returns the index at which the class was inserted. isVisible( ) [int] Returns MS_TRUE or MS_FALSE after considering the layer status, minscale, and maxscale within the context of the parent map. moveClassDown( int class ) [int] The class specied by the class index will be moved up into the array of layers. Returns MS_SUCCESS or MS_FAILURE. ex. moveClassDown(1) will have the effect of moving class 1 down to postion 2, and the class at position 2 will be moved to position 1. moveClassUp( int class ) [int] The class specied by the class index will be moved up into the array of layers. Returns MS_SUCCESS or MS_FAILURE. ex. moveClassUp(1) will have the effect of moving class 1 up to postion 0, and the class at position 0 will be moved to position 1. nextShape( ) [shapeObj] Called after msWhichShapes has been called to actually retrieve shapes within a given area returns a shape object or MS_FALSE example of usage :
156
Chapter 6. MapScript
mapObj map = new mapObj("d:/msapps/gmap-ms40/htdocs/gmap75.map"); layerObj layer = map.getLayerByName(road); int status = layer.open(); status = layer.whichShapes(map.extent); shapeObj shape; while ((shape = layer.nextShape()) != null) { ... } layer.close();
open() [void] Opens the underlying layer. This is required before operations like getFeature() will work, but is not required before a draw or query call. Note: promote() is eliminated in MapServer 4.4. queryByAttributes( mapObj map, string qitem, string qstring, int mode ) [int] Query layer for shapes that intersect current map extents. qitem is the item (attribute) on which the query is performed, and qstring is the expression to match. The query is performed on all the shapes that are part of a CLASS that contains a TEMPLATE value or that match any class in a layer that contains a LAYER TEMPLATE value. Note that the layers FILTER/FILTERITEM are ignored by this function. Mode is MS_SINGLE or MS_MULTIPLE depending on number of results you want. Returns MS_SUCCESS if shapes were found or MS_FAILURE if nothing was found or if some other error happened. queryByFeatures( mapObj map, int slayer ) [int] Perform a query set based on a previous set of results from another layer. At present the results MUST be based on a polygon layer. Returns MS_SUCCESS if shapes were found or MS_FAILURE if nothing was found or if some other error happened queryByIndex( mapObj map, int shapeindex, int tileindex [, int bAddToQuery=MS_FALSE ]) [int] Pop a query result member into the layers result cache. By default clobbers existing cache. Returns MS_SUCCESS or MS_FAILURE. queryByPoint( mapObj map, pointObj point, int mode, oat buffer ) [int] Query layer at point location specied in georeferenced map coordinates (i.e. not pixels). The query is performed on all the shapes that are part of a CLASS that contains a TEMPLATE value or that match any class in a layer that contains a LAYER TEMPLATE value. Mode is MS_SINGLE or MS_MULTIPLE depending on number of results you want. Passing buffer <=0 defaults to tolerances set in the map le (in pixels) but you can use a constant buffer (specied in ground units) instead. Returns MS_SUCCESS if shapes were found or MS_FAILURE if nothing was found or if some other error happened. queryByRect( mapObj map, rectObj rect ) [int] Query layer using a rectangle specied in georeferenced map coordinates (i.e. not pixels). The query is performed on all the shapes that are part of a CLASS that contains a TEMPLATE value or that match any class in a layer that contains a LAYER TEMPLATE value. Returns MS_SUCCESS if shapes were found or MS_FAILURE if nothing was found or if some other error happened. queryByShape( mapObj map, shapeObj shape ) [int] Query layer based on a single shape, the shape has to be a polygon at this point. Returns MS_SUCCESS if shapes were found or MS_FAILURE if nothing was found or if some other error happened removeClass( int index ) [classObj] Removes the class indicated and returns a copy, or NULL in the case of a failure. Note that subsequent classes will be renumbered by this operation. The numclasses eld contains the number of classes available. removeMetaData( string key ) [int] Delete the metadata hash at key. Returns MS_SUCCESS or MS_FAILURE.
157
Note: removeMetaData() is deprecated and will be removed in a future version. Replaced by direct metadata access, see hashTableObj. setConnectionType(int connectiontype, string library_str) [int] Changes the connectiontype of the layer and recreates the vtable according to the new connection type. This method should be used instead of setting the connectiontype parameter directly. In case when the layer.connectiontype = MS_PLUGIN the library_str parameter should also be specied so as to select the library to load by mapserver. For the other connection types this parameter is not used. setExtent( oat minx, oat miny, oat maxx, oat maxy ) [int] Sets the extent of a layer. Returns MS_SUCCESS or MS_FAILURE. setFilter( string lter ) [int] Sets a lter expression similarly to the FILTER expression in a map le. Returns MS_SUCCESS on success or MS_FAILURE if the expression fails to parse. setMetaData( string key, string value ) [int] Assign value to the metadata hash at key. Return MS_SUCCESS or MS_FAILURE. Note: setMetaData() is deprecated and will be removed in a future version. Replaced by direct metadata access, see hashTableObj. setProcessingKey( string key, string value ) [void] Adds or replaces a processing directive of the form key=value. Unlike the addProcessing() call, this will replace an existing processing directive for the given key value. Processing directives supported are specic to the layer type and underlying renderer. setProjection( string proj4 ) [int] Set the layer projection using a PROJ.4 format projection denition (ie. +proj=utm +zone=11 +datum=WGS84 or init=EPSG:26911). Returns MS_SUCCESS or MS_FAILURE. setWKTProjection( string wkt ) [int] Set the layer projection using OpenGIS Well Known Text format. Returns MS_SUCCESS or MS_FAILURE. int whichShapes( rectObj rect ) [int] Performs a spatial, and optionally an attribute based feature search. The function basically prepares things so that candidate features can be accessed by query or drawing functions (eg using nextShape function). Returns MS_SUCCESS or MS_FAILURE. legendObj legendObj is associated with mapObj
+--------+ 0..1 1 +-----+ | Legend | <--------> | Map | +--------+ +-----+
legendObj Attributes
height [int] Legend height. imagecolor [colorObj] Legend background color.
158
Chapter 6. MapScript
keysizex [int] Width in pixels of legend keys. keysizey [int] Pixels. keyspacingx [int] Horizontal padding around keys in pixels. keyspacingy [int] Vertical padding. label [labelObj immutable] legend label. map [mapObj immutable] Reference to parent mapObj. outlinecolor [colorObj] key outline color. position [int] MS_UL, MS_UC, MS_UR, MS_LL, MS_LC, or MS_LR. postlabelcache [int] MS_TRUE or MS_FALSE. status [int] MS_ON, MS_OFF, or MS_EMBED. template [string] Path to template le. width [int] Label width.
legendObj Methods
None lineObj A lineObj is composed of one or more pointObj instances.
+------+ 0..1 1..* +-------+ | Line | ---------> | Point | +------+ +-------+
lineObj Attributes
numpoints [int immutable] Number of points in the line.
lineObj Methods
add(pointObj point) [int] Add point to the line. Returns MS_SUCCESS or MS_FAILURE. get(int index) [pointObj] Return reference to point at index. project(projectionObj proj_in, projectionObj proj_out) [int] Transform line in place from proj_in to proj_out. Returns MS_SUCCESS or MS_FAILURE. set(int index, pointObj point) [int] Set the point at index to point. Returns MS_SUCCESS or MS_FAILURE.
159
outputFormatObj.
+-----+ 1 1..* +--------------+ | Map | ---------> | OutputFormat | +-----+ +------------- +
mapObj Attributes
cellsize [oat] Pixel size in map units. congoptions [hashObj immutable] A hash table of conguration options from CONFIG keywords in the .map. Direct access to cong options is discouraged. Use the setCongOption() and getCongOption() methods instead. datapattern [string] TODO not sure this is meaningful for mapscript. debug [int] MS_TRUE or MS_FALSE. extent [rectObj] Maps spatial extent. fontset [fontSetObj immutable] The maps dened fonts. height [int] Maps output image height in pixels. Note: direct setting of height is deprecated in MapServer version 4.4. Users should set width and height simultaneously using setSize(). imagecolor [colorObj] Initial map background color. imagequality [int] JPEG image quality. Note: map imagequality is deprecated in MapServer 4.4 and should instead be managed through map outputformats. imagetype [string immutable] Name of the current output format. interlace [int] Output image interlacing. Note: map interlace is deprecated in MapServer 4.4 and should instead be managed through map outputformats.
160
Chapter 6. MapScript
lablecache [labelCacheObj immutable] Maps labelcache. legend [legendObj immutable] Reference to maps legend. mappath [string] Filesystem path of the maps maple. maxsize [int] TODO ? name [string] Unique identier. numlayers [int immutable] Number of map layers. numoutputformats [int] Number of output formats. outputformat [outputFormatObj] The currently selected output format. Note: Map outputformat should not be modied directly. Use the selectOutputFormat() method to select named formats. outputformatlist [outputFormatObj[]] Array of the available output formats. Note: Currently only available for C#. A proper typemaps should be implemented for the other languages. querymap [queryMapObj immutable] TODO should this be exposed to mapscript? reference [referenceMapObj immutable] Reference to reference map. resolution [oat] Nominal DPI resolution. Default is 72. scale [oat] The nominal map scale. A value of 25000 means 1:25000 scale. scalebar [scalebarObj immutable] Reference to the scale bar. shapepath [string] Base lesystem path to layer data. status [int] MS_OFF, MS_ON, or MS_DEFAULT. symbolset [symbolSetObj immutable] The maps set of symbols. templatepattern [string] TODO not sure this is meaningful for mapscript. transparent [int] MS_TRUE or MS_FALSE. Note: map transparent is deprecated in MapServer 4.4 and should instead be managed through map outputformats. units [int] MS_DD, MS_METERS, etc. web [webObj immutable] Reference to maps web denitions. width [int] Maps output image width in pixels. Note: direct setting of width is deprecated in MapServer version 4.4. Users should set width and height simultaneously using setSize().
161
mapObj Methods
new mapObj( [ string lename= ] ) [mapObj] Create a new instance of mapObj. Note that the lename is now optional. appendOutputFormat( outputFormatObj format ) [int] Attach format to the maps output format list. Returns the updated number of output formats. applyCongOptions( ) [void] Apply the dened conguration options set by setCongOption(). applySLD( string sldxml ) [int] Parse the SLD XML string sldxml and apply to map layers. Returns MS_SUCCESS or MS_FAILURE. applySLDURL( string sldurl ) [int] Fetch SLD XML from the URL sldurl and apply to map layers. Returns MS_SUCCESS or MS_FAILURE. clone( ) [mapObj] Returns a independent copy of the map, less any caches. Note: In the Java module this method is named cloneMap. draw( ) [imageObj] Draw the map, processing layers according to their dened order and status. Return an imageObj. drawLabelCache( imageObj image ) [int] Draw maps label cache on image. MS_FAILURE. drawLegend( ) [imageObj] Draw map legend, returning an imageObj. drawQuery( ) [imageObj] Draw query map, returning an imageObj. drawReferenceMap( ) [imageObj] Draw reference map, returning an imageObj. drawScalebar( ) [imageObj] Draw scale bar, returning an imageObj. embedLegend( imageObj image ) [int] Embed maps legend in image. Returns MS_SUCCESS or MS_FAILURE. embedScalebar( imageObj image ) [int] Embed maps scalebar in image. MS_FAILURE. Returns MS_SUCCESS or Returns MS_SUCCESS or
freeQuery( [ int qlayer=-1 ] ) [void] Clear layer query result caches. Default is -1, or all layers. generateSLD( ) [string] Return SLD XML as a string for map layers. getCongOption( string key ) [string] Fetches the value of the requested conguration key if set. Returns NULL if the key is not set. getFirstMetaDataKey( ) [string] Returns the rst key in the web.metadata hash table. With getNextMetaDataKey( ), provides an opaque iterator over keys. getLayer( int index ) [layerObj] Returns a reference to the layer at index. getLayerByName( string name ) [layerObj] Returns a reference to the named layer. getLayersDrawingOrder( ) [int*] Returns an array of layer indexes in drawing order. Note: Unless the proper typemap is implemented for the modules language a user is more likely to get back an unuseable SWIG pointer to the integer array. getMetaData( string key ) [string] Return the value at key from the web.metadata hash table. getNextMetaDataKey( string lastkey ) [string] Returns the next key in the web.metadata hash table or NULL if lastkey is the last valid key. If lastkey is NULL, returns the rst key of the metadata hash table. 162 Chapter 6. MapScript
getNumSymbols( ) [int] Return the number of symbols in map. getOutputFormatByName( string imagetype ) [outputFormatObj] Return the output format corresponding to driver name imagetype or to format name imagetype. This works exactly the same as the IMAGETYPE directive in a maple, is case insensitive and allows an output format to be found either by driver (like GD/PNG) or name (like PNG24). getProjection( ) [string] Returns the PROJ.4 denition of the maps projection. getSymbolByName( string name ) [int] Return the index of the named symbol in the maps symbolset. Note: This method is poorly named and too indirect. It is preferrable to use the getSymbolByName method of symbolSetObj, which really does return a symbolObj reference, or use the index method of symbolSetObj to get a symbols index number. insertLayer( layerObj layer [, int nIndex=-1 ] ) [int] Insert a copy of layer into the Map at index nIndex. The default value of nIndex is -1, which means the last possible index. Returns the index of the new Layer, or -1 in the case of a failure. loadMapContext( string lename [, int useUniqueNames=MS_FALSE ] ) [int] Load an OGC map context le to dene extents and layers of a map. loadOWSParameters( OWSRequest request [, string version=1.1.1 ] ) [int] Load OWS request parameters (BBOX, LAYERS, &c.) into map. Returns MS_SUCCESS or MS_FAILURE. loadQuery( string lename ) [int] Load a saved query. Returns MS_SUCCESS or MS_FAILURE. moveLayerDown( int layerindex ) [int] Move the layer at layerindex down in the drawing order array, meaning that it is drawn later. Returns MS_SUCCESS or MS_FAILURE. moveLayerUp( int layerindex ) [int] Move the layer at layerindex up in the drawing order array, meaning that it is drawn earlier. Returns MS_SUCCESS or MS_FAILURE. nextLabel( ) [labelCacheMemberObj] Return the next label from the maps labelcache, allowing iteration over labels. Note: nextLabel() is deprecated and will be removed in a future version. Replaced by getLabel(). getLabel( int labelindex ) [labelCacheMemberObj] Return label at specied index from the maps labelcache. OWSDispatch( OWSRequest req ) [int] Processes and executes the passed OpenGIS Web Services request on the map. Returns MS_DONE (2) if there is no valid OWS request in the req object, MS_SUCCESS (0) if an OWS request was successfully processed and MS_FAILURE (1) if an OWS request was not successfully processed. OWS requests include WMS, WFS, WCS and SOS requests supported by MapServer. Results of a dispatched request are written to stdout and can be captured using the msIO services (ie. msIO_installStdoutToBuffer() and msIO_getStdoutBufferString()) prepareImage( ) [imageObj] Returns an imageObj initialized to map extents and outputformat. prepareQuery( ) [void] TODO this function only calculates the scale or am I missing something? processLegendTemplate( string names[], string values[], int numitems ) [string] Process MapServer legend template and return HTML. processQueryTemplate( string names[], string values[], int numitems ) [string] Process MapServer query template and return HTML. processTemplate( int generateimages, string names[], string values[], int numitems ) [string] Process MapServer template and return HTML.
163
Note: None of the three template processing methods will be useable unless the proper typemaps are implemented in the module for the target language. Currently the typemaps are not implemented. queryByFeatures( int layerindex ) [int] Query map layers, result sets contain features that intersect or are contained within the features in the result set of the MS_LAYER_POLYGON type layer at layerindex. Returns MS_SUCCESS or MS_FAILURE. queryByPoint( pointObj point, int mode, oat buffer ) [int] Query map layers, result sets contain one or more features, depending on mode, that intersect point within a tolerance buffer. Returns MS_SUCCESS or MS_FAILURE. queryByRect( rectObj rect ) [int] Query map layers, result sets contain features that intersect or are contained within rect. Returns MS_SUCCESS or MS_FAILURE. queryByShape( shapeObj shape ) [int] Query map layers, result sets contain features that intersect or are contained within shape. Returns MS_SUCCESS or MS_FAILURE. removeLayer( int index ) [int] Remove the layer at index. removeMetaData( string key ) [int] Delete the web.metadata hash at key. MS_FAILURE. Returns MS_SUCCESS or
removeOutputFormat( string name ) [int] Removes the format named name from the maps output format list. Returns MS_SUCCESS or MS_FAILURE. save( string lename ) [int] Save map to disk as a new map le. Returns MS_SUCCESS or MS_FAILURE. saveMapContext( string lename ) [int] Save map denition to disk as OGC-compliant XML. Returns MS_SUCCESS or MS_FAILURE. saveQuery( string lename ) [int] Save query to disk. Returns MS_SUCCESS or MS_FAILURE. saveQueryAsGML( string lename ) [int] Save query to disk. Returns MS_SUCCESS or MS_FAILURE. selectOutputFormat( string imagetype ) [void] Set the maps active output format to the internal format named imagetype. Built-in formats are PNG, PNG24, JPEG, GIF, GTIFF. setCongOption( string key, string value ) [void] Set the indicated key conguration option to the indicated value. Equivalent to including a CONFIG keyword in a map le. setExtent( oat minx, oat miny, oat maxx, oat maxy ) [int] Set the map extent, returns MS_SUCCESS or MS_FAILURE. offsetExtent( oat x, oat y) [int] Offset the map extent based on the given distances in map coordinates, returns MS_SUCCESS or MS_FAILURE. scaleExtent( oat zoomfactor, oat minscaledenom, oat maxscaledenom) [int] Scale the map extent using the zoomfactor and ensure the extent within the minscaledenom and maxscaledenom domain. If minscaledenom and/or maxscaledenom is 0 then the parameter is not taken into account. returns MS_SUCCESS or MS_FAILURE. setCenter( pointObj center ) [int] Set the map center to the given map point, returns MS_SUCCESS or MS_FAILURE. setFontSet( string lename ) [int] Load fonts dened in lename into map fontset. The existing fontset is cleared. Returns MS_SUCCESS or MS_FAILURE. setImageType( string name ) [void] Sets map outputformat to the named format. Note: setImageType() remains in the module but its use is deprecated in favor of selectOutputFormat(). 164 Chapter 6. MapScript
setLayersDrawingOrder( int layerindexes[]) [int] Set map layer drawing order. Note: Unless the proper typemap is implemented for the modules language users will not be able to pass arrays or lists to this method and it will be unusable. setMetaData( string key, string value ) [int] Assign value to the web.metadata hash at key. Return MS_SUCCESS or MS_FAILURE. setOutputFormat( outputFormatObj format ) [void] Sets map outputformat. setProjection( string proj4 ) [int] Set map projection from PROJ.4 denition string proj4. setRotation( oat rotation_angle ) [int] Set map rotation angle. The map view rectangle (specied in EXTENTS) will be rotated by the indicated angle in the counter- clockwise direction. Note that this implies the rendered map will be rotated by the angle in the clockwise direction. Returns MS_SUCCESS or MS_FAILURE. setSize( int width, int height ) [int] Set maps image width and height together and carry out the necessary subsequent geotransform computation. Returns MS_SUCCESS or MS_FAILURE. setSymbolSet( string lename ) [int] Load symbols dened in lename into map symbolset. The existing symbolset is cleared. Returns MS_SUCCESS or MS_FAILURE. setWKTProjection( string wkt ) [int] Sets map projection from OGC denition wkt. zoomPoint( int zoomfactor, pointObj imgpoint, int width, int height, rectObj extent, rectObj maxextent ) [int] Zoom by zoomfactor to imgpoint in pixel units within the image of height and width dimensions and georeferenced extent. Zooming can be constrained to a maximum maxextent. Returns MS_SUCCESS or MS_FAILURE. zoomRectangle( rectObj imgrect, int width, int height, rectObj extent, rectObj maxextent ) [int] Zoom to a pixel coordinate rectangle in the image of width and height dimensions and georeferencing extent. Zooming can be constrained to a maximum maxextent. Returns MS_SUCCESS or MS_FAILURE. zoomScale( oat scale, pointObj imgpoint, int width, int height, rectObj extent, rectObj maxextent) [int] Like the previous methods, but zooms to the point at a specied scale. markerCacheMemberObj An individual marker. The markerCacheMemberObj class is associated with labelCacheObj.
+------------------+ 0..* 1 +------------+ | MarkerCacheMember | <--------- | LabelCache | +------------------+ +------------+
markerCacheMemberObj Attributes
id [int immutable] Id of the marker. poly [shapeObj immutable] Marker bounding box.
markerCacheMemberObj Methods
None.
165
outputFormatObj Attributes
bands [int] The number of bands in the raster. Only used for the raw modes, MS_IMAGEMODE_BYTE, MS_IMAGEMODE_INT16, and MS_IMAGEMODE_FLOAT32. Normally set via the BAND_COUNT formatoption ... this eld should be considered read-only. driver [string] A string such as GD/PNG or GDAL/GTiff. extension [string] Format le extension such as png. imagemode [int] MS_IMAGEMODE_PC256, MS_IMAGEMODE_RGB, MS_IMAGEMODE_RGBA, MS_IMAGEMODE_INT16, MS_IMAGEMODE_FLOAT32, MS_IMAGEMODE_BYTE, or MS_IMAGEMODE_NULL. mimetype [string] Format mimetype such as image/png. name [string] A unique identier. renderer [int] MS_RENDER_WITH_GD, MS_RENDER_WITH_SWF, MS_RENDER_WITH_RAWDATA, MS_RENDER_WITH_PDF, or MS_RENDER_WITH_IMAGEMAP. Normally set internally based on the driver and some other setting in the constructor. transparent [int] MS_ON or MS_OFF.
outputFormatObj Methods
new outputFormatObj( string driver [, string name=driver ] ) [outputFormatObj] Create new instance. If name is not provided, the value of driver is used as a name. getOption( string key [, string value= ] ) [string] Return the format option at key or value if key is not a valid hash index. setExtension( string extension ) [void] Set le extension for output format such as png or jpg. Method could probably be deprecated since the extension attribute is mutable. setMimetype( string mimetype ) [void] Set mimetype for output format such as image/png or image/jpeg. Method could probably be deprecated since the mimetype attribute is mutable. setOption( string key, string value ) [void] Set the format option at key to value. Format options are mostly driver specic. validate() [int] Checks some internal consistency issues, and returns MS_TRUE if things are OK and MS_FALSE if there are problems. Some problems are xed up internally. May produce debug output if issues encountered.
166
Chapter 6. MapScript
OWSRequest Not associated with other mapscript classes. Serves as a message intermediary between an application and MapServers OWS capabilities. Using it permits creation of lightweight WMS services:
wms_map = mapscript.mapObj(wms.map) wms_request = mapscript.OWSRequest() # Convert application request parameters (req.args) for param, value in req.args.items(): wms_request.setParam(param, value) # Map loads parameters from OWSRequest, adjusting its SRS, extents, # active layers accordingly wms_map.loadWMSRequest(1.1.0, wms_request) # Render the Map img = wms_map.draw()
OWSRequest Attributes
NumParams [int immutable] Number of request parameters. Eventually should be changed to numparams lowercase like other attributes. postrequest [string] TODO type [int] MS_GET_REQUEST or MS_POST_REQUEST.
OWSRequest Methods
new OWSRequest( ) [OWSRequest] Create a new instance. setParameter( string name, string value ) [void] Set a request parameter. For example
request.setParameter(REQUEST, GetMap) request.setParameter(BBOX, -107.0,40.0,-106.0,41.0)
Note: MapServers OWSRequest supports only single valued parameters. getName( int index ) [string] Return the name of the parameter at index in the requests array of parameter names. getValue( int index ) [string] Return the value of the parameter at index in the requests array of parameter values. getValueByName( string name) [string] Return the value associated with the parameter name. loadParams() [int] Initializes the OWSRequest object from the cgi environment variables REQUEST_METHOD, QUERY_STRING and HTTP_COOKIE. Returns the number of name/value pairs collected. Warning: most errors will result in a process exit! pointObj A pointObj instance may be associated with a lineObj.
167
pointObj Attributes
m [oat] Measure. Meaningful only for measured shapeles. Given value -2e38 if not otherwise assigned to indicate nodata. x [oat] Easting y [oat] Northing z [oat] Elevation
pointObj Methods
new pointObj( [ oat x=0.0, oat y=0.0, oat z=0.0, oat m=-2e38 ] ) [pointObj] Create new instance. Easting, northing, and measure arguments are optional. distanceToPoint( pointObj point ) [oat] Returns the distance to point. distanceToSegment( pointObj point1, pointObj point2 ) [oat] Returns the minimum distance to a hypothetical line segment connecting point1 and point2. distanceToShape( shapeObj shape ) [oat] Returns the minimum distance to shape. draw( mapObj map, layerObj layer, imageObj image, int classindex, string text ) [int] Draw the point using the styles dened by the classindex class of layer and labeled with string text. Returns MS_SUCCESS or MS_FAILURE. project( projectionObj proj_in, projectionObj proj_out ) [int] Reproject point from proj_in to proj_out. Transformation is done in place. Returns MS_SUCCESS or MS_FAILURE. setXY( oat x, oat y [, oat m=2e-38 ] ) [int] Set spatial coordinate and, optionally, measure values simultaneously. The measure will be set only if the value of m is greater than the ESRI measure no-data value of 1e-38. Returns MS_SUCCESS or MS_FAILURE. setXYZ( oat x, oat y, oat z [, oat m=-2e38 ] ) [int] Set spatial coordinate and, optionally, measure values simultaneously. The measure will be set only if the value of m is greater than the ESRI measure no-data value of -1e38. Returns MS_SUCCESS or MS_FAILURE. setXYZM( oat x, oat y, oat z, oat m ) [int] Set spatial coordinate and, optionally, measure values simultaneously. The measure will be set only if the value of m is greater than the ESRI measure no-data value of -1e38. Returns MS_SUCCESS or MS_FAILURE. toString() [string] Return a string formatted like
{ x: %f , y: %f, z: %f }
with the coordinate values substituted appropriately. Python users can get the same effect via the pointObj __str__ method
>>> p = mapscript.pointObj(1, 1) >>> str(p) { x: 1.000000 , y: 1.000000, z: 1.000000 }
168
Chapter 6. MapScript
toShape() [shapeObj] Convience method to quickly turn a point into a shapeObj. projectionObj This class is not really fully implemented yet. MapServers Maps and Layers have Projection attributes, and these are C projectionObj structures, but are not directly exposed by the mapscript module. Currently we have to do some round-a-bout logic like this
point.project(projectionObj(mapobj.getProjection(), projectionObj(layer.getProjection())
projectionObj Attributes
numargs [int immutable] Number of PROJ.4 arguments.
projectionObj Methods
new projectionObj( string proj4 ) [projectionObj] Create new instance of projectionObj. Input parameter proj4 is a PROJ.4 denition string such as init=EPSG:4269. getUnits() [int] Returns the units of a projection object. Returns -1 on error. rectObj A rectObj may be a lone object or an attribute of another object and has no other associations.
rectObj Attributes
maxx [oat] Maximum easting maxy [oat] Maximum northing minx [oat] Minimum easting miny [oat] Minimum northing
rectObj Methods
new rectObj( [ oat minx=-1.0, oat miny=-1.0, oat maxx=-1.0, oat maxy=-1.0, int imageunits=MS_FALSE ] ) [rectObj] Create new instance. The four easting and northing arguments are optional and default to -1.0. Note the new optional fth argument which allows creation of rectangles in image (pixel/line) units which are also tested for validity. draw( mapObj map, layerObj layer, imageObj img, int classindex, string text ) [int] Draw rectangle into img using style dened by the classindex class of layer. The rectangle is labeled with the string text. Returns MS_SUCCESS or MS_FAILURE. getCenter() [pointObj] Return the center point of the rectagle.
169
project( projectionObj proj_in, projectionObj proj_out ) [int] Reproject rectangle from proj_in to proj_out. Transformation is done in place. Returns MS_SUCCESS or MS_FAILURE. toPolygon() [shapeObj] Convert to a polygon of ve vertices. toString() [string] Return a string formatted like
{ minx: %f , miny: %f , maxx: %f , maxy: %f }
with the bounding values substituted appropriately. Python users can get the same effect via the rectObj __str__ method
>>> r = mapscript.rectObj(0, 0, 1, 1) >>> str(r) { minx: 0 , miny: 0 , maxx: 1 , maxy: 1 }
referenceMapObj Attributes
color [colorObj] Color of reference box. extent [rectObj] Spatial extent of reference in units of parent map. height [int] Height of reference map in pixels. image [string] Filename of reference map image. map [mapObj immutable] Reference to parent mapObj. marker [int] Index of a symbol in the map symbol set to use for marker. markername [string] Name of a symbol. markersize [int] Size of marker. maxboxsize [int] Pixels. minboxsize [int] Pixels. outlinecolor [colorObj] Outline color of reference box. status [int] MS_ON or MS_OFF. width [int] In pixels.
referenceMapObj Methods
None
170
Chapter 6. MapScript
resultCacheMemberObj Has no associations with other MapScript classes and has no methods. By using several indexes, a resultCacheMemberObj refers to a single layer feature.
resultCacheMemberObj Attributes
classindex [int immutable] The index of the layer class into which the feature has been classied. shapeindex [int immutable] Index of the feature within the layer. tileindex [int immutable] Meaningful for tiled layers only, index of the shapele data tile. resultCacheObj See querying-HOWTO.txt for extra guidance in using the new 4.4 query API.
resultCacheObj Attributes
bounds [rectObj immutable] Bounding box of query results. numresults [int immutable] Length of result set.
resultCacheObj Methods
getResult( int i ) [resultCacheObj] Returns the result at index i, like layerObj::getResult, or NULL if index is outside the range of results. scalebarObj A scalebarObj is associated with mapObj.
+----------+ 0..1 1 +-----+ | Scalebar | <--------- | Map | +----------+ +-----+
scalebarObj Attributes
backgroundcolor [colorObj] Scalebar background color. color [colorObj] Scalebar foreground color. imagecolor [colorObj] Background color of scalebar.
171
height [int] Pixels. intervals [int] Number of intervals. label [labelObj] Scalebar label. outlinecolor [colorObj] Foreground outline color. position [int] MS_UL, MS_UC, MS_UR, MS_LL, MS_LC, or MS_LR. postlabelcache [int] MS_TRUE or MS_FALSE. status [int] MS_ON, MS_OFF, or MS_EMBED. style [int] 0 or 1. units [int] See MS_UNITS in mapserver.h. width [int] Pixels.
scalebarObj Methods
None shapeleObj
shapeleObj Attributes
bounds [rectObj] Extent of shapes numshapes [int] Number of shapes type [int] See mapshape.h for values of type.
shapeleObj Methods
new shapeleObj( string lename [, int type=-1 ] ) [shapeleObj] Create a new instance. Omit the type argument or use a value of -1 to open an existing shapele. add( shapeObj shape ) [int] Add shape to the shapele. Returns MS_SUCCESS or MS_FAILURE. get( int i, shapeObj shape ) [int] Get the shapele feature from index i and store it in shape. Returns MS_SUCCESS or MS_FAILURE. getShape( int i ) [shapeObj] Returns the shapele feature at index i. More effecient than get. TODO shapeObj Each feature of a layers data is a shapeObj. Each part of the shape is a closed lineObj.
+-------+ 1 1..* +------+ | Shape | --------> | Line | +-------+ +------+
172
Chapter 6. MapScript
shapeObj Attributes
bounds [rectObj] Bounding box of shape. classindex [int] The class index for features of a classied layer. index [int] Feature index within the layer. numlines [int immutable] Number of parts. numvalues [int immutable] Number of shape attributes. text [string] Shape annotation. tileindex [int] Index of tiled le for tileindexed layers. type [int] MS_SHAPE_POINT, MS_SHAPE_LINE, MS_SHAPE_POLYGON, or MS_SHAPE_NULL.
shapeObj Methods
new shapeObj( int type ) [shapeObj] Return a new shapeObj of the specied type. See the type attribute above. No attribute values created by default. initValues should be explicitly called to create the required number of values. add( lineObj line ) [int] Add line (i.e. a part) to the shape. Returns MS_SUCCESS or MS_FAILURE. boundary() [shapeObj] Returns the boundary of the existing shape. Requires GEOS support. Returns NULL/undef on failure. buffer( int distance ) [shapeObj] Returns a new buffered shapeObj based on the supplied distance (given in the coordinates of the existing shapeObj). Requires GEOS support. Returns NULL/undef on failure. contains( pointObj point ) [int] Returns MS_TRUE if the point is inside the shape, MS_FALSE otherwise. contains( shapeObj shape2 ) [int] Returns MS_TRUE if shape2 is entirely within the shape. Returns -1 on error and MS_FALSE otherwise. Requires GEOS support. convexHull() [shapeObj] Returns the convex hull of the existing shape. NULL/undef on failure. Requires GEOS support. Returns
copy( shapeObj shape_copy ) [int] Copy the shape to shape_copy. Returns MS_SUCCESS or MS_FAILURE. clone() [shapeObj] Return an independent copy of the shape. crosses( shapeObj shape2 ) [int] Returns MS_TRUE if shape2 crosses the shape. MS_FALSE otherwise. Requires GEOS support. Returns -1 on error and
difference( shapeObj shape ) [shapeObj] Returns the computed difference of the supplied and existing shape. Requires GEOS support. Returns NULL/undef on failure. disjoint( shapeObj shape2 ) [int] Returns MS_TRUE if shape2 and the shape are disjoint. Returns -1 on error and MS_FALSE otherwise. Requires GEOS support. distanceToPoint( pointObj point ) [oat] Return distance to point. distanceToShape( shapeObj shape ) [oat] Return the minimum distance to shape. draw( mapObj map, layerObj layer, imageObj img ) [int] Draws the individual shape using layer. MS_SUCCESS or MS_FAILURE. Returns
equals( shapeObj shape2 ) [int] Returns MS_TRUE if the shape and shape2 are equal (geometry only). Returns -1 on error and MS_FALSE otherwise. Requires GEOS support. 6.2. SWIG MapScript API Reference 173
fromWKT( char \*wkt ) [shapeObj] Returns a new shapeObj based on a well-known text representation of a geometry. Requires GEOS support. Returns NULL/undef on failure. get( int index ) [lineObj] Returns a reference to part at index. Reference is valid only during the life of the shapeObj. getArea() [double] Returns the area of the shape (if applicable). Requires GEOS support. getCentroid() [pointObj] Returns the centroid for the existing shape. Requires GEOS support. Returns NULL/undef on failure. getLength() [double] Returns the length (or perimeter) of a shape. Requires GEOS support. getValue( int i ) [string] Return the shape attribute at index i. initValues( int numvalues ) [void] Allocates memory for the requested number of values. intersects( shapeObj shape ) [int] Returns MS_TRUE if the two shapes intersect, MS_FALSE otherwise. Note, does not require GEOS support but will use GEOS functions if available. intersection( shapeObj shape ) [shapeObj] Returns the computed intersection of the supplied and existing shape. Requires GEOS support. Returns NULL/undef on failure. overlaps( shapeObj shape2 ) [int] Returns MS_TRUE if shape2 overlaps shape. Returns -1 on error and MS_FALSE otherwise. Requires GEOS support. project( projectionObj proj_in, projectionObj proj_out ) [int] Reproject shape from proj_in to proj_out. Transformation is done in place. Returns MS_SUCCESS or MS_FAILURE. setBounds [void] Must be called to calculate new bounding box after new parts have been added. TODO: should return int and set msSetError. setValue( int i, string value ) [int] Set the shape value at index i to value. symDifference( shapeObj shape ) [shapeObj] Returns the computed symmetric difference of the supplied and existing shape. Requires GEOS support. Returns NULL/undef on failure. touches( shapeObj shape2 ) [int] Returns MS_TRUE if the shape and shape2 touch. Returns -1 on error and MS_FALSE otherwise. Requires GEOS support. toWKT() [string] Returns the well-known text representation of a shapeObj. Requires GEOS support. Returns NULL/undef on failure. Union( shapeObj shape ) [shapeObj] Returns the union of the existing and supplied shape. Shapes must be of the same type. Requires GEOS support. Returns NULL/undef on failure. within( shapeObj shape2 ) [int] Returns MS_TRUE if the shape is entirely within shape2. Returns -1 on error and MS_FALSE otherwise. Requires GEOS support. styleObj An instance of styleObj is associated with one instance of classObj.
+-------+ 0..* 1 +-------+ | Style | <-------- | Class | +-------+ +-------+
An instance of styleObj can exist outside of a classObj container and be explicitly inserted into the classObj for use in mapping.
174
Chapter 6. MapScript
It is important to understand that insertStyle inserts a copy of the styleObj instance, not a reference to the instance itself. The older use case
new_style = new styleObj(the_class)
remains supported. These will be the only ways to access the styles of a class. Programmers should no longer directly access the styles attribute.
styleObj Attributes
angle [double] Angle, given in degrees, to draw the line work. Default is 0. For symbols of Type HATCH, this is the angle of the hatched lines. angleitem [string] Attribute/eld that stores the angle to be used in rendering. Angle is given in degrees with 0 meaning no rotation. antialias [int] MS_TRUE or MS_FALSE. Should TrueType fonts and Cartoline symbols be antialiased. backgroundcolor [colorObj] Background pen color. color [colorObj] Foreground or ll pen color. mincolor [colorObj] Attribute for Color Range Mapping (MS RFC 6: Color Range Mapping of Continuous Feature Values). mincolor, minvalue, maxcolor, maxvalue dene the range for mapping a continuous feature value to a continuous range of colors when rendering the feature on the map. minsize [int] Minimum pen or symbol width for scaling styles. minvalue [double] Attribute for Color Range Mapping (MS RFC 6: Color Range Mapping of Continuous Feature Values). mincolor, minvalue, maxcolor, maxvalue dene the range for mapping a continuous feature value to a continuous range of colors when rendering the feature on the map. minwidth [int] Minimum width of the symbol. maxcolor [colorObj] Attribute for Color Range Mapping (MS RFC 6: Color Range Mapping of Continuous Feature Values). mincolor, minvalue, maxcolor, maxvalue dene the range for mapping a continuous feature value to a continuous range of colors when rendering the feature on the map. maxsize [int] Maximum pen or symbol width for scaling. maxvalue [double] Attribute for Color Range Mapping (MS RFC 6: Color Range Mapping of Continuous Feature Values). mincolor, minvalue, maxcolor, maxvalue dene the range for mapping a continuous feature value to a continuous range of colors when rendering the feature on the map. maxwidth [int] Maximum width of the symbol. offsetx [int] Draw with pen or symbol offset from map data. offsety [int] Draw with pen or symbol offset from map data. outlinecolor [colorObj] Outline pen color.
175
rangeitem [string] Attribute/eld that stores the values for the Color Range Mapping (MS RFC 6: Color Range Mapping of Continuous Feature Values). size [int] Pixel width of the styles pen or symbol. sizeitem [string] Attribute/eld that stores the size to be used in rendering. Value is given in pixels. symbol [int] The index within the map symbolset of the styles symbol. symbolname [string immutable] Name of the styles symbol. width [int] Width refers to the thickness of line work drawn, in pixels. Default is 1. For symbols of Type HATCH, the with is how thick the hatched lines are.
styleObj Methods
new styleObj( [ classObj parent_class ] ) [styleObj] Returns new default style Obj instance. The parent_class is optional. clone [styleObj] Returns an independent copy of the style with no parent class. setSymbolByName(mapObj map, string symbolname) [int] Setting the symbol of the styleObj given the reference of the map object and the symbol name. symbolObj A symbolObj is associated with one symbolSetObj.
+--------+ 0..* 1 +-----------+ | Symbol | <-------- | SymbolSet | +--------+ +-----------+
A styleObj will often refer to a symbolObj by name or index, but this is not really an object association, is it?
symbolObj Attributes
antialias [int] MS_TRUE or MS_FALSE. character [string] For TrueType symbols. lled [int] MS_TRUE or MS_FALSE. font [string] For TrueType symbols. gap [int] TODO what is this? imagepath [string] Path to pixmap le. linecap [int] TODO unsure about the cartoline attributes. linejoin [int] TODO linejoinmaxsize [oat] TODO name [string] Symbol name numpoints [int immutable] Number of points of a vector symbol.
176
Chapter 6. MapScript
position [int] TODO ? sizex [oat] TODO what is this? sizey [oat] TODO what is this? stylelength [int] Number of intervals transparent [int] TODO what is this? transparentcolor [int] TODO is this a derelict attribute? type [int] MS_SYMBOL_SIMPLE, MS_SYMBOL_VECTOR, MS_SYMBOL_ELLIPSE, MS_SYMBOL_PIXMAP, MS_SYMBOL_TRUETYPE, or MS_SYMBOL_CARTOLINE.
symbolObj Methods
new symbolObj( string symbolname [, string imagele ] ) [symbolObj] Create new default symbol named name. If imagele is specied, then the symbol will be of type MS_SYMBOL_PIXMAP. getImage() [imageObj] Returns a pixmap symbols imagery as an imageObj. getPoints() [lineObj] Returns the symbol points as a lineObj. setImage( imageObj image ) [int] Set a pixmap symbols imagery from image. setPoints( lineObj line ) [int] Sets the symbol points from the points of line. Returns the updated number of points. setStyle( int index, int value ) [int] Set the style at index to value. Returns MS_SUCCESS or MS_FAILURE. symbolSetObj A symbolSetObj is an attribute of a mapObj and is associated with instances of symbolObj.
+-----------+ 1 0..* +--------+ | SymbolSet | --------> | Symbol | +-----------+ +--------+
symbolSetObj Attributes
lename [string] Symbolset lename numsymbols [int immutable] Number of symbols in the set.
symbolSetObj Methods
new symbolSetObj( [ string symbolle ] ) [symbolSetObj] Create new instance. If symbolle is specied, symbols will be loaded from the le. appendSymbol( symbolObj symbol ) [int] Add a copy of symbol to the symbolset and return its index. getSymbol( int index ) [symbolObj] Returns a reference to the symbol at index. getSymbolByName( string name ) [symbolObj] Returns a reference to the symbol named name.
177
index( string name ) [int] Return the index of the symbol named name or -1 in the case that no such symbol is found. removeSymbol( int index ) [symbolObj] Remove the symbol at index and return a copy of the symbol. save( string lename ) [int] Save symbol set to a le. Returns MS_SUCCESS or MS_FAILURE. webObj Has no other existence than as an attribute of a mapObj. Serves as a container for various run-time web application denitions like temporary le paths, template paths, etc.
webObj Attributes
empty [string] TODO error [string] TODO extent [rectObj] Clipping extent. footer [string] Path to footer document. header [string] Path to header document. imagepath [string] Filesystem path to temporary image location. imageurl [string] URL to temporary image location. log [string] TODO map [mapObj immutable] Reference to parent mapObj. maxscale [oat] Maximum map scale. maxtemplate [string] TODO metadata [hashTableObj immutable] metadata hash table. minscale [oat] Minimum map scale. mintemplate [string] TODO queryformat [string] TODO template [string] Path to template document.
webObj Methods
None.
178
Chapter 6. MapScript
6.3.1 Introduction
Author Jeff McKenna Contact jmckenna at gatewaygeomatics.com Last Updated 2008/07/16
Table of Contents Introduction Abstract Introduction How to Get More Information on PHP/MapScript
Abstract This document describes all of the classes, properties and methods associated with the PHP/MapScript module, and is the online version of the PHP/MapScript README le from the MapServer source code. Introduction PHP MapScript was originally developed for PHP-3.0.14 but after MapServer 3.5 support for PHP3 has been dropped and as of the last update of this document, PHP 4.1.2 or more recent was required. The module has been tested and used on Linux, Solaris, *BSD, and WinNT. This module is constantly under development. How to Get More Information on PHP/MapScript The main resource for help is the PHP/MapScript page on MapTools.org. The MapServer Wiki might have more information on this module For installation questions regarding the PHP/MapScript module, see PHP MapScript Installation. Also, see the MapScript, PHP MapScript and the Maple Refer to the main PHP site for their ofcial documentation
6.3.2 By Example
Author Vinko Vrsalovic Contact el at vinko.cl Revision $Revision: 8365 $ Date $Date: 2008-12-31 07:49:02 -0800 (Wed, 31 Dec 2008) $ Last Updated 2005/12/12
179
Introduction The purpose of this document is to be a step by step explanation of the PHP MapScript with practical examples for each of them. It is assumed a basic knowledge of MAP and MapServer, and familiarity with the PHP (scripting) and HTML (markup) languages . This document was originally created for MapServer v4.0, but the examples still apply to more recent versions. Lets Begin... Hello, kind reader. I am Tut, thank you for downloading me. I am sorry, but I am just a technical manual so I cannot answer any questions. The maintainer, a handsome, very nice and lazy guy according to what I saw from the other side of the screen, maybe will be able to answer your question(s). I am currently here to tell you about MapScript in its PHP incarnation. At my current age, I will be more useful to beginners than advanced users, even though I hope that some day I will be sufciently old to be useful to advanced MapScript programmers. Lets hope I live long enough... sigh. But enough with my personal problems, let myself begin. My duty is to familiarize you with MapScript, and in particular with PHP MapScript. When I end, you are expected to understand what MapScript is, and to be able to write applications to display and navigate that is, zooming and panning over shapeles via a web browser. What follows are the questions you must answer afrmatively before accompanying me through the rest of this journey (I apologize for my maintainers lack of literary taste).
Can you...
code PHP or are willing to learn how to? write and understand HTML documents? (Note that Javascript is a plus) tell somebody what on earth is a shapele [or a PostGIS table]?
A trivial example A simple example Conclusion You can also go to each part directly through my table of contents located at the top, if you wish to skip some sections. MapScript overview Ok, now Im at last arriving at a point I will enjoy. This overview intends to clear some common misconceptions beginners encounter when rst facing MapScript and to give a general overview about MapScripts internals. For now, just look at the following diagram (I apologize again for the maintainers lack of graphic design taste).
It all starts as everything on the Web. A browser requests a certain URL through HTTP. The request arrives at the web server, which, in turn, delivers a le or executes a program and then delivers its output back to the browser. Yes, I know you knew that, but I have been told to be as complete as possible, and I will try to. In MapScripts case, the server executes a certain script, which contains standard language functionality, that is, the same functionality you would have in that language without MapScript, plus access to almost all of the MapServer C API, the level of completeness of MapServer API support varies a bit with the language you choose, but I think it is my
181
duty to tell you almost every available avor of MapScript is usable. This API, exposed now in your scripting language through the MapScript module, allows you to do many GIS-like operations on spatial data, including read-write access to shapeles, reprojection of data, and many others. For more information on the API, click over the link above. For other avors, you can check their own documentation, you will see there is not much difference. The CGI version of MapServer is not required to run MapScript applications, just as you dont need a particular MapScript module to run the CGI. The CGI version has many features out-of-the-box, MapScript is just an API, so with MapScript you must start from scratch or with some of the examples available. Think of the CGI as of a MapScript application written directly in C, with direct access to the MapServer C API. Sometimes the out-of-the-box functionality has some limits which can be surpassed by MapScript, but not embedded within the CGI. In other words, the CGI is not scriptable, but you can program all the CGI and more with MapScript. This may seem a strange thing to clarify, but is a common misconception, just check the list archives if you are not inclined to believe me. As with MapServer itself, MapScript can be congured using only map les, but, unlike the CGI, also includes the possibility of dynamically create maps or modify existing ones and to (and here is the key to the exibility that MapScript has) mix this information with other sources of non GIS data, such as user input, non spatial and spatial databases, text les, etc. and that you can use every single module your language provides. The power of this approach is tremendous, and the most restrictive limit is your imagination. As always, exibility comes with a price, performance. Its generally slower to use a scripting language instead of C, but nowadays this shouldnt be a big worry. And you can still program directly in C (there are not much documents about how to do it, though you might want to check the mapserver-dev list) if you would like to. The input and output formats MapScript can handle are exactly the same as the ones congured when you build MapServer/MapScript. But one of the most important things to remember is that, basically, you feed geographic data and relevant user input (for instance clicks over the map image) to MapScript and as a result get one or more le(s), typically standard image les such as a PNG or JPEG. So you can apply anything youve seen in any server side scripted web application, DHTML, Java applets, CSS, HTML templates, sessions, you name it. Our rst application In this rst example, I will tell you how to display a shapele on a web page using a map le.
182
Chapter 6. MapScript
STYLE COLOR 110 50 100 OUTLINECOLOR 200 200 200 SYMBOL 0 END END END END
Here I have shown a map with a single layer, where the europe.shp, europe.shx and europe.dbf les must be located in the subdirectory called data. The symbols are located in the symbols subdirectory. All this locations are relative from the place the map le is, but better safe than sorry, I guess. The web section is used to dene where will the images be saved and in what URL will they be available.
183
The code I will present through the rest of this document will follow the following rule: Every non empty line is numbered This code will render an image corresponding to the shapele europe and display it on a HTML page.
Code Explanation
In line 2 it is loaded the MapScript extension (you may not need it if your php.ini le is congured to automatically load it). Line 3 declares a variable that holds the absolute path for the maple. Line 4 creates an instance of the MapObj object using the constructor. As you can see, the constructor receives the location of the map le as its only required parameter, and the map le received the europe.map name. Afterwards the draw method of the map object is called to render the image dened by the map le (line 5). The result (an imageObj) is saved in the $image variable. Line 6 calls the saveWebImage method to generate the image le, it returns a string which represents the URL as dened in the maple (in this case, /tmp/lename.png). The rest of the lines are pure HTML, except line 13, that denes the source URL of the image will be the value stored in $image_url. You should test the application on your system, to check that it really works and to solve the problems that may arise on your particular conguration before moving on to the more complex examples.
Output
The output (using the europe shapele) should look like this:
184
Chapter 6. MapScript
The constructors of RectObj and PointObj: $point = ms_newPointObj(); $rect = ms_newRectObj(); The setXY method of the point object: $point->setXY(double x_coord, double y_coord); The setextent method of the rectangle object: $rect->setextent(double minx, double miny, double maxx, double maxy); The .map le remains the same as the one presented in the previous example.
PHP/MapScript Code
Here I present the new code.
1 <?php 2 dl(php_mapscript.so); 3 // Default values and configuration 4 5 6 7 $val_zsize=3; $check_pan="CHECKED"; $map_path="/var/www/html/ms/map_files/"; $map_file="europe.map";
8 $map = ms_newMapObj($map_path.$map_file);
9 if ( isset($_POST["mapa_x"]) && isset($_POST["mapa_y"]) 10 && !isset($_POST["full"]) ) { 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 $extent_to_set = explode(" ",$_POST["extent"]); $map->setextent($extent_to_set[0],$extent_to_set[1], $extent_to_set[2],$extent_to_set[3]); $my_point = ms_newpointObj(); $my_point->setXY($_POST["mapa_x"],$_POST["mapa_y"]); $my_extent = ms_newrectObj(); $my_extent->setextent($extent_to_set[0],$extent_to_set[1], $extent_to_set[2],$extent_to_set[3]); $zoom_factor = $_POST["zoom"]*$_POST["zsize"]; if ($zoom_factor == 0) { $zoom_factor = 1; $check_pan = "CHECKED"; $check_zout = ""; $check_zin = ""; } else if ($zoom_factor < 0) { $check_pan = ""; $check_zout = "CHECKED"; $check_zin = ""; } else { $check_pan = ""; $check_zout = ""; $check_zin = "CHECKED";
186
Chapter 6. MapScript
33 34 35 36 37 }
38 $image=$map->draw(); 39 $image_url=$image->saveWebImage(); 40 $extent_to_html = $map->extent->minx." ".$map->extent->miny." " 41 .$map->extent->maxx." ".$map->extent->maxy; 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 ?> <HTML> <HEAD> <TITLE>Map 2</TITLE> </HEAD> <BODY> <CENTER> <FORM METHOD=POST ACTION=<?php <TABLE> <TR> <TD> <INPUT TYPE=IMAGE </TD> </TR> <TR> <TD> Pan </TD> <TD> <INPUT TYPE=RADIO </TD> </TR> <TR> <TD> Zoom In </TD> <TD> <INPUT TYPE=RADIO </TD> </TR> <TR> <TD> Zoom Out </TD> <TD> <INPUT TYPE=RADIO </TD> </TR> <TR> <TD> Zoom Size </TD>
echo $HTTP_SERVER_VARS[PHP_SELF]?>>
187
84 <TD> 85 <INPUT TYPE=TEXT NAME="zsize" VALUE="<?php echo $val_zsize?>" 86 SIZE=2> 87 </TD> 88 </TR> 89 <TR> 90 <TD> 91 Full Extent 92 </TD> 93 <TD> 94 <INPUT TYPE=SUBMIT NAME="full" VALUE="Go" 95 SIZE=2> 96 </TD> 97 </TABLE> 98 <INPUT TYPE=HIDDEN NAME="extent" VALUE="<?php echo $extent_to_html?>"> 99 </FORM> 100 </CENTER> 101 </BODY> 102 </HMTL>
This code will zoom out, zoom in, pan, and restore to full extent the image displayed in the previous example. It looks much more complicated than it really is, much of the lines are the HTML code, and much of the remaining PHP code is just to deal with the forms and such. You should try it and look at how it works rst. Try it in your own server by copying and pasting the code. Now its time for you to play with it a little and look at the source in your browser to check how it changes. Done?, now lets start the explanation with the HTML part.
188
Chapter 6. MapScript
From that last paragraph you can deduce that all the default values are set in the map le, and anything that you change through MapScript and would like to remain in your code, must be stored somehow. In this case it is done through hidden variables in a form. For more advanced applications you could use session variables or a database. Now you should be able to see why the Full Extent button works. If you check line 10, it says that if you havent pressed the button, skip the code in the if statement, so the extent is reset to the value that the map le has. You should also see that it isnt necessarily a full extent (in case the extent in the map le is not full extent). Lines 14 and 15 declare a new point object and initialize it with the values the user clicked on. You should not forget that those values are in pixels, not in georeferenced coordinates. Lines 16 through 18 create a new rectangle object and set it with the extent of the previous image, just like it is done on line 12. In fact this would work too: $my_extent = $map->extent;. To do all the zooming and panning, the zoompoint function in called on line 35, but rst the arguments it receives must be prepared. You can determine the point the user clicked on, and the extent of the image ($my_point and $my_extent, respectively), but now you have to determine the zoom factor. Thats what lines 19 to 33 do. If you wondered why the values of the radio buttons where 0, -1, and 1 for pan, zoom in and zoom out, now you will know the reason. A zoom factor of 1 tells zoompoint that the operation is pan, a negative value indicates zoom out and a positive value indicates zoom in. So, by means of multiplying the value received for the radio buttons (HTML variable zoom) by the size of the zoom the user entered the zoom factor is calculated. If that value is 0, that means the user selected the pan operation, so $zoom_factor is set to 1, otherwise the result of the multiplication is the zoom factor zoompoint needs to receive. The other lines are to preserve the button the user clicked on the next time. Line 34 tries to preserve the value of the zoom size the user entered (It doesnt do that all the time, when and why that line fails? Thats for you to nd out). And nally, line 34 calls the zoompoint method with the zoom factor obtained, the point built from the pixel coordinates (I insist on that issue because zoompoint is almost the only method that receives the coordinates in pixels, for the other methods you must convert pixels to georeferenced coordinates on your own), the height and width of the image, and the extent. After calling zoompoint, the extent of the image is changed accordingly to the operation performed (or, better put, the zoom factor). So then the image is drawn and the current extent saved (after the zooming) for use in the next iteration. Conclusions Well, its time for me to go recharge my batteries. So I will use this last energy to share some nal words. The examples I have managed to present here are very basic but you should now be able to devise ways to improve them and suit things to your needs. Keep in mind that you can preprocess, store, read, write data from any source you can usually read through PHP, plus all the sources MapServer can handle for GIS data. You can even process some GIS data with PHP only if the need would arise (SQL sources are a good example of this). You can also do hybrid approaches where some script prepares data which is then shown through the CGI interface to MapServer, or create data on the y based on input from a GPS, etc, etc. The possibilities are just too many to enumerate completely. As I already said your imagination is the limit. The next version of this document will include examples that include more than one layer, with different datasources (not just shapeles) and creation of dynamic layers and classes. If you have a better idea or would like to see some other thing here rst, please drop a note to my maintainer. In the meantime, if you need bigger examples you can refer to the GMap demo (you can download the source here or as an MS4W packaged application), or the MapTools site (MapLab, Chameleon). Goodbye, and thanks for reading this far.
189
Contents PHP MapScript Very important notes Constants Functions MapObj Class LayerObj Class ClassObj Class ImageObj Class LabelObj Class webObj Class referenceMapObj Class ColorObj Class PointObj Class LineObj Class ShapeObj Class RectObj Class ShapeleObj Class ResultCacheMemberObj Class ProjectionObj Class ScalebarObj Class LegendObj Class QuerymapObj Class StyleObj Class OutputformatObj Class GridObj Class ErrorObj Class LabelcacheObj Class SymbolObj Class OwsrequestObj Class hashTableObj Class
This is a PHP module to make MapServers MapScript functionalities available in a PHP Dynamically Loadable Library. PHP MapScript was originally developed for PHP-3.0.14 but after MapServer 3.5 support for PHP3 has been dropped and as of the last update of this document, PHP 4.1.2 or more recent was required. The module has been tested and used on Linux, Solaris, *BSD, and WinNT. There are documentation and examples for PHP MapScript available via the MapServer documentation See also the MapServer Wiki for links http://trac.osgeo.org/mapserver/wiki/PHPMapScript 190 to more information on this module:
Chapter 6. MapScript
6.3.4 Constants
The following MapServer constants are available: Boolean values MS_TRUE, MS_FALSE, MS_ON, MS_OFF, MS_YES, MS_NO Map units MS_INCHES, MS_FEET, MS_MILES, MS_METERS, MS_KILOMETERS, MS_DD, MS_PIXELS Layer types MS_LAYER_POINT, MS_LAYER_LINE, MS_LAYER_POLYGON, MS_LAYER_RASTER, MS_LAYER_ANNOTATION, MS_LAYER_QUERY, MS_LAYER_CIRCLE, MS_LAYER_TILEINDEX, MS_LAYER_CHART Layer/Legend/Scalebar/Class Status MS_ON, MS_OFF, MS_DEFAULT, MS_EMBED, MS_DELETE Layer alpha transparency allows alpha transparent pixmaps to be used with RGB map images MS_GD_ALPHA Font types MS_TRUETYPE, MS_BITMAP Label positions MS_UL, MS_LR, MS_UR, MS_LL, MS_CR, MS_CL, MS_UC, MS_LC, MS_CC, MS_AUTO, MS_XY, MS_FOLLOW Bitmap font styles MS_TINY , MS_SMALL, MS_MEDIUM, MS_LARGE, MS_GIANT Shape types MS_SHAPE_POINT, MS_SHAPE_LINE, MS_SHAPE_POLYGON, MS_SHAPE_NULL Shapele types MS_SHP_POINT, MS_SHP_ARC, MS_SHP_POLYGON, MS_SHP_MULTIPOINT Query/join types MS_SINGLE, MS_MULTIPLE Querymap styles MS_NORMAL, MS_HILITE, MS_SELECTED Connection Types MS_INLINE, MS_SHAPEFILE, MS_TILED_SHAPEFILE, MS_SDE, MS_OGR, MS_TILED_OGR, MS_POSTGIS, MS_WMS, MS_ORACLESPATIAL, MS_WFS, MS_GRATICULE, MS_MYGIS, MS_RASTER, MS_PLUGIN Error codes MS_NOERR, MS_IOERR, MS_MEMERR, MS_TYPEERR, MS_SYMERR, MS_REGEXERR, MS_TTFERR, MS_DBFERR, MS_GDERR, MS_IDENTERR, MS_EOFERR, MS_PROJERR, MS_MISCERR, MS_CGIERR, MS_WEBERR, MS_IMGERR, MS_HASHERR, MS_JOINERR, MS_NOTFOUND, MS_SHPERR, MS_PARSEERR, MS_SDEERR, MS_OGRERR, MS_QUERYERR, MS_WMSERR, MS_WMSCONNERR, MS_ORACLESPATIALERR, MS_WFSERR, MS_WFSCONNERR, MS_MAPCONTEXTERR, MS_HTTPERR, MS_WCSERR Symbol types MS_SYMBOL_SIMPLE, MS_SYMBOL_VECTOR, MS_SYMBOL_ELLIPSE, MS_SYMBOL_PIXMAP, MS_SYMBOL_TRUETYPE, MS_SYMBOL_CARTOLINE Image Mode types (outputFormatObj) MS_IMAGEMODE_PC256, MS_IMAGEMODE_RGBA, MS_IMAGEMODE_INT16, MS_IMAGEMODE_BYTE, MS_IMAGEMODE_NULL MS_IMAGEMODE_RGB, MS_IMAGEMODE_FLOAT32,
191
MS_STYLE_BINDING_ANGLE, MS_STYLE_BINDING_OUTLINECOLOR,
Label/Attribute binding MS_LABEL_BINDING_SIZE, MS_LABEL_BINDING_ANGLE, MS_LABEL_BINDING_COLOR, MS_LABEL_BINDING_OUTLINECOLOR, MS_LABEL_BINDING_FONT, MS_LABEL_BINDING_PRIORITY Alignment MS_ALIGN_LEFT, MS_ALIGN_CENTER, MS_ALIGN_RIGHT OwsRequest MS_GET_REQUEST, MS_POST_REQUEST
6.3.5 Functions
string ms_GetVersion() Returns the MapServer version and options in a string. This string can be parsed to nd out which modules were compiled in, etc. int ms_GetVersionInt() Returns the MapServer version number (x.y.z) as an integer (x*10000 + y*100 + z). (New in v5.0) e.g. V5.4.3 would return 50403. array ms_TokenizeMap(string map_le_name) Preparses a maple through the MapServer parser and return an array with one item for each token from the maple. Strings, logical expressions, regex expressions and comments are returned as individual tokens. void ms_ioinstallstdouttobuffer() Installs a mapserver IO handler directing future stdout output to a memory buffer. void ms_ioinstallstdinfrombuffer() Installs a mapserver IO handler directing future stdin reading (ie. post request capture) to come from a buffer. void ms_iogetstdoutbufferstring() Fetch the current stdout buffer contents as a string. This method does not clear the buffer. int ms_iogetStdoutBufferBytes() Writes the current buffer to stdout. The PHP header() function should be used to set the documentss content-type prior to calling the function. Returns the number of bytes written if output is sent to stdout. See MapScript Wrappers for WxS Services for more info. void ms_ioresethandlers() Resets the default stdin and stdout handlers in place of buffer based handlers. void ms_iostripstdoutbuffercontenttype() Strip the Content-type header off the stdout buffer if it has one, and if a content type is found it is return. Otherwise return false.
Note: By default, the SYMBOLSET, FONTSET, and other paths in the maple are relative to the maple location. If new_map_path is provided then this directory will be used as the base path for all the relative paths inside the maple.
192
Chapter 6. MapScript
Members Type int string int int int int int outputformatObj double rectObj double int double double string int int int int webObj referenceMapObj colorObj scalebarObj legendObj string string labelcacheObj projectionObj int int int int Methods mapObj clone() Returns a handle to a new mapObj which is a clone of the current mapObj. All parameters in the current mapObj are copied to the new mapObj. Returns NULL (0) on error. int set(string property_name, new_value) Set map object property to new value. Returns -1 on error. int getsymbolbyname(string symbol_name) Returns the symbol index using the name. symbol getsymbolobjectbyid(int symbolid) Returns the symbol object using a symbol id. Refer to the symbol object reference section for more details. void preparequery() Calculate the scale of the map and set map->scaledenom. imageObj prepareImage() Return handle on blank image object. Name numlayers (read-only) name status debug width (see setSize()) height (see setSize()) maxsize outputformat resolution (pixels per inch, defaults to 72) extent; cellsize units (map units type) scaledenom (read-only, set by drawMap()) scale (Deprecated in v5.0. Use scaledenom instead) shapepath keysizex keysizey keyspacingx keyspacingy web reference imagecolor scalebar legend symbolsetlename (read-only, set by setSymbolSet()) fontsetlename (read-only, set by setFontSet()) labelcache (no members. Used only to be able to free the the label cache (ex : map->labelcache->free()) projection transparent (deprecated, use outputFormatObj) interlace (deprecated, use outputFormatObj) imagetype (deprecated, use outputFormatObj) imagequality (deprecated, use outputFormatObj)
193
imageObj draw() Render map and return handle on image object. imageObj drawQuery() Render a query map and return handle on image object. imageObj drawLegend() Render legend and return handle on image object. imageObj drawReferenceMap() Render reference map and return handle on image object. imageObj drawScaleBar() Render scale bar and return handle on image object. int embedlegend(imageObj image) embeds a legend. Actually the legend is just added to the label cache so you must invoke drawLabelCache() to actually do the rendering (unless postlabelcache is set in which case it is drawn right away). int embedScalebar(imageObj image) embeds a scalebar. Actually the scalebar is just added to the label cache so you must invoke drawLabelCache() to actually do the rendering (unless postlabelcache is set in which case it is drawn right away). int drawLabelCache(imageObj image) Renders the labels for a map. Returns -1 on error. layerObj getLayer(int index) Returns a layerObj from the map given an index value (0=rst layer) layerObj getLayerByName(string layer_name) Returns a layerObj from the map given a layer name. Returns FALSE if layer doesnt exist. colorObj getcolorbyindex(int iCloIndex) Returns a colorObj corresponding to the color index in the palette void setExtent(double minx, double miny, double maxx, double maxy) Set the map extents using the georef extents passed in argument. int setRotation(double rotation_angle) Set map rotation angle. The map view rectangle (specied in EXTENTS) will be rotated by the indicated angle in the counter- clockwise direction. Note that this implies the rendered map will be rotated by the angle in the clockwise direction. Returns MS_SUCCESS or MS_FAILURE. int setSize(int width, int height) Set the map width and height. This method updates the internal geotransform and other data structures required for map rotation so it should be used instead of setting the width and height members directly. Returns MS_SUCCESS or MS_FAILURE. void zoompoint(int nZoomFactor, pointObj oPixelPos, int nImageWidth, int nImageHeight, rectObj oGeorefExt) Zoom to a given XY postion. Parameters are : Zoom factor : positive values do zoom in, negative values zoom out. Factor of 1 will recenter. Pixel position (pointObj) : x, y coordinates of the click, with (0,0) at the top-left Width : width in pixel of the current image. Height : Height in pixel of the current image. Georef extent (rectObj) : current georef extents. MaxGeoref extent (rectObj) : (optional) maximum georef extents. If provided then it will be impossible to zoom/pan outside of those extents. void zoomrectangle(rectObj oPixelExt, int nImageWidth, int nImageHeight, rectObj oGeorefExt) Set the map extents to a given extents. Parameters are : oPixelExt (rect object) : Pixel Extents, with (0,0) at the top-left The rectangle contains the coordinates of the LL and UR coordinates in pixel. (the maxy in the rect object should be < miny value)
194
Chapter 6. MapScript
------- UR (values in the rect object : maxx, maxy) | | | | | | -----LL (values in the rectobject minx, miny)
Width : width in pixel of the current image. Height : Height in pixel of the current image. Georef extent (rectObj) : current georef extents.
void zoomscale(double nScaleDenom, pointObj oPixelPos, int nImageWidth, int nImageHeight, rectObj oGeorefExt [, rectObj o Zoom in or out to a given XY position so that the map is displayed at specied scale. Parameters are : ScaleDenom : Scale denominator of the scale at which the map should be displayed. Pixel position (pointObj) : x, y coordinates of the click, with (0,0) at the top-left Width : width in pixel of the current image. Height : Height in pixel of the current image. Georef extent (rectObj) : current georef extents. MaxGeoref extent (rectObj) : (optional) maximum georef extents. If provided then it will be impossible to zoom/pan outside of those extents. int queryByPoint(pointObj point, int mode, double buffer) Query all selected layers in map at point location specied in georeferenced map coordinates (i.e. not pixels). The query is performed on all the shapes that are part of a CLASS that contains a Templating value or that match any class in a layer that contains a LAYER TEMPLATE value. Mode is MS_SINGLE or MS_MULTIPLE depending on number of results you want. Passing buffer -1 defaults to tolerances set in the map le (in pixels) but you can use a constant buffer (specied in ground units) instead. Returns MS_SUCCESS if shapes were found or MS_FAILURE if nothing was found or if some other error happened (note that the error message in case nothing was found can be avoided in PHP using the @ control operator). int queryByRect(rectObj rect) Query all selected layers in map using a rectangle specied in georeferenced map coordinates (i.e. not pixels). The query is performed on all the shapes that are part of a CLASS that contains a Templating value or that match any class in a layer that contains a LAYER TEMPLATE value. Returns MS_SUCCESS if shapes were found or MS_FAILURE if nothing was found or if some other error happened (note that the error message in case nothing was found can be avoided in PHP using the @ control operator). int queryByShape(shapeObj shape) Query all selected layers in map based on a single shape, the shape has to be a polygon at this point. Returns MS_SUCCESS if shapes were found or MS_FAILURE if nothing was found or if some other error happened (note that the error message in case nothing was found can be avoided in PHP using the @ control operator). int queryByFeatures(int slayer) Perform a query based on a previous set of results from a layer. At present the results MUST be based on a polygon layer. Returns MS_SUCCESS if shapes were found or MS_FAILURE if nothing was found or if some other error happened (note that the error message in case nothing was found can be avoided in PHP using the @ control operator). int queryByIndex(layerindex, tileindex, shapeindex, addtoquery) Add a specic shape on a given layer to the query result. If addtoquery (which is a non mandatory argument) is set to MS_TRUE, the shape will be added to the existing query list. Default behavior is to free the existing query list and add only the new shape. int savequery(lename) Save the current query in a le. Returns MS_SUCESS or MS_FAILURE. Can be used with loadquery int loadquery(lename) Loads a query from a le. Returns MS_SUCESS or MS_FAILURE. To be used with savequery.
195
void freequery(layerindex) Frees the query result on a specied layer. If the layerindex is -1, all queries on layers will be freed. int save(string lename) Save current map object state to a le. Returns -1 on error. Use absolute path. If a relative path is used, then it will be relative to the maple location. string getProjection() Returns a string representation of the projection. If no projection is set, MS_FALSE is returned. int setProjection(string proj_params, boolean bSetUnitsAndExtents) Set map projection and coordinate system. Parameters are given as a single string of comma-delimited PROJ.4 parameters. The argument : bSetUnitsAndExtents is used to automatically update the map units and extents based on the new projection. Possible values are MS_TRUE and MS_FALSE. By defualt it is set at MS_FALSE int setWKTProjection(string proj_params, boolean bSetUnitsAndExtents) Same as setProjection(), but takes an OGC WKT projection denition string as input. Note: setWKTProjection requires GDAL support int getMetaData(string name) Fetch metadata entry by name (stored in the WEB object in the map le). Returns if no entry matches the name. Note: getMetaDatas query is case sensitive. int setMetaData(string name, string value) Set a metadata entry for the map (stored in the WEB object in the map le). Returns MS_SUCCESS/MS_FAILURE. int removeMetaData(string name) Remove a metadata entry for the map (stored in the WEB object in the map le). Returns MS_SUCCESS/MS_FAILURE. array getLayersIndexByGroup(string groupname) Return an array containing all the layers indexes given a group name. array getAllGroupNames() Return an array containing all the group names used in the layers. array getAllLayerNames() Return an array containing all the layer names. boolean moveLayerUp(int layerindex) Move layer up in the hierarcy of drawing. boolean moveLayerDown(int layerindex) Move layer down in the hierarcy of drawing. array getlayersdrawingorder() Return an array containing layers index in the order which they are drawn. boolean setlayersdrawingorder(array layeryindex) Set the layers order array. The argument passed must be a valid array with all the layers index. Return TRUE on success or else FALSE. string processtemplate(array params, boolean generateimages) Process the template le specied in the web object and return the result in a buffer. The processing consists of opening the template le and replace all the tags found in it. Only tags that have an equivalent element in the map object are replaced (ex [scaledenom]). The are two exceptions to the previous statement : [img], [scalebar], [ref], [legend] would be replaced with the appropriate url if the parameter generateimages is set to MS_TRUE. (Note : the images corresponding to the different objects are generated if the object is set to MS_ON in the map le) the user can use the params parameter to specify tags and their values. For example if the user have a specic tag call [my_tag] and would like it to be replaced by value_of_my_tag he would do
196
Chapter 6. MapScript
string processquerytemplate(array params, boolean generateimages) Process query template les and return the result in a buffer. Second argument generateimages is not mandatory. If not given it will be set to TRUE. See Also: processtemplate string processlegendtemplate(array params) Process legend template les and return the result in a buffer. See Also: processtemplate int setSymbolSet(string leName) Load and set a symbol le dynamically. int getNumSymbols() Return the number of symbols in map. int setFontSet(string leName) Load and set a new FONTSET. int selectOutputFormat(string type) Selects the output format to be used in the map. MS_SUCCESS/MS_FAILURE. Returns
Note: the type used should correspond to one of the output formats declared in the map le. The type argument passed is compared with the mimetype parameter in the output format structure and then to the name parameter in the structure. int saveMapContext(string lename) Available only if WMS support is enabled. Save current map object state in WMS Map Context format. Only WMS layers are saved in the WMS Map Context XML le. Returns MS_SUCCESS/MS_FAILURE. int loadMapContext(string lename [, boolean unique_layer_name]) Available only if WMS support is enabled. Load a WMS Map Context XML le into the current mapObj. If the map already contains some layers then the layers dened in the WMS Map context document are added to the current map. The 2nd argument unique_layer_name is optional and if set to MS_TRUE layers created will have a unique name (unique prex added to the name). If set to MS_FALSE the layer name will be the the same name as in the context. The default value is MS_FALSE. Returns MS_SUCCESS/MS_FAILURE. int applySLD(string sldxml) Apply the SLD document to the map le. The matching between the sld document and the map le will be done using the layers name. See SLD HowTo for more information on the SLD support. int applySLDURL(string sldurl) Apply the SLD document pointed by the URL to the map le. The matching between the sld document and the map le will be done using the layers name. See SLD HowTo for more information on the SLD support. string generateSLD() Returns an SLD XML string based on all the classes found in all the layers. string getcongoption(string key) Returns the cong value associated with the key. Returns an empty sting if key not found. int setcongoption(string key, string value) Sets a cong parameter using the key and the value passed int applycongoptions() Applies the cong options set in the map le. For example setting the PROJ_LIB using the setcongoption only modies the value in the map object. applycongoptions will actually change the PROJ_LIB value that will be used when dealing with projection. 6.3. PHP MapScript 197
int loadowsparameters(owsrequest request, string version) Load OWS request parameters (BBOX, LAYERS, &c.) into map. Returns MS_SUCCESS or MS_FAILURE. 2nd argument version is not mandatory. If not given, the version will be set to 1.1.1 int owsdispatch(owsrequest request) Processes and executes the passed OpenGIS Web Services request on the map. Returns MS_DONE (2) if there is no valid OWS request in the req object, MS_SUCCESS (0) if an OWS request was successfully processed and MS_FAILURE (1) if an OWS request was not successfully processed. OWS requests include WMS, WFS, WCS and SOS requests supported by MapServer. Results of a dispatched request are written to stdout and can be captured using the msIO services (ie. ms_ioinstallstdouttobuffer() and ms_iogetstdoutbufferstring()) int insertLayer( layerObj layer [, int nIndex=-1 ] ) Insert a copy of layer into the Map at index nIndex. The default value of nIndex is -1, which means the last possible index. Returns the index of the new Layer, or -1 in the case of a failure. layerObj removeLayer( int nIndex ) Remove a layer from the mapObj. The argument is the index of the layer to be removed. Returns the removed layerObj on success, else null.
A second optional argument can be given to ms_newLayerObj() to create the new layer as a copy of an existing layer. If a layer is given as argument then all members of a this layer will be copied in the new layer created.
198
Chapter 6. MapScript
Members Type int int int int string string string string string int int double int int double double double double double double double double double double int colorObj int int int int string string string string string string string string int string string int int string gridObj int string string hashTableObj projectionObj Name numclasses (read-only) index (read-only) status (MS_ON, MS_OFF, MS_DEFAULT or MS_DELETE) debug classitem classgroup name group data type dump tolerance toleranceunits sizeunits symbolscaledenom minscaledenom maxscaledenom labelminscaledenom labelmaxscaledenom symbolscale (Deprecated in v5.0, use symbolscaledenom instead) minscale (Deprecated in v5.0, use minscaledenom instead) maxscale (Deprecated in v5.0, use maxscaledenom instead) labelminscale (Deprecated in v5.0, use labelminscaledenom instead) labelmaxscale (Deprecated in v5.0, use labelmaxscaledenom instead) maxfeatures offsite annotate transform labelcache postlabelcache labelitem labelsizeitem labelangleitem tileitem tileindex header footer connection connectiontype (read-only, use setConnectionType() to set it) lteritem template opacity transparency (Deprecated in v5.0. Use opacity instead.) styleitem grid //only available on a layer dened as grid (MS_GRATICULE) num_processing requires labelrequires metadata projection
199
Methods int updateFromString(string snippet) Update MS_SUCCESS/MS_FAILURE. a layer from a string snippet. Returns
$oLayer->updateFromString(LAYER NAME land_fn2 END); /*modify the name */ $oLayer->updateFromString(LAYER CLASS STYLE COLOR 255 255 0 END END END); /*add a new class*/
int set(string property_name, new_value) Set object property to a new value. Returns -1 on error. int draw(imageObj image) Draw a single layer, add labels to cache if required. Returns -1 on error. int drawQuery(imageObj image) Draw query map for a single layer. classObj getClass(int classIndex) Returns a classObj from the layer given an index value (0=rst class) int queryByPoint(pointObj point, int mode, double buffer) Query layer at point location specied in georeferenced map coordinates (i.e. not pixels). The query is performed on all the shapes that are part of a CLASS that contains a TEMPLATE value or that match any class in a layer that contains a LAYER TEMPLATE value. Mode is MS_SINGLE or MS_MULTIPLE depending on number of results you want. Passing buffer -1 defaults to tolerances set in the map le (in pixels) but you can use a constant buffer (specied in ground units) instead. Returns MS_SUCCESS if shapes were found or MS_FAILURE if nothing was found or if some other error happened (note that the error message in case nothing was found can be avoided in PHP using the @ control operator). int queryByRect(rectObj rect) Query layer using a rectangle specied in georeferenced map coordinates (i.e. not pixels). The query is performed on all the shapes that are part of a CLASS that contains a TEMPLATE value or that match any class in a layer that contains a LAYER TEMPLATE value. Returns MS_SUCCESS if shapes were found or MS_FAILURE if nothing was found or if some other error happened (note that the error message in case nothing was found can be avoided in PHP using the @ control operator). int queryByShape(shapeObj shape) Query layer based on a single shape, the shape has to be a polygon at this point. Returns MS_SUCCESS if shapes were found or MS_FAILURE if nothing was found or if some other error happened (note that the error message in case nothing was found can be avoided in PHP using the @ control operator). int queryByFeatures(int slayer) Perform a query set based on a previous set of results from another layer. At present the results MUST be based on a polygon layer. Returns MS_SUCCESS if shapes were found or MS_FAILURE if nothing was found or if some other error happened (note that the error message in case nothing was found can be avoided in PHP using the @ control operator). int queryByAttributes(string qitem, string qstring, int mode) Query layer for shapes that intersect current map extents. qitem is the item (attribute) on which the query is performed, and qstring is the expression to match. The query is performed on all the shapes that are part of a CLASS that contains a TEMPLATE value or that match any class in a layer that contains a LAYER TEMPLATE value. Note that the layers FILTER/FILTERITEM are ignored by this function. Mode is MS_SINGLE or MS_MULTIPLE depending on number of results you want. Returns MS_SUCCESS if shapes were found or MS_FAILURE if nothing was found or if some other error happened (note that the error message in case nothing was found can be avoided in PHP using the @ control operator). int setFilter(string expression) Set layer lter expression. string getFilterString() Returns the expression for this layer. string getFilter() Deprecated in v5.0, use getFilterString() instead. string getProjection() Returns a string representation of the projection. If no projection is set, MS_FALSE is returned. 200 Chapter 6. MapScript
int setProjection(string proj_params) Set layer projection and coordinate system. Parameters are given as a single string of comma-delimited PROJ.4 parameters. int setWKTProjection(string proj_params) Same as setProjection(), but takes an OGC WKT projection denition string as input. Note: setWKTProjection requires GDAL support int getNumResults() Returns the number of results from this layer in the last query. resultCacheMemberObj getResult(int index) Returns a resultCacheMemberObj by index from a layer object with index in the range 0 to numresults-1. Returns a valid object or FALSE(0) if index is invalid. int open() Open the layer for use with getShape(). Returns MS_SUCCESS/MS_FAILURE. int whichshapes(rectobj) Performs a spatial, and optionally an attribute based feature search. The function basically prepares things so that candidate features can be accessed by query or drawing functions (eg using nextshape function). Returns MS_SUCCESS or MS_FAILURE. shapeobj nextShape() Called after msWhichShapes has been called to actually retrieve shapes within a given area returns a shape object or MS_FALSE
$map = ms_newmapobj("d:/msapps/gmap-ms40/htdocs/gmap75.map"); $layer = $map->getLayerByName(road); $status = $layer->open(); $status = $layer->whichShapes($map->extent); while ($shape = $layer->nextShape()) { echo $shape->index ."<br>\n"; } $layer->close();
void close() Close layer previously opened with open(). shapeObj getFeature(int shapeindex [, int tileindex = -1]) Retrieve shapeObj from a layer by index. Tileindex is optional and is used only for tiled shapeles (you get it from the resultCacheMemberObj returned by getResult() for instance). Simply omit or pass tileindex = -1 for other data sources. shapeObj getShape(int tileindex, int shapeindex) Deprecated in v5.0, use getFeature() instead (note that the order of the arguments is reversed since tileindex is optional in getFeature()) rectObj getExtent() Returns the layers data extents. If the layers EXTENT member is set then this value is used, otherwise this call opens/closes the layer to read the extents. This is quick on shapeles, but can be an expensive operation on some le formats or data sources. This function is safe to use on both opened or closed layers: it is not necessary to call open()/close() before/after calling it. int addFeature(shapeObj shape) Add a new feature in a layer. Returns -1 on error. int getMetaData(string name) Fetch layer metadata entry by name. Returns if no entry matches the name. Note that the search is case sensitive. Note: getMetaDatas query is case sensitive. int setMetaData(string name, string value) Set MS_SUCCESS/MS_FAILURE. a metadata entry for the layer. Returns
int removeMetaData(string name) Remove a metadata entry for the layer. Returns MS_SUCCESS/MS_FAILURE. 6.3. PHP MapScript 201
string getWMSFeatureInfoURL(int clickX, int clickY, int featureCount, string infoFormat) Return a WMS GetFeatureInfo URL (works only for WMS layers) clickX, clickY is the location of to query in pixel coordinates with (0,0) at the top left of the image. featureCount is the number of results to return. infoFormat is the format the format in which the result should be requested. Depends on remote servers capabilities. MapServer WMS servers support only MIME (and should support GML.1 soon). Returns and outputs a warning if layer is not a WMS layer or if it is not queriable. aString getItems() return a list of items. Must call open function rst. boolean setProcessing(string) Add the string to the processing string list for the layer. The layer->num_processing is incremented by 1.
$oLayer->setprocessing("SCALE_1=AUTO"); $oLayer->setprocessing("SCALE_2=AUTO");
aString getProcessing() Returns an array containing the processing strings boolean clearProcessing() Clears all the processing strings string executeWFSGetfeature() Executes a GetFeature request on a WFS layer and returns the name of the temporary GML le created. Returns an empty string on error. int applySLD(string sldxml, string namedlayer) Apply the SLD document to the layer object. The matching between the sld document and the layer will be done using the layers name. If a namedlayer argument is passed (argument is optional), the NamedLayer in the sld that matchs it will be used to style the layer. See SLD HowTo for more information on the SLD support. int applySLDURL(string sldurl, string namedlayer) Apply the SLD document pointed by the URL to the layer object. The matching between the sld document and the layer will be done using the layers name. If a namedlayer argument is passed (argument is optional), the NamedLayer in the sld that matchs it will be used to style the layer. See SLD HowTo for more information on the SLD support. string generateSLD() Returns an SLD XML string based on all the classes found in the layers. int moveclassup(int index) The class specied by the class index will be moved up into the array of layers. Returns MS_SUCCESS or MS_FAILURE. ex layer->moveclassup(1) will have the effect of moving class 1 up to position 0, and the class at position 0 will be moved to position 1. int moveclassdown(int index) The class specied by the class index will be moved down into the array of layers. Returns MS_SUCCESS or MS_FAILURE. ex layer->moveclassdown(0) will have the effect of moving class 0 up to position 1, and the class at position 1 will be moved to position 0. classObj removeClass(int index) Removes the class indicated and returns a copy, or NULL in the case of a failure. Note that subsequent classes will be renumbered by this operation. The numclasses eld contains the number of classes available. boolean isVisible() Returns MS_TRUE/MS_FALSE depending on whether the layer is currently visible in the map (i.e. turned on, in scale, etc.). int setConenctionType(int connectiontype [,string plugin_library]) Changes the connectiontype of the layer and recreates the vtable according to the new connection type. This method should be used instead of setting the connectiontype parameter directly. In case when the layer.connectiontype = MS_PLUGIN the plugin_library parameter should also be specied so as to select the library to load by mapserver. For the other connection types this parameter is not used.
202
Chapter 6. MapScript
The second argument class is optional. If given, the new class created will be a copy of this class. Members Type string string int int double double double double string labelObj int string string hashTableObj Methods int updateFromString(string snippet) Update MS_SUCCESS/MS_FAILURE. a class from a string snippet. Returns Name name title type status (MS_ON, MS_OFF or MS_DELETE) minscaledenom maxscaledenom minscale (Deprecated in v5.0, use minscaledenom instead) maxscale (Deprecated in v5.0, use maxscaledenom instead) template label numstyles keyimage group metadata
$oClass->updateFromString(CLASS STYLE COLOR 255 0 255 END END); /*set the color */
int set(string property_name, new_value) Set object property to a new value. Returns -1 on error. int setExpression(string expression) Set the expression string for the class object. string getExpressionString() Returns the expression string for the class object. string getExpression() Deprecated in v5.0. Use getExpressionString() instead. int settext(string text) Set the text string for the class object. string getTextString() Returns the text string for the class object. int drawLegendIcon(int width, int height, imageObj im, int dstX, int dstY) Draw the legend icon on im object at dstX, dstY. Returns MS_SUCCESS/MS_FAILURE. imageObj createLegendIcon(int width, int height) Draw the legend icon and return a new imageObj. styleObj getStyle(int index) Return the style object using an index. index >= 0 && index < class->numstyles.
203
classObj clone() Returns a cloned copy of the class. int movestyleup(int index) The style specied by the style index will be moved up into the array of classes. Returns MS_SUCCESS or MS_FAILURE. ex class->movestyleup(1) will have the effect of moving style 1 up to position 0, and the style at position 0 will be moved to position 1. int movestyledown(int index) The style specied by the style index will be moved down into the array of classes. Returns MS_SUCCESS or MS_FAILURE. ex class->movestyledown(0) will have the effect of moving style 0 up to position 1, and the style at position 1 will be moved to position 0. int deletestyle(int index) Delete the style specied by the style index. If there are any style that follow the deleted style, their index will decrease by 1. Note: if you are using the numstyles parameter while using the deletestyle function on the class object you need to refetch a new class object. Example :
//class has 2 styles $class = $oLayer->getclass(0); $class->deletestyle(1); echo $class->numstyles; : will echo 2 $class = $oLayer->getclass(0); echo $class->numstyles; : will echo 1
int getMetaData(string name) Fetch class metadata entry by name. Returns if no entry matches the name. Note that the search is case sensitive. Note: getMetaDatas query is case sensitive. int setMetaData(string name, string value) Set MS_SUCCESS/MS_FAILURE. a metadata entry for the class. Returns
int removeMetaData(string name) Remove a metadata entry for the class. Returns MS_SUCCESS/MS_FAILURE.
204
Chapter 6. MapScript
Methods void free() Destroys resources used by an image object. int saveImage(string lename, MapObj oMap) Writes image object to specied lename. Passing an empty lename sends output to stdout. In this case, the PHP header() function should be used to set the documents content-type prior to calling saveImage(). The output format is the one that is currently selected in the map le. The second argument oMap is not manadatory. It is usful when saving to formats like GTIFF that needs georeference informations contained in the map le. The function returns -1 on error. On success, it returns either 0 if writing to an external le, or the number of bytes written if output is sent to stdout. string saveWebImage() Writes image to temp directory. Returns image URL. The output format is the one that is currently selected in the map le. void pasteImage(imageObj srcImg, int transparentColorHex [[, int dstX, int dstY], int angle]) Copy srcImg on top of the current imageObj. transparentColorHex is the color (in 0xrrggbb format) from srcImg that should be considered transparent (i.e. those pixels wont be copied). Pass -1 if you dont want any transparent color. If optional dstx,dsty are provided then it denes the position where the image should be copied (dstx,dsty = top-left corner position). The optional angle is a value between 0 and 360 degrees to rotate the source image counterclockwise. Note that if an angle is specied (even if its value is zero) then the dstx and dsty coordinates specify the CENTER of the destination area. Note: this function works only with 8 bits GD images (PNG or GIF).
205
Members Type string int colorObj colorObj int colorObj int int colorObj colorObj int int int int int int int int double int int int int int int int int int string int int int int Methods int updateFromString(string snippet) Update MS_SUCCESS/MS_FAILURE. a label from a string snippet. Returns Name font type color outlinecolor outlinewidth shadowcolor shadowsizex shadowsizey backgroundcolor backgroundshadowcolor backgroundshadowsizex backgroundshadowsizey size minsize maxsize position offsetx offsety angle autoangle buffer antialias wrap minfeaturesize autominfeaturesize mindistance partials force encoding align maxlength minlength priority
int set(string property_name, new_value) Set object property to a new value. Returns -1 on error. int setBinding(const labelbinding, string value) Set the attribute binding for a specied label property. Returns true on success. Example:
$oLabel->setbinding(MS_LABEL_BINDING_COLOR, "FIELD_NAME_COLOR");
This would bind the color parameter with the data (ie will extract the value of the color from the eld called FIELD_NAME_COLOR
206
Chapter 6. MapScript
string getBinding(const labelbinding) Get the attribute binding for a specied label property. Returns null if there is no binding for this property. Example:
$oLabel->setbinding(MS_LABEL_BINDING_COLOR, "FIELD_NAME_COLOR"); echo $oLabel->getbinding(MS_LABEL_BINDING_COLOR); // FIELD_NAME_COLOR
int removeBinding(const labelbinding) Remove the attribute binding for a specled style property. Returns true on success. Example:
$oStyle->removebinding(MS_LABEL_BINDING_COLOR);
int set(string property_name, new_value) Set object property to a new value. Returns -1 on error.
207
208
Chapter 6. MapScript
Members Type double double double double Methods int setXY(double x, double y [, double m]) Set X,Y coordinate values. Returns 0 on success, -1 on error. Note: the 3rd parameter m is used for measured shape les only. It is not mandatory. int setXYZ(double x, double y , double z, [, double m]) Set X,Y,Z coordinate values. Returns 0 on success, -1 on error. Note: the 4th parameter m is used for measured shape les only. It is not mandatory. int draw(mapObj map, layerObj layer, imageObj img, int class_index, string text) Draws the individual point using layer. The class_index is used to classify the point based on the classes dened for the layer. The text string is used to annotate the point. Returns MS_SUCCESS/MS_FAILURE. double distanceToPoint(pointObj poPoint) Calculates distance between two points. double distanceToLine(pointObject p1, pointObject p2) Calculates distance between a point ad a lined dened by the two points passed in argument. double distanceToShape(shapeObj shape) Calculates the minimum distance between a point and a shape. int project(projectionObj in, projectionObj out) Project the point from in projection (1st argument) to out projection (2nd argument). Returns MS_SUCCESS/MS_FAILURE. void free() Releases all resources used by the object. Name x y z (used for 3d shape les. set to 0 for other types) m (used only for measured shape les. set to 0 for other types.)
Members Type int Methods int add(pointObj point) Add a point to the end of line. int addXY(double x, double y [, double m]) Add a point to the end of line. It is not mandatory. 6.3. PHP MapScript 209 Name numpoints (read-only)
Note: the 3rd parameter m is used for measured shape les only. It is not mandatory. int addXYZ(double x, double y, double z [, double m]) Add a point to the end of line. Note: the 4th parameter m is used for measured shape les only. It is not mandatory. PointObj point(int i) Returns a reference to point number i. Reference is valid only during the life of the lineObj that contains the point. int project(projectionObj in, projectionObj out) Project the line from in projection (1st argument) to out projection (2nd argument). Returns MS_SUCCESS/MS_FAILURE. void free() Destroys resources used by a line object.
Creates new shape object from WKT string. Members Type string int int int int int rectObj int array Name text classindex type (read-only) numlines (read-only) index tileindex (read-only) bounds (read-only) numvalues (read-only) values (read-only)
The values array is an associative array with the attribute values for this shape. It is set only on shapes obtained from layer->getShape(). The key to the values in the array is the attribute name, e.g.
$population = $shape->values["Population"];
Methods int set(string property_name, new_value) Set object property to a new value. Returns -1 on error. int add(lineObj line) Add a line (i.e. a part) to the shape. LineObj line(int i) Returns a reference to line number i. Reference is valid only during the life of the shapeObj that contains the point. 210 Chapter 6. MapScript
int draw(mapObj map, layerObj layer, imageObj img) Draws the individual shape using layer. MS_SUCCESS/MS_FAILURE.
Returns
boolean contains(pointObj point) Returns MS_TRUE if the point is inside the shape, MS_FALSE otherwise. boolean intersects(shapeObj shape) Returns MS_TRUE if the two shapes intersect, MS_FALSE otherwise. int project(projectionObj in, projectionObj out) Project the shape from in projection (1st argument) to out projection (2nd argument). Returns MS_SUCCESS/MS_FAILURE. pointObj getpointusingmeasure(double m) Apply only on Measured shape les. Given a measure m, retun the corresponding XY location on the shapeobject. pointObj getmeasureusingpoint(pointObject point) Apply only on Measured shape les. Given an XY Location, nd the nearest point on the shape object. Return a point object of this point with the m value set. void free() Destroys resources used by a shape object. string getvalue(layerObj layer, string ledname) Returns the value for a given eld name. shapeobj buffer(width) Returns a new buffered shapeObj based on the supplied distance (given in the coordinates of the existing shapeObj). Only available if php/mapscript is built with GEOS library. shapeobj convexhull() Returns a shape object representing the convex hull of shape. Only available if php/mapscript is built with GEOS library. shapeobj boundary() Returns the boundary of the shape. Only available if php/mapscript is built with GEOS library. int containsShape(shapeobj shape2) Returns true if shape2 passed as argument is entirely within the shape. Else return false. Only available if php/mapscript is built with GEOS library. shapeobj union(shapeobj shape) Returns a shape object representing the union of the shape object with the one passed as parameter. Only available if php/mapscript is built with GEOS library shapeobj union_geos(shapeobj shape) [(Deprecated in v5.2. Use union instead)] Returns a shape object representing the union of the shape object with the one passed as parameter. Only available if php/mapscript is built with GEOS library. shapeobj intersection(shapeobj shape) Returns a shape object representing the intersection of the shape object with the one passed as parameter. Only available if php/mapscript is built with GEOS library. shapeobj difference(shapeobj shape) Returns a shape object representing the difference of the shape object with the one passed as parameter. Only available if php/mapscript is built with GEOS library. shapeobj symdifference(shapeobj shape) Returns the computed symmetric difference of the supplied and existing shape. Only available if php/mapscript is built with GEOS library. int overlaps(shapeobj shape) Returns true if the shape passed as argument overlaps the shape. Else returns false. Only available if php/mapscript is built with GEOS library. int within(shapeobj shape2) Returns true if the shape is entirely within the shape2 passed as argument. Else returns false. Only available if php/mapscript is built with GEOS library. int crosses(shapeobj shape) Returns true if the shape passed as argument crosses the shape. Else return false. Only available if php/mapscript is built with GEOS library. int touches(shapeobj shape) Returns true if the shape passed as argument touches the shape. Else return false. Only available if php/mapscript is built with GEOS library. int equals(shapeobj shape) Returns true if the shape passed as argument is equal to the shape (geometry only). Else return false. Only available if php/mapscript is built with GEOS library.
211
int disjoint(shapeobj shape) Returns true if the shape passed as argument is disjoint to the shape. Else return false. Only available if php/mapscript is built with GEOS library. pointObj getCentroid() Returns a point object representing the centroid of the shape. Only available if php/mapscript is built with GEOS library. double getArea() Returns the area of the shape (if applicable). Only available if php/mapscript is built with GEOS library. double getLength() Returns the length (or perimeter) of the shape. Only available if php/mapscript is built with GEOS library. pointObj getLabelPoint() Returns a point object with coordinates suitable for labelling the shape. string toWkt() Returns WKT representation of the shapes geometry. int setBounds() Updates the bounds property of the shape. Must be called to calculate new bounding box after new parts have been added. Returns true if successful, else return false.
Note: the members (minx, miny,maxx,maxy) are initialized to -1; Members: Type double double double double Methods int set(string property_name, new_value) Set object property to a new value. Returns -1 on error. void setextent(double minx, double miny, double maxx, double maxy) Set the rectangle extents. int draw(mapObj map, layerObj layer, imageObj img, int class_index, string text) Draws the individual rectangle using layer. The class_index is used to classify the rectangle based on the classes dened for the layer. The text string is used to annotate the rectangle. Returns MS_SUCCESS/MS_FAILURE. double t(int width, int height) Adjust extents of the rectangle to t the width/height specied. int project(projectionObj in, projectionObj out) Project the rectangle from in projection (1st argument) to out projection (2nd argument). Returns MS_SUCCESS/MS_FAILURE. void free() Destroys resources used by a rect object. Name minx miny maxx maxy
212
Chapter 6. MapScript
Opens a shapele and returns a new object to deal with it. Filename should be passed with no extension. To create a new le (or overwrite an existing one), type should be one of MS_SHP_POINT, MS_SHP_ARC, MS_SHP_POLYGON or MS_SHP_MULTIPOINT. Pass type as -1 to open an existing le for read-only access, and type=-2 to open an existing le for update (append). Members Type int int string rectObj Methods shapeObj getShape(int i) Retrieve shape by index. shapeObj getPoint(int i) Retrieve point by index. shapeObj getTransformed(mapObj map, int i) Retrieve shape by index. rectObj getExtent(int i) Retrieve a shapes bounding box by index. int addShape(shapeObj shape) Appends a shape to an open shapele. int addPoint(pointObj point) Appends a point to an open shapele. void free() Closes a shape le (and commits all changes in write mode) and releases all resources used by the object. Name numshapes (read-only) type (read-only) source (read-only) bounds (read-only)
213
will create a geographic projection class. The following example will convert a lat/long point to an LCC projection:
$projInObj = ms_newprojectionobj("proj=latlong"); $projOutObj = ms_newprojectionobj("proj=lcc,ellps=GRS80,lat_0=49,". "lon_0=-95,lat_1=49,lat_2=77"); $poPoint = ms_newpointobj(); $poPoint->setXY(-92.0, 62.0); $poPoint->project($projInObj, $projOutObj);
Methods int getUnits() Returns the units of a projection object. Returns -1 on error.
214
Chapter 6. MapScript
Methods int updateFromString(string snippet) Update MS_SUCCESS/MS_FAILURE. a scalebar from a string snippet. Returns
int set(string property_name, new_value) Set object property to a new value. Returns -1 on error. int setimagecolor(int red, int green, int blue) Sets the imagecolor propery (baclground) of the object. Returns false on error.
int set(string property_name, new_value) Set object property to a new value. Returns -1 on error.
215
Members Type int int int colorObj Methods int updateFromString(string snippet) Update MS_SUCCESS/MS_FAILURE. a queryMap object from a string snippet. Returns Name width height style (MS_NORMAL, MS_HILITE, MS_SELECTED) color
int set(string property_name, new_value) Set object property to a new value. Returns -1 on error.
The second argument style is optional. If given, the new style created will be a copy of the style passed as argument. Members Type int string double double double int int int colorObj colorObj colorObj double double double double string string double double string int Name symbol symbolname size minsize maxsize offsetx offsety antialias color backgroundcolor outlinecolor width minwidth maxwidth angle angleitem sizeitem minvalue maxvalue rangeitem opacity (this parameter is only supported for the AGG driver)
216
Chapter 6. MapScript
Methods int updateFromString(string snippet) Update MS_SUCCESS/MS_FAILURE. a style from a string snippet. Returns
int set(string property_name, new_value) Set object property to a new value. Returns -1 on error. styleObj clone() Returns a cloned copy of the style. int setBinding(const stylebinding, string value) Set the attribute binding for a specled style property. Returns true on success. Added in MapServer 5.0.
$oStyle->setbinding(MS_STYLE_BINDING_COLOR, "FIELD_NAME_COLOR");
This would bind the color parameter with the data (ie will extract the value of the color from the eld called FIELD_NAME_COLOR string getBinding(const stylebinding) Get the attribute binding for a specled style property. Returns null if there is no binding for this property.
$oStyle->setbinding(MS_STYLE_BINDING_COLOR, "FIELD_NAME_COLOR"); echo $oStyle->getbinding(MS_STYLE_BINDING_COLOR); // FIELD_NAME_COLOR
int removeBinding(const stylebinding) Remove the attribute binding for a specled style property. Returns true on success. Added in MapServer 5.0.
$oStyle->removebinding(MS_STYLE_BINDING_COLOR);
217
$oMap->outputformat->setOption("OUTPUT_TYPE", "RASTER");
string getOption(string property_name) Returns the associated value for the format option property passed as argument. Returns an empty string if property not found. void setFormatOption(string property_name, string new_value) Deprecated. See setOption(). string getFormatOption(string property_name) Deprecated. See getOption().
Members Type double double double double double double string Methods int set(string property_name, new_value) Set object property to a new value. Name minsubdivide maxsubdivide minarcs maxacrs mininterval maxinterval labelformat
218
Chapter 6. MapScript
Members Type int string string Method errorObj next() Returns the next errorObj in the list, or NULL if we reached the end of the list. Example: This example draws a map and reports all errors generated during the draw() call, errors can potentially come from multiple layers.
ms_ResetErrorList(); $img = $map->draw(); $error = ms_GetErrorObj(); while($error && $error->code != MS_NOERR) { printf("Error in %s: %s<br>\n", $error->routine, $error->message); $error = $error->next(); }
Creates a new symbol with default values in the symbolist. Returns the Id of the new symbol. If a symbol with the same name exists, Its id will be returned. To get a symbol object, you need to use a method on the map object:
$oSymbol = $map->getSymbolObjectById($nId);
219
Members Type string type int double double int int int int string int int string int string int int Methods int set(string property_name, new_value) Set object property to a new value. int setpoints(array double) Set the points of the symbol. Note that the values passed if an array containing the x and y values of the points. Example array[0] = 1 : x value of the rst point array[1] = 0 : y values of the rst point array[2] = 1 : x value of the 2nd point .... int setpattern(array int) Set the pattern of the symbol (used for dash patterns) array getpointsarray() Returns an array containing the points of the symbol. Refer to setpoints to see how the array should be interpreted. array getpatternarray() Returns an array containing the pattern. int setimagepath(char lename) Loads a pixmap symbol specied by the lename. The le should be of either Gif or Png format. int setstyle(array int) Deprecated in v5.0, will be removed in a future release. Use setpattern() instead. array getstylearray() Deprecated in v5.0, will be removed in a future release. Use getpatternarray() instead. Example of usage: 1. create a symbol to be used as a dash line
$nId = ms_newsymbolobj($gpoMap, "mydash"); $oSymbol = $gpoMap->getsymbolobjectbyid($nId); $oSymbol->set("filled", MS_TRUE); $oSymbol->set("sizex", 1); $oSymbol->set("sizey", 1); $oSymbol->set("inmapfile", MS_TRUE); $aPoints[0] = 1;
Name name name //Please refer to symbol type constants inmaple If set to TRUE, the symbol will be saved inside the maple. sizex sizey numpoints (Read-Only) lled patternlength (Read-Only) stylelength (Deprecated in v5.0, use patternlength instead.) (Read-Only) imagepath (Read-Only)) transparent transparentcolor character antialias font gap position
220
Chapter 6. MapScript
$aPoints[1] = 1; $oSymbol->setpoints($aPoints); $aPattern[0] = 10; $aPattern[1] = 5; $aPattern[2] = 5; $aPattern[3] = 10; $oSymbol->setpattern($aPattern); $style->set("symbolname", "mydash");
Create a new ows request object. Members Type int Name numparams (read-only)
int type (read-only): MS_GET_REQUEST or MS_POST_REQUEST =============== ==================================================================== Methods int loadparams() Initializes the OWSRequest object from the cgi environment variables REQUEST_METHOD, QUERY_STRING and HTTP_COOKIE. Returns the number of name/value pairs collected. int setparameter(string name, string value) Set a request parameter. For example :
$request->setparameter(REQUEST, GetMap);
string getname(int index) Return the name of the parameter at index in the requests array of parameter names. string getvalue(int index) Return the value of the parameter at index in the requests array of parameter values. string getvaluebyname(string name) Return the value associated with the parameter name.
221
Methods string get(string key) Fetch class metadata entry by name. Returns if no entry matches the name. Note that the search is case sensitive. int set(string key, string value) Set a metadata entry in the hashTable. Returns MS_SUCCESS/MS_FAILURE. int remove(string key) Remove a metadata entry in the hashTable. Returns MS_SUCCESS/MS_FAILURE. void clear() Clear all items in the hashTable (To NULL). string nextkey(string previousKey) Return the next key or rst key if previousKey = NULL. Return NULL if no item is in the hashTable or end of hashTable is reached
6.4.1 Introduction
The Python MapScript module contains some class extension methods that have not yet been implemented for other languages.
6.4.2 Classes
References to sections below will be added here as the documentation grows. 222 Chapter 6. MapScript
imageObj The Python Imaging Library, http://www.pythonware.com/products/pil/, is an indispensible tool for image manipulation. The extensions to imageObj are all geared towards better integration of PIL in MapScript applications.
imageObj Methods
imageObj( PyObject arg1, PyObject arg2 [, PyObject arg3 ] ) [imageObj] Create a new instance which is either empty or read from a Python le-like object that refers to a GD format image. The constructor has 2 different modes. In the blank image mode, arg1 and arg2 should be the desired width and height in pixels, and the optional arg3 should be either an instance of outputFormatObj or a GD driver name as a shortcut to a format. In the image le mode, arg1 should be a lename or a Python le or le-like object. If the le-like object does not have a seek attribute (such as a urllib resource handle), then a GD driver name must be provided as arg2. Heres an example of creating a 320 pixel wide by 240 pixel high JPEG using the constructors blank image mode:
image = mapscript.imageObj(320, 240, GD/JPEG)
write( [ PyObject le ] ) [void] Write image data to a Python le-like object. Default is stdout. pointObj
pointObj Methods
__str__() [string] Return a string formatted like
{ x: %f , y: %f }
Note that the return value can be conveniently evald into a Python dictionary:
>>> p_dict = eval(str(p)) >>> p_dict[x] 1.000000
223
rectObj
rectObj Methods
__contains__( pointObj point ) [boolean] Returns True if point is inside the rectangle, otherwise returns False.
>>> r >>> p >>> p False >>> p True = mapscript.rectObj(0, 0, 1, 1) = mapscript.pointObj(2, 0) in r not in r # outside
Note that the return value can be conveniently evald into a Python dictionary:
>>> r_dict = eval(str(r)) >>> r_dict[minx] 0.000000
The message of the error is written by msSetError and so is the same message that CGI mapserv users see in error logs.
224
Chapter 6. MapScript
Table of Contents Python MapScript Image Generation Introduction Imagery Overview The imageObj Class Image Output Images and Symbols
6.5.1 Introduction
The MapScript HOWTO docs are intended to complement the API reference with examples of usage for specic subjects. All examples in this document refer to the maple and testing layers distributed with MapServer 4.2+ and found under mapserver/tests. Pseudocode All examples will use a pseudocode that is consistent with the language independent API reference. Each line is a statement. For object attributes and methods we use the dot, ., operator. Creation and deletion of objects will be indicated by new and del keywords. Other than that, the pseudocode looks a lot like Python.
A properly sized and formatted blank image, without any layers, symbols, or labels, will be generated by prepareImage
225
blank_image = test_map.prepareImage()
Creating a new imageObj The imageObj class constructor creates new instances without need of a map
format = MapScript.outputFormatObj(GD/JPEG) image = MapScript.imageObj(300, 200, format)
If the image is using a GDAL/GTiff-based format, a GeoTIFF le can be created on disk by adding a mapObj as a second optional argument to save
map_image.save(filename, test_map)
Direct Output An image can be dumped to an open lehandle using the write method. By default, the lehandle is stdout
# Send an image to a web browser print "Content-type: " + map_image.format.mimetype + "\n\n" map_image.write()
This method is not fully functional for all SWIG MapScript languages. See the API Reference (MapScript.txt) for details. The write method is new in 4.4.
226
Chapter 6. MapScript
There is a symmetric setImage method which loads imagery into a symbol, allowing pixmap symbols to be created dynamically
new_symbol = MapScript.symbolObj(from_image) new_symbol.type = MapScript.MS_SYMBOL_PIXMAP new_symbol.setImage(image) index = test_map.symbolset.appendSymbol(new_symbol)
Contents Maple Manipulation Introduction Maple Overview The mapObj Class Children of mapObj Metadata
6.6.1 Introduction
The MapScript HowTo docs are intended to complement the API reference with examples of usage for specic subjects. All examples in this document refer to the maple and testing layers distributed with MapServer 4.2+ and found under mapserver/tests. Pseudocode All examples will use a pseudocode that is consistent with the language independent API reference. Each line is a statement. For object attributes and methods we use the dot, ., operator. Creation and deletion of objects will be indicated by new and del keywords. Other than that, the pseudocode looks a lot like Python.
New instances The maple path argument to the mapscript.mapObj constructor is now optional
empty_map = new mapscript.mapObj
generates a default mapObj with no layers. A mapObj is initialized from a maple on disk in the usual manner:
test_map = new mapscript.mapObj(tests/test.map)
Cloning An independent copy, less result and label caches, of a mapObj can be produced by the new mapObj.clone() method:
clone_map = test_map.clone()
Note: the Java MapScript module implements a cloneMap method to avoid conict with the clone method of Javas Object class. Saving A mapObj can be saved to disk using the save method:
clone_map.save(clone.map)
Frankly, the msSaveMap() function which is the foundation for mapObj::save is incomplete. Your mileage may vary.
These references are for convenience only. MapScript doesnt have any reference counting, and you are certain to run into trouble if you try to use these references after the parent mapObj has been deleted and freed from memory. Cloning a Child A completely independent Layer, Class, or Style can be created using the clone method of layerObj, classObj, and styleObj:
clone_layer = layer_i.clone()
New Children Uninitialized instances of layerObj, classObj, or styleObj can be created with the new constructors:
new_layer = new mapscript.layerObj new_class = new mapscript.classObj new_style = new mapscript.styleObj
and are added to a parent object using insertChild-like methods of the parent which returns the index at which the child was inserted:
li = test_map.insertLayer(new_layer) ci = test_map.getLayer(li).insertClass(new_class) si = test_map.getLayer(li).getClass(ci).insertStyle(new_style)
The insert* methods create a completely new copy of the object and store it in the parent with all ownership taken on by the parent. see the API reference for more details. Backwards Compatibility The old style child object constructors with the parent object as a single argument:
new_layer = new mapscript.layerObj(test_map) new_class = new mapscript.classObj(new_layer) new_style = new mapscript.styleObj(new_class)
remain in MapServer 4.4. Removing Children Child objects can be removed with removeChild-like methods of parents, which return independent copies of the removed object:
# following from the insertion example ... # remove the inserted style, returns a copy of the original new_style removed_style = test_map.getLayer(li).getClass(ci).removeStyle(si) removed_class = test_map.getLayer(li).removeClass(ci) removed_layer = test_map.removeLayer(li)
6.6.5 Metadata
Map, Layer, and Class metadata are the other arbitrarily numbered elements (well, up to the built-in limit of 41) of a maple. New API In MapServer 4.4, the metadata attributes of mapObj.web, layerObj, and classObj are instances of hashTableObj, a class which functions like a limited dictionary
229
# returns foo
See the API Reference (mapscript.txt) for more details. Backwards Compatibility for Metadata The old getMetaData and setMetaData methods of mapObj, layerObj, and classObj remain for use by older programs.
6.7 Querying
Author Sean Gillies Revision $Revision: 8278 $ Date $Date: 2008-12-23 13:34:31 -0800 (Tue, 23 Dec 2008) $
6.7.1 Introduction
All examples in this document refer to the maple and testing layers distributed with MapServer 4.2+ and found under mapserver/tests. Pseudocode All examples will use a pseudocode that is consistent with the language independent API reference. Each line is a statement. For object attributes and methods we use the dot, ., operator. Creation and deletion of objects will be indicated by new and del keywords. Other than that, the pseudocode looks a lot like Python.
230
Chapter 6. MapScript
In the case of a failed query or query with zero results, getResults returns NULL. Result Set Members Individual members of the query results are obtained like:
... if results: for i in range(results.numresults): result = results.getResult(i) # continued
This result object is a handle, of sorts, for a feature of the layer, having shapeindex and tileindex attributes that can be used as arguments to getFeature. Resulting Features The previous example code can now be extended to the case of obtaining all queried features:
layer.query() results = layer.getResults() if results: # open layer in preparation of reading shapes layer.open() for i in range(results.numresults): result = results.getResult(i) layer.getFeature(result.shapeindex, result.tileindex) ... # do something with this feature
Backwards Compatibility Scripts using the 4.2 API can continue to access query result members through layer methods:
for i in range(layer.getNumResults()): result = layer.getResult(0)
but should adopt the new API for use in new work. 6.7. Querying 231
232
Chapter 6. MapScript
Contents MapScript Variables Version Logical Control - Boolean Values Logical Control - Status Values Map Units Layer Types Font Types Label Positions Label Size (Bitmap only) Shape Types Measured Shape Types Shapele Types Query Types File Types Querymap Styles Connection Types DB Connection Types Join Types Line Join Types (for rendering) Image Types Image Modes Symbol Types Return Codes Limiters Error Return Codes
6.8.1 Version
Name MS_VERSION Type character Value 5.2
233
234
Chapter 6. MapScript
235
236
Chapter 6. MapScript
1000
6.8.23 Limiters
Name MS_MAXSYMBOLS MS_MAXVECTORPOINTS MS_MAXSTYLELENGTH MS_IMAGECACHESIZE 6.8. MapScript Variables Type long long long long Value
237
238
Chapter 6. MapScript
CHAPTER
SEVEN
DATA INPUT
7.1 Vector Data
Date 2008/09/09 Author Tyler Mitchell Contact tmitchell at osgeo.org Author Jeff McKenna Contact jmckenna at gatewaygeomatics.com This work is licensed under the Creative Commons Attribution-ShareAlike License. To view a copy of this license, visit: http://creativecommons.org/licenses/by-sa/2.0/ca/ or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA. What is vector data? This quote from is a good description of what vector data is: Vector: An abstraction of the real world where positional data is represented in the form of coordinates. In vector data, the basic units of spatial information are points, lines and polygons. Each of these units is composed simply as a series of one or more coordinate points. For example, a line is a collection of related points, and a polygon is a collection of related lines. Vector images are dened mathematically as a series of points joined by lines. Vector-based drawings are resolution independent. This means that they appear at the maximum resolution of the output device, such as a printer or monitor. Each object is self-contained, with properties such as color, shape, outline, size, and position on the screen. From: http://coris.noaa.gov/glossary/glossary_l_z.html#v The rest of this document is the data format guide. This guide is structured to show the fundamentals of each MapServer supported data format. Each section discusses one format, ranging from one to several pages in length. The sections typically start with a summary of the most important information about the format, followed by examples of le listings, connection methods, ogrinfo usage and MapServer map le syntax examples. Each section has been designed to stand alone, so you may notice that certain warnings and comments are repeated or redundant. This is intentional. Each format is presented in rough order of popular use, based on a survey of the MapServer community. The following formats are included:
Data Source - a group of layers stored in a common repository. This may be a le that handles several layers within it, or a folder that has several les. Layer - a sub-set of a data source often containing information in one type of vector format (point, line, polygon). There are three types of data mapping and GIS data formats. Each type is handled differently. Below are the types and some example formats: File-based- Shapeles, Microstation Design Files (DGN), GeoTIFF images Directory-based - ESRI ArcInfo Coverages, US Census TIGER Database connections - PostGIS, ESRI ArcSDE, MySQL File-based Data File-based data consists of one or more les stored in any arbitrary folder. In many cases a single le is used (e.g. DGN) but ESRI Shapeles, for example, consist of at least 3 les each with a different lename extension: SHP, DBF, SHX. In this case all 3 les are required because they each perform a different task internally. Filenames usually serve as the data source name and contain layers that may or may not be obvious from the lename. In Shapeles, for example, there is one data source per shapele and one layer which has the same name as that of the le. Directory-based Data Directory-based data consists of one or more les stored in a particular way within a parent folder. In some cases (e.g. Coverages) they may also require additional folders in other locations in the le tree in order to be accessed. The directory itself may be the data source. Different les within the directory often represent the layers of data available. For example, ESRI ArcInfo Coverages consist of more than one le with an ADF le extension, within a folder. The PAL.ADF le represents the Polygon data. ARC.ADF holds the arc or line string data. The folder holds the data source and each ADF le is a layer. Database Connections Database Connections are very similar to le and directory-based structures in one respect: they provide geographic coordinate data for MapServer to interpret. That may be oversimplifying what is happening inside MapServer, but in essence all you need is access to the coordinates making up the vector datasets. Database connections provide a stream of coordinate data that is temporarily stored (e.g. in memory) and read by MapServer to create the map. Other attribute or tabular data may also be required, but the focus of this guide is coordinate data. One important distinction between databases must be made. The databases discuss here are spatial databases, those which can hold geographic data in its own data type. This is opposed to strictly tabular databases which cannot hold geographic coordinates in the same way. It is possible to store some very simple coordinate data in regular tables, but for anything but the most simple use a spatial database is required. There are spatial extensions to many databases (open source and commercial). One of the most robust is the PostGIS extension to the PostgreSQL database. This database not only allows the storage of geographic data, but also allows the manipulation of that data using SQL commands. The other open source database with spatial capabilities is MySQL. Connections to databases usually consist of the following pieces of connection information: Host - Directions to the server or computer hosting the database. Database name - The name of the database you wish to access that is running on the host.
240
User name / passwords - Access privileges are usually restricted by user. Note: Some databases (e.g. Oracle) use a name service identier that includes both the host and database names. Access to specic pieces of coordinate data usually require: Table/View name - The name of the table or view holding the coordinate data. Geographic column name - Where the geometry or coordinates are stored.
Data Access / Connection Method Shapele access is built directly into MapServer. It is also available through OGR, but direct access without OGR is recommended and discussed here. The path to the shapele is required. No le extension should be specied. Shapeles only hold one layer of data, therefore no distinction needs to be made. OGRINFO Examples The directory can serve as a data source. Each shapele in a directory serves as a layer. A shapele can also be a data source. In this case the layer has the same prex as the shapele. Using ogrinfo on a directory with multiple shapeles:
> ogrinfo /data/shapefiles/ INFO: Open of /data/shapefiles/ using driver ESRI Shapefile successful. 1: wpg_h2o (Line String) 2: wpg_roads (Line String) 3: wpg_roads_dis (Line String) 4: wpgrestaurants (Point)
241
7.1.3 PostGIS/PostgreSQL
PostGIS/PostgreSQL PostGIS spatially enables the Open Source PostgreSQL database. The PostGIS wiki page may include additional information. Data Access /Connection Method PostGIS is supported directly by MapServer and must be compiled into MapServer to work. The PostgreSQL client libraries (libpq.so or libpq.dll) must be present in the systems path environment for functionality to be present. The CONNECTIONTYPE parameter must be set to POSTGIS. The CONNECTION parameter is used to specify the parameters to connect to the database. CONNECTION parameters can be in any order. Most are optional. dbname is required. user is required. host defaults to localhost, port defaults to 5432 (the standard port for PostgreSQL). The DATA parameter is used to specify the data used to draw the map. The form of DATA is [geometry_column] from [table_name|sql_subquery] using unique [unique_key] using srid=[spatial_reference_id]. The using unique 242 Chapter 7. Data Input
and using srid= clauses are optional, but using them improves performance. Here is a simple generic example:
CONNECTIONTYPE POSTGIS CONNECTION "host=yourhostname dbname=yourdatabasename user=yourdbusername password=yourdbpassword por DATA "geometrycolumn from yourtablename"
This example shows specifying the unique key and srid in the DATA line:
CONNECTIONTYPE POSTGIS CONNECTION "dbname=yourdatabasename user=yourdbusername" DATA "the_geom from the_database using unique gid using srid=4326"
This example shows using a SQL subquery to perform a join inside the database and map the result in MapServer. Note the as subquery string in the statement everything between from and using is sent to the database for evaluation:
CONNECTIONTYPE POSTGIS CONNECTION "dbname=yourdatabasename user=yourdbusername" DATA "the_geom from (select g.gid, g.the_geom, a.attr1, a.attr2 from geotable g join attrtable a on g
This example shows using a geometry function and database sort to limit the number of features and vertices returned to MapServer:
CONNECTIONTYPE POSTGIS CONNECTION "dbname=yourdatabasename user=yourdbusername" DATA "the_geom from (select g.gid, ST_Simplify(g.the_geom, 10.0) as the_geom from geotable g order by
This example shows the use of the !BOX! substitution string to over-ride the default inclusion of the map bounding box in the SQL. By default the spatial box clause is appended to the SQL in the DATA clause, but you can use !BOX! to insert it anywhere you like in the statement. In general, you wont need to use !BOX!, because the PostgreSQL planner will generate the optimal plan from the generated SQL, but in some cases (complex sub-queries) a better plan can be generated by placing the !BOX! closer to the middle of the query:
CONNECTIONTYPE POSTGIS CONNECTION "dbname=yourdatabasename user=yourdbusername" DATA "the_geom from (select g.gid, ST_Union(g.the_geom, 10.0) as the_geom from geotable g where ST_In
OGRINFO Examples OGRINFO can be used to read out metadata about PostGIS tables directly from the database. First you should make sure that your GDAL/OGR build contains the PostgreSQL driver, by using the formats command:
>ogrinfo --formats Loaded OGR Format Drivers: ... -> "PGeo" (readonly) -> "PostgreSQL" (read/write) -> "MySQL" (read/write) ...
243
If you dont have the driver, you might want to try the FWTools or MS4W packages, which include the driver. Once you have the driver you are ready to try an ogrinfo command on your database to get a list of spatial tables:
>ogrinfo PG:"host=127.0.0.1 user=postgres password=postgres dbname=canada port=5432" using driver PostgreSQL successful. 1: province (Multi Polygon)
Now use ogrinfo to get information on the structure of the spatial table:
>ogrinfo PG:"host=127.0.0.1 user=postgres password=postgres dbname=canada port=5432" province -summar INFO: Open of PG:host=127.0.0.1 user=postgres password=postgres dbname=canada using driver PostgreSQL successful. Layer name: province Geometry: Multi Polygon Feature Count: 1068 Extent: (-2340603.750000, -719746.062500) - (3009430.500000, 3836605.250000) Layer SRS WKT: (unknown) FID Column = gid Geometry Column = the_geom area: Real (0.0) island: String (30.0) island_e: String (30.0) island_f: String (30.0) name: String (30.0) ...
Maple Example
LAYER NAME "province" STATUS ON TYPE POLYGON CONNECTIONTYPE POSTGIS CONNECTION "host=127.0.0.1 port=5432 dbname=canada user=postgres password=postgres" DATA "the_geom from province" CLASS ... END END
For more info about PostGIS and MapServer see the PostGIS docs: http://postgis.refractions.net/docs/
7.1.4 OGR
Author Jeff McKenna Contact jmckenna at gatewaygeomatics.com Revision $Revision: 8597 $ Date $Date: 2009-02-19 07:10:12 -0800 (Thu, 19 Feb 2009) $
244
Table of Contents OGR Introduction What is OGR? Obtaining and Compiling MapServer with OGR Support Integrating OGR Support with MapServer Applications STYLEITEM AUTO - Rendering Layers Using Style Information from the OGR File Sample Sites Using OGR/MapServer FAQ / Common Problems
Introduction Starting with version 3.5, MapServer included the ability to access vector data sets in formats other than Shapele in their native format using the OGR library. The following document describes the process for implementing OGR support within MapServer applications. Note: Experimental OGR support was included in MapServer version 3.4 but this initial implementation had some limitations and is not covered in this document. This document assumes that you are already familiar with certain aspects of MapServer: MapServer application development and especially setting up .map les. Some compilation skills if you dont have ready access to a pre-compiled installation and need to compile your own copy of MapServer with OGR support. access to OGR utilities, such as ogrinfo, which are available in the FWTools and MS4W packages. Readers should also check out the Vector Data Access Guide, which has lots of examples of how to access specic vector formats. What is OGR? The OGR Simple Features Library is a C++ open source library (and command-line tools) providing read (and sometimes write) access to a variety of vector le formats including ESRI Shapeles, and MapInfo mid/mif and TAB formats. OGR is actually part of the GDAL library, so you will notice that some references point to GDAL (such as the mailing list).
245
UK.NTF (National Transfer Format) US Census TIGER/Line VRT - Virtual Datasource X-Plane/Flighgear aeronautical data Note: Some of the above formats (e.g. OGDI) have external dependencies and are not always included in the pre-compiled binary distributions of MapServer with OGR support.* Note: Some of the above formats are not well suited for random access by nature, thats the case of MapInfo MIF/MID les which is a TEXT format and will give very poor performance for a web application. On the other hand, some binary formats such as MapInfo TAB are better suited for random access and will give performance comparable to native shapele access in MapServer.*
247
accessing a directory-based data source you specify the directory name and OGR reads all the les in the directory as a single data source with potentially several layers (e.g. TIGER les). Some OGR drivers (e.g. SHP, TAB) can have dual behaviors, that is if theyre pointed to a single le then they behave as a le-based data source and if theyre pointed to a directory then they will behave as a directory-based data source and then every le in the directory becomes a new layer in the data source. See the OGR formats page for more info on the specic le format youre using. (Click on the format name for more specic driver info on that format)
<datasource_name> is the name of the datasource to read from and is prexed by the CONNECTION keyword. The exact organization depends on the format driver in use. The format driver to use is automatically selected by OGR based on the nature of the string passed as the datasource, and/or the format of the le referenced by it. For le based datasources this is the name of the le, including the extension, using an absolute path, or a relative path. Relative paths are interpreted relative to the SHAPEPATH rst, if not found then we try again relative to the .map le location. Note: Before version 4.1 the SHAPEPATH was ignored for OGR datasources. For directory based datasources, such as TIGER/Line, or Arc/Info Binary Coverages this is the name of the directory containing the les. If the path is relative it is interpreted relative to the .map le. For virtual datasources such as database systems, and OGDI this is the service connection string and is generally not related to the lesystem. For instance, for Oracle Spatial this might be OCI:warmerda/[email protected]. <layer_denition> is the name, number or SQL denition of the layer to use from the datasource. It is indicated via the DATA keyword in the map le. Layer Name: The (case insenstive) layer name may be used to select a layer. Layer Number: The layer number (starting from 0 for the rst layer) may be used to select a layer. Generally the layer name is preferred to this since it is more self describing. Omitted: If no DATA keyword is provided, this is equivalent to selecting layer 0. SQL SELECT: If an SQL SELECT statement is used, it is interpreted in a driver specic manner to try and generate a temporary pseudo-layer. For some formats this a restricted subset of SQL is interpreted within OGR. For RDBMS based drivers (such as PostGIS and Oracle) this is passed through to the underlying database. The OGRINFO utility can be used to nd out the list of layers and their names in a data source.
248
Example 2. Microstation DGN le using <layer_index> The entire DGN le is represented in OGR as one layer (see the DGN driver page for more details):
LAYER NAME "dgn" TYPE LINE CONNECTIONTYPE OGR CONNECTION "dgn/santabarbara02.dgn" DATA "0" STATUS ON STYLEITEM "AUTO" CLASS END END # Layer
249
Had to open data source read-only. INFO: Open of popplace.tab using driver MapInfo File successful. 1: popplace (Point)
which shows that there is one point layer in the popplace.tab le. Example 6. To get a dump of a specic layer, including eld names, projection, etc:
$ ogrinfo popplace.tab popplace Had to open data source read-only. INFO: Open of popplace.tab using driver MapInfo File successful. Layer name: popplace Geometry: Point Feature Count: 497 Layer SRS WKT: PROJCS["unnamed",GEOGCS["unnamed",DATUM["North ...snipped... AREA: Real (15.3) PERIMETER: Real (15.3) POPPLACE_: Real (11.0) POPPLACE_I: Real (15.0) NAME: String (50.0) OGRFeature(popplace):1 AREA (Real) = 0.000 PERIMETER (Real) = 0.000 POPPLACE_ (Real) = 1 POPPLACE_I (Real) = 1 NAME (String) = Port Hope Simpson POINT (2437287.249 1153656.751) OGRFeature(popplace):2
250
AREA (Real) = 0.000 PERIMETER (Real) = 0.000 POPPLACE_ (Real) = 2 POPPLACE_I (Real) = 1 NAME (String) = Hopedale ... ...
The above example shows that there are 14 layers in the TGR25001 directory. Example 8. To get a summary of a specic TIGER layer, including only eld names, projection, and extent
$ ogrinfo TGR25001 Landmarks -summary Had to open data source read-only. INFO: Open of TGR25001 using driver TIGER successful. Layer name: Landmarks Geometry: Point Feature Count: 777 Extent: (-70.674324, 41.519817) - (-69.969211, 42.046868) Layer SRS WKT: GEOGCS["NAD83",DATUM["North_American_Datum_1983", SPHEROID["GRS 1980",6378137,298.257222101]],PRIMEM["Greenwich",0], UNIT["degree",0.0174532925199433]] MODULE: String (8.0) FILE: String (5.0) STATE: Integer (2.0) COUNTY: Integer (3.0) LAND: Integer (10.0) SOURCE: String (1.0) CFCC: String (3.0) LANAME: String (30.0)
251
OGR tileindex layers should support all normal query and attribute fetching mechanisms, including from MapScript; however, this has not been heavily tested as of April/2002. Please report problems via the MapServer Trac. If auto projection support is used for tileindexed OGR layers, the tileindex is read for the projection (not the component tiles). Problems may (or may not) be encountered if the component tiles have differing schemas (different sets of attributes).
Connection Pooling
For some OGR supported formats, connecting to the dataset is quite expensive in terms of CPU use and amount of disk IO. For instance, establishing access to an S-57 dataset results in a complete read into memory of the data les. Connection pooling control aims at reducing this overhead in situations where the same le is used for several different map layers. To ensure that an OGR supported dataset is only opened once per map render (instead of separately for each map LAYER referencing the dataset, use the CLOSE_CONNECTION PROCESSING option. The default value is for CLOSE_CONNECTION is NORMAL, but if set to DEFER the dataset will be kept open till the map render is complete. It will be reused by any other layers with using the same datasource. Example 9. Preserve S-57 connection for two layers
252
In this example, we are using the same dataset (NO410810.000) for two layers. To avoid re-reading the dataset, we mark the rst layer to defer closing the connection till layer. In the second (or last) layer we request NORMAL connection handling (though this could have been left out as normal handling is the default).
LAYER NAME "AdminAreas" TYPE POLYGON CONNECTIONTYPE OGR CONNECTION "NO410810.000" DATA "ADMARE" PROCESSING "CLOSE_CONNECTION=DEFER" STATUS ON ... END LAYER NAME "Land Areas" TYPE POLYGON CONNECTIONTYPE OGR CONNECTION "NO410810.000" DATA "LNDARE" PROCESSING "CLOSE_CONNECTION=NORMAL" STATUS ON ... END
1. The text of the CONNECTION keyword must match exactly between layers for the connection to be reused. 2. Some dataset connections are quite memory expensive, and keeping them open may result in increased memory use. 3. If all layers rendered for a particular connection defer closing the connection, it will remain open till MapServer terminates. For normal cgi or MapScript use this is likely OK. 4. This use of CLOSE_CONNECTION handling is unique to OGR layers, and may be changed at some point in the future as part of a broader implementation of connection pooling in MapServer. STYLEITEM AUTO - Rendering Layers Using Style Information from the OGR File Note: This feature is only supported with MapInfo TAB and Microstation DGN les at the moment, but eventually other formats that carry colors and styles at the shape-level may also be supported through OGR.* In MapServer, ArcView, and other shapele-based applications, colors and styles are usually dened at the layer level. This means that all the shapes in a given layer are usually rendered using the same color and styles. On the other hand, some formats supported by OGR such as MapInfo TAB do have color and style information attached to each shape. OGR adds support for the STYLEITEM AUTO layer parameter which allows you to request that the shapes in a layer be rendered using colors and styles coming from the data source instead of being driven by CLASSes as was traditionally done with MapServer.
How to Implement
In order to have a layer rendered using colours and styles coming from the OGR data source, your must do the following: Your layer denition must contain the STYLEITEM AUTO parameter.
253
Your layer denition needs to contain at least one CLASS (which may be empty) and optionally a CLASSITEM to match the expressions if your CLASS contains an expression. The empty CLASS in the layer will be updated dynamically at runtime to contain colours and styles coming from the data source for each shape.
Examples
Example 10. Layer Denition Using STYLEITEM AUTO without a CLASSITEM
LAYER NAME "test_dgn" STATUS ON TYPE POLYGON CONNECTIONTYPE OGR CONNECTION "../data/dgn/test.dgn" # This enables use of colors and styles from the source file. STYLEITEM "AUTO" # Define an empty class that will be filled at runtime from the color and # styles read on each shape in the source file. CLASS END END # layer
Please Note: CLASS EXPRESSIONs are still working, so it is still possible to query and classify layers that are using STYLEITEM AUTO. The only difference is that instead of using static class denitions, the colors and style will be read from the data le.
Important Notes
NOTE 1 Even though MapInfo and other OGR data sources may support layers with mixed geometry types (e.g. points, lines and polygons in the same le) this is not yet supported in MapServer. So you still have to dene a layer TYPE and make sure that all the shapes in the OGR data source 254 Chapter 7. Data Input
are compatible with that layer type, otherwise MapServer may produce an error about incompatible geometry types at runtime. NOTE 2 Due to the dynamic nature of this feature, it is not compatible with the labelcache, so the labelcache is automatically disabled for layers that make use of STYLEITEM AUTO. NOTE 3 When you use STYLEITEM AUTO, MapServer tries to match symbol names returned by OGR to names in your symbol le. For a quick solution, try using the following symbol le: http://www2.dmsolutions.ca/msapps/yk_demo/etc/symbols_mapinfo.sym The name of the symbols returned by OGR to MapServer depends on the le format. In the case of MapInfo les, it will be: For old-style symbols (default MapInfo 3.0 symbols numbered 32 to 67) the symbol name will be mapinfosym-## where ## is the symbol number, e.g. mapinfo-sym-32. For Font Symbols, the symbol name is also mapinfo-sym-## where ## is the symbol number in the font. In this case, the name of the font itself is ignored by MapServer. MapInfo also supports custom symbols (bitmap symbols)... Im not sure what you would get from OGR for this, but Im pretty sure that MapServer doesnt do anything useful with them. The OGRINFO utility can be used to nd out exactly which symbol names OGR will return to MapServer. Look at the Style string in the ogrinfo output for each shape that is read.
Text labels The text string is mapped to CLASS.TEXT Text color is mapped to CLASS.LABEL.COLOR Text background color is mapped to CLASS.LABEL.BACKGROUNDCOLOR Text height is mapped to CLASS.LABEL.SIZE Text angle is mapped to CLASS.LABEL.ANGLE Text font mapping follows the following rules: 1. If TTF fonts are supported: (a) If the native font name (e.g. Arial) is found in your fontset then this font will be used. (b) If 1a. failed and a font called default is present in your fontset then this default font will be used. 2. If TTF fonts are not supported or if all above cases failed, then BITMAP MEDIUM font will be used.
The following label styles are supported: Label Style Description MapServer Version Implemented 5.4 5.2.0 5.2.0 5.2.0 5.4 5.4 5.4 5.4 5.4 5.4 5.4 5.4 5.4 5.4 5.4 5.4 5.4 5.4 5.4 5.4 5.4 Chapter 7. Data Input
OGR:LabelFont Comma-delimited list of fonts names OGR:LabelSize Numeric value with units OGR:LabelText Label text string OGR:LabelAngle Rotation angle (in degrees) OGR:LabelFColorForeground color OGR:LabelBColorBackground color OGR:LabelPlacement is the text drawn relative to the features geometry How OGR:LabelAnchorA value from 1 to 12 dening the labels position relative to the point to which it is attached. OGR:LabelDx X offset OGR:LabelDy Y offset OGR:LabelPerp Perpendicular offset OGR:LabelBold Bold text OGR:LabelItalic Italic text OGR:LabelUnderline Underlined text OGR:LabelPriorityNumeric value dening the order in which style parts should be drawn. OGR:LabelStrikeout Strike out text (gdal >= 1.4.0) OGR:LabelStretchStretch factor changes the width of all characters in the font by factor percent. (gdal >= 1.4.0) OGR:LabelAdjHorHorizontally adjacent text (gdal >= 1.4.0) OGR:LabelAdjVert ertically adjacent text (gdal >= 1.4.0) V OGR:LabelHColorShadow color (gdal >= 1.4.0) OGR:LabelOColorOutline color (gdal > 1.6.0) 256
Please see the OGR Feature Style Specication document for more details on those specic styles. Sample Sites Using OGR/MapServer The following sites use OGRs STYLEITEM AUTO feature: http://www2.dmsolutions.ca/msapps/yk_demo/demo_init.html http://www2.dmsolutions.ca/msapps/nd_demo/demo_init.html The following site uses OGR, as well as MapInfos Seamless Map Layers feature: http://www2.dmsolutions.ca/msapps/ro_demo/demo_init.html The following site uses OGR to display TIGER 2000 les: http://www2.dmsolutions.on.ca/msapps/tig_demo/demo_init.html FAQ / Common Problems Q What Does OGR Stand For? A Basically, OGR does not stand for anything. For a detailed explanation of how OGR was named, see GDALs FAQ at http://trac.osgeo.org/gdal/wiki/FAQ.
Q When using STYLEITEM AUTO, what should I have in my .sym symbols le? A When you use STYLEITEM AUTO, MapServer tries to match symbol names returned by OGR to names in your symbol le. For a quick solution, try using the following symbol le: http://www2.dmsolutions.ca/msapps/yk_demo/etc/symbols_mapinfo.sym The name of the symbols returned by OGR to MapServer depends on the le format. In the case of MapInfo les, it will be: For old-style symbols (default MapInfo 3.0 symbols numbered 32 to 67) the symbol name will be mapinfo-sym-## where ## is the symbol number, e.g. mapinfo-sym-32. For Font Symbols, the symbol name is also mapinfo-sym-## where ## is the symbol number in the font. In this case, the name of the font itself is ignored by MapServer. MapInfo also supports custom symbols (bitmap symbols)... Im not sure what you would get from OGR for this, but Im pretty sure that MapServer doesnt do anything useful with them. The OGRINFO utility can be used to nd out exactly which symbol names OGR will return to MapServer. Look at the Style string in the ogrinfo output for each shape that is read.
7.1.5 MapInfo
File listing The following les are also associated with .TAB les: .DAT, .ID, .MAP. An example is:
border.DAT border.ID border.MAP border.TAB
The term MID/MIF refers to les with .MID and .MIF extension. 7.1. Vector Data 257
Data Access / Connection Method TAB and MID/MIF access is available in MapServer through OGR. The CONNECTIONTYPE OGR parameter must be used. The path to the (*.tab or *.mif) le is required, and the le extension is needed. The path may be relative to the SHAPEPATH MapInfo les already contain styling information. This styling information can be used optionally by specifying the STYLEITEM AUTO parameter in the LAYER object of the map le. Note: If you use STYLEITEM AUTO you must have an empty class in the layer. OGRINFO Examples Using ogrinfo on a single TAB le
> ogrinfo elev5_poly.TAB Had to open data source read-only. INFO: Open of elev5_poly.TAB using driver MapInfo File successful. 1: elev5_poly (Polygon)
258
STATUS DEFAULT CONNECTIONTYPE OGR CONNECTION "./hypso/elev5_poly.TAB" STYLEITEM "AUTO" CLASS NAME "Elevation Poly 5" END END # Layer
7.1.6 WFS
WFS is an Open Geospatial Consortium (OGC) specication. For more information about the format itself, see: http://www.opengeospatial.org/standards/wfs WFS allows a client to retrieve geospatial data encoded in Geography Markup Language (GML) from multiple Web Feature Services. GML is built on the standard web language XML. WFS differs from the popular Web Map Service (WMS) specication in that WFS returns a subset of the data in valid GML format, not just a graphic image of data. Capabilities Requesting the capabilities using the GetCapabilities request to a WFS server returns an XML document showing what layers and projections are available, etc. Example of a WFS GetCapabilities URL:
http://www2.dmsolutions.ca/cgi-bin/mswfs_gmap?VERSION=1.0.0&SERVICE=wfs&REQUEST=GetCapabilities
259
Data Access / Connection Method WFS access is a core MapServer feature. MapServer currently supports WFS version 1.0.0 The CONNECTIONTYPE WFS parameter must be used. WFS layers can be requested through a layer in a map le, or you can request the GML directly through the browser with a GetFeature request. You can specify a specic layer with the TypeName request. In a map le the name/value pairs should be put into a METADATA object. You can limit the number of features returned in the GML by using the MaxFeatures option (e.g. &MAXFEATURES=100). Example of a WFS Request Directly Through the Browser: The following URL requests the GML for the layer road. (see the GetCapabilities above for the possible layers available on this test server) . The URL is all one line, broken up here for readability.
http://www2.dmsolutions.ca/cgi-bin/mswfs_gmap ?VERSION=1.0.0 &SERVICE=wfs &REQUEST=getfeature&TYPENAME=road
7.1.7 GML
Also known as Geographic Markup Language and GML/XML. GML is a text-based, XML format that can represent vector and attribute data. This is an Open Geospatial Consortium specication for data interchange. More information is available at http://www.opengeospatial.org/standards/gml File listing GML les are usually a single text le with a GML lename extension. Some may use XML as the lename extension:
260
coal_dep.gml
XML schema documents often accompany GML les that have been translated from some other format (e.g. using the ogr2ogr utility). GML uses sets of nested tags to dene attributes and geometry coordinates. Example of text in a GML le:
<gml:featureMember> <Coal_Deposits fid="1"> <UNKNOWN>0.000</UNKNOWN> <NA>0.000</NA> <ID>2</ID> <ID2>2</ID2> <MARK>7</MARK> <COALKEY>110</COALKEY> <COALKEY2>110</COALKEY2> <ogr:geometryProperty> <gml:Point> <gml:coordinates>78.531,50.694</gml:coordinates> </gml:Point> </ogr:geometryProperty> </Coal_Deposits> </gml:featureMember>
Data Access / Connection Method GML access is available in MapServer through OGR. More information on OGR GML support is available at http://www.gdal.org/ogr/drv_gml.html The CONNECTIONTYPE OGR parameter must be used. The path to the GML le is required, including le extension. There can be multiple layers in a GML le, including multiple feature types. OGRINFO Examples Using ogrinfo on a single GML le:
> ogrinfo /data/gml/coal_dep.gml Had to open data source read-only. INFO: Open of coal_dep.gml using driver GML successful. 1: Coal_Deposits
261
Extent: (23.293650, 37.986340) - (179.272550, 80.969670) Layer SRS WKT: (unknown) UNKNOWN: Real (0.0) NA: Real (0.0) ID: Integer (0.0) ID2: Integer (0.0) MARK: Integer (0.0) COALKEY: Integer (0.0) COALKEY2: Integer (0.0) LONG: Real (0.0) LAT: Real (0.0)
Table of Contents Virtual Spatial Data Types of Databases Types of Flat Files Steps for Display
This is an OGR extension to MapServer. It allows you to connect to databases that do not explicitly hold spatial data, as well as at text les. Your data must have an X and a Y column, and the data may be accessed through an ODBC connection or a direct pointer to a text le. The original VirtualSpatialData wiki page may contain additional information. Types of Databases The VirtualSpatialData OGR extension has been tested with the following databases and should, in theory, support all ODBC data sources.
262
Oracle MySQL SQL Server Access PostgreSQL Types of Flat Files Comma, tab or custom delimited text/at les work with VirtualSpatialData. Steps for Display
Windows users may not be required to specify a user/password, so the syntax would be:
> ogrinfo ODBC:@DSN table
Example: Accessing a comma separated text le through ODBC using ogrinfo The following is a snippet of the at text le coal_dep.txt containing lat/long points:
unknown,na,id,id2,mark,coalkey,coalkey2,long,lat 0.000,0.000,1,1,7,87,87,76.90238,51.07161 0.000,0.000,2,2,7,110,110,78.53851,50.69403 0.000,0.000,3,3,3,112,112,83.22586,71.24420 0.000,0.000,4,4,6,114,114,80.79896,73.41175
If the DSN name is Data_txt, the ogrinfo command to see a list of applicable les in the directory is:
> ogrinfo ODBC:jeff/test@Data_txt INFO: Open of ODBC:jeff/test@Data_txt using driver ODBC successful. 1: coal_dep.csv 2: coal_dep.txt 3: coal_dep_nf.txt 4: coal_dep_trim.txt 5: Copy of coal_dep.txt 6: deposit.csv
263
7: maruia.asc 8: oahuGISbathy.csv 9: oahuGISbathy.txt 10: on_pts.txt 11: on_pts_utm.txt 12: test.txt 13: utm_test.txt
Username and password may be optional, so the following may also be valid:
> ogrinfo ODBC:@Data_txt
Therefore, the command to see more information about one of the specic layers is:
> ogrinfo ODBC:@Data_txt coal_dep.txt INFO: Open of ODBC:@Data_txt using driver ODBC successful. Layer name: coal_dep.txt Geometry: Unknown (any) Feature Count: 266 Layer SRS WKT: (unknown) UNKNOWN: String (255.0) NA: String (255.0) ID: String (255.0) ID2: String (255.0) MARK: String (255.0) COALKEY: String (255.0) COALKEY2: String (255.0) LONG: String (255.0) LAT: String (255.0) OGRFeature(coal_dep.txt):0 UNKNOWN (String) = 0.000 ....
More information on ovf les can be found at: http://www.gdal.org/ogr/drv_vrt.html Example ovf le for coal_dep.txt:
264
<OGRVRTDataSource> <OGRVRTLayer name="coal-test"> <SrcDataSource>ODBC:Data_txt</SrcDataSource> <SrcLayer>coal_dep.txt</SrcLayer> <GeometryField encoding="PointFromColumns" x="Long" y="Lat"/> <GeometryType>wkbPoint</GeometryType> </OGRVRTLayer> </OGRVRTDataSource>
5. Maple Layer
Using an ovf le your layer may look like:
LAYER CONNECTION "coal.ovf" CONNECTIONTYPE OGR DATA "coal-test" METADATA "wms_srs" "4326" "wms_title" "coal-test" END NAME "coal-test" SIZEUNITS PIXELS STATUS ON TOLERANCE 0 TOLERANCEUNITS PIXELS TYPE POINT UNITS METERS CLASS STYLE COLOR 255 0 0
265
Once you successfully created a map image, then try your application. Note Windows users may come across a problem where shp2img works but their application throws an error similar to this:
Warning: [MapServer Error]: msOGRFileOpen(): Open failed for OGR connection coal.ovf. Unable to initialize ODBC connection to DSN for jeff/test@Data_txt,
266
[Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified in D:\ms4w\Apache\htdocs\quickmap.php on line 40
If that happens you should make sure you have created a System DSN.
7.1.9 ArcInfo
ESRI ArcInfo Coverage Files are also known as simply as Coverages and less commonly as ADF les. File listing Coverages are made up of a set of les within a folder. The folder itself is the coverage name. The les roughly represent different layers, usually representing different types of topology or feature types.
> ls /data/coverage/brazil aat.adf arc.adf arx.adf bnd.adf
lab.adf
prj.adf
tic.adf
tol.adf
A folder with the name INFO is also part of the coverage. It sits at the same hierarchical level as the coverage folder itself. Therefore, to copy a coverage (using regular le system tools) the coverage folder and the INFO folder must both be copied. The INFO folder holds some catalogue information about the coverage.
> ls /data/coverage/info arc0000.dat arc0001.dat arc0000.nit arc0001.nit
arc0002.dat arc0002.nit
arc.dir
Data Access / Connection Method CONNECTIONTYPE OGR must be used. The ability to use coverages is not built into MapServer. The path to the coverage folder name is required. The layer name (feature type) is specied in the DATA parameter
OGRINFO Examples
The directory is the data source. Layers are found within the directory. Using ogrinfo on a coverage directory:
> ogrinfo /data/coverage/brazil -summary INFO: Open of brazil using driver AVCBin successful. 1: ARC (Line String) 2: CNT (Point) 3: LAB (Point) 4: PAL (Polygon)
267
Layer name: PAL Geometry: Polygon Feature Count: 1 Extent: (1272793.274958, 795381.617050) - (1287078.382785, 807302.747284) Layer SRS WKT: (unknown) ArcIds: IntegerList (0.0) AREA: Real (18.5) PERIMETER: Real (18.5) F_OPER#: Integer (5.0) F_OPER-ID: Integer (5.0) OPER: String (2.0) FCODE: String (10.0)
7.1.10 ArcSDE
Spatial Database Engine (SDE) is one of ESRIs products which enables spatial data to be stored, managed, and quickly retrieved from leading commercial database management systems like Oracle, Microsoft SQL Server, Sybase, IBM DB2, and Informix. Supported ArcSDE Operations Versioned queries (query geometry and attributes from a specied version) queryByAttributes (select geometry and attributes based on the values of an attribute) Limited join support for within-database tables</li> queryByRect (select geometry based on an extent) Projection on the y SDE for Coverages (a read-only type of SDE for coverage, shapele, and ArcStorm/ArcLibrarian repositories) SDE 8.1, 8.2, 8.3, 9.0, 9.1, and 9.2 Linux, Windows, and Solaris (platforms that have SDE C API support)
268
Unsupported ArcSDE Operations queryByShape (pass in a shape with MapScript and use it for queries) Direct Connect (bypass SDE to connect directly to the database with the SDE C API) How to make a connection to SDE: Install the SDE C API client libraries for your platform (preferably matched to the server version you are using, ie 8.2 client -> 8.2 server, 8.3 client -> 8.3 server) Compile MapServer with SDE support MapServer Unix Compilation Howto for specic details) Dene a LAYER block in a MapFile that uses SDE as the CONNECTIONTYPE
LAYER NAME states TYPE POLYGON CONNECTION "sdemachine.iastate.edu,port:5151,sde,username,password" CONNECTIONTYPE SDE DATA "HOBU.STATES_LAYER,SHAPE,SDE.DEFAULT" FILTER "where MYCOLUMN is not NULL" PROCESSING "QUERYORDER=ATTRIBUTE" # <-- MapServer 4.10 and above # Within database one-to-one join support # MapServer 5.0 and above PROCESSING "JOINTABLE=SDE_MASTER.GEOSERVWRITE.JOINTABLE" # MapServer 5.0 and above CLASSITEM "SDE_MASTER.GEOSERVWRITE.JOINTABLE.VAL" # MapServer 5.0 and above FILTER "SDE_MASTER.GEOSERVWRITE.JOINTABLE.AQ_TAG=SDE_MASTER.GEOSERVWRITE.JOINTESTLAYER.AQ_TAG" # ObjectID column manipulation # MapServer 5.0 and above PROCESSING "OBJECTID=OBJECTID" TEMPLATE /where/the/template/file/is/located CLASS STYLE SYMBOL circle SIZE 3 COLOR -1 -1 -1 OUTLINECOLOR 0 0 0 END END END
269
port:5151 - The port number of SDE. The port: is important as SDE expects you to dene the service in this slot, and it can be other names like sde:oracle (for direct connect) or esri_sde (for systems with port 5151 dened as esri_sde in /etc/services) sde - The database username that the SDE server is using to connect to your database. It is often only important for SDE setups that are connecting to Oracle (and even then, not so important). Just leave it as sde if you dont know what it should be. username - The username that will be connecting to SDE. This user must have been granted rights to select the layer that you will be specifying in the DATA directive. You can use ArcCatalog or the SDE command-line utilities to grant the appropriate rights to layers. password - Password of the user connecting to SDE. Case Sensitive.
TEMPLATE
/where/the/template/le/is/located - A template directive must be specied (can point to a dummy le) in order for MapServer to be able to query attributes from SDE. If you are only going to be drawing layers, this directive is unnecessary and will slow down the query operations of SDE (especially for layers with lots of attribute columns).
PROCESSING
PROCESSING QUERYORDER=ATTRIBUTE - Allows you to force SDE to use the WHERE clause that was dened in your FILTER statement rst, without attempting to hit the spatial index. Only in very special cases will you want to do this. PROCESSING OBJECTID=OBJECTID - If you are having trouble with the SDE driver detecting your unique ID column, you can override it with this processing parameter. Doing so will also have a slight performance benet because it will save a couple of extra queries to the database. PROCESSING ATTRIBUTE_QUALIFIED=TRUE - User can set this option to always use fully qualied attribute names.
270
FILTER SDE_MASTER.GEOSERVWRITE.JOINTABLE.AQ_TAG=SDE_MASTER.GEOSERVWRITE.JOINTESTLA - An important part of the join is dening how the join is to be made. Use a FILTER to do so.
7.1.11 DGN
File listing Data are encapsulated in a single le, usually with the sufx .dgn.
0824t.dgn
Data Access / Connection Method Access is available in MapServer through OGR. The CONNECTIONTYPE OGR parameter must be used. The path to the dgn le is required, le extension is needed. All types of features in a DGN le are held in one layer of data. The layer is called elements and is the rst and only layer. The type of feature to be read from the DGN depends on the TYPE parameter in the map le. DGN les typically contain POINT, LINE, POLYGON and ANNOTATION feature types. DGN les contain styling information - how to color and present the data. This is used, optionally, by specifying the STYLEITEM AUTO parameter. Note: DGN les typically use white as a color for their features and therefore are not visible on maps with white backgrounds. OGRINFO Examples Using ogrinfo on a single DGN le:
271
> ogrinfo /data/dgn/0824t.dgn Had to open data source read-only. INFO: Open of 0842t.dgn using driver DGN successful. 1: elements
Note: No geometry/feature type for the layer is identied because it can be multiple types. DGN les are not really GIS data les. They evolved from drafting formats used by computer aided drafting/design (CADD) programs. They carry a few key attributes which are usually consistent across all DGN les. Most of the attributes relate to graphical styling of features for map presentation, such as ColorIndex, Style, etc. Spatial reference system information is not always encoded into DGN les. This can be a major problem when trying to adequately reference the DGN data in another mapping program. Measurement units can be a problem. In some cases the features could be located in kilometres or feet even though it is not obvious from the output of ogrinfo. Sometimes the only way to identify or correct a problem with units is to open the le in Microstation software. Using ogrinfo to examine the structure of the le/layer:
> ogrinfo -summary /data/dgn/0824t.dgn elements INFO: Open of 0824t.dgn using driver DGN successful. Layer name: elements Geometry: Unknown (any) Feature Count: 22685 Extent: (-513183.050000, 150292.930000) - (-224583.220000, 407463.360000) Layer SRS WKT: (unknown) Type: Integer (2.0) Level: Integer (2.0) GraphicGroup: Integer (4.0) ColorIndex: Integer (3.0) Weight: Integer (2.0) Style: Integer (1.0) EntityNum: Integer (8.0) MSLink: Integer (10.0) Text: String (0.0)
272
7.1.12 S57
Also known as S57. The IHO S-57 format is a vector interchange format used for maritime charts. It was developed by the International Hydrographic Organisation (IHO). For more information about the IHO see: http://www.iho.shom.fr/ File listing Individual S57 data les have an extension of *.000. For example:
US1BS02M.000
Data Access / Connection Method S57 access in MapServer occurs through OGR, CONNECTIONTYPE OGR must be used. Specify a full path or a relative path from the SHAPEPATH to the .000 le for the CONNECTION Use the DATA parameter to specify the s57 layer name
Special Notes
The underlying OGR code requires two les from your GDAL/OGR installation when reading S57 data in MapServer : s57objectclasses.csv and s57attributes.csv. These les can be found in the /GDAL/data/ folder (unix: /usr/local/share/gdal windows: /ms4w/gdaldata). If you receive an error in MapServer such as:
msDrawMap(): Image handling error. Failed to draw layer named s57. msOGRFileOpen(): OGR error. xxx failed for OGR connection
you may have to point MapServer to these les using the CONFIG parameter in the main section of your map le:
CONFIG GDAL_DATA "C:\ms4w\gdaldata"
273
12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
OBSTRN RDOSTA SEAARE SBDARE SLCONS SOUNDG UWTROC WATTUR WRECKS M_COVR M_NPUB M_NSYS M_QUAL C_ASSO
(Point)
274
LAYER NAME s57 TYPE POLYGON STATUS DEFAULT CONNECTIONTYPE OGR CONNECTION "./s57/us1bs02m.000" DATA "DEPARE" CLASS STYLE COLOR 247 237 219 OUTLINECOLOR 120 120 120 END END END # Layer
OGRINFO Examples First you should make sure that your GDAL/OGR build contains the personal geodatabase PGeo driver, by using the formats command:
>ogrinfo --formats Loaded OGR Format Drivers: ... -> "ODBC" (read/write) -> "PGeo" (readonly) -> "PostgreSQL" (read/write) ...
275
If you dont have the driver, you might want to try the FWTools or MS4W packages, which include the driver. Once you have the PGeo driver you are ready to try an ogrinfo command on your database to get a list of spatial tables:
>ogrinfo test.mdb INFO: Open of test.mdb using driver PGeo successful. 1: counties
Now use ogrinfo to get information on the structure of the spatial table:
>ogrinfo test.mdb counties -summary INFO: Open of test.mdb using driver PGeo successful. Layer name: counties Geometry: Unknown (any) Feature Count: 67 Extent: (-87.634943, 24.543945) - (-80.031369, 31.000975) Layer SRS WKT: GEOGCS["GCS_WGS_1984", DATUM["WGS_1984", SPHEROID["WGS_1984",6378137.0,298.257223563]], PRIMEM["Greenwich",0.0], UNIT["Degree",0.0174532925199433]] OBJECTID_1: Integer (10.0) OBJECTID: Integer (10.0) NAME: String (32.0) STATE_NAME: String (25.0) STATE_FIPS: String (2.0) CNTY_FIPS: String (3.0) FIPS: String (5.0) ...
Note that you can also use an ODBC connection to access all of the tables in your geodatabase:
>ogrinfo ODBC:jeff/pass@testDSN counties -summary INFO: Open of ODBC:jeff/pass@testDSN using driver ODBC successful. 1: counties 2: counties_Shape_Index 3: GDB_AnnoSymbols 4: GDB_AttrRules 5: GDB_CodedDomains 6: GDB_DefaultValues 7: GDB_Domains 8: GDB_EdgeConnRules 9: GDB_Extensions 10: GDB_FeatureClasses 11: GDB_FeatureDataset 12: GDB_FieldInfo 13: GDB_GeomColumns ...
276
Maple Example
LAYER NAME my_geodatabase TYPE POLYGON CONNECTIONTYPE ogr CONNECTION "test.mdb" DATA "counties" STATUS ON CLASS NAME "counties" STYLE COLOR 255 255 120 END END END
7.1.14 Inline
Inline features refer to coordinates entered directly into the map le. They are not a le or database format and do not require any DATA or CONNECTION parameters. Instead they use a FEATURE section to dene the coordinates. Inline features can be used to dene points, lines and polygons as if taken from an external le. This requires direct entry of coordinate pairs in the map le using a particular syntax. Data Access / Connection Method This is a native MapServer option that doesnt use any external libraries to support it. Map File Example
Points
Each FEATURE..END section denes a feature. Multiple points can be dened in a FEATURE section. If multiple points are dened in the same layer, they will have the same CLASS settings, e.g. for colours and styles. Coordinates are entered in the units set in the layers projection. In this case it is assuming the map le projection is using decimal degrees.
LAYER NAME inline_stops TYPE POINT STATUS DEFAULT FEATURE POINTS 72.36 33.82 END TEXT "My House" END FEATURE POINTS
277
69.43 35.15 71.21 37.95 72.02 38.60 END TEXT "My Stores" END CLASS STYLE COLOR 0 0 250 SYMBOL circle SIZE 6 END END END
Lines
Lines are simply a list of points strung together, but the layer must be TYPE LINE instead of TYPE POINT.
LAYER NAME inline_track TYPE LINE STATUS DEFAULT MAXSCALE 10000000 FEATURE POINTS 72.36 33.82 70.85 34.32 69.43 35.15 70.82 36.08 70.90 37.05 71.21 37.95 END END CLASS STYLE COLOR 255 10 0 SYMBOL circle SIZE 2 END END END
Polygons
Polygons are the same as the line example, just a list of points. They require the TYPE POLYGON parameter. Polygons also require the nal coordinate pair to be the same as the rst, making it a closed polygon.
278
Data Access / Connection Method KML access is available through OGR. See the OGR driver page for specic driver information. Read support was initially added to GDAL/OGR version 1.5.0. The CONNECTION parameter must include the kml extension, and the DATA parameter should be the name of the layer.
CONNECTIONTYPE ogr CONNECTION "myplaces.kml" DATA "layername"
OGRINFO Examples First you should make sure that your GDAL/OGR build contains the KML driver, by using the formats command:
>ogrinfo --formats Loaded OGR Format Drivers: ... -> "GML" (read/write) -> "GPX" (read/write) -> "KML" (read/write) ...
If you dont have the driver, you might want to try the FWTools or MS4W packages, which include the driver. Once you have the KML driver you are ready to try an ogrinfo command on your le to get a list of available layers:
>ogrinfo myplaces.kml INFO: Open of myplaces.kml using driver KML successful. 1: Layer #0 (Point)
279
Maple Example
LAYER NAME kml_places TYPE POINT STATUS DEFAULT CONNECTIONTYPE OGR CONNECTION "kml/fountains-hotel.kml" DATA "Layer #0" LABELITEM "NAME" CLASS NAME "My Places" STYLE COLOR 250 0 0 OUTLINECOLOR 255 255 255 SYMBOL circle SIZE 6 END LABEL SIZE TINY COLOR 0 0 0 OUTLINECOLOR 255 255 255 POSITION AUTO END END END
280
Table of Contents Oracle Spatial What MapServer 5.2 with Oracle Spatial Binaries Installation Two options for using Oracle Spatial with MapServer Maple syntax for native Oracle Spatial support Using subselects in the DATA statement Additional keywords - [FUNCTION] Additional keywords - [VERSION] More information Example of a LAYER Maple syntax for OGR Oracle Spatial support
Oracle Spatial is a spatial cartridge for the Oracle database. Remember that all Oracle databases come with Locator, which has less features than Oracle Spatial. The differences between Locator and Spatial can be found in the Oracle Spatial FAQ. You can also see the original OracleSpatial wiki page that this document was based on. What MapServer 5.2 with Oracle Spatial mode=map query modes: query, nquery, itemnquery MapScript query functions such as querybyattributes OGC:WMS: GetCapabilities, GetMap, GetFeatureInfo, DescribeLayer OGC:WFS, GetCapabilities, DescribeFeatureType, GetFeature Binaries MapServer Windows plugins with Oracle spatial support can be downloaded from MS4W. But you need Oracle client software in the server on which you are running MapServer. Oracle client software can be obtained for development purposes from the Oracle website, but you need to register, which by the way is free. The most recent version is Oracle Database 10g Release 1 Client. The ORACLE TECHNOLOGY NETWORK DEVELOPMENT LICENSE AGREEMENT applies to this software. The instant client will be satisfactory, and you can download the instant client. Make sure though your MapServer is compiled against the same version as your Oracle client, for compiling you need a full client install, not just the instant client. Installation See Oracle Installation for more conguration and installation information for MapServers native Oracle support Note: If you receive error messages like Error: .. Its likely related to MapServer being unable access or locate the ORACLE_HOME. 7.1. Vector Data 281
Two options for using Oracle Spatial with MapServer Oracle Spatial layers in MapServer can be used through 2 interfaces: The native built-in support through maporaclespatial.c OGR, but watch out: OGR is not compiled with Oracle Spatial support so it wont work without compiling in OCI (Oracle client) yourself. This requires both recompiling GDAL/OGR as well as recompiling MapServer itself against the new GDAL/OGR !!!! Maple syntax for native Oracle Spatial support The DATA statement for a LAYER of CONNECTIONTYPE oraclespatial can now have 4 options. This change is backwards compatible, i.e. the old ways of specifying DATA still work. The new options are an extension to the old DATA statements, as they needed to include identication of the primary key to be used for the query modes (UNIQUE). The following options are valid DATA statements:
"[geom_column] FROM [table]| [( SELECT [...] FROM [table]|[Spatial Operator] [WHERE condition] )] [USING [UNIQUE column] | [SRID #srid] | [FUNCTION] | [VERSION #version] ]"
Example 1
The most simple DATA statement, in this case you only need to dene one geometry column and one table. This option assumes you do not have an SRID dened.
LAYER ... CONNECTIONTYPE oraclespatial DATA "MYGEOMETRY FROM MYTABLE" ... END
Example 2
Its composed of the rst option plus the USING UNIQUE parameter. These new features are necessary when you want to use any query function. When it is used you must pass a numeric column type. This option assumes you do not have an SRID dened.
LAYER ... CONNECTIONTYPE oraclespatial
282
Example 3
This option is an extension to the rst option. In this mode you must dene the USING SRID parameter when the SRID value in your data is different from NULL.
LAYER ... CONNECTIONTYPE oraclespatial DATA "MYGEOMETRY FROM MYTABLE USING SRID 90112" ... END
Example 4
This option is a combination of examples 2 and 3.
LAYER ... CONNECTIONTYPE oraclespatial DATA "MYGEOMETRY FROM MYTABLE USING UNIQUE MYTABLE_ID SRID 90112" ... END
Using subselects in the DATA statement It is possible to dene the source of the date as a subselect and not only as a table. As source of data, used in FROM token, you can dene any SQL, table, function, or operator that returns a SDO_GEOMETRY. For example:
DATA "[geom_column] FROM (SELECT [columns] FROM [table]|[Spatial function])"
If the LAYER denition contains a CLASSITEM, LABELITEM or FILTER, it is necessary that the elds used are returned by the query. When you dene CLASSITEM you can use an expression without any problems. Additional keywords - [FUNCTION] You can add three keywords to the DATA statement for [FUNCTION] option that inuence the query which will be executed in Oracle:
USING FILTER
"[geom_column] FROM [table]|([Subselect]) USING FILTER"
283
Using this keyword triggers MapServer to use the Oracle Spatial SDO_FILTER operator. This operator executes only the Oracle Spatial primary lter over your query data. In the Oracle User guide they explain: The primary lter compares geometric approximations, it returns a superset of exact result. The primary lter therefore should be as efcient (that is, selective yet fast) as possible. This operator uses the spatial index, so you need to dene your spatial index correctly to retrieve an exact result. If the result of the query is not exact you can try the next option.
USING RELATE
"[geom_column] FROM [table]|([Subselect]) USING RELATE"
Using this keyword triggers MapServer to use the Oracle Spatial SDO_RELATE operator. This operator applies the primary and secondary Oracle Spatial lters. Its performance can be slightly slow but the result is extremely correct. You can use this mode when you want a perfect result or when you cant readjust the spatial index.
USING GEOMRELATE
"[geom_column] FROM [table]|([Subselect]) USING GEOMRELATE"
Using this keyword triggers MapServer to use the geometry function SDO_GEOM.RELATE, a function that searches the relations between geometries. SDO_GEOM.RELATE does not use the spatial index and your performance is more slow than operators but its very accurate. You can use this mode when you cant use the spatial index or when it doesnt exist.
USING NONE
"[geom_column] FROM [table]|([Subselect]) USING NONE"
Using this keyword triggers MapServer to dont use any geometry function or spatial operator. So, the internal SQL dont retrict, bases in the extent, the data from source. All the data from source will be returned for MapServer. The NONE token is very useful when the source of the data dont contains any spatial index. Its usually occur when the source is a function like SDO_BUFFER, SDO_XOR, SDO_INTERSECTION...... So this mode is recomended when you cant use the spatial index or when it doesnt exist. Additional keywords - [VERSION] You can dene what version of database you are using to improve the internal sql. This is very useful when using geodetic SRIDs and MapServer functions that retrieve the extent from data.
USING VERSION 8i
"[geom_column] FROM [table]|([Subselect]) USING VERSION 8i"
This indicates MapServer to use a internal SQL that its compatible with Oracle 8i version.
284
USING VERSION 9i
"[geom_column] FROM [table]|([Subselect]) USING VERSION 9i"
The second indicates MapServer to use 9i version, is recommended to use this parameter if you are using 9i version because the internal SQL will use specic spatial functions that is need to retrieve data correctly from 9i Oracle Spatial versions.
This indicates MapServer to use a internal SQL that its compatible with Oracle 10g version. More information You can dene any PROJECTION to your LAYER without problem, can be used for data with or without an SRID in Oracle. The native support for Oracle Spatial supports the defaults denition for SDO_GEOMETRY in database, the Oracle Spatial SDO package. Information about the primary and secondary Oracle Spatial lters can be found in the Oracle Spatial User Guide (the Query Model section). Information about the SDO_FILTER and SDO_RELATE operators can be found in the Spatial Operators section, and information about the SDO_GEOM.RELATE function can be found in the Geometry Function section of the Oracle Spatial User Guide. Example of a LAYER
LAYER NAME kwadranten TYPE POLYGON CONNECTIONTYPE oraclespatial CONNECTION "user/pwd" DATA "GEOMETRIE FROM KWADRANTEN USING SRID 90112" DUMP TRUE CLASS STYLE OUTLINECOLOR 0 0 0 COLOR 0 128 128 END END END
You can specify the SID for your database, the SID alias needs to be supplied in the tnsnames.ora le of the Oracle client, e.g. Example for tnsnames.ora:
MYDB = (DESCRIPTION = (ADDRESS_LIST =
285
Maple syntax for OGR Oracle Spatial support Syntax for your MAP le:
CONNECTION "OCI:user/pwd@service" CONNECTIONTYPE OGR DATA "Tablename"
Note: Make sure you set the wms_extent METADATA for the LAYER, as otherwise the Getcapabilities request takes a lot of time.
7.1.17 MySQL
Revision $Revision: 8472 $ Date $Date: 2009-01-28 13:08:43 -0800 (Wed, 28 Jan 2009) $ Author David Fawcett Contact david.fawcett at moea.state.mn.us
Contents MySQL Introduction Create .ovf le Test Connection with ogrinfo Create MapServer Layer More Information
Introduction This method takes advantage of OGRs MySQL driver and avoids the need to set up an ODBC connection. This is the primitive MySQL support for point data, not the recently added MySQL spatial support found in GDAL/OGR 1.3.2 . Support for this functionality is found in GDAL/OGR 1.2.6 and older on Windows and GDAL/OGR 1.3.2 on Linux. The MySQL wiki page might contain additional information. 286 Chapter 7. Data Input
Needed MySQL database containing a table with elds containing x and y coordinates .ovf le, a small xml le you will create MapServer compiled with OGR version supporting this functinality Create .ovf le Here is the .ovf le named aqidata.ovf
<OGRVRTDataSource> <OGRVRTLayer name="aqidata"> <SrcDataSource>MYSQL:aqiTest,user=uuuuu,password=ppppp,host=192.170.1.100,port=3306,tables=te <SrcSQL>SELECT areaID, x, y, sampleValue FROM testdata</SrcSQL> <GeometryType>wkbPoint</GeometryType> <GeometryField encoding="PointFromColumns" x="x" y="y"/> </OGRVRTLayer> </OGRVRTDataSource>
If you look at the connection string in <SrcDataSource> The MySQL database name is aqiTest testdata is the table containing the coordinate data host and port are for MySQL server Use the GeometryField element to tell OGR which elds store the x and y coordinate data. Mine are simply named x and y. Test Connection with ogrinfo
# usr/local/bin/ogrinfo /maps/aqidata.ovf
ogrinfo returns
ERROR 4: Update access not supported for VRT datasources. Had to open data source read-only. INFO: Open of /maps/aqidata.ovf using driver VRT successful. 1: aqidata (Point)
Dont worry about the error, this is just telling you that it is a read-only driver. If it really bugs you, call ogrinfo with the -ro (read only) ag. To see the actual data
# usr/local/bin/ogrinfo /maps/aqidata.ovf -al
287
DATA in the LAYER denition should be the same as the name attribute of the OGRVRTLayer element in the ovf le. For this to draw, you need to have a SYMBOLSET dened in your maple and have a symbol called circle in your symbols.sym le. More Information OGR Vector Data
7.1.18 NTF
NTF les are mostly used by the United Kingdom Ordnance Survey (OS). For more on the Ordnance Survey, see their website at: http://www.ordnancesurvey.co.uk/oswebsite/ File listing NTF les have an NTF extension. Data Access / Connection Method NTF access requires OGR. The path to the NTF le is required in the CONNECTION string. It may be relative to the SHAPEPATH setting in the map le or the full path. The DATA parameter is used to specify the layer to use OGRINFO Examples Using ogrinfo on an NTF le to retrieve layer names:
288
> ogrinfo llcontours.ntf ERROR 4: NTF Driver doesnt support update. Had to open data source read-only. INFO: Open of llcontours.ntf using driver UK .NTF successful. 1: LANDLINE_POINT (Point) 2: LANDLINE_LINE (Line String) 3: LANDLINE_NAME (Point) 4: FEATURE_CLASSES (None)
289
7.1.19 SDTS
This is a United States Geological Survey (USGS) format. SDTS has a raster and a vector format. The raster format is not supported in MapServer. Only the vector formats are supported, including VTP and DLG les. File listing SDTS les are often organized into state-sized pieces. For example, all of the state of Maryland (MD), U.S.A. Files are also available for multiple types of features including hydrography, transportation and administrative boundaries. This example uses transportation data, which consists of 35 separate les, each with the sufx DDF:
MDTRAHDR.DDF MDTRDQCG.DDF MDTRNA03.DDF MDTRAMTF.DDF MDTRDQHL.DDF MDTRNE03.DDF MDTRARDF.DDF MDTRDQLC.DDF MDTRNO01.DDF MDTRARDM.DDF MDTRDQPA.DDF MDTRNO02.DDF MDTRARRF.DDF MDTRFF01.DDF MDTRNO03.DDF MDTRBFPS.DDF MDTRIDEN.DDF MDTRPC01.DDF MDTRBMTA.DDF MDTRIREF.DDF MDTRPC02.DDF MDTRCATD.DDF MDTRLE01.DDF MDTRPC03.DDF MDTRCATS.DDF MDTRLE02.DDF MDTRSPDM.DDF MDTRCATX.DDF MDTRLE03.DDF MDTRSTAT.DDF MDTRDDSH.DDF MDTRNA01.DDF MDTRXREF.DDF MDTRDQAA.DDF MDTRNA02.DDF
Data Access / Connection Method SDTS access is available in MapServer through OGR. The CONNECTIONTYPE OGR parameter must be used. The path (which can be relative) to the catalog le (????CATD.DDF) is required, including le extension. There are multiple layers in the SDTS catalog, some of which are only attributes and have no geometries. The layer name is specied with the DATA parameter OGRINFO Examples Using ogrinfo on a catalog le (note that the rst 7 layers do not have geometries):
> ogrinfo /data/sdts/MD/MDTRCATD.DDF Had to open data source read-only. INFO: Open of MDTRCATD.DDF
290
using driver SDTS successful. 1: ARDF (None) 2: ARRF (None) 3: AMTF (None) 4: ARDM (None) 5: BFPS (None) 6: BMTA (None) 7: AHDR (None) 8: NE03 (Point) 9: NA01 (Point) 10: NA02 (Point) 11: NA03 (Point) 12: NO01 (Point) 13: NO02 (Point) 14: NO03 (Point) 15: LE01 (Line String) 16: LE02 (Line String) 17: LE03 (Line String) 18: PC01 (Polygon) 19: PC02 (Polygon) 20: PC03 (Polygon)
291
Data Access / Connection Method TIGER/Line access occurs through an OGR CONNECTION The full path to the directory containing the associated les is required in the CONNECTION string. The feature type is specied in the DATA parameter
OGRINFO Examples
Using ogrinfo on a TIGER directory to retrieve feature types:
> ogrinfo TGR06059 (NOTE that this is a directory) ERROR 4: Tiger Driver doesnt support update. Had to open data source read-only. INFO: Open of TGR06059 using driver TIGER successful.
292
1: CompleteChain (Line String) 2: AltName (None) 3: FeatureIds (None) 4: ZipCodes (None) 5: Landmarks (Point) 6: AreaLandmarks (None) 7: Polygon (None) 8: PolygonCorrections (None) 9: EntityNames (Point) 10: PolygonEconomic (None) 11: IDHistory (None) 12: PolyChainLink (None) 13: PIP (Point) 14: TLIDRange (None) 15: ZeroCellID (None) 16: OverUnder (None) 17: ZipPlus4 (None)
Using ogrinfo to examine the structure of the TIGER feature type CompleteChain:
> ogrinfo TGR06059 CompleteChain -summary ERROR 4: Tiger Driver doesnt support update. Had to open data source read-only. INFO: Open of TGR06059 using driver TIGER successful. Layer name: CompleteChain Geometry: Line String Feature Count: 123700 Extent: (-118.125898, 33.333992) - (-117.412987, 33.947512) Layer SRS WKT: GEOGCS["NAD83", DATUM["North_American_Datum_1983", SPHEROID["GRS 1980",6378137,298.257222101]], PRIMEM["Greenwich",0], UNIT["degree",0.0174532925199433]] MODULE: String (8.0) TLID: Integer (10.0) SIDE1: Integer (1.0) SOURCE: String (1.0) FEDIRP: String (2.0) FENAME: String (30.0) FETYPE: String (4.0) FEDIRS: String (2.0) CFCC: String (3.0) FRADDL: String (11.0) TOADDL: String (11.0) FRADDR: String (11.0) TOADDR: String (11.0) FRIADDL: String (1.0) TOIADDL: String (1.0) FRIADDR: String (1.0) TOIADDR: String (1.0) ZIPL: Integer (5.0)
293
LAYER NAME Complete_Chain TYPE LINE STATUS DEFAULT CONNECTIONTYPE OGR CONNECTION "/path/to/data/tiger/TGR06059" DATA "CompleteChain" CLASS STYLE COLOR 153 102 0 END END END # Layer
If you dont have the driver, you might want to try the FWTools or MS4W packages, which include the driver. Once you have the GPX driver you are ready to try an ogrinfo command on your le to get a list of feature types:
294
>ogrinfo test.gpx INFO: Open of test.gpx using driver GPX successful. 1: waypoints (Point) 2: routes (Line String) 3: tracks (Multi Line String) 4: route_points (Point) 5: track_points (Point)
Maple Example Since you have conrmed that OGR can read your GPX le, now you can create a MapServer layer:
LAYER NAME gpx TYPE POINT STATUS ON CONNECTIONTYPE OGR CONNECTION test.gpx DATA "track_points" CLASS NAME "gpx"
295
STYLE SYMBOL circle COLOR 0 119 255 SIZE 2 END END END # layer
Table of Contents Raster Data Introduction How are rasters added to a Map le? Supported Formats Rasters and Tile Indexing Raster Warping 24bit RGB Rendering Special Processing Directives Raster Query Raster Display Performance Tips Preprocessing Rasters Georeference with World Files
7.2.1 Introduction
MapServer supports rendering a variety of raster le formats in maps. The following describes some of the supported formats, and what capabilities are supported with what formats. This document assumes that you are already familiar with setting up MapServer Maple, but does explain the raster specic aspects of maples.
Though not shown rasters can have PROJECTION, METADATA, PROCESSING, MINSCALE, and MAXSCALE information. It cannot have labels, CONNECTION, CONNECTIONTYPE, or FEATURE information. Classifying Rasters Rasters can be classied in a manner similar to vectors, with a few exceptions. There is no need to specify a CLASSITEM. The raw pixel value itself ([pixel]) and, for paletted images, the red, green and blue color associated with that pixel value ([red], [green] and [blue]) are available for use in classications. When used in an evaluated expression the pixel, red, green and blue keywords must be in lower case.
LAYER NAME "JacksonvilleNC_CIB" DATA "Jacksonville.tif" TYPE RASTER STATUS ON CLASSITEM "[pixel]" # class using simple string comparison, equivelent to ([pixel] = 0) CLASS EXPRESSION "0" STYLE COLOR 0 0 0 END END # class using an EXPRESSION using only [pixel]. CLASS EXPRESSION ([pixel] >= 64 AND [pixel] < 128) STYLE COLOR 255 0 0 END END # class using the red/green/blue values from the palette CLASS NAME "near white" EXPRESSION ([red] > 200 AND [green] > 200 AND [blue] > 200) STYLE COLOR 0 255 0 END END # Class using a regular expression to capture only pixel values ending in 1 CLASS EXPRESSION /*1/ STYLE COLOR 0 0 255 END END END
As usual, CLASS denitions are evaluated in order from rst to last, and the rst to match is used. If a CLASS has
297
a NAME attribute it may appear in a LEGEND. Only the COLOR, EXPRESSION and NAME parameters within a CLASS denition are utilized for raster classications. The other styling or control information is ignored. Raster classications always take place on only one raster band. It defaults to the rst band in the referenced le, but this can be altered with the BANDS PROCESSING directive. In particular this means that including even a single CLASS declaration in a raster layer will result in the raster layer being rendered using the one band classication rules instead of other rules that might have applied (such as 3 band RGB rendering).
298
The following formats are potential builtins: TIFF/GeoTIFF If built with INPUT=TIFF MapServer will have builtin support for reading TIFF or GeoTIFF les. The builtin TIFF support has some limitations with regard to the organization of les that can be read (no tiled, 16bit, RGB, or odd color models). This driver supports world les, or simple builtin GeoTIFF coordinates for georeferencing. Full featured TIFF/GeoTIFF support is available through GDAL. Note that only GDAL supports tiled TIFF les and TIFF les with overviews. Tiled TIFF les with overviews pre-built are one of the highest performance ways of serving large raster images. GIF If GD is congured with GIF (OUTPUT=GIF) support, then MapServer will also be able to read GIF les for raster layers. The only way to georeference GIF les is with a world le. If GD is not congured with GIF support, it may still be available in GDAL. PNG If GD is congured with PNG (OUTPUT=PNG) support, then MapServer will also be able to read PNG les for raster layers. The only way to georeference PNG les is with a world le. If GD is not congured with PNG support, it may still be available in GDAL. JPEG If MapServer is built with JPEG (INPUT=JPEG) support then greyscale JPEG les may be rendered in raster layers. RGB les (the more common kind) will not be able to be displayed. Georeferencing is via world les. If MapServer is not built with native JPEG support, GDAL may still support the format. In this case RGB les are also supported (via the RGB color cube mechanism). Georeferencing is still via world le. 7.2. Raster Data 299
Erdas .LAN/.GIS If congured with INPUT=EPPL7 (the default) MapServer will support one band eight bit Erdas LAN/GIS les. The .trl le is read for a colormap, and if not found the layer is treated as greyscale. Georeferencing is read from the le. If MapServer is built with GDAL it is generally better to access all possible formats through GDAL rather than via the built-in drivers. The built-in drivers are less featureful, and not as well maintained.
The lenames in the tileindex are searched for relative to the SHAPEPATH or map le, not relative to the tileindex. Great care should be taken when establishing the paths put into the tileindex to ensure they will evaluate properly in use. Often it is easiest to place the tileindex in the SHAPEPATH directory, and to create the tileindex with a path relative to the SHAPEPATH directory. When all else fails, absolute paths can be used in tileindex, but then they cannot be so easily moved from system to system. While there are many ways to produce TILEINDEX shapeles for use with this command, one option is the gdaltindex program, part of the GDAL utility suite. The gdaltindex program will automatically generate a tile index shapele from a list of GDAL supported raster les passed on the command line.
Usage: gdaltindex [-tileindex field_name] index_file [gdal_file]* % gdaltindex doq_index.shp doq/*.tif
Tile Index Notes The shapele (index_le) will be created if it doesnt already exist. The default tile index eld is location. Simple rectangular polygons are generated in the same coordinate system as the rasters. Raster lenames will be put in the le exactly as they are specied on the commandline. 300 Chapter 7. Data Input
Many problems with tile indexes relate to how relative paths in the tile index are evaluated. They should be evaluated relative to the SHAPEPATH if one is set, otherwise relative to the tileindex le. When in doubt absolute paths may avoid path construction problems. The gdaltindex program is built as part of GDAL. Prebuilt binaries for GDAL including the gdaltindex program can be downloaded as part of the OSGeo4W, FWTools and MS4W distributions. See Also: Tile Indexes
301
BANDS=red_or_grey[,green,blue[,alpha]] This directive allows a specic band or bands to be selected from a raster le. If one band is selected, it is treated as greyscale. If 3 are selected, they are treated as red, green and blue. If 4 are selected they are treated as red, green, blue and alpha (opacity). Example:
PROCESSING "BANDS=4,2,1"
SCALE[_n]=AUTO or min,max This directive instructs the GDAL reader to pre-scale the incoming raster data. It is primarily used to scale 16bit or oating point data to the range 0-255, but can also be used to constrast stretch 8bit data. If an explicit min/max are provided then the input data is stretch (or squished) such that the minimum value maps to zero, and the maximum to 255. If AUTO is used instead, a min/max is automatically computed. To control the scaling of individual input bands, use the SCALE_1, SCALE_2 and SCALE_3 keywords (for red, green and blue) instead of SCALE which applies to all bands. Example:
PROCESSING or PROCESSING PROCESSING PROCESSING "SCALE=AUTO" "SCALE_1=409,1203" "SCALE_2=203,296" "SCALE_3=339,1004"
LUT[_n]=<lut_spec> This directive (MapServer 4.9+) instructs the GDAL reader to apply a custom LUT (lookup table) to one or all color bands as a form of on the y color correction. If LUT is used, the LUT is applied to all color bands. If LUT_n is used it is applied to one color band (n is 1 for red, 2 for green, 3 for blue, 4 for alpha). The LUT can be specied inline in the form:
<lut_spec> = <in_value>:<out_value>[,<in_value>:<out_value>]*
This essentially establish particular input values which are mapped to particular output values. The list implicitly begins with 0:0, and 255:255. An actual 256 entry lookup table is created from this specication, linearly interpolating between the values. The in values must be in increasing order. The LUT specication may also be in a text le with the <lut_spec> being the lename. The le contents should be in the same syntax, and the le is searched relative to the maple. Example:
PROCESSING PROCESSING PROCESSING or PROCESSING "LUT_1=red.lut" "LUT_2=green.lut" "LUT_3=blue.lut" "LUT=100:30,160:128,210:200"
302
As a special case there is also support for GIMP format curve les. That is the text les written out by the Tools->Color->Curves tool. If this is specied as the lename then it will be internally converted into linear segments based on the curve control points. Note that this will not produce exactly the same results as the GIMP because linear interpolation is used between control points instead of curves as used in the GIMP. For a reasonable number of control points the results should be similar. Also note that GIMP color curve les include an overall value curve, and curves for red, green, blue and alpha. The value curve and the appropriate color curve will be composed internally to produce the nal LUT. Example:
PROCESSING "LUT=munich.crv"
COLOR_MATCH_THRESHOLD=n Alter the precision with which colors need to match an entry in the color table to use it when producing 8bit colormapped output (IMAGEMODE PC256). Normally colors from a raster colormap (or greyscale values) need to match exactly. This relaxes the requirement to being within the specied color distance. So a COLOR_MATCH_THRESHOLD of 3 would mean that an existing color entry within 3 (sum of difference in red, green and blue) would be used instead of creating a new colormap entry. Especially with greyscale raster layers, which would normally use all 256 color entries if available, this can be a good way to avoid stealing your whole colormap for a raster layer. Normally values in the range 2-6 will give good results. Example:
PROCESSING "COLOR_MATCH_THRESHOLD=3"
RESAMPLE=NEAREST/AVERAGE/BILINEAR This option can be used to control the resampling kernel used sampling raster images. The default (and fastest) is NEAREST. AVERAGE will perform compute the average pixel value of all pixels in the region of the disk le being mapped to the output pixel (or possibly just a sampling of them). BILINEAR will compute a linear interpolation of the four pixels around the target location. This topic is discussed in more detail in MS RFC 4: MapServer Raster Resampling. Resampling options other than NEAREST result in use of the generalized warper and can dramatically slow down raster processing. Generally AVERAGE can be desirable for reducing noise in dramatically downsampled data, and can give something approximating antialiasing for black and white linework. BILINEAR can be helpful when oversampling data to give a smooth appearance. Example (chose one):
PROCESSING "RESAMPLE=NEAREST" PROCESSING "RESAMPLE=AVERAGE" PROCESSING "RESAMPLE=BILINEAR"
x georeferenced X location of pixel. y georeferenced Y location of pixel. value_list a comma separated list of the values of all selected bands at the target pixel. value_n the value for the nth band in the selected list at this pixel (zero based). There is one value_n entry for each selected band. class Name of the class this pixel is a member of (classied layers only). red red component of the display color for this pixel. green green component of the display color for this pixel. blue blue component of the display color for this pixel. The red, green and blue attribute are intended to be the nal color the pixel would be rendered with, but in some subtle cases it can be wrong (ie. classied oating point results). The selected bands are normally the band that would be used to render the layer. For a pure query-only layer BANDS PROCESSING directive can be used to select more bands than could normally be used in a render operation. For instance for a 7 band landsat scene a PROCESSING BANDS=1,2,3,4,5,6,7 directive could be used to get query results for all seven bands in results to a query operation. Care should be taken to avoid providing a large query area (selecting alot of pixels) as each selected pixel requires over 100 bytes of memory for temporary caching. The RASTER_QUERY_MAX_RESULT PROCESSING item can be used to restrict the maximum number of query results that will be returned. The default is one million which would take on the order of 100MB of RAM. Query results can be returned as HTML via the normal substitution into query template HTML. Query results are also accessible via WMS GetFeatureInfo calls, and from MapScript. The following example shows executing a feature query from Python MapScript and fetching back the results:
map = mapscript.Map(rquery.map) layer = map.getLayer(0) pnt = mapscript.Point() pnt.x = 440780 pnt.y = 3751260 layer.queryByPoint( map, pnt, mapscript.MS_MULTIPLE, 180.0 ) layer.open() for i in range(1000): result = layer.getResult( i ) if result is None: break print (%d,%d) % (result.shapeindex, result.tileindex) s = layer.getShape( result.shapeindex, result.tileindex ) for i in range(layer.numitems): print %s: %s % (layer.getItem(i), s.getValue(i)) layer.close()
This following is a simple example query TEMPLATE le. The raster pixel attributes will be substituted in before the query result is returned to the user as HTML.
Pixel:<br> values=[value_list]<br> value_0=[value_0]<br>
304
Internally raster query results are essentially treated as a set of temporary features cached in RAM. Issuing a new query operation clears the existing query cache on the layer. The transitory in-memory representation of raster query results is also responsible for the inability to save raster query results since saved query results normally only contain the feature ids, not the entire features. Some addition information is available in the RasterQuery Wiki topic.
Erdas Imagine (HFA) les are always tiled, and can be larger than 4GB (the GeoTIFF limit). Use a command like the following to translate a raster to Imagine format:
gdal_translate -of HFA original.tif tiled.img
305
Reducing RGB to 8bit Rendering and returning 24bit images (especially as PNG) can be quite expensive in render/compress time and bandwidth. Pre-reducing raster data to 8bit can save disk space, processing time, and bandwidth. However, such a color reduction also implicitly reduces the quality of the resulting map. The color reduction can be done on the y by MapServer but this requires even more processing. A faster approach is to pre-reduce the colors of 24bit imagery to 8bit. This can be accomplished with the GDAL rgb2pct.py script like this:
rgb2pct.py original.tif 8bit.tif
By default images will be reduced to 256 colors but this can mean there are not enough colors to render other colors in the map. So it may be desired to reduce to even less colors:
rgb2pct.py -n 200 original.tif 8bit.tif
Downsampling to 8bit should be done before internal tiling and overview building. The rgb2pct.py script tries to compute an optimal color table for a given image, and then uses error diffusion during the 24bit to 8bit reduction. Other packages (such as ImageMagick or Photoshop) may have alternative color reduction algorithms that are more appropriate for some uses. Building Internal Overviews Most GDAL supported raster formats can have overviews pre-built using the gdaladdo utility. However, a few formats, such as JPEG2000, MrSID, and ECW already contain implicit overviews in the format themselves and will not generally benet from external overviews. For other formats (such as GeoTIFF, and Erdas Imagine format) use a command like the following to build overviews:
gdaladdo tile.tif 2 4 8 16 32 64 128
The above would build overviews at x2 through x128 decimation levels. By default it uses nearest neighbour downsampling. That is one of the pixels in the input downsampled area is selected for each output pixel. For some kinds of data averaging can give much smoother overview results, as might be generated with this command:
gdaladdo -r average tiled.tif 2 4 8 16 32 64 128
Note that overview building should be done after translating to a nal format. Overviews are lost in format conversions using gdal_translate. Also, nothing special needs to be done to make MapServer use GDAL generated overviews. They are automatically picked up by GDAL when mapserver requests a reduced resolution map. Building External Overviews When working with large collections of raster les using a MapServer tileindex, it is desirable to build reduced resolution overview layers that kick in at high scales (using MINSCALE/MAXSCALE to control which layer activates). Preparing the overviews can be a somewhat complex process. One approach is to use the gdal_merge.py script to downsample and mosaic all the images. For instance if we want to produce an overview of many 1meter ortho photos with 250 meter pixels we might do something like:
gdal_merge.py -o overview.tif -ps 250 250 ortho_*.tif
The gdal_merge.py utility suffers from a variety of issues, including no support for different resampling kernels. With GDAL 1.3.2 or later it should be able to accomplish something similar with the more exible gdalwarp utility:
306
In some cases the easiest way of generating an overview is to let MapServer do it using the shp2img utility. For instance if the tileindex layer is called orthos we could do something like:
shp2img -m ortho.map -l orthos -o overview.png
Note that the overview will be generated with the extents and size in the .map le, so it may be necessary to temporarily adjust the map extents and size values to match the raster extents and the desired output size. Also, if using this method, dont leave large les in PNG (or GIF or JPEG) format as they are slow formats to extract subareas from.
The name of the world le is based on the le it relates to. For instance, the world le for aerial.tif might be aerial.tfw. Conventions vary for appropriate endings, but with MapServer the extension .wld is always OK for world les.
307
308
CHAPTER
EIGHT
OUTPUT GENERATION
8.1 AGG Rendering Specics
Author Thomas Bonfort Contact thomas.bonfort at gmail Revision $Revision: 8295 $ Date $Date: 2008-12-26 21:08:04 -0800 (Fri, 26 Dec 2008) $ Last Updated 2008/11/24
Table of Contents AGG Rendering Specics Introduction Setting the OutputFormat New Features Modied Behavior
8.1.1 Introduction
MapServer 5.0 released with a new rendering backend. This howto details the changes and new functionality that this adds to map creation. This howto assumes you already now the basics of maple syntax. If not, you should probably be reading the maple syntax.
24 bit jpeg (jpeg compression artifacts may appear, but smaller le size):
OUTPUTFORMAT NAME AGG_JPEG DRIVER AGG/JPEG IMAGEMODE RGB END
A line symbolizer has been added, that works with vector or pixmap symbols, to draw textured lines. This happens by default if a lines style is given a symbol of type vector or pixmap. To enable shield symbolization, i.e. a marker placed only on some points of the line, you must add a GAP parameter to your symbol denition. This GAP value is scaled w.r.t the styles SIZE parameter. Specify a positive gap value for symbols always facing north (optionally rotated by the ANGLE of the current style), or a negative value for symbols that should follow the line orientation
310
This happens by default if a lines style is given a symbol of type vector or pixmap. To enable shield symbolization, i.e. a marker placed only on some points of the line, you must add a GAP parameter to your symbol denition. This GAP value is scaled w.r.t the styles SIZE parameter - specify a positive gap value for symbols always facing north (optionally rotated by the ANGLE of the current style), or a negative value for symbols that should follow the line orientation Pixmap and font symbols can now be rotated without loosing their transparency For POLYGON layers with no specic SYMBOL, the WIDTH keyword species the width of the outline, if an OUTLINECOLOR was specied. This is a shorthand that avoids having to create multiple styles for basic rendering, and will provide a marginal performance gain. Note that in this case, the width of the outline is /not/ scale dependent.
layers of type CIRCLE support hatch type symbol lling the ENCODING keyword for labels is now enforced. If unset, MapServer will treat your label text byte-by-byte (resulting in corrupt special characters).
311
1. Add ANTIALIAS keyword to the STYLE object within the CLASS object within the LAYER and set value to TRUE
MAP ... IMAGETYPE P N G 24
312
... LAYER ... TRANSPARENCY ALPHA ... CLASS ... STYLE ... ANTIALIAS TRUE ... END \.\.\. END # end class END # end layer END # end map
Note: Dont use the SYMBOL or the SIZE keywords within the CLASS object, instead use WIDTH to specify width of line or polygon outline. Dont use WIDTH unless you have to. If you must dene a SYMBOL, use symbol of type CARTOLINE or ELLIPSEit supports antialiasing. Heres an example of a real-world maple:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
MAP NAME ms101 EXTENT -2198022.00 -2444920.25 2707932.00 1234545.25 SIZE 640 480 SHAPEPATH data SYMBOLSET symbols/symbols.txt IMAGETYPE P N G 24 PROJECTION "init=epsg:2163" END
# The layer below will be rendered as 1-pixel wide, antialiased line # If youd like to change the line thickness add the WIDTH keyword # in the STYLE object with a value of 3 or greater. LAYER # begin antialiased country boundary (line) layer NAME country_line DATA shapefile/WorldCountryBorders TYPE LINE STATUS ON TRANSPARENCY ALPHA PROJECTION "init=epsg:4326" END CLASS NAME Country Boundary STYLE COLOR 96 96 96 ANTIALIAS TRUE END END
313
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
END # end country boundary layer # The layer below shows one way to draw a polygon with antialiased outline LAYER # begin antialiased country boundary (polygon) layer NAME country_line DATA shapefile/Countries_area TYPE POLYGON STATUS ON TRANSPARENCY ALPHA PROJECTION "init=epsg:4326" END CLASS NAME Country Boundary STYLE COLOR 212 212 212 OUTLINECOLOR 96 96 96 WIDTH 3 ANTIALIAS TRUE END END END # end country boundary polygon layer # The layer below shows one way to draw a polygon with antialiased outline LAYER # begin antialiased state boundary (line) layer NAME state_line DATA shapefile/us_states TYPE LINE STATUS ON TRANSPARENCY ALPHA PROJECTION "init=epsg:4326" END CLASS NAME State Boundary STYLE COLOR 144 144 144 SYMBOL cartoline ANTIALIAS TRUE END END END # end state line layer END # end of map file
314
Note: The examples provided here are for illustrative purposes onlykeep your map le denitions simple. Antialiasing adds computing overhead on the server and could slow/degrade its performance. Dont use it unless you must and certainly dont use symbols with it unless you really have to.
Table of Contents Dynamic Charting Setup Adding a Chart Layer to a Maple Pie Charts Bar Graphs
Starting with version 5.0, MapServer included the ability to automatically draw pie or bar graphs whose values are taken and adjusted from attributes of a datasource. This document assumes that you are already familiar with MapServer application development and especially setting up Maple s. You can also check out the Vector Data Access Guide, which has lots of examples of how to access specic data sources.
8.3.1 Setup
Supported Renderers Dynamic charts are supported solely with the GD and AGG renderers. Attempting to add a chart layer with any other renderer (e.g. PDF or SWF) will result in an error. Rendering quality with the GD renderer is less than optimal, especially with small graphs, due to the lack of subpixel rendering functions. Output from AGG and GD Renderers MapServer AGG Rendering
315
MapServer GD Rendering
No other specic keywords have been added in order to keep the number of different keywords to a minimum in the maple syntax, therefore all the chart specic conguration is determined by PROCESSING directives. Specifying the Size of each Chart The size of each chart is specied by the CHART_SIZE directive. If two values are given for this parameter, this will specify the width and height of each chart (this only applies for bar graphs). By default, the charts are 20x20 pixels.
LAYER TYPE CHART PROCESSING "CHART_SIZE=21" # specify size of the chart for pie or bar graphs #PROCESSING "CHART_SIZE=20 10" # specify width and height for bar graphs ... END
From version 5.2 and onwards, the diameter of a pie chart can be bound to an attribute,using the CHART_SIZE_RANGE PROCESSING attribute:
PROCESSING "CHART_SIZE_RANGE = itemname minsize maxsize minval maxval"
where: itemname is the name of the attribute that drives the chart size (e.g. total_sales) minsize and maxsize are the minimum and maximum chart size values in pixels (e.g. 10 100) minval and maxval are the minimum values of the attribute that correspond to chart sizes of minsize and maxsize (e.g. 10000 1000000). If the attribute value is smaller than minval then the chart size will be minsize pixels, and if the attribute value is larger than maxval, the chart size will be maxsize pixels.
316
Specifying the Values to be Plotted Each value to be plotted (i.e. a slice in a pie chart, or a bar in a par graph) is specied in a CLASS of the chart layer. The value to be plotted is taken from the SIZE keyword from the rst STYLE block of the class. This is semantically a bit awkward, but keeps the number of different keywords to a minimum in the maple syntax. The value given to the SIZE keyword could of course be given a static value, but dynamic charting really only makes sense with attribute binding.
LAYER ... CLASS # include a NAME keyword if you want this class to be included # in the legend NAME "value 1" STYLE # specify which value from the data source will be used as the # value for the graph SIZE [ a t t r i b u t e ] ... END END CLASS ... END ... END
At least 2 CLASS blocks must be specied before charting can occur (but you already knew this if you want your charts to convey at least some information ;) ). Specifying Style The styling of each value in the charts is specied by the usual MapServer syntax. Only one style per class is supported, any other STYLE block will be silently ignored. Only a subset of the styling keywords are supported:
STYLE SIZE [ a t t r i b u t e ] # specify the fill color COLOR r g b # if present will draw an outline around the corresponding bar or slice OUTLINECOLOR r g b #specify the width of the outline if OUTLINECOLOR is present (defaults to 1) WIDTH w # only for pie charts. a is the number of pixels the corresponding # slice will be offset relative to the center of the pie. This is useful # for emphasizing a specific value in each chart. b is required by the # mapfile parser but is ignored. OFFSET a b END
317
For each shape in the layers datasource, the STYLE SIZE is used to set the relative size (value) of each pie slice, with the angles of the slices that are automatically computed so as to form a full pie. For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
LAYER NAME "Ages" TYPE CHART CONNECTIONTYPE postgis CONNECTION "blabla" DATA "the_geom from demo" PROCESSING "CHART_TYPE=pie" PROCESSING "CHART_SIZE=30" STATUS ON CLASS NAME "Population Age 0-19" STYLE SIZE [ v 1006] COLOR 255 244 237 END END CLASS NAME "Population Age 20-39" STYLE SIZE [ v 1007] COLOR 255 217 191 END END CLASS NAME "Population Age 40-59" STYLE SIZE [ v 1008] COLOR 255 186 140 END END END
In the example above, if for a given shape we have v1006=1000, v1007=600 and v1008=400 then the actual pie slices for each class will be respectively 50%, 30% and 20% of the total pie size.
For each shape in the layers datasource, the STYLE SIZE is used to set the relative size (value) of each bar in the graph. By default, the vertical axis of each bar graph is scaled for the values of the corresponding shape, and will always include the origin (=0). For example
318
a shape whose STYLE SIZEs contains values {5,8,10,3} will be plotted on a graph whose vertical axis spans 0 to 10. a shape whose STYLE SIZEs contains values {-5,-8,-10,-3} will be plotted on a graph whose vertical axis spans -10 to 0. a shape whose STYLE SIZEs contains values {-5,-8,10,3} will be plotted on a graph whose vertical axis spans -8 to 10. Additional PROCESSING directives are used to optionally specify the bounds of vertical axes so that the graphs for all the shapes can be plotted with the same scale:
PROCESSING "CHART_BAR_MINVAL=val" PROCESSING "CHART_BAR_MAXVAL=val"
Values in the datasource that are above CHART_BAR_MAXVAL or below CHART_BAR_MINVAL will be clipped respectively to these values. If only one of these directives is included, the other will be automatically adjusted for each shape to include at least the origin, i.e. the graphs for all the shapes will be in the same scale only if all the values are of the same sign (positive or negative).
Table of Contents Flash Output Introduction Installing MapServer with Flash Support How to Output SWF Files from MapServer What is Currently Supported and Not Supported
8.4.1 Introduction
Since MapServer 4.0, MapServer can output Flash les, in SWF format (or Shockwave Flash Format). The following document outlines how to enable Flash output in MapServer. Links to Flash-Related Information Open Source Flash Viewer Flash maps demo 8.4. Flash Output 319
Using Pre-compiled Binaries Windows users can use MS4W, which supports SWF output. Compiling MapServer with Flash Support The library chosen to output SWF les is the Ming library. Ming is a C library for generating SWF (Flash) format movies, and it contains a set of wrappers for using the library from C++ and popular scripting languages like PHP, Python, and Ruby.
Building on Windows
download the Ming library (the version currently supported is 0.2a) as of Ming 0.3 there was no makele for Windows available in the distribution yet, but you can download a MS VC++ makele (makele.vc) from here (contains makele and also libming.lib) copy makele.vc under the src directory (ming-0.2/src) execute:
nmake /f makefile.vc
at this point you should have a libming.lib that will be linked with MapServer edit the nmake.opt in your MapServer directory and uncomment the MING=-DUSE_MING_FLASH ag, and point MING_DIR to your Ming directory. build MapServer as usual
Building on Unix
Use the with-ming congure ag to enable MING support on Unix. with-ming=dir will try to nd the include les and library in the indicated directory.
320
Note: compiling MapServer 4.4.2 with flash support (mingbeta version 0.3) requires the -DMING_VERSION_03 option otherwise the make fails. This option should be included in the configure.in after -DUSE_MING_FLASH as below: MING ENABLED= "-DUSE_MING_FLASH -DMING_VERSION_03"
2. A movie for every layer (vector movies for vector layers and raster movies for raster layers). To enable this, declare the following in the map le:
OUTPUTFORMAT NAME swf MIMETYPE "application/x-shockwave-flash" DRIVER swf IMAGEMODE PC256 FORMATOPTION "OUTPUT_MOVIE=MULTIPLE" END
Other OutputFormat Options FORMATOPTION FULL_RESOLUTION=FALSE The FULL_RESOLUTION applies only for vector layers. If set to FALSE, ltering will be applied to the vector elements. It results in a smaller SWF le. The default value is TRUE. FORMATOPTION LOAD_AUTOMATICALLY=OFF Setting this option to OFF will not load the SWF les for each layer. The default value is ON. Composition of the Resulting SWF Files Several SWF Files will be produced from a single map le: there will be one SWF le for each layer dened in the map le and one main SWF le containing critical information on the map le and the layers produced. The main SWF File will contain Action Script (AS) code that gives critical information on the map le and the SWF layers produced. Basically there will be an object called mapObj containing the height, width, extent, scale, number of layers, etc. Here is an example (in AS) of the contents of this main movie:
321
mapObj = new Object (); mapObj.name = "DEMO_SWF"; mapObj.width = 400; mapObj.height = 300; mapObj.extent = "-2594561.353333,3467361.353333,3467361.353333,3840000.000000"; ; mapObj.numlayers = 4; mapObj.layers = new Array (); function LayerObj (name, type, fullname, relativename) { this.name = name; this.type = type; this.fullname = fullname; this.relativename = relativename; } mapObj.layers[0] = new LayerObj ("park", "2", "c:/tmp/ms_tmp/102389536132841_layer_0.swf", "1023 mapObj.layers[1] = new LayerObj ("popplace", "4", "c:/tmp/ms_tmp/102389536132841_layer_1.swf", " mapObj.layers[2] = new LayerObj ("rail", "1", "c:/tmp/ms_tmp/102389536132841_layer_2.swf", "1023 mapObj.layers[3] = new LayerObj ("road", "1", "c:/tmp/ms_tmp/102389536132841_layer_3.swf", "1023
This example is produced based on a maple with two layers dened in it. We create a layer class object containing useful information on a layer. The parameters are: Name : the name found in the map le Type : the type of layer ( 0 = Point Layer; 1=Line; 2=Polygon; 3=Raster; 4=Annotation; 6=Circle) Fullname : Full name of the le with path included Relative name : Relative Name For example you can use mapObj.layers[0].name to extract the name of the rst layer. Note: All map parameters from MapServer are not exported at this time. We should come up with a list of information of what we want to output. Note that this information can be used in a Flash application to load the SWF le, to build a legend, to build a scale bar, etc. SWF Files for each layer Each layer dened in the maple will have an associated SWF le created. The names of these SWF les are based on the name of the main le with an addition of layer_X at the end of the name (where X is the layer index). These SWF les will contain vector and raster data as well as some Action Script depending on the layer and some congurations in the map le. We will see these congurations in detail in the following section. Exporting Attributes Exporting attributes works on a layer basis (it is only available for Vector Layers). To be able to export attributes to the SWF les, you have to dene a metadata item called SWFDUMPATTRIBUTES in the layer section of the maple. Here is an example :
... LAYER NAME park METADATA "DESCRIPTION""Parks" "RESULT_FIELDS" "NAME_E YEAR_EST AREA_KMSQ" "SWFDUMPATTRIBUTES" "NAME_E,AREA_KMSQ " END TYPE POLYGON STATUS ON
322
In the above example, the values for the attributes NAME_E and AREA_KMSQ will be exported for each element in the layer. The resulting SWF File will have the values of these attributes (written in Action Script). Here is an example related to the above layer:
nAttributes= 2; Attributes = new Array(); Attributes[0] = "NAME_E"; Attributes[1] = "AREA_KMSQ"; Element = new Array (); Element[0] = new Array(); Element[0][0] = "Ellesmere Island National Park Reserve"; Element[0][1] = "1500"; Element[1][0] = " Aulavik National park"; Element[1][1] = "1500";
Events and Highlights Here is what is currently implemented concerning events (events here refer to mouse events happening on an element. The available events are MOUSEUP, MOUSEDOWN, MOUSEOVER, MOUSEOUT): Events are only available for layers that have dened attributes exported (using SWFDUMPATTRIBUTES). This is like dening that a certain layer is queryable. When a mouse event happens on one of the elements, there is an Action Script call that is made: _root.ElementSelecetd(LayerId, ShapeId, Event) . The Flash application who wants to receive these events should dene the function ElementSelected and use the information received to do actions like retrieving the attribute values from the specic SWF for the specied shape and display it. In order to have highlighting, it has to be dened when the SWF is produced (basically highlighting means that the shape is redrawn using a different color). As of MapServer 5.0, highlighting is available on queryable layers by using the QueryMap object in the map le to extract the color and do a highlight when on MOUSEOVER. The current implementation will highlight all objects that are in a layer that uses SWFDUMPATTRIBUTES, using the COLOR set in the QueryMap object in the maple. Before MapServer 5.0, all objects that are in a layer that uses SWFDUMPATTRIBUTES are highlighted using a red color. Fonts Ming uses a special type of font called FDB les. It does not yet support Truetype fonts. Please refer to ming documentation on how to produce FDB les. Outputting Raster SWF for Vector Layers One mechanism would be to use the metadata for layer objects to dene a raster output for vector layers. We could use something like SWFOUTPUT RASTER. If this sounds desirable, please le an enhancement ticket with this request, specifying the Output-SWF component.
323
324
Contents HTML Legends with MapServer Introduction Sample Site Using the HTML Legend
8.5.1 Introduction
The HTML legend is an alternative to the traditional GIF legend in MapServer. The following document describes the process for implementing an HTML legend in MapServer CGI applications (NOTE: MapServer version > 3.5 is required). This document assumes that you are already familiar with certain aspects of MapServer: Setting up MapServer maples and templates. Implementation Key components for generating HTML legends are 1) a template parameter in the legend object, 2) a CGI [legend] tag in the HTML le, and 3) an HTML legend template le. So that means that if the HTML page has the CGI [legend] parameter set, and the maple has a LEGEND object with its TEMPLATE set to a valid HTML legend le then an HTML legend will be returned. The following sections discuss these components. Legend Object of Maple The HTML legend is enabled by a new TEMPLATE parameter in the Legend Object of the maple. If TEMPLATE is set in the Legend Object, then the HTML legend template le is read and used to generate an HTML legend which will be inserted at the location of the [legend] tag in the main HTML template. Similar to other MapServer templates, the HTML legend template lename MUST end with an .html extension. Example 1. Sample Legend Object with the new TEMPLATE parameter
... # LEGEND object LEGEND STATUS ON KEYSIZE 18 12 # LABEL object LABEL TYPE BITMAP
325
If TEMPLATE is not set, then the [legend] tag produces a regular image in a GIF/PNG image (the traditional behaviour). CGI [legend] tag The traditional CGI [legend] tag returns the URL of an image, so it is usually used inside an <IMG SRC=[legend]> tag in the HTML le. The new HTML [legend] tag returns a block of HTML, so when converting an existing application template from using a traditional image legend to the new HTML legend, you have to remove the IMG tag in the main application template. Also note that if legend mode is specied in the URL, then MapServer will return a gif containing the whole legend if no template is specied. See the CGI Reference doc for more information on CGI parameters. Example 2. [legend] tag in the main HTML template (with TEMPLATE set)
... <FONT SIZE=+1><B>Legend</B></FONT><BR><HR>[legend]<HR> ...
Example 3. [legend] tag in the main HTML template (with TEMPLATE not set)
... <FONT SIZE=+1><B>Legend</B></FONT><BR><HR><IMG SRC="[legend]"><HR> ...
HTML Legend Template File The HTML legend template le is a separate le that contains 0 or 1 of each of the following tags that dene blocks of HTML to use in building the legend:
[leg_group_html] ... [/leg_group_html] [leg_layer_html <OPTIONAL PARAMS>] ... [/leg_layer_html] [leg_class_html <OPTIONAL PARAMS>] ... [/leg_class_html]
Note Any text or HTML tags outside the [leg_*_html] tag pairs in the legend template le are ignored by the template parser. The following example shows what an HTML legend TEMPLATE le could look like: Example 4. An HTML legend TEMPLATE le
[leg_group_html] <tr> <td colspan=3 bgcolor=#cccccc><b>[leg_group_name]</b></td> </tr> [/leg_group_html]
326
[leg_layer_html order_metadata=legend_order opt_flag=5] <tr> <td> <input type=checkbox name="map_[leg_layer_name]_status" value=1 [if name=layer_status oper=eq value=2]CHECKED[/if]> </td> <td colspan=2> <a href="[metadata name=href]">[metadata name=layer_title]</a> </td> </tr > [/leg_layer_html] [leg_class_html] <tr> <td width=15> </td> <td> <img src="[leg_icon width=20 height=10]" width=20 height=10> </td> <td> [leg_class_name] </td> </tr> [/leg_class_html]
HEADER block
Tag [leg_header_html]...[/leg_header_html] Description HTML block to use as the header of the legend.
FOOTER block
Tag [leg_footer_html]...[/leg_footer_html] Description HTML block to use as the footer of the legend. Example 5. HTML Legend File Using Header/Footer Blocks
[leg_header_html] <p><b>my header</b></p> [/leg_header_html] [leg_layer_html] ... [/leg_layer_html] [leg_footer_html] <p><b>my footer</b></p> [/leg_footer_html]
327
GROUP block
Tag [leg_group_html <OPTIONAL PARAMS>]...[/leg_group_html] Description HTML block to use for layer group headers if layers should be grouped in the legend. If not set then layers are not grouped in the legend. When the [leg_group_html] tag is used, then layers that dont belong to any group (i.e. LAYER GROUP not set in the maple) and their classes will not show up at all in the legend. The group list is decided by the order_metadata parameter, which is explained later. SUPPORTED PARAMETERS: Parameter opt_ag=<bit_mask> Description Control the groups display, by adding the following values (default is 15). The opt_ag is applied on all layers in the group. If at least one layer matches the ag, the group will show up in the legend. 1 If set, show group even if all layers in group are out of scale (default: hide groups out of scale). 2 If set, show group even if all layers in group have status OFF (default: hide groups with STATUS OFF). 4 If set, show group even if all layers in group are of type QUERY (default: hide group of TYPE QUERY) 8 If set, show group even if all layers in group are of type ANNOTATION (default: hide groups of TYPE ANNOTATION) e.g. opt_ag=12 (shown below) means show all layer types, including QUERY and ANNOTATION layers (4 + 8)
[leg_group_html opt_flag=12] ... [/leg_group_html]
SUPPORTED TAGS: Tag [leg_group_name] Description Returns the groups name. Tag [layer_status] Description Returns the status of the rst layer in the group. Tag [leg_icon width=<optional_width> height=<optional_height>] Description In the group context, the [leg_icon] tag returns the URL of a legend icon for the rst class in the rst layer thats part of this group. Tag [metadata name=<metadata_eld_to_display>] Description Returns specied metadata value from webs metadata. e.g. the group block below simply displays the name of the group in the legend:
[leg_group_html] <tr><td colspan=2><b>[leg_group_name]</b></td></tr> [/leg_group_html]
328
LAYER block
Tag [leg_layer_html <OPTIONAL PARAMS>] ... [/leg_layer_html] Description HTML block to use for layer header. If not set then no layer headers are displayed (could allow a legend with only classes in it). SUPPORTED PARAMETERS: Parameter order_metadata=<eld_to_order_by> Description Species that the value of the layer metadata <eld_to_order_by> controls the order and visibility of the layers in the legend. Layers with <eld_to_order_by> >= 0 are sorted in order of this value, with multiple layers with same value being accepted, in which case the map layer orderapplies between those layers. Layers with <eld_to_order_by> < 0 are always hidden in the legend. Parameter opt_ag=<bit_mask> Description Control the layer display process. Add the values below to acquire the desired options (default is 15): If set, show layer even if out of scale (default: hide layers out of scale). If set, show layer even if status is OFF (default: hide layers with STATUS OFF). If set, show layer even if type is QUERY (default: hide layers of TYPE QUERY) If set, show layer even if type is ANNOTATION (default: hide layers of TYPE ANNOTATION) e.g. opt_ag=14 (shown below) means do not show layers in the legend that are out of scale.
[leg_layer_html opt_flag=14] ... [/leg_layer_html]
1 2 4 8
SUPPORTED TAGS: Tag [leg_layer_group] Description Returns the group name of the layer. This was added to MapServer v4.8. Tag [leg_layer_index] Description Returns the maple index value of the layer, which is useful for ordering. This was added to MapServer v4.8. Tag [leg_layer_maxscale] Description Returns the maximum scale set for the layer. This was added to MapServer v4.8. Tag [leg_layer_minscale] Description Returns the minimum scale set for the layer. This was added to MapServer v4.8. Tag [leg_layer_name] Description Returns the current LAYER NAME value. Tag [leg_icon width=<optional_width> height=<optional_height>] Description In the layer context, the [leg_icon] tag returns the URL of a legend icon for the rst class in this layer. Tag [metadata name=<metadata_eld_to_display>] Description Returns specied metadata value from this layers metadata and webs metadata. 8.5. HTML Legends with MapServer 329
e.g. the layer block below simply displays an icon of the layers class and the layer name:
[leg_layer_html] <tr><td><img src=[leg_icon width=15 height=15]><b>[leg_layer_name]</b></td></tr> [/leg_layer_html]
CLASS block
Tag [leg_class_html <OPTIONAL PARAMS>] ... [/leg_class_html] Description HTML block to use for classes. If not set then no classes are displayed (could allow a legend with only layer headers in it). Note that classes with NULL (i.e. empty) NAMEs are not displayed. SUPPORTED PARAMETERS: Parameter opt_ag=<bit_mask> Description Control the layer (i.e. class) display process. Add the values below to acquire the desired options (default is 15). Note that using this parameter for the CLASS block has the same effect as using the opt_ag parameter in the LAYER block. If set, show layer even if out of scale (default: hide layers out of scale). If set, show layer even if status is OFF (default: hide layers with STATUS OFF). If set, show layer even if type is QUERY (default: hide layers of TYPE QUERY) If set, show layer even if type is ANNOTATION (default: hide layers of TYPE ANNOTATION) e.g. opt_ag=14 (shown below) means do not show classes in the legend that are out of scale.
[leg_class_html opt_flag=14] ... [/leg_class_html]
1 2 4 8
SUPPORTED TAGS: Tag [leg_class_index] Description Returns the maple index value of the class, which is useful for ordering and legend icon creation. This was added to MapServer v4.8. Tag [leg_class_maxscale] Description Returns the maximum scale set for the class. This was added to MapServer v4.8. Tag [leg_class_minscale] Description Returns the minimum scale set for the class. This was added to MapServer v4.8. Tag [leg_class_name] Description Returns the CLASS NAME value. Tag [leg_class_title] Description Returns the CLASS TITLE value. Tag [leg_layer_name] Description Returns the parent layer name. This was added to MapServer v4.8. Tag [leg_icon width=<optional_width> height=<optional_height>]
330
Description In the layer context, the [leg_icon] tag returns the URL of a legend icon for the rst class in this layer. Tag [metadata name=<metadata_eld_to_display>] Description Returns specied metadata value from the metadata of the layer to which this class belongs and webs metadata. e.g. the class block below simply displays an icon of the layers class and the class name:
[leg_class_html] <tr><td><img src=[leg_icon width=15 height=15]><b>[leg_class_name]</b></td></tr> [/leg_class_html]
CONDITIONAL text
[if] tags can be used in any of the [leg_*_html] tags above to place conditional text. The syntax is:
[if name=<field_to_check> oper=<eq|neq|isset|isnull> value=<to_compare_with_field>] ... [/if]
Note: Nested IFs are supported. Parameter oper can be eq for equal, neq for not equal, isset (self-explanatory), or isnull (self-explanatory). The default value is equal. Example 6. [if] tag can be used to maintain the state of a layer checkbox
[leg_layer_html order_metadata=legend_order opt_flag=5] <tr> <td> <input type=checkbox name="map_[leg_layer_name]_status" value=1 [if name=layer_status oper=eq value=2]CHECKED[/if] > </td> <td colspan=2> <a href="[metadata name=href]">[metadata name=layer_title]</a> </td> </tr > [/leg_layer_html]
The possible values that can be tested in an [if] tag depend on the context in which the [if] tag is used. At the moment, the number of values that can be tested is limited, but new values may be added as needed. Note that the order of the items in the following [if] contexts are listed by their order of precedence. The rule is always that special keywords have top priority (e.g. layer_status, etc.), followed by layer-level metadata, and ending with map-level metadata. The possible values that can be tested are as follows: In a [leg_group_html] context: [if name=layer_status value=...] ... [/if] value is the layer status of the rst layer that belongs to the group in integer format: 0=OFF, 1=ON, 2=DEFAULT [if name=layer_visible value=...] ... [/if] value is the visibility of the rst layer in the group: 0=NOT VISIBLE, 1=VISIBLE [if name=group_name value=...] ... [/if] 8.5. HTML Legends with MapServer 331
[if name=any_layer_metadata value=...] ... [/if] Uses metadata value from the rst layer in the maple that belongs to that group [if name=any_web_metadata value=...] ... [/if] In a [leg_layer_html] context: [if name=layer_status value=...] ... [/if] value is the layers status in integer format: 0=OFF, 1=ON, 2=DEFAULT [if name=layer_type value=...] ... [/if] value is the layers type in integer format: 0=POINT, 1=LINE, 2=POLYGON, 3=RASTER, 4=ANNOTATION, 5=QUERY, 6=CIRCLE [if name=layer_name value=...] ... [/if] value is the layers name in string format [if name=layer_group value=...] ... [/if] value is the layers group name in string format [if name=layer_visible value=...] ... [/if] value is the visibility of the layer: 0=NOT VISIBLE, 1=VISIBLE [if name=any_layer_metadata value=...] ... [/if] [if name=any_web_metadata value=...] ... [/if] In a [leg_class_html] context: [if name=layer_status value=...] ... [/if] value is the status of the layer in which the class is located [if name=layer_type value=...] ... [/if] value is the layers type in integer format: 0=POINT, 1=LINE, 2=POLYGON, 3=RASTER, 4=ANNOTATION, 5=QUERY, 6=CIRCLE [if name=layer_name value=...] ... [/if] value is the layers name in string format [if name=layer_group value=...] ... [/if] value is the layers group name in string format [if name=layer_visible value=...] ... [/if] value is the visibility of the layer: 0=NOT VISIBLE, 1=VISIBLE [if name=class_name value=...] ... [/if] [if name=any_layer_metadata value=...] ... [/if] [if name=any_web_metadata value=...] ... [/if]
332
HTML Legend 2 - displays layer titles with HREF links and classes:
[leg_layer_html order_metadata=WMS_ORDER visibility_flag=15] <a href="[leg_layer_name]">[metadata name=WMS_TITLE]</a><BR> [/leg_layer_html] [leg_class_html visibility_flag=15] <img src=[leg_icon]> [leg_class_name]<br> [/leg_class_html]
HTML Legend 3 - displays layers by group, with checkboxes to turn layers on/off:
[leg_group_html] <tr><td colspan=2><b>[leg_group_name]</b></td></tr> [/leg_group_html] [leg_layer_html order_metadata=WMS_ORDER opt_flag=15] <tr> <td><input type=checkbox name=layer value=[leg_layer_name] [if name=layer_status value=1]CHECKED[/if]> [if name=layer_type value=4] <img src=[leg_icon width=22 height=18]> [/if] [if name=layer_type oper=neq value=4]<img src=[leg_icon]>[/if] </td> <td> <a href="[leg_layer_name]">[metadata name=WMS_TITLE]</a> </td> </tr> [/leg_layer_html]
333
Contents HTML Imagemaps Introduction Maple Layer Denition Templates Request URL Additional Notes More Information
8.6.1 Introduction
The shpxy method of creating imagemaps uses MapServer query functionality to build a html imagemap. Just like a regular MapServer query, you send a query request and MapServer uses the templates to build a block of html that it sends back to the browser. The rst example shows you how to build an imagemap based on a point layer. An example template for a polygon layer is also included. Components MapServer maple query template le query header template query footer template
334
LAYER NAME "sites" STATUS DEFAULT TYPE point DATA aqiAreas TEMPLATE "bodytemplate.html" HEADER "imapheader.html" FOOTER "imapfooter.html" END END
You can see that we have a maple with one point layer, and that it contains references to three query templates.
8.6.3 Templates
In MapServer, the query header and footers get processed only once. The main query template, bodytemplate.html in this example, gets processed once for each record in the record set returned by the query. Point Layers Here is the query header, imapheader.html. It creates the opening tag for your html imagemap.
<map id="mymap" name="mymap">
Here is the query template, bodytemplate.html. It creates the body of the html imagemap.
This template is used to create circular imagemap elements for a point layer. NAME is a eldname in the data source, the value for NAME for each individual record gets substituted as the template is processed. The href species the URL link if the element is clicked. Title and alt will display the value when an element is moused over. The resulting html element looks like
<area shape="circle" coords="80,103,7" href="http://my.url/mypage.cfm?region=Northern" >
This is where MapServer will substitute the image coordinates for that query record. With Precision=0, the coordinates will be integers. You also see shpxy template formatting options xf and yf. xf=, tells MapServer to place a comma after the x coordinate. yf=,7 after the y coordinate. This is done to specify a radius of 7 pixels for the circle. More options can be found in the Template Reference. The query footer template simply adds the closing tag for the html imagemap
</map>
335
Table of Contents PDF Output Introduction What is currently supported and not supported Implementing PDF Output PHP/MapScript and PDF Output
336
8.7.1 Introduction
PDF output support was added to MapServer 3.7. Previous versions of MapServer had support for pdf output using a utility program (shp2pdf) to output a pdf le given a MapServer maple. The difference in this new version is that the output to PDF can now be directly specied in the maple using the IMAGETYPE or the OUTPUTFORMAT parameters in the maple. Additionally, raster layers are now supported for pdf output.
open the project PDFlib.dsw in MS Visual C++ build the project pdib_dll after a sucessful build, you should have a pdib.lib and pdblib.dll under the pdib directory copy the pdib.dll under your system directory (ex : c:/winnt/system32) the pdib.lib will be used while building mapserver with the PDF support Build MapServer with PDF support Windows platform Edit the makele.vc and uncomment the following lines (make sure that the paths are adapted to your installation):
PDF_LIB=../pdflib-4.0.3/pdflib/pdflib.lib PDF_INC=-I../pdflib-4.0.3/pdflib PDF=-DUSE_PDF
See the Windows Compilation document for general MapServer compile instructions. Unix platforms Add with-pdf to your congure command line before compiling. See the Unix Compilation document for general MapServer compile instructions. Maple denition The IMAGETYPE parameter in the Maple should be set to pdf in order to output to PDF:
NAME pdf-test STATUS ON ... IMAGETYPE pdf .. WEB ... END LAYER ... END END
You can also specify the output using the OUTPUTFORMAT tag (this tag was introduced in mapserver 3.7) :
OUTPUTFORMAT NAME pdf MIMETYPE "application/x-pdf" DRIVER pdf FORMATOPTION "OUTPUT_TYPE=RASTER" ##not mandatory END
338
If the OUTPUT_TYPE=RASTER all the layers will be rendered as rasters. Note that when WMS layers are included in the maple, this option should be set since there is a problem with transparency and wms layers. See the OUTPUTFORMAT object in the Maple reference for parameter explanations. Testing The easiest way to test your pdf output maple is with the MapServer shp2img utility. Windows users can nd this utility in MS4W, as well as FWTools. You simply pass a maple to the executable and a name for the output pdf, and a pdf le is generated:
shp2img -m gmap_pdf.map -o test.pdf
Possible Errors
PDFlib I/O error: Resource configuration file pdflib.upr not found
This is related to fonts. If you remove the LABEL object from your maple you will see this error go away. The pdf error is described here. Basically, until this issue is xed, if you want to use a font other than the included standard PostScript fonts in pdf output (such as truetype fonts), consult the PDFlib documentation.
Get this stage and section 4.5 working before you try inserting MapServer elements. 8.7. PDF Output 339
Render PNG views at a suitable resolution Work back from the assumption that you will need no more than 300 dpi on your page for your map to look presentable. For an A4 map, I am using 150 dpi for an 8 x 8 main map, which is 1200 x 1200 pixels.
$map->set(width,1200); $map->set(height,1200);
Of course, our map will not be very useful unless it is zoomed in to the extent our user requested, and the layers they selected are switched on. Maintain arrays in your application that record:
- The current extent (say $ext[]) - Layer status (say $layer[])
Open your map le and pass these back through to set the map le into the state the user is expecting, something like:
$map->setextent($ext[0], $ext[1], $ext[2], $ext[3]); while($layer[]) { $layer=$map->getLayer($n); if($layer[$n]==1) { $layer->set(status,1); } else { $layer->set(status,0); } }
Use the same method for all your map elements, such as drawReferenceMap?(), drawScaleBar?() and drawLegend(). Insert the PNG elements into your PDF document This is really easy, use the pdf_open_image_le() function to import the map elements into your PDF document:
$element = pdf_open_image_file($my_pdf, "png", "$webroot/$url"); pdf_place_image($my_pdf, $element, $xpos, $ypos); pdf_close_image($my_pdf, $element);
Repeat as needed for any map elements you created. Buffer the PDF and send it to the user Assuming we have been creating the document $my_pdf, when we are done, we merely buffer it and send it to the user using echo():
<?php .... pdf_close($my_pdf);
340
$data = pdf_get_buffer($my_pdf); header(Content-type: application/pdf); header(Content-disposition: inline; filename=my_pdf.pdf); header(Content-length: . strlen($data) ); echo $data; ?>
Gotcha: remember that you cannot send headers if you have at any stage outputed text to the browser. Additional stuff to try Rendering everything as PNG can look ugly, so I step through the key and extract labels so I can render them using PDFs text functions. This can be done for other map element, such as map titles, layer descriptions, or anything else that can be read from the maple.
8.8 SVG
Author Jeff McKenna Contact jmckenna at gatewaygeomatics.com Revision $Revision: 8365 $ Date $Date: 2008-12-31 07:49:02 -0800 (Wed, 31 Dec 2008) $ Last Updated 2005/12/13
Table of Contents SVG Introduction Feature Types and SVG Support Status Testing your SVG Output goSVG
8.8.1 Introduction
SVG (or Scalable Vector Graphics) is a standardized XML language for describing 2D graphics via vector graphics, text and raster graphics. As of version 4.5, MapServer can output SVG v1.1 maps. The following documentation is based on the World Wide Web Consortiums (W3C) Scalable Vector Graphics (SVG) 1.1 Specication. This document assumes that you are already familiar with certain aspects of MapServer: MapServer application development and setting up map les.
8.8. SVG
341
Links to SVG-Related Information SVG 1.1 specication SVG Discussion Paper G-XML Project Page SVG Tiny Prole MapFile Reference Doc
Raster Layers The following items describe how raster layers are handled by MapServer for SVG output: Temporary image is created through the GD library, and GD functions are used to draw the layer. You must have at least PNG or JPEG support compiled in MapServer. You must have the WEB objects IMAGEPATH and IMAGEURL set properly in your maple. Text Features The following items describe how text features are handled by MapServer for SVG output: Text is converted to SVG text element. Only TRUETYPE fonts are supported. Supports labels with ENCODING (output as UTF-8 hexadecimal values). The FONT name used in MapServer is parsed to form the SVG font-family, font-style, and font-weight. WMS Layers WMS layers are not yet supported. Setting up a Maple for SVG Output You must have valid IMAGEPATH and IMAGEURL parameters set in the WEB object of the maple. To be able to output a valid SVG le, the user needs to dene an OUTPUTFORMAT object in the map le and set the IMAGETYPE parameter to svg. Here is an example:
MAP ... IMAGETYPE svg ... OUTPUTFORMAT NAME svg MIMETYPE "image/svg+xml" DRIVER svg FORMATOPTION "COMPRESSED_OUTPUT=TRUE" FORMATOPTION "FULL_RESOLUTION=TRUE" END ... WEB IMAGEPATH "/tmp/ms_tmp/" IMAGEURL "/ms_tmp/" END ... LAYER ... END END
8.8. SVG
343
Note: If FORMATOPTION COMPRESSED_OUTPUT=TRUE is set MapServer will produce a compressed SVG le (svgz). By default this option is FALSE. Note that to be able to create compressed output, MapServer must be built with the compile ag USE_ZLIB. If FORMATOPTION FULL_RESOLUTION=TRUE is set MapServer will not eliminate duplicate points and collinear lines when outputting SVG. By default this option is set to FALSE.
You can also use PHP/MapScript to test your SVG maple. Your php le might look like the following:
<?php dl("php_mapscript_45.dll"); $oMap = ms_newmapObj("my/path/to/my-svg.map"); $img = $oMap->draw(); header("Content-type: image/svg+xml"); $url = $img->saveImage(""); ?>
An SVG le should be created in your IMAGEPATH directory. If you open the SVG le in a text editor you can see that it is an XML le. Below is a sample SVG le of a point layer with labels:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-flat.dtd <svg version="1.1" width="400" height="300" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://ww <!-- START LAYER popplace --> <ellipse cx="252" cy="130" rx="3" ry="3" fill="#000000" /> <ellipse cx="37" cy="227" rx="3" ry="3" fill="#000000" /> <ellipse cx="127" cy="239" rx="3" ry="3" fill="#000000" /> <ellipse cx="255" cy="282" rx="3" ry="3" fill="#000000" /> <polygon fill="#000000" stroke-width="1" points=" 267,263 270,263 271,260 <ellipse cx="288" cy="247" rx="3" ry="3" fill="#000000" /> <ellipse cx="313" cy="243" rx="3" ry="3" fill="#000000" /> <ellipse cx="328" cy="233" rx="3" ry="3" fill="#000000" /> <ellipse cx="331" cy="245" rx="3" ry="3" fill="#000000" /> <ellipse cx="366" cy="196" rx="3" ry="3" fill="#000000" /> <ellipse cx="161" cy="246" rx="3" ry="3" fill="#000000" /> <ellipse cx="92" cy="208" rx="3" ry="3" fill="#000000" /> <ellipse cx="40" cy="125" rx="3" ry="3" fill="#000000" /> <ellipse cx="108" cy="146" rx="3" ry="3" fill="#000000" /> <text x="40" y="143" font-family="fritqat" font-size="8pt" fill="#000000" <text x="43" y="121" font-family="fritqat" font-size="8pt" fill="#000000" <text x="34" y="205" font-family="fritqat" font-size="8pt" fill="#000000"
344
<text <text <text <text <text <text <text <text <text <text </svg>
x="164" y="258" font-family="fritqat" font-size="8pt" fill="#000000" stroke="#ffffff" stroke x="316" y="190" font-family="fritqat" font-size="8pt" fill="#000000" stroke="#ffffff" stroke x="334" y="258" font-family="fritqat" font-size="8pt" fill="#000000" stroke="#ffffff" stroke x="249" y="230" font-family="fritqat" font-size="8pt" fill="#000000" stroke="#ffffff" stroke x="241" y="242" font-family="fritqat" font-size="8pt" fill="#000000" stroke="#ffffff" stroke x="223" y="260" font-family="fritqat-italic" font-size="8pt" fill="#ff0000" stroke="#ffffff" x="210" y="279" font-family="fritqat" font-size="8pt" fill="#000000" stroke="#ffffff" stroke x="82" y="234" font-family="fritqat" font-size="8pt" fill="#000000" stroke="#ffffff" strokex="40" y="223" font-family="fritqat" font-size="8pt" fill="#000000" stroke="#ffffff" strokex="214" y="125" font-family="fritqat" font-size="8pt" fill="#000000" stroke="#ffffff" stroke
You can now view the SVG le in a supported browser (see the ofcial list of SVG implementations for possible SVG viewers). The Adobe Viewer plugin is very popular.
8.8.4 goSVG
goSVG is now supported as a vector output format in MapServer 4.5 (and later). Denition This denition of goSVG was obtained from here. goSVG is short for G-XML over SVG and g-contents over SVG. This is a subset for mobiles specied within the G-XML (a Japanese Spatial Information Format which is an XML based protocol with the ability to describe, communicate and exchange Spatial Information and Electric Maps), and is a Spatial Information Exchanging format that determines the method to expand spatial information and connect to the backend system(G-XML standard mark format). goSVG is an expanded SVG Tiny prole (a Mobile prole of SVG 1.1. suited for cellular phones) that adds functions that are useful for Spatial Information Services (SVG Map Service). Support for Specic goSVG Elements Name space extension: supported Content Area Denition (bounding box): supported Geographic Coordinate System: supported Map Request Protocol: supported Setting up a Maple for goSVG Output
Requirements
A valid MapServer Maple. Valid IMAGEPATH and IMAGEURL parameters set in the WEB object of the maple. A PROJECTION object dened beneath the MAP object, using an EPSG code. For example:
MAP ... WEB
8.8. SVG
345
IMAGEPATH "/tmp/ms_tmp/" IMAGEURL "/ms_tmp/" END ... PROJECTION "init=epsg:42304" END ... LAYER ... END END
346
GOSVG_ZoomOutTH controls the zoomout threshold when outputting the Map R equest Protocol. If it is not dened the default value is set to 100. GOSVG_ScrollTH controls the scrolling threshold when outputting the Map Request Protocol. If it is not dened the default value is set to 10. Testing your goSVG Output Refer to the section Testing your SVG Output to generate and test your goSVG output. goSVG can be read by regular SVG viewers (they will just ignore the goSVG headers). Sample goSVG File Produced by MapServer Below is a sample goSVG le of a point layer with labels:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-flat.dtd <svg version="1.1" width="400" height="300" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://ww <title>DEMO</title> <metadata> <rdf:RDF xmlns:rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:crs = "http://www.ogc.org/crs" xmlns:svg="http://wwww.w3.org/2000/svg"> <rdf:Description> <crs:CoordinateReferenceSystem svg:transform="matrix(0.000066,0.000000,0.000000,-0.000066,171.243002, rdf:resource="http://www.opengis.net/gml/srs/epsg.xml#42304"/> </rdf:Description> </rdf:RDF> <au:lbs protocol="maprequest"> <au:zoomin th="20" xlink:href="."/> <au:zoomout th="40" xlink:href="."/> <au:scroll th="60" xlink:href="."/> </au:lbs> </metadata>
<!-- START LAYER popplace --> <ellipse cx="252" cy="130" rx="3" ry="3" fill="#000000" /> <ellipse cx="37" cy="227" rx="3" ry="3" fill="#000000" /> <ellipse cx="127" cy="239" rx="3" ry="3" fill="#000000" /> <ellipse cx="255" cy="282" rx="3" ry="3" fill="#000000" /> <polygon fill="#000000" stroke-width="1" points=" 267,263 270,263 271,260 272,263 275,263 273,265 <ellipse cx="288" cy="247" rx="3" ry="3" fill="#000000" /> <ellipse cx="313" cy="243" rx="3" ry="3" fill="#000000" /> <ellipse cx="328" cy="233" rx="3" ry="3" fill="#000000" /> <ellipse cx="331" cy="245" rx="3" ry="3" fill="#000000" /> <ellipse cx="366" cy="196" rx="3" ry="3" fill="#000000" /> <ellipse cx="161" cy="246" rx="3" ry="3" fill="#000000" /> <ellipse cx="92" cy="208" rx="3" ry="3" fill="#000000" /> <ellipse cx="40" cy="125" rx="3" ry="3" fill="#000000" /> <ellipse cx="108" cy="146" rx="3" ry="3" fill="#000000" /> <text x="40" y="143" font-family="fritqat" font-size="8pt" fill="#000000" stroke="#ffffff" stroke<text x="43" y="121" font-family="fritqat" font-size="8pt" fill="#000000" stroke="#ffffff" stroke<text x="34" y="205" font-family="fritqat" font-size="8pt" fill="#000000" stroke="#ffffff" stroke<text x="164" y="258" font-family="fritqat" font-size="8pt" fill="#000000" stroke="#ffffff" stroke <text x="316" y="190" font-family="fritqat" font-size="8pt" fill="#000000" stroke="#ffffff" stroke <text x="334" y="258" font-family="fritqat" font-size="8pt" fill="#000000" stroke="#ffffff" stroke <text x="249" y="230" font-family="fritqat" font-size="8pt" fill="#000000" stroke="#ffffff" stroke
8.8. SVG
347
x="241" y="242" font-family="fritqat" font-size="8pt" fill="#000000" stroke="#ffffff" stroke x="223" y="260" font-family="fritqat-italic" font-size="8pt" fill="#ff0000" stroke="#ffffff" x="210" y="279" font-family="fritqat" font-size="8pt" fill="#000000" stroke="#ffffff" stroke x="82" y="234" font-family="fritqat" font-size="8pt" fill="#000000" stroke="#ffffff" strokex="40" y="223" font-family="fritqat" font-size="8pt" fill="#000000" stroke="#ffffff" strokex="214" y="125" font-family="fritqat" font-size="8pt" fill="#000000" stroke="#ffffff" stroke
8.9.1 Introduction
MapServer can feed tile-based map clients directly using the CGI tile mode. Tile-based map clients work by dividing the map of the world up into a discrete number of zoom levels, each partitioned into a number of identically sized tiles. Instead of accessing a map by requesting a bounding box, a tile client builds a map by accessing individual tiles.
8.9.2 Conguration
Tile requests are handled by the mapserv CGI program. In order to return tiles in the correct projection, MapServer must be built with the use-proj option turned on. You can check if your version of mapserv has projection support by running it with the -v option and looking for SUPPORTS=PROJ. Example 1. On Unix:
$ ./mapserv -v MapServer version 4.6.1 OUTPUT=GIF OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF OUTPUT=SWF OUTPUT=SVG SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT SUPPORTS=WCS_SERVER INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE DEBUG=MSDEBUG
Example 2. On Windows:
348
C:\apache\cgi-bin> mapserv -v MapServer version 4.6.1 OUTPUT=GIF OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF OUTPUT=SWF OUTPUT=SVG SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT SUPPORTS=WCS_SERVER INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE DEBUG=MSDEBUG
MapServer requires that each LAYER in your map le have a valid PROJECTION block to support reprojection. Because the tile mode uses reprojection, you will have to ensure each LAYER has a valid PROJECTION block. Conguration checklist: MapServer compiled with PROJ support Map le with a PROJECTION dened for every LAYER
8.9.3 Utilization
The MapServer tile support adds three new directives to the CGI interface: mode=tile tells the server to generate tiles based on the other tile mode parameters tilemode=gmap tells the server use the Google Maps tile scheme for the tiles tile=x+y+z tells the server what tile you want to retrieve, using the Google Maps tile addressing system tilemode=ve tells the server use the Virtual Earth tile naming scheme for the tiles tile=10231 tells the server what tile you want to retrieve, using the Virtual Earth tile addressing system About Spherical Mercator Spherical Mercator (also called web mercator by some) is a world projection. All the major tile-based map interfaces (Google Maps, Microsoft Virtual Earth, Yahoo Maps, OpenLayers) use the spherical mercator system to address tiles. A spherical mercator set of tiles has the following properties: The map has been reprojected to mercator using a spherical mercator algorithm There is one tile in the top zoom level, zoom level zero Each successive zoom level (z) has 2^z tiles along each axis Tiles are 256x256 in size Google Maps and Virtual Earth both use spherical mercator as their underlying tile projection, but use different formats to address the individual tiles. Google Maps uses an x, y, zoom format. The zoom indicates which level to pull tiles from, and the x and y indicate while tile in that zoom level to pull. Virtual Earth uses a single string to address each tile. The top zoom level in Virtual Earth has four tiles (equivalent to Googles zoom level 1). The top left tile in the Virtual Earth top zoom level is addessed as 0, top right as 1, bottom left as 2 and bottom right as 3. Each tile the next level is addressed by rst referencing the top level tile that contains it, then its address relative to that tile. So the top left tile in the second zoom level is 00 and the bottom right one is 33. See the Virtual Earth site for more details: http://msdn.microsoft.com/en-us/library/bb545006.aspx
349
Using Google Maps The Google Maps API includes support for using alternative tile sets as overlays, or as alternate base maps. Here is an example of an GTileLayerOverlay
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <title>Google/MapServer Tile Example</title> <script src="http://maps.google.com/maps?file=api&v=2&key=[YOUR KEY HERE]" type="text/javascript"></script> <script type="text/javascript"> function load() { if (GBrowserIsCompatible()) { var urlTemplate = http://localhost/cgi-bin/mapserv?; urlTemplate += map=/var/map.map&; urlTemplate += layers=layer1 layer2&; urlTemplate += mode=tile&; urlTemplate += tilemode=gmap&; urlTemplate += tile={X}+{Y}+{Z}; var myLayer = new GTileLayer(null,0,18,{ tileUrlTemplate:urlTemplate, isPng:true, opacity:1.0 }); var map = new GMap2(document.getElementById("map")); map.addControl(new GLargeMapControl()); map.addControl(new GMapTypeControl()); map.setCenter(new GLatLng(35.35, -80.55), 15); map.addOverlay(new GTileLayerOverlay(myLayer)); } } </script> </head> <body onload="load()" onunload="GUnload()"> <div id="map" style="width: 500px; height: 500px"></div> </body> </html>
Note the format of the tileUrlTemplate: a valid URL, with {X}, {Y} and {Z} substitution tokens that Google Maps will replace with the tile coordinates and zoom level on the y to retrieve tiles from your server. You can also use a MapServer tile layer as an alternate base map:
1 2 3 4 5 6 7 8 9 10
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <title>Google/MapServer Tile Example</title> <script src="http://maps.google.com/maps?file=api&v=2&key=[YOUR KEY HERE]" type="text/javascript"></script> <script type="text/javascript">
350
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
function load() { if (GBrowserIsCompatible()) { var urlTemplate = http://localhost/cgi-bin/mapserv?; urlTemplate += map=/var/map.map&; urlTemplate += layers=layer1 layer2&; urlTemplate += mode=tile&; urlTemplate += tilemode=gmap&; urlTemplate += tile={X}+{Y}+{Z}; var myLayer = new GTileLayer(null,0,18,{ tileUrlTemplate:urlTemplate, isPng:true, opacity:0.3 }); var map = new GMap2(document.getElementById("map")); map.addControl(new GLargeMapControl()); map.addControl(new GMapTypeControl()); map.setCenter(new GLatLng(35.35, -80.55), 15); var myMapType = new GMapType([myLayer], new GMercatorProjection(18), MapServer); map.addMapType(myMapType); } } </script> </head> <body onload="load()" onunload="GUnload()"> <div id="map" style="width: 500px; height: 500px"></div> </body> </html>
The only change from the previous example is that we dont create a GTileLayerOverlay, we create a GMapType, and use addMapType(), instead of addOverlay(). Using Virtual Earth The Virtual Earth API also includes support for using alternative tile sets as overlays, or as alternate base maps. Here is an example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-stri <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <title>Virtual Earth Example</title> <script type="text/javascript" src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.1">< <script type="text/javascript"> var map = null; function OnLoadMap () { map = new VEMap("myMap"); map.LoadMap(); var url url url url url url = "http://localhost/cgi-bin/mapserv?"; += "map=/var/map.map&"; += "mode=tile&"; += "layers=layer1 layer2&"; += "tilemode=ve&"; += "tile=%4";
351
21 22 23 24 25 26 27 28 29 30 31 32
var tileSourceSpec = new VETileSourceSpecification( "myLayer", url ); tileSourceSpec.Opacity = 0.3; map.AddTileLayer(tileSourceSpec, true); } </script> </head> <body onload="OnLoadMap();"> <div id="myMap" style="position:relative; width:500px; height:500px;"></div> </body> </html>
352
CHAPTER
NINE
Table of Contents WMS Server Introduction Setting Up a WMS Server Using MapServer WMS 1.3.0 Support Reference Section FAQ / Common Problems
9.1.1 Introduction
A WMS (or Web Map Server) allows for use of data from several different servers, and enables for the creation of a network of Map Servers from which clients can build customized maps. The following documentation is based on the Open Geospatial Consortiums (OGC) Web Map Server Interfaces Implementation Specication v1.1.1. MapServer v3.5 or more recent is required to implement WMS features. At the time this document was written, MapServer supports the following WMS versions: 1.0.0, 1.0.7, 1.1.0 (a.k.a. 1.0.8), 1.1.1 and 1.3.0 This document assumes that you are already familiar with certain aspects of MapServer: MapServer application development and setting up .map les. 353
Familiarity with the WMS spec would be an asset. A link to the WMS specication document is included in the WMS-Related Information section below. Links to WMS-Related Information MapServer WMS Client Howto WMS 1.1.1 specication WMS 1.3.0 specication Open Geospatial Consortium (OGC) home page WMS-Dev mailing list and archive WMS Cookbook MapServer OGC Web Services Workshop package MapServer Styled Layer Descriptor (SLD) Howto MapServer WMS Time Support Howto How does a WMS Work WMS servers interact with their clients via the HTTP protocol. In most cases, a WMS server is a CGI program. This is also the case with MapServer. The WMS specication denes a number of request types, and for each of them a set of query parameters and associated behaviors. A WMS-compliant server MUST be able to handle at least the following 2 types of WMS requests: 1. GetCapabilities: return an XML document with metadata of the Web Map Servers information 2. GetMap: return an image of a map according to the users needs. And support for the following types is optional: 1. GetFeatureInfo: return info about feature(s) at a query (mouse click) location. MapServer supports 3 types of responses to this request: text/plain output with attribute info. text/html output using MapServer query templates specied in the CLASS template parameter. The MIME type returned by the Class templates defaults to text/html and can be controlled using the metadata wms_feature_info_mime_type. application/vnd.ogc.gml, GML.1 or GML for GML features. 2. DescribeLayer: return an XML description of one or more map layers. To execute this: for vector layers: to have a valid return the user needs to setup wfs_onlineresource (or ows_onlineresource) metadata either at the map level or at the layer level (the layer level metadata is the one which is used if both are dened) for raster layers: the metadata is wcs_onlineresource with the same logic as above. 3. GetLegendGraphic: returns a legend image (icon) for the requested layer, with label(s). More information on this request can be found in the GetLegendGraphic section later in this doc. With respect to MapServer specically, it is the mapserv CGI program that knows how to handle WMS requests. So setting up a WMS server with MapServer involves installing the mapserv CGI program and a setting up a maple with appropriate metadata in it. This is covered in the rest of this document. 354 Chapter 9. OGC Support and Conguration
Example 2. On Windows:
C:\apache\cgi-bin> mapserv -v MapServer version 4.6.1 OUTPUT=GIF OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF OUTPUT=SWF OUTPUT=SVG SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT SUPPORTS=WCS_SERVER INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE DEBUG=MSDEBUG
Setup a Maple For Your WMS Each instance of WMS server that you setup needs to have its own maple. It is just a regular MapServer maple in which some parameters and some metadata entries are mandatory. Most of the metadata is required in order to produce a valid GetCapabilites output. Here is the list of parameters and metadata items that usually optional with MapServer, but are required (or strongly recommended) for a WMS conguration: At the MAP level: Map NAME Map PROJECTION Map Metadata (in the WEB Object): wms_title wms_onlineresource wms_srs (unless PROJECTION object is dened using init=epsg:...) And for each LAYER: Layer NAME Layer PROJECTION Layer METADATA
355
wms_title wms_srs (optional since the layers inherit the maps SRS value) Layer STATUS Layers set to STATUS DEFAULT will always be sent to the client. Layers set to STATUS ON or STATUS OFF can be requested by the client. Layer TEMPLATE (required for GetFeatureInfo requests) Layer DUMP TRUE (only required for GetFeatureInfo GML requests) Lets go through each of these paramters in more detail: Map Name and wms_title: WMS Capabilities requires a Name and a Title tag for every layer. The Maps NAME and wms_title metadata will be used to set the root layers name and title in the GetCapabilities XML output. The root layer in the WMS context corresponds to the whole maple. Layer Name and wms_title metadata: Every individual layer needs its own unique name and title. Layer names are also used in GetMap and GetFeatureInfo requests to refer to layers that should be included in the map output and in the query. Layer names must start with a letter when setting up a WMS server (layer names should not start with a digit or have spaces in them). Map PROJECTION and wms_srs metadata: WMS servers have to advertise the projection in which they are able to serve data using EPSG projection codes (see http://www.epsg.org/ for more background on EPSG codes). Recent versions of the PROJ4 library come with a table of EPSG initialization codes and allow users to dene a projection like this:
PROJECTION "init=epsg:4269" END
(Note that epsg has to be in lowercase when used in the PROJ4 init directive.) If the MAP PROJECTION block is provided in the format init=epsg:xxxx then MapServer will also use this information to generate a <BoundingBox> tag for the top-level layer in the WMS capabilities document. Note that the BoundingBox is an optional element of WMS capabilities, but it is good practice to allow MapServer to include it when possible. The above is sufcient for MapServer to recognize the EPSG code and include it in SRS tags in the capabilities output (wms_srs metadata is not required in this case). However, it is often impossible to nd an EPSG code to match the projection of your data. In those cases, the wms_srs metadata is used to list one or more EPSG codes that the data can be served in, and the PROJECTION object contains the real PROJ4 denition of the datas projection. Here is an example of a server whose data is in an Lambert Conformal Conic projection (42304). Its capabilities output will advertize EPSG:4269 and EPSG:4326 projections (lat/lon), but the PROJECTION object is set to the real projection that the data is in:
NAME "DEMO" ... WEB ... METADATA
356
"wms_title" "wms_onlineresource" "wms_srs" END END PROJECTION "init=epsg:42304" END ... END
In addition to EPSG:xxxx projections, a WMS server can advertize projections in the AUTO:xxxx namespace. AUTO projections 42001 to 42005 are internally supported by MapServer. However, AUTO projections are useful only with smart WMS clients, since the client needs to dene the projection parameters in the WMS requests to the server. For more information see Annex E of the WMS 1.1.1 specication and section 6.5.5.2 of the same document. See also the FAQ on AUTO projections at the end of this document. Layer PROJECTION and wms_srs metadata: By default layers inherit the SRS of their parent layer (the maps PROJECTION in the MapServer case). For this reason it is not necessary (but still strongly recommended) to provide PROJECTION and wms_srs for every layer. If a layer PROJECTION is not provided then the top-level map projecion will be assumed. Layer PROJECTION and wms_srs metadata are dened exactly the same way as the maps PROJECTION and wms_srs metadata. For vector layers, if a PROJECTION block is provided in the format init=epsg:xxxx then MapServer will also use this information to generate a <BoundingBox> tag for this layer in the WMS capabilities document. Note that the BoundingBox is an optional element of WMS capabilities, but it is good practice to allow MapServer to include it when possible. wms_onlineresource metadata: The wms_onlineresource metadata is set in the maps web object metadata and species the URL that should be used to access your server. This is required for the GetCapabilities output. If wms_onlineresource is not provided then MapServer will try to provide a default one using the script name and hostname, but you shouldnt count on that too much. It is strongly recommended that you provide the wms_onlineresource metadata. See section 6.2.2 of the WMS 1.1.1 specication for the whole story about the online resource URL. Basically, what you need is a complete HTTP URL including the http:// prex, hostname, script name, potentially a map= parameter, and and terminated by ? or &. Here is a valid online resource URL:
http://my.host.com/cgi-bin/mapserv?map=mywms.map&
By creating a wrapper script on the server it is possible to hide the map= parameter from the URL and then your servers online resource URL could be something like:
http://my.host.com/cgi-bin/mywms?
This is covered in more detail in the section More About the Online Resource URL below. Conguring for GetFeatureInfo Requests: You must set the layer TEMPLATE parameter for the layer to be queryable by GetFeatureInfo requests. For requests of type text/html you should also set the layer HEADER and FOOTER parameters. For GetFeatureInfo requests of GML you must set the layer to DUMP TRUE in the maple. As of MapServer 4.6 you must also set the gml_* metadata for the layer attributes to be served (see the Layer Object metadata in the Reference Section later in this document). 9.1. WMS Server 357
Here are working examples of GetFeatureInfo requests: text/plain / text/html / gml (for gml, your browser might ask you to save the le, if so save it locally as a .gml le and view it in a text editor) Test Your WMS Server
Here is a working GetCapabilities request (note that the SERVICE parameter is required for all GetCapabilities requests): http://www2.dmsolutions.ca/cgi-bin/mswms_gmap?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetCapabilities This should return a document of MIME type application/vnd.ogc.wms_xml, so your browser is likely going to prompt you to save the le. Save it and open it in a text editor (Emacs, Notepad, etc.), and you will see the returned XML from the WMS server. If you get an error message in the XML output then take necessary actions. Common problems and solutions are listed in the FAQ at the end of this document. If everything went well, you should have a complete XML capabilities document. Search it for the word WARNING... MapServer inserts XML comments starting with <!WARNING: in the XML output if it detects missing maple parameters or metadata items. If you notice any warning in your XML output then you have to x all of them before you can register your server with a WMS client, otherwise things are likely not going to work. Note that when a request happens, it is passed through WMS, WFS, and WCS in MapServer (in that order) until one of the services respond to it.
358
HEIGHT=output_height: Height in pixels of map picture. FORMAT=output_format: Output format of map. Note: WMS Servers only advertise supported formats that are part of the gd / gdal libraries. A valid example would therefore be:
http://my.host.com/cgi-bin/mapserv?map=mywms.map&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&LAYERS=prov
However, some people will argue that the above URL contains mandatory vendor-specic parameters and that this is illegal. First we would like to point that map=... is not considered a vendor-specic parameter in this case since it is part of the Online Resource URL which is dened as an opaque string terminated by ? or & (See WMS 1.1.1 section 6.2.2). But anyway, even if its valid, the above URL is still ugly. And you might want to use a nicer URL for your WMS Online Resource URL. Here are some suggestions: 1. On Unix servers, you can setup a wrapper shell script that sets the MS_MAPFILE environment variable and then passes control to the mapserv executable... that results on a cleaner OnlineResource URL:
#! /bin/sh MS_MAPFILE=/path/to/demo.map export MS_MAPFILE /path/to/mapserv
359
1. Another option is to use the setenvif feature of Apache: use symbolic links that all point to a same mapserv binary, and then for each symbolic link test the url, and set the MAP environment accordingly. For Windows and Apache users the steps are as follows (this requires Apache 1.3 or newer): Copy mapserv.exe to a new name for your WMS, such as mywms.exe. In httpd.conf, add:
SetEnvIf Request_URI "/cgi-bin/mywms" MS_MAPFILE=/path/to/mymap.map
2. On IIS servers (Windows), you can use the following ASP script: Note: The script below, while functional, is intended only as an example of using ASP to lter MapServer requests. Using ASP in a production WMS server will likely require additional ASP especially in the area of error handling and setting timeouts.*
<% Server.ScriptTimeout = 360 Select Case Request.ServerVariables("REQUEST_METHOD") Case "GET" strRequest = Request.QueryString Case "POST" strRequest = Request.Form End Select
strURL = "http://myserver/cgi-bin/mapserv.exe?map=C:\Inetpub\wwwroot\workshop\itasca.map&" & s Dim objHTTP Set objHTTP = Server.CreateObject("MSXML2.ServerXMLHTTP") objHTTP.open "GET", strURL, false objHTTP.send "" Response.ContentType = objHTTP.getResponseHeader("content-type") Response.BinaryWrite objHTTP.responseBody Set objHTTP = Nothing %>
3. Some OGC services (WFS, SOS) support both GET and POST requests. Here, you can use a minimal MapScript WxS wrapper. Heres a Python example:
#!/usr/bin/python import mapscript req = mapscript.OWSRequest() req.loadParams() map = mapscript.mapObj(/path/to/config.map) map.OWSDispatch(req)
GetLegendGraphic Request This request returns a legend image (icon) for the specied layer. The request will draw an icon and a label for all classes dened on the layer.
360
Requirements
The following are required in the WMS server maple to enable this request: a LEGEND object. a CLASS object for each layer. a NAME in the CLASS object. the STATUS of each LAYER must be set to ON.
Parameters
The following are valid parameters for this request: LAYER - (Required) Name of the WMS layer to return the legend image of. Note that this is the <Name> parameter of the Layer in the GetCapabilities. FORMAT - (Required) Format of the legend image (e.g. image/png). WIDTH - (Optional) Width of the legend image. Note that the Width parameter is only used when the Rule parameter is also used in the request. HEIGHT - (Optional) Height of the legend image. Note that the Height parameter is only used when the Rule parameter is also used in the request. SLD - (Optional) The URL to the SLD. Applies the SLD on the layer and the legend is drawn after the SLD is applied (using the classes speced by the SLD). Note here that you need to put a <Name>class1</Name> inside the Rule element so that a class name is created from the SLD and therefore a correct legend image. SLD_BODY - (Optional) The body (code) of the SLD, instead of specifying a URL (as in the SLD parameter). SCALE - (Optional) Specify a scale so that only layers that fall into that scale will have a legend. RULE - (Optional) Specify the name of the CLASS to generate the legend image for (as opposed to generating an icon and label for ALL classes for the layer). Note: All rules that are used to draw the legend in normal CGI mode apply here. See the CGI Reference doc if necessary. The CLASS objects KEYIMAGE parameter can also be used to specify a legend image for a CLASS. See the MapFile Reference doc if necessary. Example Request An example request might look like:
http://127.0.0.1/cgi-bin/mapserv.exe?SERVICE=WMS&VERSION=1.1.1&layer=park& REQUEST=getlegendgraphic&FORMAT=image/png
361
Major features related to the WMS 1.3.0 support Support WMS 1.3.0 basic operations: GetCapabilities, GetMap and GetFeatureInfo. Implement the Styled Layer Descriptor prole of the Web Map Service Implementation Specication. This specication extends the WMS 1.3.0 and allows to advertise styling capabilities (Styled Layer Descriptor (SLD) support). It also denes two addition operations GetLegendGraphic and DescribeLayer Implement the Symbology Encoding Implementation Specication, which is the new version of the SLD. Read support was added for Point, Line, Polygon, Raster symbolizers Upgrade the generation of SLD to version 1.1.0 (SLD generated through through the GetStyles operation or through MapScript) Coordinate Systems and Axis Orientation The most notable changes introduced in WMS 1.3.0 are the: the axis changes the introduction of new coordinate reference systems the use of CRS parameter (instead of SRS) The axis order in previous versions of the WMS specications was to always use easting (x or lon ) and northing (y or lat). WMS 1.3.0 species that, depending on the particular CRS, the x axis may or may not be oriented West-to-East, and the y axis may or may not be oriented South-to-North. The WMS portrayal operation shall account for axis order. This affects some of the EPSG codes that were commonly used such as ESPG:4326. The current implementation makes sure that coordinates passed to the server (as part of the GetMap BBOX parameter) as well as those advertised in the capabilities document reect the inverse axe orders for EPSG codes between 4000 and 5000. In addition, the WMS 1.3.0 denes a series of new coordinate system. These are the once that are currently supported in MapServer: CRS:84 (WGS 84 longitude-latitude) CRS:83 (NAD83 longitude-latitude) CRS:27 (NAD27 longitude-latitude) AUTO2:420001 (WGS 84 / Auto UTM ) AUTO2:420002 (WGS 84 / Auto Tr. Mercator) AUTO2:420003 (WGS 84 / Auto Orthographic) AUTO2:420004 (WGS 84 / Auto Equirectangular) AUTO2:420005 (WGS 84 / Auto Mollweide) Example of requests Users can use the CRS:84 coordinate system and order the BBOX coordinates as long/lat: ...&CRS=CRS:84&BBOX=-180.0,-90.0,180.0,90.0&... -
Users can also use the ESPG:4326 coordinates and use the axis odering of lat/long: - ...&EPSG:4326&BBOX=-90.0,180.0,90,180.0&...
362
Some Missing features WMS 1.3.0 Post request should be an XML document containing the different operations and parameters. SLD documents containing elements form the Feature Encoding 1.1 specication could potentially use ESPG projections with some lters. It is not yet clear nor implemented if the axis ordering should be taken into account in these specic cases. OCG compliance tests As of version 5.4, MapServer passes all the basic and query tests of the OGC CITE test suite for WMS 1.3.0.
363
WMS TAG Name: Abstract (WMS1.1.1, sect. 7.1.4.2) Description: (Optional) A blurb of text providing more information about the WMS server. wms_accessconstraints WMS TAG Name: AccessConstraints (WMS1.1.1, sect. 7.1.4.2) Description: (Optional) Access constraints information. Use the reserved word none if there are no access constraints. wms_addresstype, wms_address, wms_city, wms_stateorprovince, wms_postcode, wms_country WMS TAG Name: ContactAddress and family (WMS1.1.1, sect. 7.1.4.2) Description: Optional contact address information. If provided then all six metadata items are required. wms_attribution_logourl_format Description: (Optional) The MIME type of the logo image. (e.g. image/png). Note that the other wms_attribution_logourl_* metadata must also be specied. refer to section 7.1.4.5.11 of the WMS 1.1.1 spec. wms_attribution_logourl_height Description: (Optional) Height of the logo image in pixels. Note that the other wms_attribution_logourl_* metadata must also be specied. refer to section 7.1.4.5.11 of the WMS 1.1.1 spec. wms_attribution_logourl_href Description: (Optional) URL of the logo image. Note that the other wms_attribution_logourl_* metadata must also be specied. refer to section 7.1.4.5.11 of the WMS 1.1.1 spec. wms_attribution_logourl_width Description: (Optional) Width of the logo image in pixels. Note that the other wms_attribution_logourl_* metadata must also be specied. refer to section 7.1.4.5.11 of the WMS 1.1.1 spec. wms_attribution_onlineresource Description: (Optional) The data providers URL. refer to section 7.1.4.5.11 of the WMS 1.1.1 spec. wms_attribution_title Description: (Optional) Human-readable string naming the data provider. refer to section 7.1.4.5.11 of the WMS 1.1.1 spec. 364 Chapter 9. OGC Support and Conguration
wms_contactelectronicmailaddress WMS TAG Name: ContactElectronicMailAddress (WMS1.1.1, sect. 7.1.4.2) Description: Optional contact Email address. wms_contactfacsimiletelephone WMS TAG Name: ContactFacsimileTelephone (WMS1.1.1, sect. 7.1.4.2) Description: Optional contact facsimile telephone number. wms_contactperson, wms_contactorganization, wms_contactposition WMS TAG Name: ContactInformation, ContactPerson, ContactOrganization, ContactPosition (WMS1.1.1, sect. 7.1.4.2) Description: Optional contact information. If provided then all three metadata items are required. wms_contactvoicetelephone WMS TAG Name: ContactVoiceTelephone (WMS1.1.1, sect. 7.1.4.2) Description: Optional contact voice telephone number. wms_encoding WMS TAG Name: Encoding Description: Optional XML capabilities encoding type. The default is ISO-8859-1. wms_feature_info_mime_type WMS TAG Name: Feature_info_mime_type Description: Used to specify an additional MIME type that can be used when responding to the GetFeature request. For example if you want to use the layers HTML template as a base for its response, you need to add WMS_FEATURE_INFO_MIME_TYPE text/html. Setting this will have the effect of advertizing text/html as one of the MIME types supported for a GetFeature request. You also need to make sure that the layer points to a valid html template. The client can then call the server with INFO_FORMAT=text/html. If not specied, MapServer by default has text/plain and GML implemented. Note that for GML to be returned the layer in the wms-server maple must be set to DUMP TRUE. wms_fees WMS TAG Name: Fees (WMS1.1.1, sect. 7.1.4.2) Description: (Optional) Fees information. Use the reserved word none if there are no fees. wms_keywordlist WMS TAG Name: KeywordList (WMS1.1.1, sect. 7.1.4.2) 9.1. WMS Server 365
Description: (Optional) A comma-separated list of keywords or keyword phrases to help catalog searching. As of WMS 1.1.0 no controlled vocabulary has been dened. wms_onlineresource WMS TAG Name: OnlineResource (WMS1.1.1, sect. 6.2.2) Description: (Recommended) The URL that will be used to access this WMS server. This value is used in the GetCapabilities response. See Also: sections Setup a Maple / wms_onlineresource metadata and More About the Online Resource URL above. wms_resx, wms_resy WMS TAG Name: BoundingBox (WMS1.1.1, sect. 6.5.6) Description: (Optional) Used in the BoundingBox tag to provide info about spatial resolution of the data, values are in map projection units. wms_service_onlineresource Description: (Optional) Top-level onlineresource URL. MapServer uses the onlineresource metadata (if provided) in the following order: 1. wms_service_onlineresource 2. ows_service_onlineresource 3. wms_onlineresource (or automatically generated URL, see the onlineresource section of this document) wms_srs WMS TAG Name: SRS (WMS1.1.1, sect. 6.5.5) Description: (Recommended) Contains a list of EPSG projection codes that should be advertized as being available for all layers in this server. The value can contain one or more EPSG:<code> pairs separated by spaces (e.g. EPSG:4269 EPSG:4326) This value should be upper case (EPSG:42304.....not epsg:42304) to avoid problems with case sensitive platforms. See Also: section Setup a Maple / Map PROJECTION and wms_srs metadata above. wms_timeformat Description: The time format to be used when a request is sent. (e.g. wms_timeformat %Y-%m-%d %H, %Y-%m-%d %H:%M). Please see the WMS Time Support Howto for more information. wms_title WMS TAG Name: Title (WMS1.1.1, sect. 7.1.4.1) Description: (Required) A human-readable name for this Layer.
366
Layer Object Metadata gml_exclude_items Description: (Optional, applies only to GetFeatureInfo GML requests) A comma delimited list of items to exclude. As of MapServer 4.6, you can control how many attributes (elds) you expose for your data layer with metadata. The previous behaviour was simply to expose all attributes all of the time. The default is to expose no attributes at all. An example excluding a specic eld would be:
"gml_include_items" "all" "gml_exclude_items" "Phonenum"
gml_groups Description: (Optional, applies only to GetFeatureInfo GML requests) A comma delimited list of group names for the layer. gml_[group name]_group Description: (Optional, applies only to GetFeatureInfo GML requests) A comma delimited list of attributes in the group. Here is an example:
"gml_include_items" "all" "gml_groups" "display" "gml_display_group" "Name_e,Name_f"
gml_include_items Description: (Optional, applies only to GetFeatureInfo GML requests) A comma delimited list of items to include, or keyword all. As of MapServer 4.6, you can control how many attributes (elds) you expose for your data layer with this metadata. The previous behaviour was simply to expose all attributes all of the time. You can enable full exposure by using the keyword all, such as:
"gml_include_items" "all"
You can specify a list of attributes (elds) for partial exposure, such as:
"gml_include_items" "Name,ID"
The new default behaviour is to expose no attributes at all. gml_[item name]_alias Description: (Optional, applies only to GetFeatureInfo GML requests) An alias for an attributes name. The served GML will refer to this attribute by the alias. Here is an example:
"gml_province_alias" "prov"
gml_[item name]_type Description: (Optional, applies only to GetFeatureInfo GML requests) Species the type of the attribute. Valid values are Integer|Real|Character|Date|Boolean.
367
gml_xml_items Description: (Optional, applies only to GetFeatureInfo GML requests) A comma delimited list of items that should not be XML-encoded. wms_abstract Same as wms_abstract in the Web Object. wms_attribution_logourl_format Description: (Optional) The MIME type of the logo image. (e.g. image/png). Note that the other wms_attribution_logourl_* metadata must also be specied. refer to section 7.1.4.5.11 of the WMS 1.1.1 spec. wms_attribution_logourl_height Description: (Optional) Height of the logo image in pixels. Note that the other wms_attribution_logourl_* metadata must also be specied. refer to section 7.1.4.5.11 of the WMS 1.1.1 spec. wms_attribution_logourl_href Description: (Optional) URL of the logo image. Note that the other wms_attribution_logourl_* metadata must also be specied. refer to section 7.1.4.5.11 of the WMS 1.1.1 spec. wms_attribution_logourl_width Description: (Optional) Width of the logo image in pixels. Note that the other wms_attribution_logourl_* metadata must also be specied. refer to section 7.1.4.5.11 of the WMS 1.1.1 spec. wms_attribution_onlineresource Description: (Optional) The data providers URL. refer to section 7.1.4.5.11 of the WMS 1.1.1 spec. wms_attribution_title Description: (Optional) Human-readable string naming the data provider. refer to section 7.1.4.5.11 of the WMS 1.1.1 spec. wms_dataurl_format Description: (Optional) Non-standardized le format of the metadata. The layer metadata wms_dataurl_href must also be specied. refer to section 7.1.4.5.14 of the WMS 1.1.1 spec. 368 Chapter 9. OGC Support and Conguration
wms_dataurl_href Description: (Optional) The URL to the layers metadata. The layer metadata wms_dataurl_format must also be specied. refer to section 7.1.4.5.14 of the WMS 1.1.1 spec. wms_extent WMS TAG Name: BoundingBox (WMS1.1.1, sect. 6.5.6) Description: (Optional) Used for the layers BoundingBox tag for cases where it is impossible (or very inefcient) for MapServer to probe the data source to gure its extents. The value for this metadata is minx miny maxx maxy separated by spaces, with the values in the layers projection units. If wms_extent is provided then it has priority and MapServer will NOT try to read the source les extents. For Rasters served through WMS, MapServer can now use the wms_extent metadata parameter to register the image. If a .wld le cannot be found, MapServer will then look for the wms_extent metadata parameter and use the extents of the image and the size of the image for georegistration. wms_group_abstract Description: (Optional) A blurb of text providing more information about the group. Only one layer for the group needs to contain wms_group_abstract, MapServer will nd and use the value. The value found for the rst layer in the group is used. So if multiple layers have wms_group_abstract set then only the rst value is used. wms_group_title WMS TAG Name: Group_title (WMS1.1.1, sect. 7.1.4.1) Description: (Optional) A human-readable name for the group that this layer belongs to. Only one layer for the group needs to contain wms_group_title, MapServer will nd and use the value. The value found for the rst layer in the group is used. So if multiple layers have wms_group_title set then only the rst value is used. wms_keywordlist Same as wms_keywordlist in the Web Object . wms_layer_group Description: (Optional) Can be used to assign a layer to a number of hierarchically nested groups. This grouped hierarchy will be expressed in the capabilities. WMS_LAYER_GROUP is different from the GROUP keyword in that it does not publish the name of the group in the capabilities, only the title. As a consequence the groups set with WMS_LAYER_GROUP can not be requested with a GetMap or GetFeatureInfo request (see section 7.1.4.5.2 of the WMS implementation specication version 1.1.1. (OGC 01-068r2)). Another difference is that GROUP does not support nested groups. The purpose of this metadata setting is to enable making a WMS client aware of layer grouping. All group names should be preceded by a forward slash (/). It is not allowed to use both the WMS_LAYER_GROUP setting and the GROUP keyword for a single layer.
369
LAYER NAME "mylayer" DATA "mylayer" TYPE LINE CLASS STYLE COLOR 100 100 255 END END METADATA "WMS_LAYER_GROUP" "/rootgroup/subgroup" END END
wms_metadataurl_format Description: (Optional) The le format MIME type of the metadata record (e.g. text/plain). The layer metadata wms_metadataurl_type and wms_metadataurl_href must also be specied. refer to section 7.1.4.5.10 of the WMS 1.1.1 spec. wms_metadataurl_href Description: (Optional) The URL to the layers metadata. The layer metadata wms_metadataurl_format and wms_metadataurl_type must also be specied. refer to section 7.1.4.5.10 of the WMS 1.1.1 spec. wms_metadataurl_type Description: (Optional) The standard to which the metadata complies. Currently only two types are valid: TC211 which refers to [ISO 19115], and FGDC which refers to [FGDC-STD-001-1988]. The layer metadata wms_metadataurl_format and wms_metadataurl_href must also be specied. refer to section 7.1.4.5.10 of the WMS 1.1.1 spec. wms_opaque WMS TAG Name: Opaque (WMS1.1.1, sect. 7.1.4.6.3) Description: (Optional) Set this metadata to 1 to indicate that the layer represents an area-lling coverage of space (e.g. a bathymetry and elevation layer). This should be taken by the client as a hint that this layer should be placed at the bottom of the stack of layers. wms_srs Same as wms_srs in the Web Object . wms_style Description: (Optional) The LegendURL style name. Requires the following metadata: wms_style_<styles_name>_width, wms_style_<styles_name>_legendurl_height, wms_style_<styles_name>_legendurl_format, wms_style_<styles_name>_legendurl_href refer to section 7.1.4.5.4 of the WMS 1.1.1 spec. 370 Chapter 9. OGC Support and Conguration
wms_style_<styles_name>_legendurl_height Description: (Optional) The height of the legend image in pixels. Requires the following metadata: wms_style_<styles_name>_width, wms_style, wms_style_<styles_name>_legendurl_format, wms_style_<styles_name>_legendurl_href. refer to section 7.1.4.5.4 of the WMS 1.1.1 spec. wms_style_<styles_name>_legendurl_href Description: (Optional) The URL to the layers legend. Requires the following metadata: wms_style_<styles_name>_width, wms_style_<styles_name>_legendurl_height, wms_style_<styles_name>_legendurl_format, wms_style. refer to section 7.1.4.5.4 of the WMS 1.1.1 spec. wms_style_<styles_name>_legendurl_format Description: (Optional) The le format MIME type of the legend image. Requires the following metadata: wms_style_<styles_name>_width, wms_style_<styles_name>_legendurl_height, wms_style, wms_style_<styles_name>_legendurl_href. refer to section 7.1.4.5.4 of the WMS 1.1.1 spec. wms_style_<styles_name>_legendurl_width Description: (Optional) The width of the legend image in pixels. Requires the following metadata: wms_style_<styles_name>_format, wms_style_<styles_name>_legendurl_height, wms_style, wms_style_<styles_name>_legendurl_href. refer to section 7.1.4.5.4 of the WMS 1.1.1 spec. wms_timedefault Description: (Optional for Time Support) This value is used if it is dened and the Time value is missing in the request. Please see the WMS Time Support Howto for more information. wms_timeextent Description: (Mandatory for Time Support) This is used in the capabilities to return the valid time values for the layer. The value dened here should be a valid time range. Please see the WMS Time Support Howto for more information. wms_timeitem Description: (Mandatory for Time Support) This is the name of the eld in the DB that contains the time values. Please see the WMS Time Support Howto for more information. wms_title Same as wms_title in the Web Object. Sample WMS Server Maple The following is a very basic WMS Server maple:
371
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
NAME "WMS-test" STATUS ON SIZE 400 300 SYMBOLSET ../ e t c / s y m b o l s . s y m EXTENT -2200000 -712631 3072800 3840000 UNITS METERS SHAPEPATH "../data" IMAGECOLOR 255 255 255 FONTSET ../ e t c / f o n t s . t x t WEB IMAGEPATH "/ms4w/tmp/ms_tmp/" IMAGEURL "/ms_tmp/" METADATA "wms_title" "WMS Demo Server" ##required "wms_onlineresource" "http://yourpath/cgi-bin/mapserv.exe?" "wms_srs" "EPSG:42304 EPSG:42101 EPSG:4269 EPSG:4326" END END PROJECTION "init=epsg:42304" END
##required ##recommended
##required
# # Start of layer definitions # LAYER NAME "park" METADATA "wms_title" "Parks" ##required END TYPE POLYGON STATUS OFF DATA p a r k PROJECTION "init=epsg:42304" ##recommended END CLASS NAME "Parks" STYLE COLOR 200 255 0 OUTLINECOLOR 120 120 120 END END END # Layer LAYER NAME p o p p l a c e METADATA "wms_title" "Cities" ##required END TYPE POINT STATUS ON DATA p o p p l a c e PROJECTION "init=epsg:42304" ##recommended
372
59 60 61 62 63 64 65 66 67 68 69 70
END CLASS NAME "Cities" STYLE SYMBOL 2 SIZE 8 COLOR 0 0 0 END END END # Layer END # Map File
Q My WMS server produces the error msProcessProjection(): no system list, errno: .. A Thats likely PROJ4 complaining that it cannot nd the epsg projection denition le. Make sure you have installed PROJ 4.4.3 or more recent and that the epsg le is installed at the right location. On Unix it should be under /usr/local/share/proj/, and on Windows PROJ looks for it under C:/PROJ/ or C:/PROJ/NAD (depending on the installation). You should also check the error documentation to see if your exact error is discussed. If you dont have the epsg le then you can get it as part of the PROJ4 distribution at http://trac.osgeo.org/proj/ or you can download it at http://www.maptools.org/dl/proj4-epsg.zip.
Q How do AUTO projections work? A When a WMS client calls a WMS server with an auto projection, it has to specify the SRS in the form: AUTO: proj_id,unit_id,lon0,lat0 where: proj_id is one of 42001, 42002, 42003, 42004, or 42005 (only ve auto projections are currently dened). unit_id is always 9001 for meters. (It is uncertain whether anyone supports any other units.) lon0 and lat0 are the coordinates to use as the origin for the projection. When using an AUTO projection in WMS GetCapabilities, you include only the AUTO:42003 string in your wms_srs metadata, you do not include the projection parameters. Those are added by the application (client) at runtime depending on the map view. For example:
373
NAME "DEMO" ... WEB ... METADATA "wms_title" "wms_onlineresource" "wms_srs" END END
Table of Contents WMS Client Introduction Compilation / Installation MapFile Conguration Limitations/TODO
9.2.1 Introduction
A WMS (or Web Map Server) allows for use of data from several different servers, and enables for the creation of a network of Map Servers from which clients can build customized maps. The following document contains information about using MapServers WMS connection type to include layers from remote WMS servers in MapServer applications. This document assumes that you are already familiar with certain aspects of MapServer: MapServer application development and setting up .map les. Familiarity with the WMS spec would be an asset. A link to the WMS specication document is included below. WMS-Related Information MapServer WMS Server HowTo WMS 1.1.1 specication MapServer OGC Web Services Workshop package 374 Chapter 9. OGC Support and Conguration
Install Optional PROJ4 EPSG Codes (Note: installing these PROJ4 codes is optional, install only if you need them) 9.2. WMS Client 375
Some Canadian WMS servers will use some non-standard projection codes not included in the default distribution (e.g. EPSG:42304, etc.). If you are planning to use MapServer to connect to Canadian WMS servers then you might want to download a custom Canadian epsg le with those codes, and unzip it in the /usr/local/share/proj directory (or /ms4w/proj/nad/ for MS4W users). Finally, ESRI WMS servers also come with their own series of non-standard codes. If you are planning to connect to ESRI WMS servers then you might want to get a custom epsg le that contains the canadian codes and the ESRI codes, allowing you to connect to any server. Download the custom ESRI epsg le and unzip it in /usr/local/share/proj (or /ms4w/proj/nad/ for MS4W users). Q But why not always install and distribute the proj4-epsg-with-42xxx-and-esri.zip le then since its more complete? A You should install only the epsg projection codes that you need, the epsg le with all ESRI codes in it is 20% larger than the default one, so it comes with extra overhead that you may not need. Also note that when creating WMS servers, in order to be really interoperable, only EPSG codes that are part of the standard EPSG list should be used. i.e. it is a bad idea for interoperability to use the custom canadian codes or the custom ESRI codes and we do not want to promote their use too much.
If you want to keep this temporary le for debugging purposes, you should add the following statement to the LAYER object of your maple:
LAYER .... DEBUG ON ... END
376
Adding a WMS Layer WMS layers are accessed via the WMS connection type in the Maple. Here is an example of a layer using this connection type:
LAYER NAME "prov_bound" TYPE RASTER STATUS ON CONNECTION "http://www2.dmsolutions.ca/cgi-bin/mswms_gmap?" CONNECTIONTYPE WMS METADATA "wms_srs" "EPSG:42304" "wms_name" "prov_bound" "wms_server_version" "1.1.1" "wms_format" "image/gif" END END
PROJECTION object - it is optional at this point. MapServer will create one internally if needed. wms_auth_username metadata - msEncrypt-style authorization string. Empty strings are also accepted.
METADATA "wms_auth_username" "foo" "wms_auth_password" "{FF88CFDAAE1A5E33}" END
wms_auth_type metadata - Authorization type. Supported types include: basic digest ntlm any (the underlying http library picks the best among the opotions supported by the remote server) anysafe (the underlying http library picks only safe methods among the options supported by the remote server)
wms_connectiontimeout metadata - the maximum time to wait for a remote WMS layer to load, set in seconds (default is 30 seconds). This metadata can be added at the layer level so that it affects only that layer, or it can be added at the map level (in the web object) so that it affects all of the layers. Note that wms_connectiontimeout at the layer level has priority over the map level.
METADATA ... "wms_connectiontimeout" "60" ... END
wms_exceptions_format metadata - set the format for exceptions (as of MapServer 4.6). MapServer defaults to application/vnd.ogc.se_inimage (the exception will be in a picture format). You can check the GetCapabilities of the server to see what formats are available for exceptions. The application/vnd.ogc.se_inimage exception format is actually a non-required exception format in the WMS 1.1.1 spec, so there are servers out there which dont support this format. In that case you would use:
LAYER ... METADATA "wms_exceptions_format " a p p l i c a t i on/ v n d . o g c . s e _ x m l " END ... END
378
wms_force_separate_request metadata - set this to 1 to force this WMS layer to be requested using its own separate GetMap request. By default MapServer will try to merge multiple adjacent WMS layers from the same server into a single multi-layer GetMap request to reduce the load on remote servers and improve response time. This metadata is used to bypass that behavior. wms_formatlist metadata - comma-separated list of image formats supported by the remote WMS server. Note that wms_formatlist is used only if wms_format is not set. If both wms_format and wms_formatlist are provided then wms_format takes precedence. wms_latlonboundingbox metadata - the bounding box of this layer in geographic coordinates in the format lon_min lat_min lon_max lat_max. If it is set then MapServer will request the layer only when the map view overlaps that bounding box. You normally get this from the servers capabilities output.
METADATA "wms_latlonboundingbox" "-124 48 -123 49" END
wms_proxy_auth_type metadata - the authorization type to use for a proxy connection. Supported types include: basic digest ntlm any (the underlying http library picks the best among the opotions supported by the remote server) anysafe (the underlying http library picks only safe methods among the options supported by the remote server)
METADATA "wms_proxy_auth_type" "ntlm" END
wms_proxy_host metadata - the hostname of the proxy to use, in dot-quad format, with an optional port component (e.g. 192.168.2.10:8080).
METADATA "wms_proxy_host" "192.168.2.10" END
wms_proxy_type metadata - the type of the proxy connection. Valid values are http and socks5, which are case sensitive.
METADATA "wms_proxy_type" "http" END
wms_proxy_username metadata - msEncrypt-style string for a proxy connection. Empty strings are also accepted.
379
wms_sld_body metadata - can be used to specify an inline SLD document. wms_sld_url metadata - can be used to specify a link to an SLD document. wms_style metadata - name of style to use for the STYLES parameter in GetMap requests for this layer. wms_style_<stylename>_sld metadata URL of a SLD to use in GetMap requests. Replace <stylename> in the metadta name with the name of the style to which the SLD applies.
METADATA ... "wms_style" "wms_style_mystyle_sld" ... END
"mystyle" "http://my.host.com/mysld.xml"
For more information on SLDs in MapServer see the SLD HowTo document. wms_time metadata - value to use for the TIME parameter in GetMap requests for this layer. Please see the WMS Time HowTo for more information. wms_bgcolor metadata - species the color to be used as the background of the map. The general format of BGCOLOR is a hexadecimal encoding of an RGB value where two hexadecimal characters are used for each of Red, Green, and Blue color values. The values can range between 00 and FF for each (0 and 255, base 10). The format is 0xRRGGBB; either upper or lower case characters are allowed for RR, GG, and BB values. The 0x prex shall have a lower case x. wms_transparent metadata - species whether the map background is to be made transparent or not. TRANSPARENT can take on two values, TRUE or FALSE. If not specied, MapServer sets default to TRUE Note: Note that each of the above metadata can also be referred to as ows_* instead of wms_*. MapServer tries the wms_* metadata rst, and if not found it tries the corresponding ows_* name. Using this reduces the amount of duplication in maples that support multiple OGC interfaces since ows_* metadata can be used almost everywhere for common metadata items shared by multiple OGC interfaces.
Old CONNECTION parameter format from version 3.5 and 3.6 (deprecated)
In MapServer version 3.5 and 3.6, the CONNECTION parameter had to include at a minimum the VERSION, LAYERS, FORMAT and TRANSPARENT WMS parameters. This mode of operation is still supported but is deprecated and you are encouraged to use metadata items for those parameters as documented in the previous section above. Here is an example of a layer denition using this deprecated CONNECTION parameter format:
LAYER NAME "bathymetry" METADATA "wms_title" "Elevation/Bathymetry" "wms_srs" "EPSG:4269 EPSG:4326" END TYPE RASTER
380
9.2.4 Limitations/TODO
1. GetFeatureInfo is not fully supported since the output of getFeatureInfo is left to the discretion of the remote server. A method layer.getWMSFeatureInfoURL() has been added to MapScript for applications that want to access featureInfo results and handle them directly. 2. MapServer does not attempt to fetch the layers capabilities. Doing so at every map draw would be extremely inefcient. And caching that information does not belong in the core of MapServer. This is better done at the application level, in a script, and only the necessary information is passed to the MapServer core via the CONNECTION string and metadata.
Table of Contents WMS Time Introduction Enabling Time Support in MapServer Future Additions Limitations and Known Bugs
9.3.1 Introduction
A WMS server can provide support to temporal requests. This is done by providing a TIME parameter with a time value in the request. MapServer 4.4 and above provides support to interpret the TIME parameter and transform the resulting values into appropriate requests. Links to WMS-Related Information MapServer WMS Server HowTo
381
MapServer WMS Client HowTo WMS 1.1.1 specication MapServer OGC Web Services Workshop
Setting Up a WMS Layer with Time Support To have a valid WMS layer with time support, the user has to dene the following metadata at the layer level: wms_timeextent: (Mandatory) this is used in the capabilities document to return the valid time values for the layer. The value dened here should be a valid time range. (more on this in Specifying Time Extents below) wms_ timeitem: (Mandatory) this is the name of the eld in the DB that contains the time values. wms_timedefault: (Optional) this value is used if it is dened and the TIME value is missing in the request.
GetCapabilities Output If your layer is set up properly, requesting the capabilities on the server outputs a Dimension element. Here is an example of a GetCapabilities result for a layer congured for time support:
<Layer queryable="0" opaque="0" cascaded="0"> <Name>earthquakes</Name> <Title>Earthquakes</Title> <SRS>EPSG:4326</SRS> <LatLonBoundingBox minx="-131.02" miny="24.84" maxx="-66.59" maxy="48.39" /> <BoundingBox SRS="EPSG:4326" minx="-131.02" miny="24.84" maxx="-66.59" maxy="48.39" /> <Dimension name="time" units="ISO8601"/> <Extent name="time" default="2004-01-01 14:10:00" nearestValue="0">2004-01-01/2004-02-01</Extent> </Layer>
Supported Time Requests When sending a request with the TIME parameter, different types of time values can be specied. The following are supported by MapServer: single value: for example: ...&TIME=2004-10-12&... multiple values: for example: ...&TIME=2004-10-12, 2004-10-13, 2004-10-14&... single range value: for example: ...&TIME=2004-10-12/2004-10-13&... multiple range values: for example: ...&TIME=2004-10-12/2004-10-13, 2004-10-15/2004-10-16&... Interpreting Time Values When MapServer receives a request with a TIME parameter, it transforms the time requests into valid expressions that are assigned to the lter parameter on layers that are time-aware. Here are some examples of how different types of requests are treated (wms_timeitem is dened here as being time_eld):
383
single value (2004-10-12) transforms to ([time_eld] eq 2004-10-12) multiple values (2004-10-12, 2004-10-13) transform to ([time_eld] eq 2004-10-12 OR [time_eld] eq 2004-10-13) single range : 2004-10-12/2004-10-13 transforms to (([time_eld] ge 2004-10-12) AND ([time_eld] le 2004-10-13)) multiple ranges (2004-10-12/2004-10-13, 2004-10-15/2004-10-16) transform to (([time_eld] ge 2004-1012 AND [time_eld] le 2004-10-13) OR ([time_eld] ge 2004-10-15 AND [time_eld] le 2004-1016)) As shown in the above examples, all elds and values are written inside back tics () - this is the general way of specifying time expressions inside MapServer. Exceptions to this rule: 1. When dealing with layers that are not Shapeles nor through OGR, the expression built has slightly different syntax. For example, the expression set in the lter for the rst example above would be ([time_eld] = 200410-12). 2. For PostGIS/PostgreSQL layers, the time expression built uses the date_trunc function available in PostgreSQL. For example, if the user passes a time value of 2004-10-12, the expression set in the lter is date_trunc(day, time_eld) = 2004-10-12. The use of the date_trunc function allows requests to use the concept of time resolution. In the example above, for a request of 2004-10-12, MapServer determines that the resolution is day by parsing the time string and the result gives all records matching the date 2004-10-12 regardless of the values set for Hours/Minutes/Seconds in the database. For more information on the date_trunc function, please refer to the PostgreSQL documentation. Limiting the Time Formats to Use The user has the ability to dene the time format(s) to be used when a request is sent, in metadata at the WEB level. For example, the user can dene the following two formats:
"wms_timeformat" "YYYY-MM-DDTHH, YYYY-MM-DDTHH:MM"
Another example is for a WMS layer that is based on time data that contains precise time values taken every minute (e.g., 2004-10-12T13:55, 2004-10-12T13:56, 2004-10-12 T13:57, ...). Normally, a valid request on such a layer would require the time value to be as complete as the data underneath. By dening a set of patterns to use, MapServer introduces the notion of resolution to be used when doing a query. Using the example above, a request TIME= 200410-12T13:55 would be valid and a request TIME= 2004-10-12T13 would also be valid and would return all elements taken for that hour. Note that this functionality is only available on layers based on Shapeles and OGR. Example of WMS-T with PostGIS Tile Index for Raster Imagery This example currently requires latest 4.9 CVS build! Here is an example maple snippet for a raster WMS-T instance using a PostGIS tileindex. This example shows US Nexrad Base Reectivity running at Iowa State U at http://mesonet.agron.iastate.edu/cgibin/wms/nexrad/n0r.cgi?SERVICE=WMS&request=GetCapabilities
384
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
# Tile Index LAYER STATUS ON NAME "time_idx" TYPE POLYGON DATA "the_geom from nexrad_n0r_tindex" METADATA "wms_title" "TIME INDEX" "wms_srs" "EPSG:4326" "wms_extent" "-126 24 -66 50" "wms_timeextent" "2003-08-01/2006-12-31/P5M" "wms_timeitem" "datetime" #column in postgis table of type timestamp "wms_timedefault" "2006-06-23T03:10:00Z" END CONNECTION "dbname=postgis host=10.10.10.20" CONNECTIONTYPE postgis END
# raster layer LAYER NAME "nexrad-n0r-wmst" TYPE RASTER STATUS ON DEBUG ON DUMP TRUE PROJECTION "init=epsg:4326" END METADATA "wms_title" "NEXRAD BASE REF WMS-T" "wms_srs" "EPSG:4326" "wms_extent" "-126 24 -66 50" "wms_timeextent" "2003-08-01/2006-12-31/P5M" "wms_timeitem" "datetime" #datetime is a column in postgis table of type timestamp "wms_timedefault" "2006-06-23T03:10:00Z" END OFFSITE 0 0 0 TILEITEM "filepath" #filepath is a column in postgis table with varchar of the filepath to each imag TILEINDEX "time_idx" END
You can nd more information on Time and tileindexes in the WCS documentation.
385
9.4.1 Introduction
The term map context comes from the Open Geospatial Constortiums (OGC) Web Map Context Specication v1.0.0, which coincides with the OGC Web Map Server Specication (WMS) v1.1.1. A map context is a XML document that describes the appearance of layers from one or more WMS servers, and can be transferred between clients while maintaining startup views, the state of the view (and its layers), and storing additional layer information. Support for OGC Web Map Context was added to MapServer in version 3.7/4.0. This allows client applications to load and save a map conguration in a standard XML format. MapServer can read context documents of versions 0.1.2, 0.1.4, 0.1.7, 1.0.0, 1.1.0 and can export contents in versions 0.1.4, 0.1.7, 1.0.0, 1.1.0. Web Map Context 1.1.0 support was added to MapServer 4.10 This document assumes that you are already familiar with certain aspects of MapServer: MapServer application development and setting up maples. Familiarity with the WMS spec would be an asset. Please see the following section for links to associated sources. Links to WMS / Map Context Related Information MapServer WMS Client HowTo Open Geospatial Consortium (OGC) home page WMS 1.1.1 specication Map Context 1.0.0 specication MapServer OGC Web Services Workshop
Build/install the above libraries on your system and then build MapServer with the with-wmsclient with-proj withogr with-gdal with-php congure options. Also make sure that your build uses the USE_WMS_LYR and USE_OGR ags. For more details on MapServer compilation see the appropriate HowTo: Unix / Windows Windows users can use MS4W, which is ready for Map Context use. Map Context Maple A map context document can ONLY contain WMS layers (e.g. CONNECTIONTYPE WMS). Please refer to the MapServer WMS Client HowTo for more information on declaring WMS layers.
MapFile Metadata
The following maple metadata are used by MapServer to handle map context information: (Note that some parameters have width, height, format, and href, and some only have format and href. This is because width and height are only used for images and parameters that do not have them are text or html. For consistency with the spec MapServer supports height and width for all parameters, but they should only be used for images)
387
wms_keywordlist : A comma-separated list of keywords or keyword phrases to help catalog searching. wms_logourl_width : Width of the context logo. wms_logourl_height : Height of the context logo. wms_logourl_format : Format of the context logo. wms_logourl_href : Location of the context logo. wms_postcode : If provided must also then provide wms_address, wms_city, wms_stateorprovince, wms_addresstype, and wms_country. wms_stateorprovince : If provided must also then provide wms_address, wms_city, wms_addresstype, wms_postcode, and wms_country. wms_title : (Required) A human-readable name for this Layer (this metadata does not exist beyond version 0.1.4)
388
wms_onlineresource : Required URL to access the server. wms_server_version : The version of the web map server specication. wms_server_title : The title of the web map server. wms_stylelist : Current style used. wms_style_%s_legendurl_width : Width of an image describing the style. %s = the name of the style. wms_style_%s_legendurl_height : Height of an image describing the style. %s = the name of the style. wms_style_%s_legendurl_format : Format of an image describing the style. %s = the name of the style. wms_style_%s_legendurl_href : Location of an image describing the style. %s = the name of the style. wms_style_%s_sld : URL to the SLD document of this style. %s = the name of the style. wms_style_%s_sld_body : SLD_BODY document of this style. %s = the name of the style. wms_style_%s_title : Title of the layer. %s = the name of the style. wms_title : (Required) A human-readable name for this Layer.
NAME W M S _ C O N TEXT STATUS ON SIZE 400 300 SYMBOLSET ../ e t c / s y m b o l s . s y m EXTENT -2200000 -712631 3072800 3840000 UNITS METERS SHAPEPATH "../data" IMAGECOLOR 255 255 255 FONTSET ../ e t c / f o n t s . t x t WEB IMAGEPATH "/ms4w/tmp/ms_tmp/" IMAGEURL "/ms_tmp/" METADATA "wms_abstract" "Demo for map context document. Blah blah..." "wms_title" "Map Context demo" #### REQUIRED END END PROJECTION "init=epsg:42304" END LAYER NAME "prov_bound" TYPE RASTER STATUS ON CONNECTION "http://www2.dmsolutions.ca/cgi-bin/mswms_gmap?" CONNECTIONTYPE WMS METADATA "wms_name" "prov_bound" "wms_server_version" "1.1.1"
389
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
"wms_server_title" "GMap WMS Demo Server" "wms_format" "image/gif" "wms_srs" "EPSG:42304" "wms_title" "Canadian boundaries" #### REQUIRED "wms_onlineresource" "http://www2.dmsolutions.ca/cgi-bin/mswms_gmap?" "wms_dimensionlist" "time,width" "wms_dimension" "time" "wms_dimension_time_unitsymbol" "t" "wms_dimension_time_units" "ISO8601" "wms_dimension_time_uservalue" "1310" "wms_dimension_time_default" "1310" "wms_dimension_time_multiplevalues" "1310,1410" "wms_dimension_time_nearestvalue" "0" END END
#### REQUIRED
LAYER NAME p o p p l a c e TYPE RASTER STATUS ON CONNECTIONTYPE WMS CONNECTION "http://www2.dmsolutions.ca/cgi-bin/mswms_gmap?" METADATA "wms_name" "popplace" "wms_server_version" "1.1.1" "wms_server_title" "GMap WMS Demo Server" "wms_format" "image/png" "wms_srs" "EPSG:42304" "wms_title" "Canadian Cities" #### REQUIRED "wms_onlineresource" "http://www2.dmsolutions.ca/cgi-bin/mswms_gmap?" #### REQUIRED END END # Layer END # Map File
Testing Map Context Support 1. The rst thing to do is to save your maple using the saveMapContext function available from the PHP/MapScript library. An example script is shown below:
<?php dl("php_mapscript.dll"); $oMap = ms_newMapObj("gmap_wms_context.map"); $oMap->saveMapContext("gmap_wms_context_output.xml"); ?>
2. Scan the XML output to look for <! WARNING: ... > comments. Then make the necessary changes to x every warning that you encounter. At the end of this you should have a maple compatible with the Map Context specication. 3. Now you can load your new Map Context document into an application using the loadMapContext function from the PHP/MapScript library.
390
Sample Map Context Document The following is a sample Map Context document:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
<?xml version=1.0 encoding="ISO-8859-1" standalone="no" ?> <ViewContext version="1.1.0" id="WMS_CONTEXT" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instanc <General> <Window width="400" height="300"/> <!-- Bounding box corners and spatial reference system --> <BoundingBox SRS="EPSG:42304" minx="-2200000.000000" miny="-712631.000000" maxx="3072800.0000 <!-- Title of Context --> <Title>Map Context demo</Title> <Abstract>Demo for map context document. Blah blah...</Abstract> <ContactInformation> </ContactInformation> </General> <LayerList> <Layer queryable="0" hidden="0"> <Server service="OGC:WMS" version="1.1.1" title="Canadian boundaries"> <OnlineResource xlink:type="simple" xlink:href="http://www2.dmsolutions.ca/cgi-bin/mswms_ </Server> <Name>prov_bound</Name> <Title>Canadian boundaries</Title> <SRS>EPSG:42304</SRS> <FormatList> <Format current="1">image/gif</Format> </FormatList> <DimensionList> <Dimension name="time" units="ISO8601" unitSymbol="t" userValue="1310" default="1310" mul </DimensionList> </Layer> <Layer queryable="0" hidden="0"> <Server service="OGC:WMS" version="1.1.1" title="Canadian Cities"> <OnlineResource xlink:type="simple" xlink:href="http://www2.dmsolutions.ca/cgi-bin/mswms_ </Server> <Name>popplace</Name> <Title>Canadian Cities</Title> <SRS>EPSG:42304</SRS> <FormatList> <Format current="1">image/png</Format> </FormatList> </DimensionList> </Layer> </LayerList> </ViewContext>
Map Context Support Through CGI MapServer CGI allows you to load a map context through the use of a CONTEXT parameter, and you can point this parameter to a locally stored context le or a context le accessible through a URL. For more information on MapServer CGI see the CGI Reference.
391
Note: All layers created from a context le have their status set to ON. To be able to display layers, the user needs to add the LAYERS argument in the URL.
Due to security concerns loading a le from a URL is disabled by default. To enable this functionality, the user needs to set a CONFIG parameter called CGI_CONTEXT_URL in the default maple that will allow this functionality. Here is an example of a map le with the CONFIG parameter:
# Start of map file NAME "map-context" STATUS ON SIZE 400 300 EXTENT -2200000 -712631 3072800 3840000 UNITS METERS IMAGECOLOR 255 255 255 IMAGETYPE png CONFIG "CGI_CONTEXT_URL" "1" ... WEB ... END LAYER ... END END
Default Maple
To smoothly run a MapServer CGI application with a Map Context, the application administrator needs to provide a default maple with at least the basic required parameters that will be used with the Context le. This default maple can contain as little information as the imagepath and imageurl or contain a list of layers. Information coming from the context (e.g.: layers, width, height, ...) would either be appended or will replace values found in the maple. Here is an example of a default map le containing the minimum required parameters:
1 2 3
392
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
EXTENT -2200000 -712631 3072800 3840000 UNITS METERS IMAGECOLOR 255 255 255 IMAGETYPE png # # Start of web interface definition # WEB MINSCALE 2000000 MAXSCALE 50000000 # # On Windows systems, /tmp and /tmp/ms_tmp/ should be created at the root # of the drive where the .MAP file resides. # IMAGEPATH "/ms4w/tmp/ms_tmp/" IMAGEURL "/ms_tmp/" END END # Map File
Map Context Support Through WMS MapServer can also output your WMS layers as a Context document. MapServer extends the WMS standard by adding a request=GetContext operation that allows you to retrieve a context for a WMS-based maple with a call like:
http://localhost/mapserver.cgi?map=/path/to/mapfile.map&service=WMS& request=GetContext&version=1.1.0
The VERSION parameter controls the version of context document to return. GetContext is disabled by default because it could be considered a security issue: it could publicly expose the URLs of WMS layers used (cascaded) by a maple. To enable it, set the wms_getcontext_enabled web metadata to 1 in your WMS servers maple.
393
Contents WFS Server Introduction Conguring your MapFile to Serve WFS layers Reference Section To-do Items and Known Limitations
9.5.1 Introduction
A WFS ( Web Feature Service ) publishes feature-level geospatial data to the web. This means that instead of returning an image, as MapServer has traditionally done, the client now obtains ne-grained information about specic geospatial features of the underlying data, at both the geometry AND attribute levels. As with other OGC specications, this interface uses XML over HTTP as its delivery mechanism, and, more precisely, GML (Geography Markup Language), which is a subset of XML. WFS-Related Information Here are some WFS related links (including a newly added OGC services workshop with MapServer). Since these are highly detailed technical specications, there is no need to read through them in their entirety to get a MapServer WFS up and running. It is still recommended however to read them over and get familiar with the basics of each of them, in order to understand how it all works: The OGC Web Feature Service Implementation Specication. The Geography Markup Language Implementation Specication. MapServer OGC Web Services Workshop package. Working knowledge of MapServer is of course also required. Software Requirements In order to enable MapServer to serve WFS, it MUST be compiled against certain librairies: PROJ.4: The reprojection library. Version 4.4.3 or greater is required. GDAL/OGR: I/O support libraries. Version 1.1.8 or greater is required. Please see the MapServer UNIX Compilation and Installation HowTo for detailed instructions on compiling mapserver with support for these libraries and features. For Windows users, the MS4W installer comes ready to serve both WFS and WMS. Version of GML Supported MapServer can output both GML2 and GML3. By default MapServer serves GML2. You can test this by adding an OUTPUTFORMAT parameter to a GetFeature request, such as: GML2 request output 394 Chapter 9. OGC Support and Conguration
GML3 request output For a detailed discussion on the versions supported, see bug#884.
By creating a wrapper script on the server it is possible to hide the map= parameter from the URL and then your servers online resource URL could be something like:
http://my.host.com/cgi-bin/mywfs?
This is covered in more detail in the More About the Online Resource URL section of the WMS Server document. Example WFS Server Maple The following is an example of a bare minimum WFS Server maple. Note the comments for the required parameters.
NAME "WFS_server" STATUS ON SIZE 400 300 SYMBOLSET ../ e t c / s y m b o l s . s y m EXTENT -2200000 -712631 3072800 3840000 UNITS METERS SHAPEPATH "../data" IMAGECOLOR 255 255 255 FONTSET ../ e t c / f o n t s . t x t WEB
395
IMAGEPATH "/ms4w/tmp/ms_tmp/" IMAGEURL "/ms_tmp/" METADATA "wfs_title" "GMap WFS Demo Server" ## REQUIRED "wfs_onlineresource" "http://127.0.0.1/cgi-bin/mapserv.exe?" ## Recommended "wfs_srs" "EPSG:42304 EPSG:42101 EPSG:4269 EPSG:4326" ## Recommended "ows_schemas_location" "http://ogc.dmsolutions.ca" ## Optional END END PROJECTION "init=epsg:42304" END LAYER NAME "province" METADATA "wfs_title" "Provinces" ## REQUIRED "gml_featureid" "ID" ## REQUIRED "gml_include_items" "all" ## Optional (serves all attributes for layer) END TYPE POLYGON STATUS ON DATA p r o v i n c e PROJECTION "init=epsg:42304" END DUMP TRUE ## REQUIRED CLASS NAME "Canada" STYLE COLOR 200 255 0 OUTLINECOLOR 120 120 120 END TEMPLATE "ttt_query.html" END END # Layer END # Map File
Rules for Handling SRS in MapServer WFS Contrary to WMS, the OGC WFS specication doesnt allow a layer (feature type) to be advertised in more than one SRS. Also, there is no default SRS that applies to all layers by default in the OGC WFS spec. However, it is possible to have every layer in a WFS server advertised in a different SRS. Here is how MapServer decides the SRS to advertise and use for each layer in your WFS: If a top-level map SRS is dened* then this SRS is used and applies to all layers (feature types) in this WFS. In this case the SRS of individual layers is simply ignored even if its set. If there is no top-level map SRS dened* then each layer is advertised in its own SRS in the capabilities. By SRS is dened, we mean either the presence of a PROJECTION object dened using an EPSG code, or of a wfs_srs metadata at this level.
396
Note that at the map top-level the wfs_srs metadata value takes precedence over the contents of the PROJECTION block. At the layer level, if both the wfs_srs metadata and the PROJECTION object are set to different values, then the wfs_srs metadata denes the projection to use in advertising this layer (assuming there is no top-level map SRS), and the PROJECTION value is assumed to be the projection of the data. So this means that the data would be reprojected from the PROJECTION SRS to the one dened in the wfs_srs metadata before being served to WFS clients. Confusing? As a rule of thumb, simply set the wfs_srs at the map level (in web metadata) and never set the wfs_srs metadata at the layer level and things will work ne for most cases. Test Your WFS Server
397
398
Description: (Optional) XML encoding for all XML documents returned by the server. The default is ISO8859-1. wfs_fees WFS TAG Name: Fees (WFS 1.0.0, sect. 12.3.3) Description: (Optional) Any fees imposed by the service provider for usage of this service or for data retrieved from the WFS. wfs_keywordlist WFS TAG Name: Keyword (WFS 1.0.0, sect. 12.3.3) Description: (Optional) List of words to aid catalog searching. wfs_maxfeatures Description: (Optional) The number of elements to be returned by the WFS server. This has priority over the maxfeatures parameter passed by the user. If the not set the current behaviour is not changed. wfs_namespace_prex Description: (Optional) User dened namespace prex to be used in the response of a WFS GetFeature request. e.g. wfs_namespace_prex someprex. wfs_namespace_uri Description: (Optional) User dened namespace URI to be used in the response of a WFS GetFeature request. e.g. wfs_namespace_uri http://somehost/someurl. wfs_onlineresource WFS TAG Name: Onlineresource (WFS 1.0.0, sect. 12.3.3) Description: (Recommended) The URL prex for HTTP GET requests. wfs_service_onlineresource Description: (Optional) Top-level onlineresource URL. MapServer uses the onlineresource metadata (if provided) in the following order: 1. wfs_service_onlineresource 2. ows_service_onlineresource 3. wfs_onlineresource (or automatically generated URL, see the onlineresource section of this document) wfs_title WFS TAG Name: Title (WFS 1.0.0, sect. 12.3.3) Description: (Required) Human readable title to identify server. wfs_srs 9.5. WFS Server 399
Description: (Recommended) The SRS to use for all layers in this server. (e.g. EPSG:4326) See the notes below about the SRS rules in the WFS. wfs_feature_collection Description: Replaces the default name of the feature-containing element (<msFeatureCollection>) with a userdened value. Layer Object gml_exclude_items Description: (Optional) A comma delimited list of items to exclude. As of MapServer 4.6, you can control how many attributes (elds) you expose for your data layer with metadata. The previous behaviour was simply to expose all attributes all of the time. The default is to expose no attributes at all. An example excluding a specic eld would be:
"gml_include_items" "all" "gml_exclude_items" "Phonenum"
gml_featureid Description: (Required for MapServer 4.10) Field to be used for the ID of the feature in the output GML. wfs_featureid or ows_feature_id can be specied instead. gml_groups Description: (Optional) A comma delimited list of group names for the layer. gml_[group name]_group Description: (Optional) A comma delimited list of attributes in the group. Here is an example:
"gml_include_items" "all" "gml_groups" "display" "gml_display_group" "Name_e,Name_f"
gml_include_items Description: (Optional) A comma delimited list of items to include, or keyword all. As of MapServer 4.6, you can control how many attributes (elds) you expose for your data layer with this metadata. The previous behaviour was simply to expose all attributes all of the time. You can enable full exposure by using the keyword all, such as:
"gml_include_items" "all"
You can specify a list of attributes (elds) for partial exposure, such as:
"gml_include_items" "Name,ID"
The new default behaviour is to expose no attributes at all. gml_[item name]_alias 400 Chapter 9. OGC Support and Conguration
Description: (Optional) An alias for an attributes name. The served GML will refer to this attribute by the alias. Here is an example:
"gml_province_alias" "prov"
gml_[item name]_type Description: (Optional) Species the type of the attribute. Valid values are Integer|Real|Character|Date|Boolean. gml_xml_items Description: (Optional) A comma delimited list of items that should not be XML-encoded. gml_geometries Description: provides a name other than the default msGeometry for geometry elements. The value is specied as a string to be used for geometry element names. gml_[name]_type Description: When employing gml_geometries, it is also necessary to specify the geometry type of the layer. This is accomplished by providing a value for gml_[name]_type, where [name] is the string value specied for gml_geometries, and a value which is one of: point multipoint line multiline polygon multipolygon gml_[name]_occurances Description: MapServer applies default values of 0 and 1, respectively, to the minOccurs and maxOccurs attributes of geometry elements, as can be seen in the preceding examples. To override these defaults, a value is assigned to a gml_[name]_occurances layer metadata item, where again [name] is the string value specied for gml_geometries, and the value is a comma-delimited pair containing the respective lower and upper bounds. wfs_abstract Same as wfs_abstract in the Web Object. wfs_extent Description: (Optional) Used for the layers BoundingBox tag for cases where it is impossible (or very inefcient) for MapServer to probe the data source to gure its extents. The value for this metadata is minx miny maxx maxy separated by spaces, with the values in the layers projection units. If wfs_extent is provided then it has priority and MapServer will NOT try to read the source les extents. wfs_featureid
401
Description: (Required for MapServer 4.10) Field to be used for the ID of the feature in the output GML. gml_featureid or ows_feature_id can be specied instead. wfs_keywordlist Same as wfs_keywordlist in the Web Object. wfs_metadataurl_format Description: (Optional) The le format of the metadata record. Valid values are XML, SGML, or HTML. The layer metadata wfs_metadataurl_type and wfs_metadataurl_href must also be specied. refer to section 12.3.5 of the WFS 1.0.0 spec. wfs_metadataurl_href Description: (Optional) The URL to the layers metadata. The layer metadata wfs_metadataurl_type and wfs_metadataurl_format must also be specied. refer to section 12.3.5 of the WFS 1.0.0 spec. wfs_metadataurl_type Description: (Optional) The standard to which the metadata complies. Currently only two types are valid: TC211 which refers to [ISO 19115], and FGDC which refers to [FGDC CSDGM]. The layer metadata wfs_metadataurl_format and wfs_metadataurl_href must also be specied. refer to section 12.3.5 of the WFS 1.0.0 spec. wfs_srs Description: If there is no SRS dened at the top-level in the maple then this SRS will be used to advertize this feature type (layer) in the capabilities. See the note below about the SRS rules in the WFS. wfs_title Same as wfs_title in the Web Object.
402
Contents WFS Client Introduction Setting up a WFS-client Maple TODO / Known Limitations
9.6.1 Introduction
MapServer can retrieve and display data from a WFS server. The following document explains how to display data from a WFS server using MapServer. A WFS ( Web Feature Service ) publishes feature-level geospatial data to the web. This means that it is possible to use this data as a data source to render a map. In effect, this is not unlike having a shapele accessible over the web, only its not a shapele, its XML-Encoded geospatial data (GML to be exact), including both geometry AND attribute information. WFS-Related Information Although in-depth understanding of WFS and GML is neither necessary nor required in order to implement a MapServer application that reads remote WFS data, it is recommended to at least get aquainted with the concepts and basic functionality of both. Here are the ofcial references (including a newly added OGC workshop with MapServer): OGC Web Feature Service Implementation Specication. Geography Markup Language Implementation Specication. MapServer OGC Web Services Workshop package. Software Requirements In order to enable MapServer to serve WFS, it MUST be compiled against certain libraries: PROJ.4: The reprojection library. Version 4.4.3 or greater is required. GDAL/OGR: I/O support librairies. Version 1.1.8 or greater is required. LibCURL: Used to help MapServer act as an HTTP client. Version 7.10 or greater is required. 9.6. WFS Client 403
Please see the MapServer UNIX Compilation and Installation HOWTO for detailed instructions on compiling mapserver with support for these librairies and features. For Windows users, look on the MapServer website to see if there are any binaries available that meet these requirements.
WFS Layer A WFS layer is a regular maple layer, which can use CLASS objects, with expressions, etc. As of MapServer 4.4, the suggested method to dene a WFS Client layer is through the CONNECTION parameter and the layers METADATA. The necessary maple parameters are dened below: CONNECTIONTYPE: must be wfs CONNECTION: The URL to the WFS Server. e.g. http://www2.dmsolutions.ca/cgi-bin/mswfs_gmap? The path to the maple on the WFS server is required if it was required in the GetCapabilities request e.g. you would have to specify the MAP parameter in the CONNECTION for the following server: http://map.ns.ec.gc.ca/MapServer/mapserv.exe?MAP=/mapserver/services/envdat/cong.map &SERVICE=WFS&VERSION=1.0.0&REQUEST=GetCapabilities METADATA: The LAYERs must contain a METADATA object with the following parameters: wfs_connectiontimeout (optional): The maximum time to wait for a remote WFS layer to load, set in seconds (default is 30 seconds). This metadata can be added at the layer level so that it affects only that layer, or it can be added at the map level (in the web object) so that it affects all of the layers. Note that wfs_connectiontimeout at the layer level has priority over the map level. wfs_lter: This can be included to include a lter encoding parameter in the getFeature request (see the Filter Encoding Howto for more information on ltering). The content of the wfs_lter is a valid lter encoding element.
... METADATA "wfs_filter" END ...
wfs_latlongboundingbox (optional): The bounding box of this layer in geographic coordinates in the format lon_min lat_min lon_max lat_max. If it is set then MapServer will request the layer only when the map view overlaps that bounding box. You normally get this from the servers capabilities output.
404
wfs_maxfeatures (optional): Limit the number of GML features to return. wfs_request_method (optional): Can be set to GET to do a Get request to WFS servers that do not support Post requests. The default method in MapServer is Post.
... METADATA "wfs_filter" END ...
"GET"
wfs_typename (required): the <Name> of the layer found in the GetCapabilities. An example GetCapabilities request is: http://www2.dmsolutions.ca/cgibin/mswfs_gmap?SERVICE=WFS&VERSION=1.0.0&REQUEST=getcapabilities wfs_version (required): WFS version, currently 1.0.0 Note: Each of the above metadata can also be referred to as ows_* instead of wfs_*. MapServer tries the wfs_* metadata rst, and if not found it tries the corresponding ows_* name. Using this reduces the amount of duplication in maples that support multiple OGC interfaces since ows_* metadata can be used almost everywhere for common metadata items shared by multiple OGC interfaces. Example WFS Layer
LAYER NAME "park" TYPE POLYGON STATUS ON CONNECTIONTYPE WFS CONNECTION "http://www2.dmsolutions.ca/cgi-bin/mswfs_gmap?" METADATA "wfs_typename" "park" "wfs_version" "1.0.0" "wfs_request_method" "GET" "wfs_connectiontimeout" "60" "wfs_maxfeatures" "1" END PROJECTION "init=epsg:42304" END CLASS NAME "Parks" STYLE COLOR 200 255 0 OUTLINECOLOR 120 120 120 END END END # Layer
Connection - deprecated As of MapServer v4.4 the method of specifying all of the connection information in the CONNECTION parameter has beendeprecated. The preferred method is mentioned above. If the metadata is not provided, VERSION, SERVICE, and TYPENAME will be fetched from the CONNECTION, as shown below
CONNECTION
"http://www2.dmsolutions.ca/cgi-bin/mswfs_gmap?SERVICE=WFS&VERSION=1.0.0&TYPENAME=park"
405
Table of Contents WFS Filter Encoding Introduction Currently Supported Features Get and Post Requests Use of Filter Encoding in MapServer Limitations Tests
9.7.1 Introduction
This document describes the procedures for taking advantage of the Filter Encoding (FE) support in WFS GetFeature requests, which was added to MapServer in version 4.2. This document assumes that you are already familiar with the following aspects of MapServer: MapServer application development and setting up .map les. Familiarity with the WFS specication would be an asset. Links to the MapServer WFS documents are included in the next section.
406
Links to SLD-related Information Filter Encoding Implementation Specication. MapServer WFS Client Howto. MapServer WFS Server Howto. MapServer OGC Web Services Workshop. Open GIS Consortium (OGC) home page.
407
GetFeatures DescribeFeatureType Supporting these WFS requests in Post was implemented to keep consistency between all supported WFS requests. When sending requests, the default request method used is Post. To change this behavior, we have introduced a layer level meta data, wfs_request_method, which can be set to GET.
<?xml version=1.0 encoding="ISO-8859-1" ?> <WFS_Capabilities version="1.0.0" updateSequence="0" xmlns="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://ogc.dmsolutions.ca/wfs/1.0.0/WFS-capabilitie <!-- MapServer version 4.1 OUTPUT=GIF OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE --> <Service> <Name>MapServer WFS</Name> <Title>GMap WMS Demo Server</Title> <OnlineResource>http://localhost/cgi-bin/mapserv.exe?map= c:/msapps/wfs_filter/htdocs/ns_wfsserver.map & </OnlineResource> </Service> <Capability> <Request> <GetCapabilities> <DCPType> <HTTP> <Get onlineResource="http://localhost/cgi-bin/mapserv.exe?map= c:/msapps/wfs_filter/htdocs/ns_wfsserver.map&" /> </HTTP> </DCPType> <DCPType> <HTTP> <Post onlineResource="http://localhost/cgi-bin/mapserv.exe?map= c:/msapps/wfs_filter/htdocs/ns_wfsserver.map&" /> </HTTP>
408
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
</DCPType> </GetCapabilities> ... </Request> </Capability> ... <Filter_Capabilities> <Spatial_Capabilities> <Spatial_Operators> <Intersect/> <DWithin/> <BBOX/> </Spatial_Operators> </Spatial_Capabilities> <Scalar_Capabilities> <Logical_Operators /> <Comparison_Operators> <Simple_Comparisons /> <Like /> <Between /> </Comparison_Operators> </Scalar_Capabilities> </Filter_Capabilities> </WFS_Capabilities>
Client Side To be able to generate a Filter to a WFS server, a layer level metadata called wfs_lter has been added, which should contain the lter to be sent to the server. Following is an example of a valid WFS client layer with a lter:
LAYER NAME p o p p l a c e METADATA "wfs_version" "1.0.0" "wfs_typename" "popplace" "wfs_filter" "<PropertyIsGreaterThan><PropertyName>POP_RANGE</PropertyName> < L i t e r a l >4</ L i t e r a l ></ P r o p e r t y I s G END TYPE POINT STATUS ON PROJECTION "init=epsg:42304" END CONNECTIONTYPE WFS CONNECTION "http://www2.dmsolutions.ca:8090/cgi-bin/mswfs_filter?" LabelItem "Name" CLASSITEM "Capital" CLASS SYMBOL 2 SIZE 8 NAME "Cities" LABEL COLOR 255 0 0 FONT f r i t q a t - i t a l i c TYPE truetype
409
SIZE 8 POSITION AUTO OUTLINECOLOR 255 255 255 FORCE TRUE END COLOR 0 0 0 END END # Layer
Note: The lter given as a value of the wfs_lter metadata should not contain <Filter> start and end tags. The CONNECTION points to a valid WFS server supporting lters The returned shapes will be drawn using the class dened in the layer.
9.7.5 Limitations
A limited set of spatial operators are supported.
9.7.6 Tests
Here are some test URLs for the different supported lters: PropertyIsEqualTo
http://www2.dmsolutions.ca/cgi-bin/mswfs_filter?&VERSION=1.0.0&SERVICE=WFS&REQUEST=GetFeature& TYPENAME=popplace&Filter=<Filter><PropertyIsEqualTo><PropertyName>NAME</PropertyName> <Literal>Digby</Literal></PropertyIsEqualTo></Filter>
PropertyIsNotEqualTo
http://www2.dmsolutions.ca/cgi-bin/mswfs_filter?&VERSION=1.0.0&SERVICE=WFS&REQUEST=GetFeature& TYPENAME=popplace&Filter=<Filter><PropertyIsNotEqualTo><PropertyName>NAME</PropertyName> <Literal>Digby</Literal></PropertyIsNotEqualTo></Filter>
PropertyIsLessThan
http://www2.dmsolutions.ca/cgi-bin/mswfs_filter?&VERSION=1.0.0&SERVICE=WFS&REQUEST=GetFeature& TYPENAME=popplace&Filter=<Filter><PropertyIsLessThan><PropertyName>POP_RANGE</PropertyName> <Literal>2</Literal></PropertyIsLessThan></Filter>
PropertyIsGreaterThan
http://www2.dmsolutions.ca/cgi-bin/mswfs_filter?&VERSION=1.0.0&SERVICE=WFS&REQUEST=GetFeature& TYPENAME=popplace&Filter=<Filter><PropertyIsGreaterThan><PropertyName>POP_RANGE</PropertyName> <Literal>5</Literal></PropertyIsGreaterThan></Filter>
410
PropertyIsLessThanOrEqualTo
http://www2.dmsolutions.ca/cgi-bin/mswfs_filter?&VERSION=1.0.0&SERVICE=WFS&REQUEST=GetFeature& TYPENAME=popplace&Filter=<Filter><PropertyIsLessThanOrEqualTo><PropertyName>POP_RANGE</PropertyName> <Literal>2</Literal></PropertyIsLessThanOrEqualTo></Filter>
PropertyIsGreaterThanOrEqualTo
PropertyIsBetween
http://www2.dmsolutions.ca/cgi-bin/mswfs_filter?&VERSION=1.0.0&SERVICE=WFS&REQUEST=GetFeature& TYPENAME=popplace&Filter=<Filter><PropertyIsBetween><PropertyName>POP_RANGE</PropertyName> <LowerBoundary>5</LowerBoundary><UpperBoundary>6</UpperBoundary></PropertyIsBetween></Filter>
PropertyIsLike
http://www2.dmsolutions.ca/cgi-bin/mswfs_filter?&VERSION=1.0.0&SERVICE=WFS&REQUEST=GetFeature& TYPENAME=popplace&Filter=<Filter><PropertyIsLike wildcard=* singleChar=. escape=!> <PropertyName>NAME</PropertyName><Literal>Syd*</Literal></PropertyIsLike></Filter>
Logical operator OR
http://www2.dmsolutions.ca/cgi-bin/mswfs_filter?&VERSION=1.0.0&SERVICE=WFS&REQUEST=GetFeature& TYPENAME=popplace&Filter=<Filter><OR><PropertyIsEqualTo><PropertyName>NAME</PropertyName> <Literal>Sydney</Literal></PropertyIsEqualTo><PropertyIsEqualTo><PropertyName>NAME</PropertyName> <Literal>Digby</Literal></PropertyIsEqualTo></OR></Filter>
411
client
and
WFS
server
are
available
at
The OGC conformance tests (http://cite.occamlab.com/tsOGC/) have been run on the FE support. The following table and notes reect the current status. Table 2. WFS OGC test suite (over the HTTP Get and Post method) Test # 1 1.1 1.2 1.3 1.3.1 1.3.2 1.3.3 1.3.4 1.3.4.1 1.3.4.2 1.3.4.3 1.3.4.4 1.3.4.5 1.3.4.6 1.3.4.7 1.3.4.8 1.3.4.9 1.3.4.10 1.3.5 1.3.5.1 1.3.5.2 1.3.5.3 1.3.6 1.3.6.1 1.3.6.2 2 412 Description Basic WFS tests over the HTTP Get and Post method GetCapabilities DescribeFeatureType GetFeature Basic WFS tests Complex WFS tests Arithmetic lter WFS tests Comparison WFS tests GetFeature PropertyIsGreaterThanOrEqualTo lter GetFeature PropertyIsBetween lter GetFeature PropertyIsEqualTo lter GetFeature PropertyIsGreaterThan lter GetFeature PropertyIsGreaterThanOrEqualTo lter GetFeature PropertyIsLessThan lter GetFeature PropertyIsLessThanOrEqualTo lter GetFeature PropertyIsLike lter GetFeature PropertyIsNotEqualTo lter GetFeature PropertyIsNull lter Logical WFS test GetFeature AND PropertyIsEqualTo PropertyIsEqualTo lter GetFeature OR PropertyIsEqualTo PropertyIsEqualTo lter GetFeature NOT PropertyIsNotEqualTo lter Spatial operator WFS test GetFeature BBOX lter GetFeature with other lter types Transactional WFS test # of Tests 402 16 18 368 20 18 8 50 2 6 4 4 6 6 6 2 6 8 20 8 8 4 252 36 216 69 # of Failed Tests 281 0 0 281 1 18 8 26 0 2 0 2 6 4 4 0 0 8 0 0 0 0 228 12 216 69
The OGC Cite WFS test suite can be found on the OGC Cite portal. Following are some MapServer specic notes on this test suite: 1. Test number 1.3.1: There is a contradiction between the wfs/1.0.0/basic/getfeature/post/3 assertion and the XPath expected value of the test. The assertion says: Test that a GetFeature request with no output format dened returns a wfs:FeatureCollection with GML data. and the expected XPath value for this request: boolean(/ogc:ServiceExceptionReport) is supposed to be true. So, the assertion means that when a WFS server receives a request which contains an undened output format or no output format at all, the WFS server must return a WFS collection containing GML data. The XPath expected value means that when a WFS server receives a request with an undened output format or no output format at all, the WFS server must return a service exception report. 2. Tests number 1.3.2 and 1.3.3: Not supported. 3. Tests number 1.3.4.2, 1.3.4.4 to 1.3.4.7: The string comparison is not supported using >, <, >=, <=. The date comparison is not supported. See Also: bug 461 4. Test number 1.3.4.10: This property is not supported in MapServer. 5. Test number 1.3.6.1: The returned feature xml wont validate because the validation is done against a specic xsd (geomatry.xsd). The data conversion on multipoints and multilayers are not supported within GDAL. See Also: bug 461 6. Test number 2: The transaction requests are not supported.
9.8 SLD
Author Jeff McKenna Contact jmckenna atgatewaygeomatics.com Author Yewondwossen Assefa Contact assefa at dmsolutions.ca Last Updated 2008/07/18 Revision $Revision: 8583 $ Date $Date: 2009-02-18 15:02:30 -0800 (Wed, 18 Feb 2009) $
9.8. SLD
413
Contents SLD Introduction Server Side Support Client Side Support Named Styles support Other Items Implemented Issues Found During Implementation
9.8.1 Introduction
This document describes the procedures for taking advantage of the Styled Layer Descriptor (SLD) support in WMS GetMap requests with MapServer. SLD support exists for the server side (ability to read an SLD and apply it with a GetMap request) and for the client side (includes sending SLD requests to server and generate SLD les on the y from MapServer map le). SLD support was added to MapServer in version 4.2. This document assumes that you are already familiar with the following aspects of MapServer: MapServer application development and setting up .map les. Familiarity with the WMS specication would be an asset. Links to the MapServer WMS documents are included in the next section. Links to SLD-related Information Styled Layer Descriptor Implementation Specication. MapServer WMS Client HowTo. MapServer WMS Server HowTo. MapServer OGC Web Services Workshop. Open GIS Consortium (OGC) home page.
414
Test the remote SLD request. The SLD in the above request follows:
<?xml version="1.0" encoding="UTF-8"?> <StyledLayerDescriptor version="1.0.0" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd"> <NamedLayer> <Name>WorldGen_Outline</Name> <UserStyle> <Title>xxx</Title> <FeatureTypeStyle> <Rule> <LineSymbolizer> <Geometry> <ogc:PropertyName>center-line</ogc:PropertyName> </Geometry> <Stroke> <CssParameter name="stroke">#0000ff</CssParameter> </Stroke> </LineSymbolizer> </Rule> </FeatureTypeStyle> </UserStyle> </NamedLayer> </StyledLayerDescriptor>
9.8. SLD
415
<se:Stroke> <se:SvgParameter name="stroke">#0000ff</se:SvgParameter> </se:Stroke> </se:LineSymbolizer> </se:Rule> </se:FeatureTypeStyle> </UserStyle> </NamedLayer> </StyledLayerDescriptor>
When MapServer gets a valid SLD through a request, it parses this SLD to extract all the styles attached to the NamedLayers, and then it applies these styles to the map before it is returned to the client. When applying the SLD, MapServer compares the <Name> parameter of the NamedLayers in the SLD document to the WMS layer names (WMS layer names are available in a GetCapabilities request). Note: All the examples given in this document are live uses of valid SLDs and a MapServer installation with SLD support. Additional WMS features related to SLDs have also been developed: Table1. Additional WMS Features Features Method GET : SLD URL Method GET : SLD_BODY Describer Layer GetLegendGraphic GetStyles Supported Yes Yes Yes Yes Yes Notes Additional item
Note: As of MapServer version 4.2.3, the GetLegendGraphic request (see section 12 of the Styled Layer Descriptor Implementation Specication) works as follows: if the RULE keyword is absent from the request, an image containing the entire legend for the specied layer will be returned. This image consists of the layer name and a symbolization graphic and label for each class. Specic SLD Elements Supported The following tables give a lot of additional details about SLD support in MapServer. Table2. Named Layers and User Layers Features Named Layers User Layers Supported Yes No Notes
Table3. Named Styles and User Styles Features Named Styles User Styles Supported Yes Yes Notes
416
Supported No No No No Yes
Notes This was removed at implementation time, since it does not t with MapServer No use in the MapServer environment No use in the MapServer environment Only one style is available per layer MapServer has a concept of one feature type style per layer (either point, line, polygon, or raster)
Table 5. FeatureTypeStyle Features Name Title Abstract FeatureTypeName SemanticTypeIdentier Rule Table 6. Rule Features Name Title Abstract LegendGraphic Filter ElseFilter MinScaleDenominator MaxScaleDenominator LineSymbolizer PolygonSymbolizer PointSymbolizer TextSymbolizer RasterSymbolizer Filter and ElseFilter For each rule containing a lter, there is a class created with the class expression set to reect that lter. Available lters that can be used are Comparison Filters and Logical Filters (see the Filter Encoding HowTo). The ElseFilter parameters are converted into a class in MapServer and placed at the end of the class list with no expression set. They are used to render elements that did not t into any other classes. MinScaleDenomibator and MaxScaleDenominator are translated in minscale and maxscale in MapServer. The following are examples of valid requests using the Filters: line with one lter: sld 6a / full request 6a line with multiple lters: sld 6b / full request 6b line with one lter and an else lter: sld 6c / full request 6c spatial lter using BBOX: sld 6d/ full request 6d The above example enables spatial ltering using the BBOX parameter as a Filter for a selected area (Africa). Note that an ElseFilter will not work with a spatial lter. 9.8. SLD 417 Supported Yes Yes No Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Notes Supported No No No No No Yes Notes No use in the MapServer environment No use in the MapServer environment No use in the MapServer environment No use in the MapServer environment Still an experimental element in the SLD specications
Table 7. LineSymbolizer Features Geometry Stroke: GraphicFill Stroke: GraphicStroke Stroke (CssParameter): stroke Stroke (CssParameter): width Stroke (CssParameter): opacity Stroke (CssParameter): linejoin and linecap Stroke (CssParameter): dasharray Stroke (CssParameter): dashoffset PerperdicularOffset (only in SLD 1.1.0) InitialGap(GraphicStroke SLD 1.1.0) Gap (GraphicStroke parameter SLD 1.1.0) Supported No No Yes Yes Yes No No Yes No Yes No No Notes MapServer uses the data geometry to do the rendering Solid color is used Draws the symbol along the line RGB colors are supported Not supported in MapServer Not supported in MapServer
Note that SvgParameter instead of CssParameter are required for SLD 1.1.0. The following are examples of valid requests using the LineSymbolizer: simple line: sld 7a / full request 7a line with width: sld 7b / full request 7b dashed line: sld 7c / full request 7c Table 8. PolygonSymbolizer A Fill can be a solid ll or be a Graphic Fill, which is either a well-known Mark symbol (e.g., square, circle, triangle, star, cross, x) or an ExternalGraphic element (e.g., gif, png) available through a URL. When a Mark symbol is used in an SLD, MapServer creates a corresponding symbol in the map le and uses it to render the symbols. When a ExternalGraphic is used, the le is saved locally and a pixmap symbol is created in the maple referring to the this le. Note that the Web object IMAGEPATH is used to save the le. The following are examples of valid requests using the PolygonSymbolizer: simple solid ll: sld 8a / full request 8a solid ll with outline: sld 8b / full request 8b ll with mark symbol: sld 8c / full request 8c ll with external symbol: sld 8d/ full request 8d Table 9. PointSymbolizer Features Geometry Graphic: Mark symbol Graphic: ExternalGraphic Opacity Size Rotation Displacement AnchorPoint Supported No Yes Yes Yes Yes Yes Yes No Notes Well-known names (square, circle, triangle, star, cross, X) are supported Was developed to support symbol ll polygons in addition to solid ll Support added in Mapserver 5.4 Support added in MapServer 5.4 SLD 1.1.0 Paramater. Support added in MapServer 5.4
Note: refer to the PolygonSymbolizer notes for how the Mark and ExternalGraphic symbols are applied in MapServer. The following are examples of valid requests using the PointSymbolizer: 418 Chapter 9. OGC Support and Conguration
lled mark symbol: sld 9a / full request 9a default settings (square, size 6, color 128/128/128): sld 9b / full request 9b external symbol: sld 9c / full request 9c Table 10. TextSymbolizer Features Geometry Label Font(fontfamily) Font-style (Italic, ...) Fontweight Font-size LabelPlacement Halo Fill Supported No Yes Yes Yes Yes Yes Yes Yes Yes If true-type fonts are not used, default bitmap sizes are given PointPlacement is supported. LinePlacement is supported for versions >=5.2.1. Only PerperdicularOffset and IsAligned are suported for LinePlacement. Supported (ll converted to outlinecolor, and radius is converted to outlinewidth. Note that outlinewidth is only available for AGG in >=5.2) Only solid color is available Notes
Font names used are those available in MapServer font le. If no fonts are available there, default bitmap fonts are used
Notes on the TextSymbolizer: Font names: when converting Font parameters to MapServer, the following rule is applied to get the font name: FontFamily-FontStyle-FontWeight. For example, if there is an SLD with a Font Family of arial, a Font Style of italic, and a Font weight equal to bold, the resulting MapServer font name is arial-bold-italic. Font Style and Weight are not mandatory and, if not available, they are not used in building the font name. When a Font Style or a Font Weight is set to normal in an SLD, it is also ignored in building the name. For example, if there is an SLD with a Font Family of arial, a Font Style of normal and a Font weight equals to bold, the resulting MapServer font name is arial-bold. A TextSymbolizer can be used in MapServer either on an Annotation layer or on a Point, Line, or Polygon layer - in addition to other symbolizers used for these layers. PointPacement: a point placement includes AnchorPoint (which is translated to Position in MapServer) Displacement (which is translated to Offset) and Angle (which is translated to Angle). Angle setting: by default the angle parameter is set to AUTO. For point features, users can use the PointPlacement to alter the value. For line features, the user can add a LinePlacement: If an empty LinePlacement is part of the SLD, the angle will be set to FOLLOW, If a LinePlacement contains the PerpendicualarOffset parameter, the angle will be set to 0 and the PerpendicualarOffset will be used to set the offset values in the label object. SLD 1.1.0 introduces the IsAligned parameter for LinePlacement: if this parameter is set to false, the angle will be set to 0. The following are examples of valid requests using the TextSymbolizer: annotation layer : test for label, font, point placement, color, angle: sld 10a / full request 10a annotation layer with text and symbols using 2 symbolizers: sld 10b / full request 10b line layer with text using 2 symbolizers: sld 10c / full request 10c 9.8. SLD 419
Table 11. RasterSymbolizer Features Geometry Opacity ChannelSelection OverlapBehaviour ColorMap ContrastEnhancement ShadedRelief ImageOutline Supported No Yes No No Yes No No No Notes
The current support in MapServer includes only ColorMap parameter support. It can be used to classify 8-bit rasters. Inside the ColorMap parameters, the color and quantity parameters are extracted and used to do the classication. Table 12. ColorMap The following Features are available in SLD 1.0 Features Color Opacity Quantity Label Supported Yes No Yes No Notes
The following is an example of ColorMap usage for SLD 1.0. If we have following ColorMap in an SLD:
<ColorMap> <ColorMapEntry <ColorMapEntry <ColorMapEntry <ColorMapEntry <ColorMapEntry <ColorMapEntry </ColorMap>
Note that the ColorMapEntry quantity parameters should be in increasing order. The following Features are available in SLD 1.1 The following is an example of and SLD 1.1.0 with a raster symbolizer
<StyledLayerDescriptor version="1.1.0" xsi:schemaLocation="http://www.opengis.net/sld http://schemas. <NamedLayer> <se:Name>landsat</se:Name> <UserStyle> <se:Name>xxx</se:Name> <se:FeatureTypeStyle> <se:Rule>
420
<se:RasterSymbolizer> <se:Opacity>0.7</se:Opacity> <se:ColorMap> <se:Categorize fallbackValue="#78c818"> <se:LookupValue>Rasterdata</se:LookupValue> <se:Value>#ffffff</se:Value> <se:Threshold>22</se:Threshold> <se:Value>#00ff00</se:Value> <se:Threshold>30</se:Threshold> <se:Value>#00bf3f</se:Value> <se:Threshold>37</se:Threshold> <se:Value>#007f7f</se:Value> <se:Threshold>45</se:Threshold> <se:Value>#003fbf</se:Value> <se:Threshold>52</se:Threshold> <se:Value>#0000ff</se:Value> <se:Threshold>60</se:Threshold> <se:Value>#000000</se:Value> </se:Categorize> </se:ColorMap> </se:RasterSymbolizer> </se:Rule> </se:FeatureTypeStyle> </UserStyle> </NamedLayer> </StyledLayerDescriptor>
Examples using 8 bits and 16 bits rasters can be seen at: example 1 example 2
9.8. SLD
421
The other major item is the generation of an SLD document from MapServer classes. These functions are currently available through MapServer/MapScript interface. Here are the functions available: on a map object: generatesld on a layer object: generatesld Additional MapScript functions have been added or will be added to complement these functions: on a map object: applysld on a layer object: applysld Note: When generating an SLD from MapServer classes, if there is a pixmap symbol you need to have this symbol available through a URL so it can be converted as an ExternalGraphic symbol in the SLD. To do this, you need to dene the URL through a web object level metadata called WMS_SLD_SYMBOL_URL in your map le. The SLD generated uses this URL and concatenates the name of the pixmap symbol le to get the value that is generated as the ExternaGraphic URL. PHP/MapScript Example that Generates an SLD from a Maple The following is a small script that calls the generateSLD() function to create an SLD for a specic layer in a maple:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
<?php // define variables define( "MAPFILE", "D:/ms4w/apps/cadastra/map/cadastra.map" ); define( "MODULE", "php_mapscript.dll" ); // load the mapscript module if (!extension_loaded("MapScript")) dl(MODULE); // open map $oMap = ms_newMapObj( MAPFILE ); // get the parcel layer $oLayer = $oMap->getLayerByName("parcel"); // generate the sld for that layer $SLD = $oLayer->generateSLD(); // save sld to a file $fp = fopen("parcel-sld.xml", "a"); fputs( $fp, $SLD ); fclose($fp); ?>
422
LAYER ... CLASSGROUP "group1" ... CLASS NAME "name1" GROUP "group1" ... END CLASS NAME "name2" GROUP "group2" ... END CLASS NAME "name3" GROUP "group1" ... END ...
At rendering time, if the CLASSGROUP is dened, only classes that have the same group name would be used. Based on this concept, WMS/SLD support uses the class groups as named styles. Each group of classes is considered equivalent to a named style: The GetCapbilities request will output all the styles that are available The GetMap request can use the STYLES parameter to specify a named style The GetLegendGraphic can use the STYLES parameter to specify a named style
423
Table of Contents WCS Server Introduction Conguring Your Maple to Serve WCS Layers Test Your WCS 1.0 Server WCS 1.1.0+ Issues Reference Section Rules for handling SRS in a MapServer WCS Spatio/Temporal Indexes To-do Items and Known Limitations
9.9.1 Introduction
A WCS (or Web Coverage Service) allows for the publication of coverages- digital geospatial information representing space-varying phenomena. In the MapServer world it allows for unltered access to raster data. Conceptually it is easy think of WCS as a raster equivalent of WFS. The following documentation is based on the Open GIS Consortiums (OGC) Web Coverage Server Interfaces Implementation Specication version 1.0.0. Links to WCS-Related Information WCS 1.0.0 specication WCS 1.1.1c1 specication WMS Server HowTo Software Requirements In order to enable MapServer to serve WCS data, it MUST be compiled against certain libraries: PROJ.4: The reprojection library. Version 4.4.3 or greater is required. GDAL: raster support library. MapServer: version >= 4.4 (tested with 5.0.2 while updating this document) For WCS 1.1.x support (MapServer 5.2) there is an additional requirement: libxml2: An xml parser and generation library. Please see the MapServer UNIX Compilation and Installation HowTo for detailed instructions on compiling MapServer with support for these libraries and features. For Windows users, MapServer for Windows (MS4W) comes WCS Server support.
424
# # Start of web interface definition # WEB IMAGEPATH "/ms4w/tmp/ms_tmp/" IMAGEURL "/ms_tmp/" METADATA "wcs_label" "GMap WCS Demo Server" ### required "wcs_description" "Some text description of the service" "wcs_onlineresource" "http://127.0.0.1/cgi-bin/mapserv.exe?" ### recommended "wcs_fees" "none" "wcs_accessconstraints" "none" "wcs_keywordlist" "wcs,test" "wcs_metadatalink_type" "TC211" "wcs_metadatalink_format" "text/plain" "wcs_metadatalink_href" "http://someurl.com" "wcs_address" "124 Gilmour Street" "wcs_city" "Ottawa" "wcs_stateorprovince" "ON" "wcs_postcode" "90210"
425
"wcs_country" "Canada" "wcs_contactelectronicmailaddress" "blah@blah" "wcs_contactperson" "me" "wcs_contactorganization" "unemployed" "wcs_contactposition" "manager" "wcs_contactvoicetelephone" "613-555-1234" "wcs_contactfacimiletelephone" "613-555-1235" "wcs_service_onlineresource" "http://127.0.0.1/cgi-bin/mapserv.exe?" END END PROJECTION "init=epsg:42304" END
LAYER NAME b a t h y m e t r y METADATA "wcs_label" "Elevation/Bathymetry" "wcs_rangeset_name" "Range 1" "wcs_rangeset_label" "My Label" END TYPE RASTER ### required STATUS ON DATA b a t h _ m a p s e r v e r . t i f PROJECTION "init=epsg:42304" END DUMP TRUE ### required END
### required ### required to support DescribeCoverage request ### required to support DescribeCoverage request
If you get an error message in the XML output then take necessary actions. Common problems and solutions are listed in the FAQ at the end of this document. If everything went well, you should have a complete XML capabilities document. Search it for the word WARNING... MapServer inserts XML comments starting with <!WARNING: in the XML output if it detects missing maple parameters or metadata items. Note that when a request happens, it is passed through WMS, WFS, and WCS in MapServer (in that order) until one of the services respond to it.
426
http://maps.dnr.state.mn.us/cgi-bin/mapserv50?MAP=/usr/local/www/docs_maps/mapserver_demos/wcs/demo.map&SERVICE=wcs& Test With a DescribeCoverage Request OK, now that we know that our server can produce a valid XML GetCapabilities response we should test the DescribeCoverage request. The DescribeCoverage request lists more information about specic coverage offerings. Using a web browser, access your servers online resource URL to which you add the parameters SERVICE=WCS&VERSION=1.0.0&REQUEST=DescribeCoverage&COVERAGE=layername to the end, e.g.
http://my.host.com/cgi-bin/mapserv?map=mywcs.map&SERVICE=WCS&VERSION=1.0.0&REQUEST=DescribeCoverage&C
http://maps.dnr.state.mn.us/cgi-bin/mapserv50?MAP=/usr/local/www/docs_maps/mapserver_demos/wcs/demo.map&SERVICE=wcs& Test With a GetCoverage Request The GetCoverage request allows for the retrieval of coverages in a specied output format to the client. The following is a list of the required GetCoverage parameters according to the WCS spec: VERSION=version: Request version REQUEST=GetCoverage: Request name COVERAGE=coverage_name: Name of an available coverage, as stated in the GetCapabilities CRS=epsg_code: Coordinate Reference System in which the request is expressed. BBOX=minx,miny,maxx,maxy: Bounding box corners (lower left, upper right) in CRS units. One of BBOX or TIME is required. TIME=time1,time2: Request a subset corresponding to a time. One of BBOX or TIME is required.. WIDTH=output_width: Width in pixels of map picture. One of WIDTH/HEIGHT or RESX/Y is required. HEIGHT=output_height: Height in pixels of map picture. One of WIDTH/HEIGHT or RESX/Y is required. RESX=x: When requesting a georectied grid coverage, this requests a subset with a specic spatial resolution. One of WIDTH/HEIGHT or RESX/Y is required. RESY=y: When requesting a georectied grid coverage, this requests a subset with a specic spatial resolution. One of WIDTH/HEIGHT or RESX/Y is required. FORMAT=output_format: Output format of map, as stated in the GetCapabilities. The following are optional GetCoverage parameters according to the WCS spec: RESPONSE_CRS=epsg_code: Coordinate Reference System in which to express coverage responses. So to follow our above examples, a valid DescribeCoverage request would look like:
http://my.host.com/cgi-bin/mapserv?map=mywcs.map&SERVICE=wcs&VERSION=1.0.0&REQUEST=GetCoverage &coverage=bathymetry&CRS=EPSG:42304&BBOX=-2200000,-712631,3072800,3840000 &WIDTH=3199&HEIGHT=2833&FORMAT=GTiff
427
Here is a working example of a GetCoverage request (note that a 3MB tif is being requested, so this may take a few seconds):
http://gws2.pcigeomatics.com/wcs1.0.0/wcs?SERVICE=wcs&VERSION=1.0.0&REQUEST=GetCoverage&COVERAGE=demo/wcs_ 117.88341239280106,33.707704191028995,-117.65485697866967,33.89850474983795&WIDTH=700&HEIGHT=700&FORMAT=G
The format of the returned capabilities document is substantially altered from WCS 1.0, and makes use of OWS Common for service descriptions. DescribeCoverage The DescribeCoverage request is similar to WCS 1.0, but the IDENTIFIER keyword is used instead of COVERAGE to name the coverage being requested:
SERVICE=WCS&VERSION=1.1.0&REQUEST=DescribeCoverage&IDENTIFIER=spaceimaging
GetCoverage The format for GetCoverage is substantially changed from 1.0. The following is a list of GetCoverage required parameters: VERSION=version: Request version REQUEST=GetCoverage: Request name IDENTIFIER=coverage_name: Name of an available coverage, as stated in the GetCapabilities BOUNDINGBOX=minx,miny,maxx,maxy,crs: Bounding box corners (lower left, upper right), and the CRS they are in. The CRS is described using a URN. FORMAT=output_format: Output format (mime type) of grid product, as stated in the GetCapabilities. If an alternate spatial resolution is desired, then the following set of keywords must be used to specify the sample origin and step size of the output grid to be produced. The produced grid will be of a number of pixels and lines as can be t in the BOUNDINGBOX starting at GridOrigin, at GridOffsets resolution. GRIDBASECRS=crs: The grid base CRS (URN). GRIDCS=crs: The grid CRS (URN). GridType=urn:ogc:def:method:WCS:1.1:2dGridIn2dCrs: This is the only supported value for MapServer. GridOrigin=x_origin,y_origin: The sample point for the top left pixel. GridOffsets=xstep,ystep: The x and y step size for grid sampling (resolution). Both are positive. 428 Chapter 9. OGC Support and Conguration
As well, the following optional parameters are available. RangeSubset=selection: Selects a range subset, and interpolation method. Currently only subsetting on bands are allowed. Depending on rangeset names, this might take the form BandsName[bands[1]] to select band 1, or BandsName:bilinear[bands[1]] to select band 1 with bilinear interpolation. So a simple GetCoverage might look like:
SERVICE=WCS&VERSION=1.1.0&REQUEST=GetCoverage&IDENTIFIER=dem&FORMAT=image/tiff &BOUNDINGBOX=43,33,44,34,urn:ogc:def:crs:EPSG::4326
It should also be noted that return results from WCS 1.1 GetCoverage requests are in multi-part mime format. Typically this consists of a rst part with an xml document referencing the other parts of the message, and an image le part. However, for output formats that return multiple les, each will be a separate part. For instance, this means it is possible to return a jpeg le with a world le, the OUTPUTFORMAT is appropriately congured. URNs In WCS 1.1 protocol coordinate systems are referenced by URN. Some typical URNs are:
urn:ogc:def:crs:EPSG::4326 urn:ogc:def:crs:EPSG:27700 urn:ogc:def:crs:OGC::CRS84
The rst two are roughly equivalent to EPSG:4326, and EPSG:27700 while the third is a CRS dened by OGC (essentially WGS84). One critical thing to note is that WCS 1.1 follows EPSG dened axis/tuple ordering for geographic coordinate systems. This means that coordinates reported, or provided in urn:ogc:def:EPSG::4326 (WGS84) are actually handled as lat, long, not long,lat. So, for instance the BOUNDINGBOX for an area in California might look like:
BOUNDINGBOX=34,-117,35,-116,urn:ogc:def:crs:EPSG::4326
And, likewise the bounds reported by GetCapabilities, and DescribeCoverage will be in this ordering as appropriate.
429
Web Object Metadata wcs_abstract Description: (Optional) A brief description of the service, maps to ows:Abstract (WCS 1.1+ only). wcs_accessconstraints Description: (Optional) A list of codes describing any access constraints imposed by the service provider. The keyword NONE is reserved to mean no access constraints are imposed. wcs_address, wcs_city, wcs_contactelectronicmailaddress, wcs_contactfacimiletelephone, wcs_contactorganization, wcs_contactperson, wcs_contactposition, wcs_contactvoicetelephone, wcs_country, wcs_postcode, wcs_service_onlineresource, wcs_stateorprovince Description: (Optional) Contact address information. If provided then all twelve metadata items are required. You can also use the responsibleparty* metadata instead. wcs_description Description: (Optional) A description of the server. wcs_fees Description: (Optional) A text string indicating any fees imposed by the service provider. wcs_keywords Description: (Optional) Short words for catalog searching. wcs_label Description: (Required) A human-readable label for the server. wcs_metadatalink_format Description: (Optional) The le format MIME type of the metadata record (e.g. text/plain). The web metadata wcs_metadatalink_type and wcs_metadatalink_href must also be specied. wcs_metadatalink_href Description: (Optional) The URL to the servers metadata. The web metadata wcs_metadatalink_format and wcs_metadatalink_type must also be specied. wcs_metadatalink_type Description: (Optional) The standard to which the metadata complies. Currently only two types are valid: TC211 which refers to [ISO 19115], and FGDC which refers to [FGDC-STD-001-1988]. The web metadata wcs_metadatalink_format and wcs_metadatalink_href must also be specied. wcs_name
430
Description: (Optional) A name for the server. wcs_responsibleparty_address_administrativearea, wcs_responsibleparty_address_city, wcs_responsibleparty_address_country, wcs_responsibleparty_address_deliverypoint, wcs_responsibleparty_address_electronicmailaddress, wcs_responsibleparty_address_postalcode, wcs_responsibleparty_individualname, wcs_responsibleparty_onlineresource, wcs_responsibleparty_organizationname, wcs_responsibleparty_phone_facsimile, wcs_responsibleparty_phone_voice, wcs_responsibleparty_postionname Description: (Optional) Contact address information. If provided then all twelve metadata items are required. You can also use the address* metadata instead. Layer Object Metadata wcs_abstract Description: (Optional) A brief description of the service, maps to ows:Abstract (WCS 1.1+ only). wcs_description Description: (Optional) A description of the layer. wcs_extent Description: (Optional) Bounding box of layer, which must be provided for tiled data. Comma-delimited, in the format of: minx,miny,maxx,maxy wcs_formats Description: (Optional) The formats which may be requested for this layer, in a comma-delimited list. (e.g. GTiff,MrSID) wcs_keywords Description: (Optional) Short words for catalog searching. wcs_label Description: (Required) A human-readable label for the layer. wcs_metadatalink_format Description: (Optional) The le format MIME type of the metadata record (e.g. text/plain). The web metadata wcs_metadatalink_type and wcs_metadatalink_href must also be specied. wcs_metadatalink_href Description: (Optional) The URL to the layers metadata. The web metadata wcs_metadatalink_format and wcs_metadatalink_type must also be specied. wcs_metadatalink_type
431
Description: (Optional) The standard to which the metadata complies. Currently only two types are valid: TC211 which refers to [ISO 19115], and FGDC which refers to [FGDC-STD-001-1988]. The web metadata wcs_metadatalink_format and wcs_metadatalink_href must also be specied. wcs_name Description: (Optional) A name for the layer. wcs_nativeformat Description: (Optional) The current format of the served raster layer. (e.g. GTiff) Axes Descriptions MapServer allows you dene a number of these for a layer. Individual axis are identied by name when dening specic metadata (e.g. description). All dened axes must be listed in the rangeset_axes metadata tag so MapServer knows in advance what to expect. A special rangeset for multiband date is automatically generated by adding the name bands to the rangeset_axes list. If found MapServer will automatically generate metadata for the image bands. You may of course extend that basic support using the naming conventions below. wcs_rangeset_axes Description: (Optional) Delimited list of dened range sets. If dened, you can also use the following nine metadata items, where rangeset axis matches the axis name provided in this wcs_rangeset_axes metadata: {rangeset axis}_semantic {rangeset axis}_refsys {rangeset axis}_refsyslabel {rangeset axis}_description {rangeset axis}_label {rangeset axis}_values {rangeset axis}_values_semantic {rangeset axis}_values_type {rangeset axis}_interval wcs_rangeset_label Description: (Required for DescribeCoverage request) wcs_rangeset_name Description: (Required for DescribeCoverage request) wcs_srs Description: (Optional) Spatial reference system of the layer, in the form of: EPSG:code (e.g. EPSG:42304) wcs_timeitem Description: (Optional) The attribute in the spatio/temporal index that contains time values. wcs_timeposition Description: (Optional) A list of the start and end time of a given coverage (i.e. 2000-11-11T11:11:11Z,200111-11T11:11:11Z), used when advertising GetCapabilities. 432 Chapter 9. OGC Support and Conguration
433
This document explains how to use MapServer to deliver Landsat, SPOT, DEM, and NetCDF temporal/banded data through the MapServer WCS interface. Thanks go to Steve Lime and Frank Warmerdam for their assistance with these projects
9.10.1 Landsat
To serve Landsat imagery through the MapServer Web Coverage Service specify the OUTPUTFORMAT object. For format support install the GDAL library and from the command prompt and cd to where GDAL is installed and use the command, gdalinfo formats. A list of all supported formats will appear and will specify if the format is read only <ro> or read and write <rw> for WCS the format needs to be supported for read and write (except for GDALs own WCS format, however). For the example below the Landsat 7 15m resolution mosaic is in a Enhanced Compressed Wavelets format (ECW). By running the gdalinfo.exe program I could verify that the ECW format has write permissions, therefore the format can be specied in the MapFile and requested using the GetCoverage request.
434
OUTPUTFORMAT NAME "ECW" DRIVER "GDAL/ECW" MIMETYPE "image/ecw" IMAGEMODE "BYTE" EXTENSION "ecw" END
The keyword DUMP must be set to true to allow the data to download during a GetCoverage request.
LAYER NAME "Landsat7" STATUS OFF TYPE RASTER PROCESSING "SCALE=AUTO" UNITS Meters DUMP TRUE TILEINDEX "MapServer/wcs/landsat7/l7mosaic15m.shp" TILEITEM "Location" METADATA "wcs_description" "Landsat 7 15m resolution mosaic" "wcs_name" "Landsat7" "wcs_label" "Landsat 7 15m resolution mosaic" "ows_srs" "EPSG:27700" "ows_extent" "0 0 700005 1050000" "wcs_resolution" "75 75" "wcs_bandcount" "3" "wcs_formats" "ECW" END END
A GetCoverage request can then be requested (using the parameters set in the MapFile) by creating a URL with the elements: - Your Server, MapServer Program, Location of MapFile, Type of Service (WCS), Request (GetCoverage), Coverage (Landsat7), BBOX (0,0,700005,1050000), CRS (EPSG:27700), ResX (75) ResY (75), Format (ECW).
9.10.2 SPOT
SPOT imagery can be delivered through MapServer Web Coverage Service similarly to the Landsat example above. The main difference is that as SPOT is a greyscale image the wcs_bandcount = 1 rather than a Landsat image which consists of 3 bands. For this example the well known GeoTiff format will be used to demonstrate what to specify in a MapFile for SPOT data.
OUTPUTFORMAT NAME "GEOTIFF" DRIVER "GDAL/GTiff" MIMETYPE "image/tiff" IMAGEMODE "BYTE" EXTENSION "tif" END LAYER NAME "SPOT" STATUS OFF TYPE RASTER PROCESSING "SCALE=AUTO" UNITS Meters DUMP TRUE
435
TILEINDEX "MapServer/wcs/orthospot/spot.shp" TILEITEM "Location" METADATA "wcs_description" "Orthospot mosaic" "wcs_name" "SPOT" "wcs_label" "Orthospot mosaic" "ows_srs" "EPSG:27700" "ows_extent" "375960 64480 497410 200590" "wcs_resolution" "100 100" "wcs_bandcount" "1" "wcs_formats" "GEOTIFF" "wcs_nativeformat" "8-bit GeoTIF" END END
The key parameters to specify in the WCS MapFile for any data layer and format are:
- Layer Name = Create a short name for the data - Layer Type = Raster - Layer Dump = True
The following examples further demonstrate how WCS can be implemented and also how to create WCS containing layers with a temporal dimension (see NetCDF example).
9.10.3 DEM
It is possible to deliver 16 bit DEM data through the MapServer Web Coverage Service. Firstly it is necessary to specify the output format in the map le
OUTPUTFORMAT NAME "GEOTIFFINT16" DRIVER "GDAL/GTiff" MIMETYPE "image/tiff" IMAGEMODE "INT16" EXTENSION "tif" END
436
END END
by
using
the
gdaladdo
utility
described
at
9.10.4 NetCDF
Firstly GDAL doesnt support all versions of netCDF (there are a lot, it is a generic format), so for stability it may be necessary to convert the les into GeoTiff format rst. This can be achieved using the netCDF libraries here http://my.unidata.ucar.edu/content/software/netcdf/index.html. Denis Nadeau and Frank Warmerdam have added netCDF CF as a read only format within GDAL, so it now possible to read the CF convention netCDF les directly from disk. We placed the Z-levels in the bands of the GDAL data le (either GeoTiff or netCDF), and created a shape index for the time levels. GDAL data is a 2-D format (x,y) and bands. netCDF is an N-D le format, supporting time, x,y,z, and experiment parameters. By using a set of GDAL netCDF / geoTiff les it is possible to represent this, and to store the z-level (height) as bands within the data le. Although a hack, it is possible for a custom client to receive important metadata from the describeCoverage operation of a WCS about the which z-level a band of a geotiff represents by encoding this in the returned axes description tag. To create the shape le for the temporal dimension we had to do some hacking with Java code, but we also got it to work with Steve Lime s perl script in the MODIS MapServer demo download (which doesnt seem to be available now). The perl script used in Modis demo by Steve Lime is as follows, and I have placed inline comments below. The script assumes that gdaltindex has already been run in this directory to create a tile index shape and dbf le. It assumes that the lenames of your data les have the date in the lename, for example myleYYYYMMDDHH.tif
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
#!/usr/bin/perl use XBase; opendir(DIR, .); # open the current directory foreach $file (readdir(DIR)) { next if !($file =~ /\.dbf$/); # read the dbf file in this directory created by gdaltindex print "Working on $file...\n"; $tfile = temporary.dbf; system("mv $file $tfile"); $oldtable = new XBase $tfile or die XBase->errstr; print join("\t", $oldtable->field_names) ."\n"; print join("\t", $oldtable->field_types) ."\n"; print join("\t", $oldtable->field_lengths) ."\n"; print join("\t", $oldtable->field_decimals) ."\n"; $newtable = XBase->create("name" => $file, "field_names" => [$oldtable->field_names, "IMGDATE"], # this is the FILTERITEM in "field_types" => [$oldtable->field_types, "C"], # character column type "field_lengths" => [$oldtable->field_lengths, 13], # length of the date string "field_decimals" => [$oldtable->field_decimals, undef]) or die "Error creating new foreach (0 .. $oldtable->last_record) { ($deleted, @data) = $oldtable->get_record($_); print " ...record $data[0]\n"; # extract the date $year = substr $data[0], 8, 4; # year is at position 8 in the filename string $month = substr $data[0], 12, 2; # month is at position 12 in the filename string $day = substr $data[0], 14, 2; # day is at position 14 in the filename string $hour = substr $data[0], 16, 2; # hour is at position 16 in the filename string $date = "$year-$month-$day" . "T" . "$hour\n"; # format is YYYY-MM-DDTHH, or any ISO format
437
28 29 30 31 32 33 34 35
print "$date"; push @data, "$date"; $newtable->set_record($_, @data); } $newtable->close(); $oldtable->close(); unlink($tfile); }
If have used the perl script then skip to the layer denitions below, if you wish to code your own the description is here. The DBF le has to have the column location that indicates the location of the data le (either absolute path or relative to the map le location, and the second column that can be called whatever you want but indexes time. In our case we called it time :-) The corresponding shapele then has to contain Polygons with the bounding boxes of the tif le for each time. So OGRInfo timeIndex.shp looks something like:
OGRFeature(timeIndex):116 location(String) = mytime.tif time(String) = 2001-01-31T18:00:00 POLYGON ((xxx,xxxx,.......))
Then you need to dene your tile index within the map le
LAYER NAME time_idx TYPE TILEINDEX DATA timeIndex FILTERITEM time FILTER %time% END
438
"ows_extent" -180 -90 180 90 "wcs_resolution" 1.125 -1.125 "ows_srs" EPSG:4326 "wcs_formats" GEOTIFF_FLOAT "wcs_nativeformat" netCDF "wcs_bandcount" 27 "wcs_rangeset_axes" bands "wcs_rangeset_label" Pressure (hPa units) Levels "wcs_rangeset_name" bands "wcs_rangeset_description" Z levels "wcs_timeposition" 2001-01-01T06:00:00,2001-01-01T12:00:00,2001-01-01T18:00:00,2001-01-02T00:00: "wcs_timeitem" time END END
The TempData coverage layer will now let you subset with the &bands=... &time=... subset parameters! To do a coordinate reprojection specify in the request &Response_CRS=ESPG:xxxx When you start doing temporal subsetting with WCS and MapServer you can see the need for an automatic way of generating map les such as using an XSL stylesheet! For a tile-index layer you need to provide the following extra metadata in order to use it for WCS:
"OWS_EXTENT" "10050 299950 280050 619650" "WCS_RESOLUTION" "100 100" "WCS_SIZE" "2700 3197" "WCS_BANDCOUNT" "3"
If your image has a colortable and only one band, it will come out greyscale unless you set the IMAGEMODE to PC256 instead of BYTE.
Table of Contents SOS Server Introduction Setting Up an SOS Server Using MapServer Limitations / TODO Reference Section Use of sos_procedure and sos_procedure_item
439
9.11.1 Introduction
SOS (Sensor Observation Service), currently an OGC discussion paper, is part of of the OGCs SensorWeb Enablement (SWE) group of specications. These specications describe how applications and services will be able to access sensors of all types over the Web. Specically, SOS provides an API for managing deployed sensors and retrieving sensor data. SOS support is available in MapServer 4.10.0 or more recent. Note that no client tools currently exist in MapServer for SOS. More SWE based software is available at http://www.52north.org/ SOS support was implemented in MapServer to the guidelines of MapServer MS RFC 13: Support of Sensor Observation Service in MapServer. This document assumes that you are already familiar with certain aspects of MapServer: MapServer application development and setting up .map les. Links to SOS-Related Information SOS discussion paper Sensor Web Enablement and OpenGIS SensorWeb Relevant Denitions The following is taken from the SOS discussion paper: Observation An observation is an event with a result which has a value describing some phenomenon. Observation Offering An observation offering is a logical grouping of observations offered by a service that are related in some way. Observed Value A value describing a natural phenomenon, which may use one of a variety of scales including nominal, ordinal, ratio and interval. Sensor An entity capable of observing a phenomenon and returning an observed value. A sensor can be an instrument or a living organism (e.g. a person).
Example 2. On Windows:
440
C:\Apache\cgi-bin> mapserv -v MapServer version 4.9 OUTPUT=GIF OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=SVG S UPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER SUPPORTS=WMS_CLIENT SUPPORTS= WFS_SERVER SUPPORTS=WFS_CLIENT SUPPORTS=WCS_SERVER SUPPORTS=SOS_SERVER SUPPORTS= THREADS INPUT=JPEG INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE DEBUG=MSDEBUG
If you dont have SOS support in your MapServer build, then you must compile MapServer with the following in mind: ag -DUSE_SOS_SVR is required requires either -DUSE_WMS_SVR or -DUSE_WFS_SVR ags to be enabled requires libxml2 and proj libraries requires ICONV support (-DUSE_ICONV) on Windows For more help with MapServer compilation see the appropriate HowTo: Unix / Windows Congure a Maple For SOS Each instance of SOS server that you setup needs to have its own maple. It is just a regular MapServer maple in which some parameters and some metadata entries are mandatory. Most of the metadata is required in order to produce a valid GetCapabilites output. Here is the list of parameters and metadata items that usually optional with MapServer, but are required (or strongly recommended) for a SOS conguration: MAP level: Map NAME Map PROJECTION Map Metadata (in the WEB Object): sos_title sos_onlineresource sos_srs see the Reference Section of this document for a full list of metadata and descriptions LAYER level: Layer NAME Layer PROJECTION Layer METADATA sos_offering_id sos_observedproperty_id sos_observedproperty_id sos_describesensor_url see the Reference Section of this document for a full list of metadata and descriptions 9.11. SOS Server 441
Onlineresource URL
The sos_onlineresource metadata is set in the maps web object metadata and species the URL that should be used to access your server. This is required for the GetCapabilities output. If sos_onlineresource is not provided then MapServer will try to provide a default one using the script name and hostname, but you shouldnt count on that too much. It is strongly recommended that you provide the wfs_onlineresource metadata. Here is a valid online resource URL:
http://my.host.com/cgi-bin/mapserv?map=mysos.map&
By creating a wrapper script on the server it is possible to hide the map= parameter from the URL and then your servers online resource URL could be something like:
http://my.host.com/cgi-bin/mapserv?
This is covered in more detail in the More About the Online Resource URL section of the WMS Server document. Example SOS Server Maple The following is an example of a bare minimum SOS Server maple. Note the comments for the required parameters.
NAME "SOS_DEMO" STATUS ON SIZE 300 300 EXTENT -66 44 -62 45 UNITS METERS SHAPEPATH "./data/" IMAGECOLOR 255 255 0 SYMBOLSET "./etc/symbols.sym" IMAGETYPE png WEB IMAGEPATH "/ms4w/tmp/ms_tmp/" IMAGEURL "/ms_tmp/"
METADATA "sos_onlineresource" "http://127.0.0.1/cgi-bin/mapserv.exe?map=D:/ms4w/apps/sos/sos_test.map" ## R "sos_title" "My SOS Demo Server" ## Recommended "sos_srs" "EPSG:4326" ## REQUIRED END END PROJECTION "init=epsg:4326" END LAYER NAME "test_sos_layer" METADATA "sos_procedure" "NS01EE0014" ## REQUIRED "sos_offering_id" "WQ1289" ## REQUIRED "sos_observedproperty_id" "Water Quality" ## REQUIRED "sos_describesensor_url" "http://some/url/NS01EE0014.xml" ## REQUIRED END
442
TYPE POINT STATUS ON DATA "sos_test" PROJECTION "init=epsg:4326" END CLASS NAME "water quality" STYLE COLOR 255 0 0 SYMBOL "circle" SIZE 8 END END END END #map
GetCapabilities Request
The GetCapabilities request allows the clients to retrieve service metadata about a specic service instance. For an SOS service, it allows to identify such things as offerings and observed property available, as well as information on sensors that are used. Using a web browser, access your servers online resource URL to which you add the parameters SERVICE=SOS&REQUEST=GetCapabilities to the end, e.g.
http://my.host.com/cgi-bin/mapserv?MAP=mysos.map&SERVICE=SOS&REQUEST=GetCapabilities
If everything went well, you should have a complete XML capabilities document. Search it for the word WARNING... MapServer inserts XML comments starting with <!WARNING: in the XML output if it detects missing maple parameters or metadata items. If you notice any warning in your XML output then you have to x all of them before you can try your server with an SOS client, otherwise things are likely not going to work. Note: The SERVICE parameter is required for all SOS requests.
GetObservation Request
The GetObservation request is designed to query sensor systems to retrieve observation data in the form dened in the Observation and Measurement specication (O&M), and more information on this O&M spec can be found at http://www.opengeospatial.org/functional/?page=swe. Upon receiving a GetObservation request, a SOS shall either satisfy the request or return an exception report. The following is a list of the possible parameters for a GetObservation request: request: (Required) value must be GetObservation. service: (Required) value must be SOS. version: (Required) value must be 1.0.0. offering: (Required) The Offering identied in the capabilities document. 9.11. SOS Server 443
observedProperty: (Required) The property identied in the capabilities document. responseFormat: (Required) The format / encoding to be returned by the response. eventTime (Optional) Species the time period for which observations are requested. procedure: (Optional) The procedure species the sensor system used. In this implementation, the procedure is equivalent to be the sensor id that will be used when doing a DescribeSensor request. featureOfInterest: (Optional) In this implementation, this will be represented by a gml envelope dening the lower and upper corners. Result: (Optional) The Result parameter provides a place to put OGC lter expressions based on property values. resultModel: (Optional) Identier of the result model to be used for the requested data. The resultModel values supported by a SOS server are listed in the contents section of the service metadata (GetCapabilities). MapServer currently supports om:Observation and om:Measurement. om:Measurement provides a at model of the geometry and attributes, similar to WFS GetFeature output. om:Observations provides a more compact denition which includes an XML header of the eld names and dentions, followed by a DataBlock of delimited records (default is CSV delimited output). The default output is om:Measurement. srsName: (Optional) srs (EPSG code) of the output response. Here are some valid examples: Example 1:
Example 2:
Example 3:
http://127.0.0.1/cgi-bin/mapserv.exe?map=D:/ms4w/apps/sos/sos_test.map&Request=GetObservation&service Offering=WQ1289&observedproperty=Water Quality&featureofinterest= <gml:Envelope><gml:lowerCorner srsName=EPSG:4326>-66 43</gml:lowerCorner><gml:upperCorner srsName= -64 45</gml:upperCorner></gml:Envelope>&version=1.0.0&responseFormat=text/xml; subtype="om/1.0.0"
Example 4:
DescribeSensor Request
The DescribeSensor request gives the client the ability to retrieve the characteristics of a particular sensor and return the information in a SensorML xml document. In this implementation, MapServer does not generate the SensorML document but only redirect the request to an existing SensorML document. The following is a list of the possible parameters for a DescribeSensor request:
444
request: (Required) value must be DescribeSensor service: (Required) value must be SOS. version: (Required) value must be 1.0.0. procedure: (Required) This is the sensor id, which was specied in the sos_procedure metadata. outputFormat: (Required) The format encoding to be returned by the response. Here is a valid example:
445
Description: (Optional) Descriptive narrative for more information about the server. sos_keywordlist Description: (Optional) A comma-separated list of keywords or keyword phrases to help catalog searching. sos_accessconstraints Description: (Optional) Text describing any access constraints imposed by the service provider on the SOS or data retrieved from this service. sos_addresstype, sos_address, sos_city, sos_stateorprovince, sos_postcode, sos_country Description: Optional contact address information. If provided then all six metadata items are required. sos_contactelectronicmailaddress Description: Optional contact Email address. sos_contactperson, sos_contactposition, sos_contactorganization Description: Optional contact information. If provided then all three metadata items are required. sos_contactvoicetelephone Description: Optional contact voice telephone number. sos_contactfacsimiletelephone - * Description: Optional contact facsimile telephone number. sos_fees Description: (Optional) Fees information. Use the reserved word none if there are no fees. sos_onlineresource Description: (Required) The URL that will be used to access this OGC server. This value is used in the GetCapabilities response. See the section Onlineresource URL above for more information. sos_service_onlineresource Description: (Optional) Top-level onlineresource URL. sos_srs Description: (Required) Contains a list of EPSG projection codes that should be advertized as being available for all layers in this server. The value can contain one or more EPSG:<code> pairs separated by spaces (e.g. EPSG:4269 EPSG:4326) This value should be upper case (EPSG:42304.....not epsg:42304) to avoid problems with case sensitive platforms. sos_title 446 Chapter 9. OGC Support and Conguration
Description: (Recommended) A human-readable name for this Layer. sos_hoursofservice Description: (Optional) Time period (including time zone) when individuals can contact the organization or individual. sos_contactinstructions Description: (Optional) Supplemental instructions on how or when to contact the individual or organization. sos_role Description: (Optional) Function performed by the responsible party. Possible values of this Role shall include the values and the meanings listed in Subclause B.5.5 of ISO 19115:2003. sos_maxfeatures Description: (Optional) The number of elements to be returned by the WFS server. If the not set all observations are returned sos_encoding_blockSeparator Description: (Optional) For GetObservation requests using resultModel=om:Observation (SWE DataBlock encoding). Record separator to be used. Default is \n sos_encoding_tokenSeparator Description: (Optional) For GetObservation requests using resultModel=om:Observation (SWE DataBlock encoding). Token (eld) separator to be used. Default is , Layer Object Metadata sos_describesensor_url Description: (Required) This metadata item is only a temporary measure until the describe sensor is generated from MapServer. Right now when a DescribeSensor request is sent with a procedure (sensorid), it will redirect it to the url dened by this metadata item. In MapServer 5.0, it is possible to use variable substituion on the url. For example sos_describesensor_url http://foo/foo?mysensor=%procedure% will substitute the %procedure% in the metadata with the procedure value coming from the request.
"sos_describesensor_url" "http://some/url/NS01EE0014.xml"
sos_[item name]_alias Description: (Optional) An alias for an attributes name that will be returned when executing a GetObservation request. sos_[item name]_denition
447
Description: (Optional) An associated denition (usually a URN) for a component, that will be returned when executing a GetObservation request. Default is urn:ogc:object:denition sos_[item name]_uom Description: (Optional) An associated unit of measure URN) for a component, that will be returned when executing a GetObservation request. Default is urn:ogc:object:uom sos_observedproperty_id Description: (Required) ID of observed property, possibly in number format. sos_observedproperty_name Description: (Optional) Name of observed property, possibly in string format. sos_observedproperty_authority Description: (Optional) An associated authority for a given component of an observed property sos_observedproperty_version Description: (Optional) An associated version for a given component of an observed property sos_offering_description Description: (Optional) Description of offering. sos_offering_extent Description: (Optional) Spatial extents of offering, in minx, miny, maxx, maxy format:
"sos_offering_extent" "-66, 43, -62, 45"
The logic for the bounding box returned as part of the offering is the following: note that it is a mandatory element that needs an espg code and lower/upper corner coordinates looks for the espg parameter in the rst layer of the offering (this could be an ows/sos_srs or a projection object with the epsg code (mandatory) looks for sos_offering_extent. If the metadata is not available, the extents of all layers in the offering will be used to compute it. Here is an example result from a GetCapabilities request:
<gml:boundedBy> <gml:Envelope> <gml:lowerCorner srsName="EPSG:4326">-66 43</gml:lowerCorner> <gml:upperCorner srsName="EPSG:4326">-62 45</gml:upperCorner> </gml:Envelope> </gml:boundedBy>
sos_offering_id
448
Description: (Required) ID of offering, possibly in number format. sos_offering_intendedapplication Description: (Optional) The intended category of use for this offering. sos_offering_name Description: (Optional) Name of offering, possibly in string format. sos_offering_timeextent Description: (Optional) Time extent of offering, in the format of begin/end. Here is an example:
"sos_offering_timeextent" "1990/2006"
If end is not specied it will be set to now. Here is an example result from a GetCapabilities request:
<sos:eventTime> <gml:TimePeriod> <gml:beginPosition>1990</gml:beginPosition> <gml:endPosition>2006</gml:endPosition> </gml:TimePeriod> </sos:eventTime>
sos_procedure Description: (Required) Normally a sensor unique id. One per layer:
"sos_procedure" "NS01EE0014"
All sos_procedure links from layers in the offerings will be outputed together, such as the following taken from a GetCapabilities response:
<procedure xlink:href="urn:ogc:object:feature:Sensor:3eTI:csi-sensor-1"/> <procedure xlink:href="urn:ogc:object:feature:Sensor:3eTI:csi-sensor-2"/>
sos_procedure_item Description: (Required if sos_procedure is not present): See section 5 for more details
"sos_procedure_item" "attribute_field_name"
sos_timeitem Description: (Optional) Name of the time eld. It will be used for queries when a GetObservation request is called with an EVENTTIME parameter. It is layer specic and should be set on all layers.
449
"sos_timeitem" "TIME"
Contents MapScript Wrappers for WxS Services Introduction Python Examples Perl Example Java Example PHP Example Use in Non-CGI Environments (mod_php, etc) Post Processing Capabilities
9.12.1 Introduction
With the implementation of MapServer MS RFC 16: MapScript WxS Services in MapServer 4.9, MapScript now has the ability to invoke MapServers ability to execute OGC Web Service requests such as WMS, WCS, and WFS as well as capturing the results of processing the requests. This makes it possible to dynamically congure a map object based on information in the original request, and to capture the output of processing requests for further post-processing.
The OWSRequest object is used to manage a parsed list of OWS processing options. In the above example they are loaded from the environment using the loadParams() call which fetches and parses them from QUERY_STRING in the same way the mapserv executable would. Then we load a map, and invoke OWSDispatch with the given arguments on that map. By default the results of the dispatched request are written to stdout which returns them back to the client.
451
The following example ignores all passed in arguments, and manually constructs a request argument by argument. It is likely more useful for testing purposes than for deploying WxS services, but demonstrates direct manipulation of the request object.
import mapscript req = mapscript.OWSRequest() req.setParameter( SERVICE, WMS ) req.setParameter( VERSION, 1.1.0 ) req.setParameter( REQUEST, GetCapabilities ) map = mapscript.mapObj( /u/www/maps/ukpoly/ukpoly.map ) map.OWSDispatch( req )
The previous example have all let results be returned directly to the client. But in some cases we want to be able to capture, and perhaps modify the results of our requests in some custom way. In the following example we force the hated OGC required mime type for errors to simple text/xml (warning - non-standard!)
import mapscript req = mapscript.OWSRequest() req.loadParams() map = mapscript.mapObj( /u/www/maps/ukpoly/ukpoly.map ) mapscript.msIO_installStdoutToBuffer() map.OWSDispatch( req ) content_type = mapscript.msIO_stripStdoutBufferContentType() content = mapscript.msIO_getStdoutBufferBytes() if content_type == vnd.ogc.se_xml: content_type = text/xml print Content-type: + content_type print print content
This example demonstrates capture capturing output of OWSRequest to a buffer, capturing the Content-type: header value, and capturing the actual content as binary data. The msIO_getStdoutBufferBytes() function returns the stdout buffer as a byte array. If the result was known to be text, the msIO_getStdoutBufferString() function could have been used to fetch it as a string instead, for easier text manipulation.
452
$map = new mapscript::mapObj( "/u/www/maps/ukpoly/ukpoly.map" ); mapscript::msIO_installStdoutToBuffer(); $dispatch_out = $map->OWSDispatch( $req ); printf "%s\n", mapscript::msIO_getStdoutBufferString();
One issue in Perl is that there is currently no wrapping for binary buffers so you cannot call msIO_getStdoutBufferBytes(), and so cannot manipulate binary results. More Perl example code
#!/usr/bin/perl ############################################################################ # # Name: wxs.pl # Project: MapServer # Purpose: MapScript WxS example # # Author: Tom Kralidis # ############################################################################## # # Copyright (c) 2007, Tom Kralidis # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies of this Software or works derived from this Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. ############################################################################/ use use use use use use CGI::Carp qw(fatalsToBrowser); mapscript; strict; warnings; XML::LibXSLT; XML::LibXML;
453
# heres the actual document inline for # testing save and alter $xsltFile above =comment <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:wfs="http://www.opengis.net/wfs"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <WFSLayers> <xsl:for-each select="//wfs:FeatureType"> <wfs_layer> <name><xsl:value-of select="wfs:Name"/></name> <title><xsl:value-of select="wfs:Title"/></title> </wfs_layer> </xsl:for-each> </WFSLayers> </xsl:template> </xsl:stylesheet> =cut my $mapfile = "/tmp/config.map"; # init OWSRequest object my $req = new mapscript::OWSRequest(); # pick up CGI paramters passed $req->loadParams(); # init mapfile my $map = new mapscript::mapObj($mapfile);
# if this is a WFS GetCapabilities request, then intercept # what is normally returned, process with an XSLT document # and then return that to the client if ($req->getValueByName(REQUEST) eq "GetCapabilities" && $req->getValueByName(SERVICE) eq "WFS") # push STDOUT to a buffer and run the incoming request my $io = mapscript::msIO_installStdoutToBuffer(); $dispatch = $map->OWSDispatch($req); # at this point, the clients request is sent # pull out the HTTP headers my $ct = mapscript::msIO_stripStdoutBufferContentType(); # and then pick up the actual content of the response my $content = mapscript::msIO_getStdoutBufferString(); my $xml = XML::LibXML->new(); my $xslt = XML::LibXSLT->new(); # load XML content my $source = $xml->parse_string($content); # load XSLT document my $style_doc = $xml->parse_file($xsltfile);
454
my $stylesheet = $xslt->parse_stylesheet($style_doc); # invoke the XSLT transformation my $results = $stylesheet->transform($source); # print out the result (header + content) print "Content-type: $ct\n\n"; print $stylesheet->output_string($results); } # else process as normal else { $dispatch = $map->OWSDispatch($req); }
public void run() { mapObj map = new mapObj(mapName); map.setMetaData( "ows_onlineresource", "http://dummy.org/" ); OWSRequest req = new OWSRequest(); req.setParameter( "SERVICE", "WMS" ); req.setParameter( "VERSION", "1.1.0" ); req.setParameter( "REQUEST", "GetCapabilities" ); mapscript.msIO_installStdoutToBuffer(); int owsResult = map.OWSDispatch( req ); if( owsResult != 0 ) System.out.println( "OWSDispatch Result (expect 0): " + owsResult ); resultBytes = mapscript.msIO_getStdoutBufferBytes(); } } public class WxSTest { public static void main(String[] args) { try { WxSTest_thread tt[] = new WxSTest_thread[100]; int i;
455
int expectedLength=0, success = 0, failure=0; for( i = 0; i < tt.length; i++ ) { tt[i] = new WxSTest_thread(); tt[i].mapName = args[0]; } for( i = 0; i < tt.length; i++ ) tt[i].start();
for( i = 0; i < tt.length; i++ ) { tt[i].join(); if( i == 0 ) { expectedLength = tt[i].resultBytes.length; System.out.println( "Document Length: " + expectedLength + ", expecting somewhere a } else if( expectedLength != tt[i].resultBytes.length ) { System.out.println( "Document Length:" + tt[i].resultBytes.length + " Expected:" + failure++; } else success++; } System.out.println( "Successes: " + success ); System.out.println( "Failures: " + failure ); } catch( Exception e ) { e.printStackTrace(); } } }
<?php dl("php_mapscript_4.10.0.dll"); $request = ms_newowsrequestobj(); $request->loadparams(); /*exampple on how to modify the parameters : forcing the version from 1.1.1 to 1.1.0 */
456
$request->setParameter("VeRsIoN","1.1.0"); ms_ioinstallstdouttobuffer(); $oMap = ms_newMapobj("../../service/wms.map"); $oMap->owsdispatch($request); $contenttype = ms_iostripstdoutbuffercontenttype(); $buffer = ms_iogetstdoutbufferstring(); header(Content-type: application/xml); echo $buffer; ms_ioresethandlers(); ?>
Example2 : get the map This is for example what a url could look like : http://.../php/ows.php?SERVICE=WMS&VeRsIoN=1.1.1&Request=GetMap& LAYERS=WorldGen_Outline
<?php dl("php_mapscript_4.10.0.dll"); $request = ms_newowsrequestobj(); $request->loadparams(); ms_ioinstallstdouttobuffer(); $oMap = ms_newMapobj("../../service/wms.map"); $oMap->owsdispatch($request); $contenttype = ms_iostripstdoutbuffercontenttype(); if ($contenttype == image/png) header(Content-type: image/png); ms_iogetStdoutBufferBytes(); ms_ioresethandlers(); ?>
457
and perl are used as loaded modules in Apache, or Java with Tomcat, the loadParams() call will not work - in fact in 4.10.x it will terminate the web server instance. It is necessary in these circumstances for the calling script/application to parse the request url into keyword/value pairs and assign to the OWSRequest object by other means, as shown in some of the above examples explicitly setting the request parameters.
458
CHAPTER
TEN
OPTIMIZATION
10.1 Maple
Author David Fawcett Contact david.fawcett at gmail.com Revision $Revision: 8365 $ Date $Date: 2008-12-31 07:49:02 -0800 (Wed, 31 Dec 2008) $ Last Updated 2007/08/01
10.1.1 Introduction
The contents of a Map File are used by MapServer for conguration, data access, projection, and more. Because the Map File is parsed every time a map image is requested, it is important to think about what you include in the le in order to optimize performance. The optimal Map File is one that doesnt include or reference anything that isnt needed. 1. Projections There are two ways to dene projections in a Map File. You can either use inline projection parameters or specify an EPSG code for that projection. If you use the EPSG code method, Proj.4 looks up the projection parameters in the Proj4 database using the EPSG code as an ID. This database lookup takes signicantly more resources than when the projection parameters are dened inline. This lookup takes place for each projection denition using EPSG codes in a Map File. Projection dened using inline projection parameters
PROJECTION "proj=utm" "ellps=GRS80" "datum=NAD83"
459
Optimization Suggestions Use inline projection parameter denitions in place of EPSG codes. If you want to use EPSG codes, remove all unneeded projection denition records from the Proj.4 EPSG database. 2. Layers For every layer in a Map File that has a status of ON or DEFAULT, MapServer will load that layer and prepare it for display, even if that layer never gets displayed. Optimization Suggestions Build lean Map Files, only include layers that you plan to use. Turn off unnecessary layers; the more layers MapServer is displaying, the more time it takes. Have your opening map view show only the minimum necessary to orient the user, and allow them to turn on additional layers as needed. This is particularly true of remote WMS or very large rasters. Related to turning off layers, is turning them on but using MINSCALEDENOM and MAXSCALEDENOM to determine at what zoomlevels the layer is available. If a maps display is outside of the layers MINSCALEDENOM and MAXSCALEDENOM range, then MapServer can skip processing that layer. It also makes for a really cool effect, that the national boundaries magically change to state boundaries. If you have a complex application, consider using multiple simple and specic Map Files in place of one large do everything Map File. In a similar vein, each class also supports MINSCALEDENOM and MAXSCALEDENOM. If your dataset has data that are relevant at different zoomlevels, then you may nd this a very handy trick. For example, give a MINSCALEDENOM of 1:1000000, county roads a MINSCALEDENOM of 1:100000, and streets a MAXSCALEDENOM of 1:50000. You get the cool effect of new data magically appearing, but you dont have MapServer trying to draw the nations roads when the entire nation is in view! Classes are processed in order, and a feature is assigned to the rst class that matches. So try placing the most commonly-used classes at the top of the class list, so MapServer doesnt have to try as many classes before nding a match. For example, if you wanted to highlight the single state of Wyoming, you would probably do this:
CLASS EXPRESSION ([NAME] eq WY]) STYLE COLOR 255 0 0 END
460
But it would be a lot more efcient to do this, since 98% of cases will be matched on the rst try:
CLASS EXPRESSION ([NAME] ne WY]) STYLE COLOR 128 128 128 END END CLASS STYLE COLOR 255 0 0 END END
Use tile indexes instead of multiple layers. 3. Symbols When the Map File is loaded, each raster symbol listed in the symbols le is located on the lesystem and loaded. Optimization Suggestions Only include raster symbols in your symbols le if you know that they will be used by your application. 4. Fonts To load a font, MapServer opens up the fonts.list FONTSET le which contains an alias for the font and the path for that font le. If you have a fonts.list le with a long list of fonts, it will take more time for MapServer to locate and load the font that you need. Optimization Suggestions Limit the entries in fonts.list to fonts that you actually use.
10.2 Vector
Author HostGIS Revision $Revision: 8365 $ Date $Date: 2008-12-31 07:49:02 -0800 (Wed, 31 Dec 2008) $ Last Updated 2008/08/08
10.2. Vector
461
Table of Contents Vector Splitting your data Shapeles PostGIS Databases in General (PostGIS, Oracle, MySQL)
10.2.2 Shapeles
Use shptree to generate a spatial index on your shapele. This is quick and easy (shptree foo.shp) and generates a .qix le. MapServer will automagically detect an index and use it. MapServer also comes with the sortshp utility. This reorganizes a shapele, sorting it according to the values in one of its columns. If youre commonly ltering by criteria and its almost always by a specic column, this can make the process slightly more efcient. Although shapeles are a very fast data format, PostGIS is pretty speedy as well, especially if you use indexes well and have memory to throw at caching.
10.2.3 PostGIS
The single biggest boost to performance is indexing. Make sure that theres a GIST index on the geometry column, and each record should also have an indexed primary key. If you used shp2pgsql, then these statements should create the necessary indexes:
ALTER TABLE table ADD PRIMARY KEY (gid); CREATE INDEX table_the_geom ON table (the_geom) USING GIST;
PostgreSQL also supports reorganizing the data in a table, such that its physically sorted by the index. This allows PostgreSQL to be much more efcient in reading the indexed data. Use the CLUSTER command, e.g.
CLUSTER the_geom ON table;
Then there are numerous optimizations one can perform on the database server itself, aside from the geospatial component. The easiest is to increase max_buffers in the postgresql.conf le, which allows PostgreSQL to use more memory for caching. More information can be found at the PostgreSQL website.
462
This causes MapServer to not close the database connection for each layer until after it has nished processing the maple and this may shave a few seconds off of map generation times.
10.3 Raster
Author HostGIS Revision $Revision: 8365 $ Date $Date: 2008-12-31 07:49:02 -0800 (Wed, 31 Dec 2008) $ Last Updated 2008/08/08
Table of Contents Raster Overviews Tileindexes and Internal Tiling Image formats Remote WMS
10.3.1 Overviews
TIFF supports the creation of overviews within the le, which is basically a downsampled version of the raster data suitable for use at lower resolutions. Use the gdaladdo program to add overviews to a TIFF, and MapServer (via GDAL) will automagically choose which downsampled layer to use. Note that overviews signicantly increase the disk space required by a TIFF, and in some cases the extra disk reading may offset the performance gained by MapServer not having to resample the image. Youll just have to try it for yourself and see how it works.
10.3. Raster
463
10.4 FastCGI
Author Frank Warmerdam Contact warmerdam at pobox.com Author Howard Butler Contact hobu.inc at gmail.com Revision $Revision: 8295 $ Date $Date: 2008-12-26 21:08:04 -0800 (Fri, 26 Dec 2008) $ Last Updated 2008/07/15
Table of Contents FastCGI Introduction Obtaining the necessary software Conguration Common Problems FastCGI on Win32
464
10.4.1 Introduction
FastCGI is a protocol for keeping cgi-bin style web applications running as a daemon to take advantage of preserving memory caches, and amortizing other high startup costs (like heavy database connections) over many requests.
With those pieces in place, the MapServer CGI (mapserv) should now be FastCGI-enabled. You can verify this by testing it on with the command line:
[hobu@kenyon mapserver-4.4.2]# ./mapserv -v MapServer version 4.4.2 OUTPUT=GIF OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT SUPPORTS=FASTCGI INPUT=EPPL7 INPUT=SDE INPUT=ORACLESPATIAL INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE DEBUG=MSDEBUG
10.4.3 Conguration
1. Modify http.conf to load the FastCGI module.
LoadModule fastcgi_module /usr/lib/apache/1.3/mod_fastcgi.so
4. In your maple, set a PROCESSING directive to tell FastCGI to cache the connections and layer information on all layers for which connection caching is desired - ie. all slow layers.
PROCESSING "CLOSE_CONNECTION=DEFER"
10.4. FastCGI
465
Im sure there is a better way of accomplishing this. If you know how, please let me know!
466
Building libfcgi The makele.nt should be ne. Just ensure you have run VCVARS32.BAT (as is needed for building MapServer) and then issue the command:
nmake /f makefile.nt
Then the .lib and .dll will be in libfcgi/Debug?. Make sure you copy the DLL somewhere appropriate (such as your cgi-bin directory). Other Issues 1) FastCGIs receive a very limited environment on win32, seemingly even more restricted than normal cgis started by apache. Make sure that all DLLs required are either in the fastcgi directory or in windowssystem32. Any missing DLLs will result in very cryptic errors in the error_log, including stuff about Overlapping read requests failing or something like that. 2) Make sure you use a libfcgi.dll built against the same runtime library as your mapserv.exe (and possibly libmap_fcgi.dll) or you will suffer a world of pain! Different runtime libraries have different environ variables (as well as their own stdio and heaps). You can check that everything is using MSVCRT.DLL (or all using MSVCRTD.DLL) using the MS SDK Dependency Walker.
Table of Contents Tile Indexes Introduction What is a tileindex and how do I make one? Using the tileindex in your maple Tileindexes may make your map faster
10.5.1 Introduction
An introduction to tileindexes, MapServers method for doing on-the-y mosaicing.
Making a tileindex is easy using gdaltindex for GDAL data sources (rasters) and ogrtindex for OGR data sources (vectors). You just run them, specifying the index le to create and the list of data sources to add to the index. For example, to make a mosaic of several TIFFs:
gdaltindex imagery.shp imagery/*.tif
Note: ogrtindex and gdaltindex add the specied les to the index. Sometimes youll have to delete the index le to avoid creating duplicate entries.
There are two items of note here: TILEINDEX and TILEITEM. TILEINDEX is simply the path to the index le, and TILEITEM species the eld in the shapele which contains the lenames referenced by the index. The TILEITEM will usually be LOCATION unless you specied the -tileindex option when running gdaltindex or ogrtindex. Two important notes about the pathnames: The path to TILEINDEX follows the same conventions as for any other data source, e.g. using the SHAPEPATH or else being relative to the location of the maple. The lenames specied on the command line to gdaltindex or ogrtindex will be used with the same conventions as well, following the SHAPEPATH or else being relative to the maples location. I nd it very useful to change into the SHAPEPATH directory and then run ogrtindex/gdaltindex from there; this ensures that I specify the correct pathnames.
468
The ideal case for a tileindex is when the most typically requested map areas fall into very few tiles. For example, if youre showing state and larger regions, try tting your data into state-sized blocks instead of county-sized blocks; and if youre showing cities and counties, go for county-sized blocks. Youll just have to experiment with it and see what works best for your use cases.
469
470
CHAPTER
ELEVEN
UTILITIES
11.1 legend
11.1.1 Purpose
Creates a legend from a maple. Output is either PNG or GIF depending on what version of the GD library used.
11.1.2 Syntax
legend [mapfile] [output image]
11.2 msencrypt
11.2.1 Purpose
Used to create an encryption key or to encrypt portions of connection strings for use in maples (added in v4.10) . Typically you might want to encrypt portions of the CONNECTION parameter for a database connection. The following CONNECTIONTYPEs are supported for using this encryption method:
OGR Oracle Spatial PostGIS SDE
11.2.2 Syntax
To create a new encryption key:
msencrypt -keygen [key_filename]
To encrypt a string:
msencrypt -key [key_filename] [string_to_encrypt]
471
Use the { and } characters as delimiters for encrypted strings inside database CONNECTIONs in your maple. For example:
CONNECTIONTYPE ORACLESPATIAL CONNECTION "user/{MIIBugIBAAKBgQCP0Yj+Seh8==}@service"
Example
LAYER NAME "provinces" TYPE POLYGON CONNECTIONTYPE POSTGIS CONNECTION "host=127.0.0.1 dbname=gmap user=postgres password=iluvyou18 port=5432" DATA "the_geom FROM province using SRID=42304" STATUS DEFAULT CLASS NAME "Countries" COLOR 255 0 0 END END
Here are the steps to encrypt the password in the above connection: 1. Generate an encryption key (note that this key should not be stored anywhere within your web servers accessible directories):
msencrypt -keygen "E:\temp\mykey.txt"
Which returns the password encrypted, at the commandline (youll use it in a second):
3656026A23DBAFC04C402EDFAB7CE714
1. Edit the maple to make sure the mykey.txt can be found, using the MS_ENCRYPTION_KEY environment variable. The CONFIG parameter inside the MAP object can be used to set an environment variable inside a maple:
472
1. Modify the layers CONNECTION to use the generated password key, making sure to use the {} brackets around the key:
1. Done! Give your new encrypted maple a try with the shp2img utility!
11.3 scalebar
11.3.1 Purpose
Creates a scalebar from a maple. Output is either PNG or GIF depending on what version of the GD library used.
11.3.2 Syntax
scalebar [mapfile] [output image]
11.4 shp2img
11.4.1 Purpose
Creates a map image from a maple. Output is either PNG or GIF depending on what version of the GD library is used. This is a useful utility to test your maple. You can simply provide the path to your maple and the name of an output image, and an image should be returned. If an image cannot be created an error will be displayed at the command line that should refer to a line number in the maple.
11.4.2 Syntax
shp2img -m mapfile [-o image] [-e minx miny maxx maxy] [-s sizex sizey] [-l "layer1 [layers2...]"] [-i format] [-all_debug n] [-map_debug n] [-layer_debug n] [-p n] [-c n] [-d layername datavalue] -m mapfile: Map file to operate on - required -i format: Override the IMAGETYPE value to pick output format -o image: output filename (stdout if not provided) -e minx miny maxx maxy: extents to render -s sizex sizey: output image size -l layers: layers to enable - make sure they are quoted and space separated if more than one listed -all_debug n: Set debug level for map and all layers
11.3. scalebar
473
-map_debug n: Set map debug level -layer_debug layer_name n: Set layer debug level -c n: draw map n number of times -p n: pause for n seconds after reading the map -d layername datavalue: change DATA value for layer
Example #1
shp2img -m vector_blank.map -o test.png
Result A le named test.png is created, that you can drag into your browser to view. Example #2
shp2img -m gmap75.map -o test2.png -map_debug 3
Result A le named test2.png is created, and layer draw speeds are returned such as:
msDrawRasterLayerLow(bathymetry): entering msDrawMap(): Layer 0 (bathymetry), 0.601s msDrawMap(): Layer 3 (drain_fn), 0.200s msDrawMap(): Layer 4 (drainage), 0.300s msDrawMap(): Layer 5 (prov_bound), 0.191s msDrawMap(): Layer 6 (fedlimit), 0.030s msDrawMap(): Layer 9 (popplace), 0.080s msDrawMap(): Drawing Label Cache, 0.300s msDrawMap() total time: 1.702s msSaveImage() total time: 0.040s
Example #3
shp2img -m gmap75.map -o test3.png -all_debug 3
Result A le named test3.png is created, layer draw speeds are returned, and some warnings that index qix les are not found, such as:
msLoadMap(): 0.671s msDrawRasterLayerLow(bathymetry): entering. msDrawGDAL(): src=72,417,3077,2308, dst=0,0,400,300 msDrawGDAL(): red,green,blue,alpha bands = 1,0,0,0 msDrawMap(): Layer 0 (bathymetry), 0.090s msSearchDiskTree(): Search returned no results. Unable to open spatial index for D:\ms4w\apps\gmap\htdocs/.\../data/drain_fn.qix. In most cases you can safely ignore this message, otherwise check file names and permissions. msDrawMap(): Layer 3 (drain_fn), 0.010s msDrawMap(): Layer 4 (drainage), 0.050s msSearchDiskTree(): Search returned no results. Unable to open spatial index
474
for D:\ms4w\apps\gmap\htdocs/.\../data/province.qix. In most cases you can safely ignore this message, otherwise check file names and permissions. msDrawMap(): Layer 5 (prov_bound), 0.030s msSearchDiskTree(): Search returned no results. Unable to open spatial index for D:\ms4w\apps\gmap\htdocs/.\../data/fedlimit.qix. In most cases you can safely ignore this message, otherwise check file names and permissions. msDrawMap(): Layer 6 (fedlimit), 0.010s msDrawMap(): Layer 9 (popplace), 0.010s msDrawMap(): Drawing Label Cache, 0.201s msDrawMap() total time: 0.401s msSaveImage() total time: 0.010s shp2img total time: 1.082s
11.5 shptree
11.5.1 Purpose
Creates a quadtree-based spatial index for a shapele. The default tree depth is calculated so that each tree node (quadtree cell) contains 8 shapes. Do not use the default with point les, a value between 6 and 10 seems to work ok. Your millage may vary and youll need to do some experimenting. The shptree wiki page may also contain information on this utility.
11.5.2 Description
This utility is a must for any MapServer application that uses shapeles. Shptree creates a spatial index of your shapele, using a quadtree method. This means that MapServer will use this index to quickly nd the appropriate shapes to draw. It creates a le of the same name as your shapele, with a .qix le extension. The quadtree method breaks the le into 4 quadrants, recursively until only a few shapes are contained in each quadrant. This minimum number can be set with the <depth> parameter of the command.
11.5.3 Syntax
shptree <shpfile> [<depth>] [<index_format>] Where: <shpfile> is the name of the .shp file to index. <depth> (optional) is the maximum depth of the inde to create, default is 0 meaning that shptre will calculate a reasonable default depth. <index_format> (optional) is one of: NL: LSB byte order, using new index format NM: MSB byte order, using new index format The following old format options are deprecated N: Native byte order L: LSB (intel) byte order M: MSB byte order The default index_format on this system is: NL
Example
11.5. shptree
475
LSB format
Result A le named us_states.qix is created in the same location. (note that you can use the shptreevis utility, described next, to view the actual quadtree quadrants that are used by MapServer in this qix le)
Note: As of MapServer 5.2 the qix will be used even when the .shp extension is specied
11.6 shptreevis
11.6.1 Purpose
This utility can be used to view the quadtree quadrants that are part of a .qix le (that was created with the shptree utility).
11.6.2 Syntax
shptreevis shapefile new_shapefile
Example
shptreevis us_states.shp quad.shp This new LSB index supports a shapefile with 2895 shapes, 10 depth
Result A shapele named quad.shp is created. You can now view this shapele in a desktop GIS (such as QGIS for example) to see the quadtrees that were created with the shptree command, as shown below. Figure: shptreevis result displayed in QGIS
476
11.7 sortshp
Purpose Sorts a shapele based on a single column in ascending or descending order. Supports INTEGER, DOUBLE and STRING column types. Useful for prioritizing shapes for rendering and/or labeling. Description The idea here is that if you know that you need to display a certain attribute classed by a certain value, it will be faster for MapServer to access that value if it is at the beginning of the attribute le. Syntax sortshp [infile] [outfile] [item] [ascending|descending] Example This example uses a roads le (roads_ugl) that has a eld with road classes in integer format (class1).
sortshp roads_ugl roads-sort class1 ascending
Result A new shapele named roads-sort.shp is created with shapes sorted in ascending order, according to the values in the class1 eld, as shown below. Figure1: Attributes Before sortshp
11.7. sortshp
477
478
11.8 sym2img
11.8.1 Purpose
Creates a graphic dump of a symbol le. Output is either PNG or GIF depending on what version of the GD library used. (this utility is not currently included in pre-compiled packages, due to issues mentioned in bug#506)
11.8.2 Syntax
sym2img [symbolfile] [outfile]
11.8. sym2img
479
11.9 tile4ms
11.9.1 Purpose
Creates a tile index shapele for use with MapServers TILEINDEX feature. The program creates a shapele of rectangles from extents of all the shapeles listed in [metale] (one shapele name per line) and the associated DBF with the lename for each shape tile in a column called LOCATION as required by mapserv.
11.9.2 Description
This utility creates a shapele containing the MBR (minimum bounding rectangle) of all shapes in the les provided, which can then be used in the LAYER objects TILEINDEX parameter of the maple. The new led created with this command is used by MapServer to only load the les assocated with that extent (or tile).
11.9.3 Syntax
tile4ms <meta-file> <tile-file> [-tile-path-only] <meta-file> INPUT file containing list of shapefile names (complete paths 255 chars max, no extension) <tile-file> OUTPUT shape file of extent rectangles and names of tiles in <tile-file>.dbf -tile-path-only Optional flag. If specified then only the path to the shape files will be stored in the LOCATION field instead of storing the full filename.
DOS: dir wp.shp /b /s > wp_list.txt (this includes full paths to the data, you might want to edit the txt file to remove the full path) UNIX: find -name *wp.shp -print > wp_list.txt
The newly created le might look like the following (after removing the full path):
001\wp.shp 003\wp.shp 005\wp.shp 007\wp.shp 009\wp.shp 011\wp.shp 013\wp.shp 015\wp.shp 017\wp.shp 019\wp.shp . . .
1. Execute the tile4ms command with the newly created meta-le to create the index le:
tile4ms wp_list.txt index Processed 87 of 87 files
1. A new le named index.shp is created. This is the index le with the MBRs of all wp.shp les for the entire state, as shown in Figure1. The attribute table of this le contains a eld named LOCATION, that contains the path to each wp.shp le, as shown in Figure2. Figure 1: Index le created by tile4ms utility
11.9. tile4ms
481
482
1. The nal step is to use this in your maple. LAYER objects TILEINDEX - must point to the location of the index le LAYER objects TILEITEM - specify the name of the eld in the index le containing the paths (default is location) do not need to use the LAYERs DATA parameter For example:
LAYER NAME mn-lakes STATUS ON TILEINDEX "index" TILEITEM "location" TYPE POLYGON CLASS NAME "mn-lakes" STYLE COLOR 0 0 255 END END END
When you view the layer in a MapServer application, you will notice that when you are zoomed into a small area of the state only those lakes layers are loaded, which speeds up the application.
11.9. tile4ms
483
11.10.1 Windows
type the following at the command prompt:
for %f in (*.shp) do shptree %f
11.10.2 Linux
find /path/to/data -name "*.shp" -exec shptree {} \;
484
Windows The following .bat le can be used in Scheduled Tasks to remove these temporary images daily:
REM this script deletes the contents of the ms_tmp directory REM (i.e. the MapServer-created gifs) cd D:\ms4w\tmp\ms_tmp echo Y | del *.*
485
486
CHAPTER
TWELVE
CGI
Date 2008/09/09 Author Daniel Morissette Contact dmorissette at mapgears.com Author Jeff McKenna Contact jmckenna at gatewaygeomatics.com Author Frank Koormann
12.1.2 Changes
From MapServer version 4.x to version 5.x Modifying map parameters through a URL has changed to allow for chunks of a maple to be modied at once. The syntax has changed accordingly, so please see the Changing map le parameters via a form or a URL section. From MapServer version 3.x to version 4.x New way to perform attribute queries: No longer do you set a layer lter, but rather you pass a query string (and optionally an query item) to the query function. To do this 2 new CGI parameters were added to MapServer: QSTRING and QITEM. SAVEMAP is switched off: The SAVEMAP functionality is considered insecure, since the saved les are accessible by everyone.
487
TEMPLATE has been removed, since the map_web_template syntax can be used to alter a template le. Simplies security maintenance by only having to deal with this option in a single place. Note that the TEMPLATEPATTERN of the maple has to be used to enable this feature.
12.2 mapserv
The CGI interface can be tested at the commandline by using the QUERY_STRING switch, such as:
mapserv "QUERY_STRING=map=/ms4w/apps/gmap/htdocs/gmap75.map&mode=map"
To suppress the HTTP headers, you can use the -nh switch, such as:
mapserv -nh "QUERY_STRING=map=/ms4w/apps/gmap/htdocs/gmap75.map&mode=map"
To save the output into an image le, use the pipe command such as:
mapserv -nh "QUERY_STRING=map=/ms4w/apps/gmap/htdocs/gmap75.map&mode=map" > test.png
Note: All layers created from a context le have their status set to ON. To be able to display layers, the user needs to add the LAYERS argument in the URL.
Due to security concerns loading a le from a URL is disabled by default. To enable this functionality, the user needs to set a CONFIG parameter called CGI_CONTEXT_URL in the default map le that will allow this functionality. Here is an example of a map le with the CONFIG parameter:
# Start of map file NAME DEMO STATUS ON SIZE 400 300 EXTENT -2200000 -712631 3072800 3840000 UNITS METERS IMAGECOLOR 255 255 255
488
IMGBOX [x1] [y1] [x2] [y2] Coordinates (in pixels) of a box drag in the image. Most often used in conjunction with Java based front ends to the MapServer. IMGEXT [minx] [miny] [maxx] [maxy] The spatial extent of the existing inline image, that is, the image the users can see in their browser. IMGSHAPE [x1 y1 x2 y2 x3 y3 ...] Shape given in image coordinates. An arbitrary polygon shape to be used for query purposes. Multiple instances simply add parts to the shape so it is possible to construct a shape with holes. Used with modes NQUERY and NQUERYMAP. IMGSIZE [cols] [rows] The size (in pixels) of the exiting inline image. IMGXY [x] [y] Coordinates (in pixels) of a single mouse click. Used most often in conjunction with Java based front ends to the MapServer. LAYER [name] The name of a layer as it appears in the map le. Sending mapserv a layer name sets that layers STATUS to ON. LAYERS [name name ...] The names of the layers to be turned on. Layer names must be seperated by spaces. Version 4.4 and above: passing LAYERS=all will automatically turn on all layers. MAP [lename] Path, relative to the CGI directory, of the map le to be used. MAPEXT [minx] [miny] [maxx] [maxy] , MAPEXT (shape) The spatial extent of the map to be created. Can be set to shape as an alternative option. In this case mapextent is set to the extent of a selected shape. Used with queries. MAPSIZE [cols] [rows] The size (in pixels) of the image to be created. Useful for allowing users to change the resolution of the output map dynamically. MAPSHAPE [x1 y1 x2 y2 x3 y3 ...] Shape in map coordinates. An arbitrary polygon shape to be used for query purposes. Multiple instances simply add parts to the shape so it is possible to construct a shape with holes. Used with modes NQUERY and NQUERYMAP. MAPXY [x] [y] , MAPXY (shape) A point, in the same coordinate system as the shapeles, to be used in conjuction with a buffer or a scale to construct a map extent. Can be set to shape as an alternative option. In this case mapextent is set to the extent of a selected shape. Used with queries. MINX | MINY | MAXX | MAXY [number] Minimum/Maximum x/y coordinate of the spatial extent for a new map/query. This set of parameters are the pieces of MAPEXT. MODE [value] Mode of operation. The following options are supported (note that all of the query modes also support map-only modes, e.g. ITEMQUERYMAP, which for brevity are not all listed): BROWSE Fully interactive interface where maps (and interactive pages) are created. This is the default mode. QUERY A spatial search (nds closest) is triggered by a click in a map. NQUERY A spatial search (nds all) is triggered by a click in a map or by user-dene selection box. ITEMQUERY A text search of attribute data is triggered using a layer QSTRING. Returns 1st match. ITEMNQUERY A text search of attribute data is triggered using a QSTRING. Returns all matches. FEATUREQUERY A spatial search that uses one feature from SLAYER to query other layers. FEATURENQUERY A spatial search that uses multiple features from SLAYER to query other layers. ITEMFEATUREQUERY A text search of attribute data is triggered using a QSTRING. Returns rst match. Layer to be searched is dened using slayer parameter. The results of this search are applied to other searchable layers (which can be limited using the QLAYER parameter). 490 Chapter 12. CGI
ITEMFEATURENQUERY A text search of attribute data is triggered using a QSTRING. Returns all matches. Layer to be searched is dened using slayer parameter. The results of this search are applied to other searchable layers (which can be limited using the QLAYER parameter). LEGENDICON A legend icon is returned. The ICON parameter must also be used to specify the layername and a class index. Class index value is optional and defaults to 0. For example:
mapserv.exe?map=/ms4w/apps/gmap/htdocs/gmap75.map&MODE=legendicon&ICON=popplace,0
MAP The created map is returned. Used within an <img ... > tag. REFERENCE The created reference map is returned. Used within an <img ... > tag. SCALEBAR The created scalebar is returned. Used within an <img ... > tag. LEGEND The created legend is returned. Used within an <img ... > tag. ZOOMIN Switch to mode BROWSE with ZOOMDIR=1 ZOOMOUT Switch to mode BROWSE with ZOOMDIR=-1 INDEXQUERY Looks up a feature based on the values of SHAPEINDEX and TILEINDEX parameters. SHAPEINDEX is required, TILEINDEX is optional and is only used with tiled shapele layers. COORDINATE To be claried. QLAYER [name] Query layer. The name of the layer to be queried as it appears in the map le. If not specied then all layers are searched in turn. QITEM [name] (optional) The name of an attribute in a layer attribute table to query on. The parameter is optional and used in conjunction with the QSTRING for attribute queries. QSTRING [expression] Attribute queries: Query string passed to the query function. QUERYFILE [lename] Used with BROWSE or NQUERY mode. This option identies a query le to load before any regular processing. In BROWSE mode this result in a query map being produced instead of a regular map. This is useful when you want to hilite a feature while still in a pan/zoom mode. In NQUERY mode youd gain access to any of the templates used in normally presenting the query, so you have access to query maps AND attribute information. See the SAVEQUERY option. REF The name associated with the inline reference map image used to record user clicks. What actually is passed are two variables, ref.x and ref.y. For the CGI Applications this is an essential variable when reference maps are used, see the examples for sample usage. REFXY [x] [y] Coordinates (in pixels) of a single mouse click in the reference image. Used in conjunction with Java based front ends to the MapServer. SAVEQUERY When used with any of the query modes this tells the MapServer to save the query results to a temporary le for use in subsequent operations (see QUERYFILE). Useful for making queries persistent. SCALEDENOM [number] Scale to create a new map at. Used with mapxy. Scale is given as the denominator of the actual scale fraction, for example for a map at a scale of 1:24,000 use 24000. Implemented in MapServer 5.0, to replace the deprecated SCALE parameter. SCALE [number] - deprecated Since MapServer 5.0 the proper parameter to use is SCALEDENOM instead. The deprecated SCALE is the scale to create a new map at. Used with mapxy. Scale is given as the denominator of the actual scale fraction, for example for a map at a scale of 1:24,000 use 24000. SEARCHMAP It is possible to do pan/zoom interfaces using querymaps. In these cases you will likey want information about the contents of the new map rather than the previous map which is the normal way queries work. When searchmap is specied the new map is created and its extent is used to query layers. Useful with NQUERY mode only.
491
SHAPEINDEX [index] Used for index queries (in conjunction with INDEXQUERY). SLAYER [name] Select layer. The name of the layer to be used for any of the feature (i.e. staged) query modes. The select layer must be a polygon layer. The selection feature(s) are available for presentation to the user. TILEINDEX [index] Used for index queries (in conjunction with INDEXQUERY), used with tiled shapele layers. ZOOM [number] Zoom scaling to apply to the creation of the new map. Values greater than 0 resulting in zooming in, 0 is a pan, and values less than zero are for zooming out. A value of 2 means zoom in twice. ZOOM can be used as a shortcut for the combination ZOOMDIR/ZOOMSIZE. The zoom is limited by the MINZOOM/MAXZOOM settings compiled into the MapServer (-25/25) by default. ZOOMDIR [1 | 0 | -1] Direction to zoom. See above. ZOOMSIZE [number] Absolute magnitude of a zoom. Used with ZOOMDIR. ZOOMDIR is limited to MAXZOOM compiled into the MapServer (25 by default).
The variable identies an object uniquely (by name or index in the case of layerObjs and classObjs). The value is a snippet of a maple. You cannot create new objects other than inline features at this point. 492 Chapter 12. CGI
Using MapServer version < 5 For MapServer version < 5, any value can be expressed using the hierarchy used in a map le. A map contains a layer, which contains a class, which contains a label, which has a color. This hierarchy is expressed as a sequence of MapServer keywords seperated by underscores. For example to change the color of a layer called lakes with only one class dened you would use a form variable named map_lakes_class_color and could assign it a color like 0 0 255. Layers can be referenced by index (i.e. map_layer_0...) or by name as shown above. Layer classes are referenced by index value (i.e. map_layer_0_class_2). If there is only 1 class for a layer then the index should be ommited. These variables must always begin with the sequence map_. Values assigned must conform to the syntax of a map le. It is also possible to dene inline features using this mechanism. This is the only case where you can add on to the map le. You can edit/change layer parameters but you cannot create a new layer. With inline features you have to rst create a feature and then build upon it, however, the layer the feature belongs to must exist. Heres a snippet from a GET request that adds a feature to a webuser layer:
. . . &map_webuser_feature=new&map_webuser_feature_points=12345.6789+12345.6789&map_webuser_feature_t
The map_webuser_feature=new creates a new feature for the webuser layer. All subsequent calls to the feature object for that layer will modify the new feature. You can repeat the process to create additional features. This is really intended for very small (point, rectangle) amounts of data.
493
12.5.1 Introduction
Run-time substitution for the MapServer CGI has been around since version 4.0 and its use has continued to expand. In short, it allows you to alter portions of a maple based on data passed via a CGI request. This functionality is only available via the standard CGI application. Within MapScript this is easy to do since the developer has complete control over how input is handled.
When a request is processed the value for ctype is substituted for the string %ctype% and the maple is processed as normal. If no ctype is passed in the EXPRESSION will never be true so it doesnt really hurt anything except for a slight performance hit. Often you would set a default class to draw features that dont match, but that is not required.
CLASS EXPRESSION FILTERs You can use runtime substitutions to change values within a FILTER as you go. For example your FILTER could be written like so:
FILTER ("multimedia=[multimedia] and seats >= [nseats] and Sound= [sound])
Then (assuming youre using the CGI interface) you could pass in variables named multimedia, nseats and sound with values dened by the user in an HTML form. You should also dene validation expressions on these variables to guard against unintentional SQL being submitted to postgis. Within the layer metadata youd do the following:
METADATA multimedia_validation_string ^yes|no$ sound_validation_string ^yes|no$ nseats_validation_string ^[0-9]{1,2}$ ... more metadata ... END
The validation strings are regular expressions that are applied against the appropriate variable value before being added to the FILTER. The rst two limit the value of multimedia and sound to yes or no. The third limits the value for nseats to a 2 digit integer.
12.6.1 Introduction
This document presents a simple shell script that can be used to wrap the MapServer CGI, in order to avoid having to specify the map parameter (or any other chosen parameters) in your MapServer URLs.
495
You should set the MAPSERV and MAPFILE variables as appropriate for your conguration. MAPSERV points to your MapServer executable, and MAPFILE points to the maple you want MapServer to use. Both variables should be absolute le paths that your webserver has permission to access, although they need not (and probably should not) be in web-accessible locations. Then put the script in your web servers cgi-bin directory, and make it executable. Although this script only sets the map parameter, it is easily modied to set any number of other MapServer parameters as well. For example, if you want to force your MapServer to map mode, you can simply add mode=map to the front of the QUERY_STRING variable. Just remember to separate your parameters with ampersands (&). Finally, note that the script only works for GET requests.
496
CHAPTER
THIRTEEN
COMMUNITY ACTIVITIES
13.1 IRC
Some of the development of MapServer is coordinated through IRC. This page describes how you log on to chat, ask questions, and hack around with the developers.
There are many other IRC clients available. This page provides a good listing for many different platforms.
497
13.2.2 mapserver-users
The mapserver-users is the primary means for MapServer users and developers to exchange application ideas, discuss potential software improvements, and ask questions. Subscribing to mapserver-users To subscribe to the mapserver-users listserv visit http://lists.osgeo.org/mailman/listinfo/mapserver-users. You can later change your subscription information or leave the list at this website. Submitting Questions to mapserver-users To submit questions to the mapserver-users listserv, rst join the list by following the subscription procedure above. Then post questions to the list by sending an email message to [email protected]. Searching the Archives All MapServer-Users archives are located in http://lists.osgeo.org/pipermail/mapserver-users/. Searching the archives is best done with Nabble.
13.2.3 mapserver-dev
A separate listserv is available for MapServer developers. It is meant to be used by individuals working on MapServer source code and related libraries to discuss issues that would not be of interest to the entire mapserver-users listserv. Subscribing to mapserver-dev To subscribe to the mapserver-dev listserv visit http://lists.osgeo.org/mailman/listinfo/mapserver-dev, enter your e-mail address, name, and create a password and click subscribe. You can later change your subscription information or leave the list at this website. Submitting Questions to mapserver-dev To submit questions to the mapserver-dev listserv, rst join the list by following the subscription procedure above. Then post questions to the list by sending an email message to [email protected]. Searching the Archives All MapServer-Dev archives are located in http://lists.osgeo.org/pipermail/mapserver-dev/. archives is best done with Nabble. 498 Searching the
499
500
CHAPTER
FOURTEEN
DEVELOPMENT
14.1 Sponsors
DM Solutions OGC support (2001-2005) PHP-MapScript implementation and Support MapServer Release Management Windows Binaries MS4W and FGS installers Product Documentation Environment Canada i-cubed RealGo RFC 13: SOS Server support (2006-2007)
OUTPUTFORMAT / 24-bit color raster support (2002) SWIG mapscript improvements (2003-2004) FastCGI implementation (2004). RFC 5: MapServer Horizon Reprojection Improvements (2005).
RFC 4: MapServer Raster Resampling (2005) Note: The MapServer project relies on its developers to keep this page up to date and accurate. If you feel that due credit is overlooked, please contact the developer that completed the work for your company or organization.
4. In your description please indicate whether you built from source or got it from an prepared binary build. The most important thing when reporting a bug is to boil down a minimum example that is needed to reproduce the bug. That means a minimal maple + any data les it depends on. Remove everything from the map le that isnt needed to reproduce the bug. The developers often dislike having to spend the rst 30 minutes working on a bug, having to x paths, remove unnecessary layers, removing references to external symbols or fonts that were not included or even needed and otherwise doctoring your test case to get it to a point when they can actually use it. If the bug is easily demonstrated with shp2img, without the need to setup a proper web service and test it through http, then please show it that way. If a standalone MapScript script can demonstrate a problem without it having to be a web service, likewise submit it that way. The chances of a bug being addressed in a timely manner is directly related to the speed with which the developer can reproduce the bug. If you make that hard for the developer, chances are the bug will be given up on or ignored for quite a while.
14.3 Subversion
14.3.1 Code Developers Subversion Access
MapServers source code and documentation are under Subversion control. Subversion access is mostly intended for use by developers, but users can also access the MapServer source between releases as it is being developed. CVS access is only recommended for those who need the absolute latest and greatest code, if they are not afraid of getting their hands dirty building the source. The Subversion version does not contain GD or any of the support libraries, and it requires ex and bison to build it. Building MapScript will also require SWIG be installed on your machine. Heres how to access the read-only source: 1. Install a Subversion client, see Subversion Homepage for more information. TortoiseSVN is a good solution if you are on Windows, and most Unixes should have a client available. 2. Issue svn co https://svn.osgeo.org/mapserver/trunk/mapserver mapserver to check out a copy of the current trunk into your working directory.
Table of Contents Documentation Development Guide Background General Guidelines reStructuredText Reference Guides reStructuredText Formatting Installing and Using Sphinx for rst-html Generation Reference Labels
14.4.1 Background
The current structure of the MapServer documentation process is for developers with Subversion commit access to maintain their documents in reStructuredText format, and therefore all documents live in the /docs directory in SVN. The Sphinx documentation generator is used to convert the reStructuredText les to html, and the live website is then updated on an hourly basis.
503
All external links should live at the bottom of your document, under the heading:
.. #### rST Link Section ####
Always include the :Revision: and :Date: lines (as-is) at the top of your document, such as:
:Revision: $Revision: 8659 $ :Date: $Date: 2009-03-08 07:31:00 -0800 (Sun, 08 Mar 2009) $
...you should see message: Finished processing dependencies for Sphinx 5. inside the MapServer /docs directory, create /build/doctrees and /build/html directories 6. inside the /docs directory, execute:
sphinx-build -b html -d build\doctrees . build\html
...you should see a message: build succeeded, ... On Linux: 1. make sure you have the Python dev and setuptools packages installed. On Ubuntu:
sudo apt-get install python-dev sudo apt-get install python-setuptools
504
make html
or
make latex
505
506
507
Regenerating the reference labels You can regenerate the reference labels by issuing:
make labels
from the docs directory like when you are building the html or latex versions
14.5 Testing
MapServer provides testing in multiple forms. The Regression Testing framework uses CGI and other tools to test the generation of images and OGC output. The MapScript Unit Testing framework tests the MapScript and its object hierarchy.
Table of Contents Regression Testing Getting msautotest Running msautotest Checking Failures PerceptualDiff Background TODO Adding New Tests
The msautotest is a suite of test maps, data les, expected result images, and test scripts intended to make it easy to run an a set of automated regression tests on MapServer. Getting msautotest The autotest is available from SVN. On Unix it could be fetched something like:
% svn checkout http://svn.osgeo.org/mapserver/trunk/msautotest
This would create an msautotest subdirectory whereever you are. I normally put the autotest within my MapServer directory. 508 Chapter 14. Development
Running msautotest The autotest requires python (but not python MapScript), so if you dont have python on your system - get and install it. More information on python is available at http://www.python.org. Most Linux system have some version already installed. The autotest also requires that the executables built with MapServer, notably shp2img, legend, mapserv and scalebar, are available in the path. I generally accomplish this by adding the MapServer build directory to my path. csh:
% setenv PATH $HOME/mapserver:$PATH
bash/sh:
% PATH=$HOME/mapserver:$PATH
Verify that you can run stuff by typing shp2img -v in the autotest directory:
warmerda@gdal2200[152]% shp2img -v MapServer version 3.7 (development) OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP SUPPORTS=PROJ SUPPORTS=TTF SUPPORTS=WMS_SERVER SUPPORTS=GD2_RGB INPUT=TIFF INPUT=EPPL7 INPUT=JPEG INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE
Now you are ready to run the tests. The tests are subdivided into categories, currently just gdal, misc, and wxs each as a subdirectory. To run the gdal tests cd into the gdal directory and run the run_test.py script. Unix:
./run_test.py
Windows:
python.exe run_test.py
The results in the misc directory might look something like this:
warmerda@gdal2200[164]% run_test.py version = MapServer version 3.7 (development) OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP SUPPORTS=PROJ SUPPORTS=TTF SUPPORTS=WMS_SERVER SUPPORTS=GD2_RGB INPUT=TIFF INPUT=EPPL7 INPUT=JPEG INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE Processing: rgba_scalebar.map results match. Processing: tr_scalebar.map results match. Processing: tr_label_rgb.map results match. Processing: ogr_direct.map results match. Processing: ogr_select.map results match. Processing: ogr_join.map results match. Test done: 0 tested skipped 6 tests succeeded
14.5. Testing
509
In general you are hoping to see that no tests failed. Checking Failures Because most msautotest tests are comparing generated images to expected images, the tests are very sensitive to subtle rounding differences on different systems, and subtle rendering changes in libraries like freetype and gd. So it is quite common to see some failures. These failures then need to be reviewed manually to see if the differences are acceptable and just indicating differences in rounding/rendering or whether they are real bugs. This is normally accomplished by visually comparing les in the result directory with the corrresponding le in the expected directory. It is best if this can be done in an application that allows images to be layers, and toggled on and off to visually highlight what is changing. OpenEV can be used for this. PerceptualDiff If you install the PerceptualDiff program (http://pdiff.sourceforge.net/) and it is in the path, then the autotest will attempt to use it as a last fallback when comparing images. If images are found to be perceptually the same the test will pass with the message result images perceptually match, though les differ. This can dramatically cut down the number of apparent failures that on close inspection are for all intents and purposes identical. Building PerceptualDiff is a bit of a hassle. Background The msautotest suite was initially developed by Frank Warmerdam (warmerdam at pobox.com), who can be contacted with questions it. The msautotest suite is organized as a series of .map les. The python scripts basically scan the directory in which they are run for les ending in .map. They are then run with the result dumped into a le in the result directory. A binary comparison is then done to the corresponding le in the expected directory and differences are reported. The general principles for the test suite are that: The test data should be small so it can be easily stored and checked out of svn without big les needing to be downloaded. The test data should be completely contained within the test suite ... no dependencies on external datasets, or databases that require additional conguration. PostGIS and Oracle will require separate testing mechanisms. The tests should be able to run without a signicant deal of user interaction. This is as distinct from the DNR test suite described in FunctionalityDemo. The testing mechanism should be suitable to test many detailed functions in relative isolation. The test suite is not dependent on any of the MapScript environments, though I think it would be valuable to extend the testsuite with some mapscript dependent components in the future (there is a start on this in the mspython directory).
This is accomplished by capturing the version output of shp2img -v and using the various keys in that to decide which tests can be run. A directory can have a le called all_require.txt with a REQUIRES: line indicating components required for all tests in the directory. If any of these requirements are not met, no tests at all will be run in this directory. For instance, the gdal/all_require.txt lists:
REQUIRES: INPUT=GDAL OUTPUT=PNG
In addition, individual .map les can have additional requirements expressed as a REQUIRES: comment in the maple. If the requirements are not met the map will be skipped (and listsed in the summary as a skipped test). For example gdal/256_overlay_res.map has the following line to indicate it requires projection support (in addition to the INPUT=GDAL and OUTPUT=PNG required by all les in the directory):
REQUIRES: SUPPORTS=PROJ
The output les generated by processing a map is put in the le results/<maplebasename>.png (regardless of whether it is PNG or not). So when gdal/256_overlay_res.map is processed, the output le is written to gdal/results/256_overlay_res.png. This is compared to gdal/expected/256_overlay_res.png. If they differ the test fails, and the wrong result le is left behind for investigation. If they match the result le is deleted. If there is no corresponding expected le the results le is moved to the expected directory (and reported as an initialized test) ready to be committed to CVS. There is also a RUN_PARMS keyword that may be placed in map les to override a bunch of behaviour. The default behaviour is to process map les with shp2img, but other programs such as mapserv or scalebar can be requested, and various commandline arguments altered as well as the name of the output le. For instance, the following line in misc/tr_scalebar.map indicates that the output le should be called tr_scalebar.png, the commandline should look like [SCALEBAR] [MAPFILE] [RESULT] instead of the default [SHP2IMG] -m [MAPFILE] -o [RESULT].
RUN_PARMS: tr_scalebar.png [SCALEBAR] [MAPFILE] [RESULT]
For testing things as they would work from an HTTP request, use the RUN_PARMS with the program [MAPSERV] and the QUERY_STRING argument, with results redirected to a le.
For web services that generate images that would normally be prexed with the Content-type header, use [RESULT_NOMIME] to instruct the test harnass to script off any http headers before doing the comparison.
14.5. Testing
511
TODO Add lots of tests for different stuff! Very little vector testing done yet. Add a high level script in the msautotest directory that runs the subscripts in all the subdirectories and produces a summary report. Adding New Tests Pick an appropriate directory to put the test in. Feel free to start a new one for new families of testing functionality. Create a minimal map le to test a particular issue. I would discourage starting from a real maple and cutting down as it is hard to reduce this to the minimum. Give the new maple a name that hints at what it is testing without making the name too long. For instance ogr_join.map tests OGR joins. rgb_overlay_res_to8bit.map tests RGB overlay layers with resampling and converting to 8bit output. Put any MapServer functionality options in a # REQUIRES: item in the header as described in the internal functioning topic above. Write some comments at the top of the .map le on what this test is intended to check. Add any required datasets within the data directory beneath the test directory. These test datasets should be as small as possible! Reuse existing datasets if at all possible. run the run_tests.py script. verify that the newly created expected/<testname>.png le produces the results you expect. If not, revise the map and rerun the test, now checking the results/<testname>.png le. Move the results/<testname>.png le into the expected directory when you are happy with it. add the .map le, and the expected/<testname>.png le to CVS when you are happy with them. Make sure the .png le (and any supporting data les) are marked as binary les. For example,
% svn add mynewtest.map expected/mynewtest.png % svn commit -m "new" mynewtest.map expected/mynewtest.png
Youre done!
512
Test Driven Development is also a book by Kent Beck. New features that I develop for MapServer begin as test expressions. There are a bazillion good reasons for working this way. The most obvious are 1. accumulation of automated unit tests 2. accumulation of excellent usage examples 3. that im prevented from starting work on aky ideas that cant be tested About the tests Tests are committed to the MapServer CVS under mapscript/python/tests. They are written in Python using the JUnit inspired unittest module. A good introduction to unit testing with Python is found at http://diveintopython.org/unit_testing/index.html. The test framework imports mapscript from python/tests/cases/testing.py. This allows us to test the module before installation
[sean@lenny python]$ python setup.py build [sean@lenny python]$ python tests/runtests.py -v
Test cases are implemented as Python classes, and individual tests as class methods named beginning with test*. The special setUp() and tearDown() methods are for test xtures and are called before and after every individual test. Since version 4.2, MapServer includes a very lightweight testing dataset under mapserver/tests. The set consists of symbols, fonts, three single-feature shapeles, and a test.map maple. This is the only data used by the unit tests. Many tests that require a mapObj derive from testing.MapTestCase:
class MapTestCase(MapPrimitivesTestCase): """Base class for testing with a map fixture""" def setUp(self): self.map = mapscript.mapObj(TESTMAPFILE) def tearDown(self): self.map = None
One example is the MapSymbolSetTestCase, the test case I used for development of the expanded symbolset functionality present in the 4.2 release:
class MapSymbolSetTestCase(MapTestCase): def testGetNumSymbols(self): """expect getNumSymbols == 2 from test fixture test.map""" num = self.map.getNumSymbols() assert num == 2, num ...
Status This unit testing framework only covers functionality that is exposed to the Python mapscript module. It can help to check on pieces of the core MapServer code, but is no guarantor of the mapserv program or of the PHP MapScript module. As of this writing, there are 159 tests in the suite. These are tests of features added since mid-2003. Much of MapServers older stuff remains untested and it is doubtful that well make the time to go back and ll in.
14.5. Testing
513
514
12. Addition and removal of members from the committee, as well as selection of a Chair should be handled as a proposal to the committee. 13. The Chair adjudicates in cases of disputes about voting. When is Vote Required? Anything that could cause backward compatability issues. Adding substantial amounts of new code. Changing inter-subssytem APIs, or objects. Issues of procedure. When releases should take place. Anything that might be controversial. Boundaries of Technical If it relates to changes in the code, it is technical. If it relates to how the developers cooperate, it is technical. If it relates to legal issues around code ownership it is technical. If it relates to documentation, or the web site it is not technical. If it relates to events such as conferences, it is not technical. Observations The Chair is the ultimate adjudicator if things break down. The absolute majority rule can be used to override an obstructionist veto, but it is intended that in normal circumstances vetoers need to be convinced to withdraw their veto. We are trying to reach consensus. It is anticipated that seperate committees will exist to manage conferences, documentation and web sites. Bootstrapping Steve Lime is declared initial Chair of the Technical Steering Committee. Steve Lime, Daniel Morissette, Frank Warmerdam, Sean Gilles, Assefa Yewondwossen, Howard Butler and Perry Nacionales are declared to be the founding Technical Steering Committee.
Version MapServer 4.8 Id $Id: ms-rfc-2.txt 8278 2008-12-23 21:34:31Z hobu $ Description: Developing inline features or shapes within MapScript can be a bit cumbersome. One alternative would be to allow users to dene feature using the Well-Known Text format. The proposed solution would allow users to use this format: 1. within a maple 2. via URL 3. via MapScript 4. via MapServer query template Instead of writing a new WKT parser we would provide access to underlying GEOS or OGR functionality to do this. Notes about the actual implementation are included below. Files affected maple.h => new constant, WKT maplexer.l => recognize the new constant maple.c => process new maple parameter with FEATURE block (WKT), and update URL parsing in a similar manner mapgeos.cpp => wrap GEOS WKT reading/writing code mapogr.cpp => wrap OGR WKT reading/writing code mapprimitive.c => wrap the GEOS and OGR WKT writer/reading code, this would be the public interface maptemplate.c => update the shpxy tag with a -wkt option so it would output the WKT version of a shape. Placing here would allow us to take advantage of the projection support already in place, plus any future options (thining, buffers and so on). mapscript/swiginc/shape.i => update constructor to pass a WKT string and to dene a toString method that would output a WKT string. Similar modications would have to be made within PHP/MapScript, patterned after the SWIG-based interface. Backwards compatabilty issues N/A, new functionality Implementation Details The C API will take the form:
shapeObj *msShapeFromWKT( const char * ); char *msShapeToWKT( shapeObj * );
These are contrary to some of the older code (e.g. msLayerNextShape()). However there are 2 places the WKT APIs will be used: 1) MapScript and 2) creating inline features via URL or MapFiles. In both cases the above functions would be prefered. 516 Chapter 14. Development
In MapScript, creating a shape will take the form of an overloaded constructor, e.g.: $shape = new shapeObj($mapscript::MS_SHAPE_LINE); OR $shape = new shapeObj(LINESTRING(0 0,1 1,1 2)); In MapScript, a toWKT() method will be added to shapeObj object. WKT is geometry only. The attributes, index, tileindex, classindex, and text elds do not exist in WKT and will have to be set elsewhere. There is no widely supported, or standardized approach to measure values in WKT though Refractions does support it in EWKT. For now it is assumed that measure values will not be preserved from WKT. There is a well dened way of including Z coordinates and these should be carried through if MapServer is built with Z and M support enabled. Development will be accompanied by a set of tests. Sean Gillies has already created a test case or two.
Voting history Vote proposed by Steve Lime on 9/4/2005, result was +4 (3 non-voting members). Voting +1: Lime, Warmerdam, Morissette, Gillies Proposal passes and will move forward.
2.1.2. FreeItemInfo
void (*LayerFreeItemInfo)(layerObj *layer);
2.1.3. Open
int (*LayerOpen)(layerObj *layer);
Currently there are two layers which accept more than the generic layer arg for LayerOpen function:
518
int msOGRLayerOpen(layerObj *layer, const char *pszOverrideConnection); int msWFSLayerOpen(layerObj *lp, const char *pszGMLFilename, rectObj *defaultBBOX);
However, these are called from msLayerOpen with NULL args, so I think that proposed interface for this virtual table function should be ne. 2.1.4. IsOpen
int (*LayerIsOpen)(layerObj *layer);
2.1.5. WhichShapes
int (*LayerWhichShapes)(layerObj *layer, rectObj rect);
2.1.6. NextShape
int (*LayerNextShape)(layerObj *layer, shapeObj *shape);
2.1.7. GetShape
int (*LayerGetShape)(layerObj *layer, shapeObj *shape, int tile, long record);
2.1.8. LayerClose
int (*LayerClose)(layerObj *layer);
2.1.9. LayerGetItems
int (*LayerGetItems)(layerObj *layer);
2.1.10. GetExtent
int (*LayerGetExtent)(layerObj *layer, rectObj *extent);
2.1.11. GetAutoStyle
int (*LayerGetAutoStyle)(mapObj *map, layerObj *layer, classObj *c, int tile, long record);
2.2. New functions and/or elds for vtable 2.2.1. CloseConnection This function is used to actually close the connection, in case that layer implements some kind of connection pooling by its own. If layer doesnt use any connection pooling, this function should be implemented as no-op. Caller should rst call layers close function, and nally at the very end CloseConnection. The signature of function is
int (*LayerCloseConnection)(layerObj *layer);
And the main place where this function will be called, is mapfile.c:
4822
519
This function is needed because e.g. POSTGIS is implementing this usage pattern at the moment maplayer.c:599
void msLayerClose(layerObj *layer) ... /* * Due to connection sharing, we need to close the results * and free the cursor, but not close the connection. */ msPOSTGISLayerResultClose(layer);
2.2.2. SetTimeFilter This function is used to create a time lter for layer. At the moment we have three special cases (maplayer.c: 1635): (a) POSTGIS with its own function (b) Layers with backticks delimited expressions (c) Layers without backticks The idea is provide a generic helper function,
int makeTimeFilter(layerObj *lp, const char *timestring, const char *timefield, const bool bBackTicks)
And the actual layers SetTimeFilter could use the above, or implement something totally different as POSTGIS is doing at the moment. The signature for layers vtable function is
int (*LayerSetTimeFilter)(layerObj *lp, const char *timestring, const char *timefield);
2.3. Extra functions to add to the vtable 2.3.1. FLTApplyFilterToLayer (mapogcfilter.c: 1084)
This is the main lter interface for layers. We will provide two helper functions, one for SQL case and the another for non-SQL case, and set all layers, except POSTGIS, ORACLESPATIAL and OGR to call directly this non-SQL version of this helper function (else-branch of if). ORACLESPATIAL, POSTGIS and OGR could use SQL version of the helper function (actual if-branch) if the conditions for this are met, otherwise they will use Non-SQL version of the function. 2.3.2. layerObj->items allocation There will be vtable function for allocation items and initialization for numitems. If layer has some special needs for these objects it can override default function. The signature for function will be:
int (*CreateItems)(layerObj *)
which does the allocation and set numitems to correct value. 2.3.3. msCheckConnection (mapfile.c: 4779) This API is deprecated. It is called only from msMYGISLayerOpen. We will not provide this functionality through vtable. 2.4. Interface functions for internal layers 520 Chapter 14. Development
We have to add some new interface functions to access layers. 2.4.1 Function interface to initialize internal layer type We need a per layer type a function which will be called when the layers vtable has to be initialized. These functions will be
int msXXXInitializeLayerVirtualTable(layerObj *)
where XXX will be name of the layer. This function is called anytime when the vtable isnt initialized and the layer is accessed at the rst time. 2.4.2 Function interface to change the connectiontype of layer To change the connection type of layer, it has to be done by function interface. Accessing directly connectiontype eld is not supported anymore. To change the connectiontype and to connect to the new layer, there will be following interface function
int msConnectLayer(int connectiontype, const char *library_str)
where connectiontype is the type of new layer, and library_str is the name of library which will prodive functionality for this new layer. For internal layer types this second argument is ignored. 3. Remove unwanted interfaces Frank Warmerdam proposed [FW1] that we remove all layer specic interface functions from map.h. I see each built-in module such as mapsde.c providing a registration function such as msSDEInitializeLayerVirtualTable so that none of the layer type specic denitions need to appear in map.h any more. Files and objects affected This proposal will affect at least following les and objects: map.h layerObj will contain new elds. There will be a new object vtableObj in the map.h. maplayer.c Various changes, layer specic switch-statements will go away, vtable handling and layers vtable initialization will be added. mapfile.c Cleaning of msCheckConnection Vtable for msCloseConnection mapogcfilter.c Remove layer-logic from FLTApplyFilterToLayer mapXXX.c, where XXX is the name of layer. Add new initialization function Add all new interface functions Fix existing interface functions, msWFSLayerOpen. 14.6. Request for Comments if needed / add wrappers for msOGRLayerOpen and
521
Backwards compatibility issues This is binary and source code level backward incompatible change. The proposal will remove some previously public functions, and add new eld(s) to the layerObj struct. This proposal is not MapScript backward compatible, it will break scripts which change directly connectiontype eld in layerObj. The proposal is MAP-le backward compatible. Implementation Issues Biggest problem is probably that the author has ignored or missed something by oversight which will show up during implementation. However, there is a prototype implementation of external plug-in architecture which works at the moment and is based on ideas presented in this proposal. So there is some real life experience that this architecture change is feasible thing to do. I also like to note that this proposal wont remove all layer specic code from MapServer e.g. WMF, WMS and GRATICULE are used as special cases from place to place. Bug ID Bug 1477 Voting history Vote proposed by Jani Averbach on 9/19/2005, result was +4 (3 non-voting members). Voting +1: Howard Butler, Frank Warmerdam, Yewondwossen Assefa, Daniel Morissette Proposal passes and will move forward. Open questions How do we like to expose layers virtual table to the layers. We have at least two different routes to go: expose it as a struct, layers will ll vtable pointers by accessing directly structs eld. expose it as a complete opaque type, vtable pointers will be set by accessing functions setLayerOpenFP, setLayerCloseFP and so on. The advance of second option is that this way we could easily add new functions to the struct if we refactor code more or found some logic which is ignored by oversight in this proposal. Are there any special issues with the raster query layer support which is handled via the layer API?
Overview Additional resampling kernels will be implemented in the MapServer GDAL raster resampler code including averaging, bilinear and cubic. Technical Details The new resampling options will be implemented in mapresample.c and will only be accessible for datasets processing through that mechanism (ie. GDAL raster formats, requires coordinate system information dened). The resampling kernel to use will be selected with one of the following. The default will be RESAMPLE=NEAREST, the current behavior.
PROCESSING PROCESSING PROCESSING PROCESSING "RESAMPLE=NEAREST" "RESAMPLE=AVERAGE" "RESAMPLE=BILINEAR" "RESAMPLE=BICUBIC"
The mapraster.c code currently decides whether to invoke the simple GDAL renderer or the resampling GDAL renderer based on whether the projection seems to differ. It will also now check for the RESAMPLE processing option, and force use of mapresample.c if the resampling kernel select is other than NEAREST. Note that resampling kernels other than NEAREST can have a substantial effect on rendering performance. For this reason NEAREST will remain the default. Maple Implications All new options are selected via new PROCESSING options. There is no change in the maple syntax. There should be no compatibility problems with old maples. MapScript Implications There are no additions or changes to the MapScript API. The new options are controlled via PROCESSING information on the layers which I believe is already manipulatable from MapScript. Documentation Implications The new processing options will need to be documented in the Raster Data (and possibly the MAP reference). Test Plan New test cases for each mode will be incorporated in msautotest/gdal. Stafng / Timeline The new feature will be implemented by Frank Warmerdam and completed by October 15th, 2005, in time for the MapServer 4.8 release. Implementation is generously funded by Tydac AG and managed by DM Solutions.
523
Tolerances MapServer will need make a decision on how detailed to get when doing the iterative horizon determination. The tolerance will be xed as half the size of a pixel in the current map rendering. In normal map drawing this should mean that the nal rendering is effectively exact. However, communicating the tolerance into msProjectShape() will require substantial work as the msProjectShape() function does not normally know anything about the map or current rendering information. To communicate this information to msProjectShape(), I will add a transformation options structure with this information (and possibly other ags controlling transformation) which will be passed into msProjectShape(). If NULL particular defaults will be used. All appropriate uses of msProjectShape() will need to be updated to reect this change, and to setup the transformation options information ahead of time. layerObj level PROCESSING options will also be provided to control (override) the default transformation options. Caveats 1. msProjectShape() may produce slightly invalid polygons from a GIS point of view, though it shouldnt matter much for rendering purposes. 2. The straight line segment for area horizon edges will result in visible clipping of the horizon for very large polygons (ie. the Soviet Union). 3. This change is too disruptive to back port to the stable 4.6.x release, so it would only be available as part of CVS based MapServer builds (aka 4.7) until such time as the 4.8 release is made, likely in December or January. Maple Implications There will be no changes to the maple. MapScript Implications There will be no changes to MapScript. Backward Compatibility Issues Some maps that previous dropped incompletely reprojected features will now produce clipped features. I dont foresee this causing obvious problems other than a slight change (improvement!) in appearance. Stafng and Timeline The new feature will be implemented by October 15th, 2005, in time for inclusion in MapServer 4.8. It will be implemented by Frank Warmerdam with generous funding from TMC Technologies.
Status Proposed Id $Id: ms-rfc-6.txt 8278 2008-12-23 21:34:31Z hobu $ Description: This proposal addresses the need to be able to easily map continuous feature values to a continuous range of colors. This RFC is the result of (and my interpretation of) the discussion that surrounded Bug #1305. A preliminary patch has already been applied to Mapserver 4.6+ (before the RFC process was in place), however, there is little consensus on the format being used and there is no support for proper display of legends for classes using ColorRanges. Background This work started as a patch that I created to be able to quickly visualize data with a large range of values. In particular, I was wishing to map property values, and various ratios that could take on a large range of values. To me, the natural way to do this was to set a max value, a min value and what colors those mapped to. The patch I wrote had Mapserver do a linear interpolation of the value for each feature on to that color range. The initial syntax for this feature simply added 5 new keywords to the STYLE block and looked as follows:
STYLE COLOR 60 60 60 MINCOLOR 0 0 0 MAXCOLOR 255 255 0 MINVALUE 0.0 MAXVALUE 300000.0 GRADIENTITEM "sale_price" END
After some discussion, the term Gradient was shown to be problematic. Also, the number of new keywords seemed high. After some discussion, the syntax was changed to this format:
STYLE COLORRANGE 0 0 0 255 255 0 # black to yellow DATARANGE 0.0 100.0 RANGEITEM "foobar" END
While this is still just a set of keywords under a Style, it seemed simpler and is now working in the Mapserver 4.6 branch. Current Syntax Problems Several people pointed out that the current syntax could be improved by: 1. Moving the new keywords into a block 2. Adding a METHOD keyword with the type of interpolation used (linear being the rst dened type, logarithmic being a potential second type, etc. 3. Adding an INTERVALS keyword that would limit the number of colors actually used by rounding values before interopolation. 4. Moving all of the keywords out of the Style block. 5. Allowing the ColorRange to be dened separately so that it can be reused
526
Proposed New Syntax To meet the above needs, I propose the following new Block Syntax:
COLORRANGE RANGEITEM itemname #required MINCOLOR 0 0 0 #optional - default = Black MAXCOLOR 255 255 0 #optional -default = White MINVALUE 0.0 #optional - default = 0 MAXVALUE 100.0 #optional - default = 1 INTERVALS 10 #optional - default = 0 (unlimited) METHOD LINEAR #optional - default = LINEAR END
I propose that this block lives at the CLASS level. My reasons for putting it at the CLASS, rather than the LAYER (or above) level are as follows: 1. CLASS is the lowest level that can dene a Legend entry (by using a named class) 2. Allows multiple COLORANGES to be applied to a single layer (i.e. Red->Yellow and Yellow->Green to make a contiguous Reg->Yellow->Green). 3. Allows out of bounds values to be highlighted separately (with a different CLASS). (If we wish to provide this capability on the OUTLINECOLOR, then I would suggest we create a OUTLINECOLORRANGE block with identical format.) Note: I am (and have always been) exible on all of the keyword names and formats here. However, given the discussion thats gone on around (and around) this, I thought Id put a straw man up and start here. Proposed Legend Format I have posted a mockup of how I believe legends should look at http://trac.osgeo.org/mapserver/ticket/324 The format only changes the height of the legend (which is already dynamic) so it should not have major layout implications. (Nit-picking about how tall the colorbar should be can be worked out during implementation.) I have not started the legend support, and would like some help in this area. However, I do believe it is straightforward, and I will do it on my own if there are no volunteers. MapScript Issues As Sean Gillies mentioned in the discussion, this should be encapsulated in MapScript as a class. While I disagree with his putting it on the LAYER (see above), the rest of his suggestions all seem right in line. I Propose a class named ColorRamp with the following read/write attributes:
Color minColor Color maxColor double minValue double maxValue String rangeItem String method int intervals
527
ColorRamps can be obtained through an appropriate constructor or through a new (read/write) attribute on the ClassObj object:
ColorRange colorRange
Note: I will need help in adding these to MapScript as I do not have the SWIG experience to do it well. Files affected I will update this list as the RFC evolves, but right now, these are what I see: maple.h => Change Keywords maplexer.l => Change Keywords maple.c => process new Keywords mapscript/swiginc/*.i => various interface modications to t the above requirements maplegend.c => Add new Legend support mapdraw.c => update existing ColorRange code to use new keywords & add intervals and LOGARITHMIC method Backwards compatabilty issues Right now, certain code _requires_ that there is a COLOR attribute set on any layer that is going to be displayed. Either this will need to be changed, or we will have to decide what that means if both a COLOR and a COLORRANGE are dened. One option is to use the COLOR for any values that are outside of the range. Multiple Mapping Methods The system will allow new color mapping methods to be added with as little effort as possible. If a new color mapping method uses only the keywords dened by this RFC, it should be a simple as: 1. Implement a function with the signature
int mappingFn(colorRangeObj\* range, shapeObj\* shape, colorObj \*color) This function should use the shape and range parameters to determine the shapes color, and modify the color parameter accordingly.
1. Choose a unique method name (linear, logarithmic, discrete) modify the method msMapColorRamp() to call its method when its method name is found on a ColorRange denition. Note: Whether the msMapColorRamp() method uses if/then logic or dispatches by function pointer can be determined later. For now, I believe the simplest approach would be to move all of the mapping logic + all current methods into a mapColorRange.c le. 528 Chapter 14. Development
529
Email address: A current email address at which the committer can be reached. It may be altered in normal ways to make it harder to auto-harvest. A brief indication of areas of responsibility. CVS Administrator One member of the Technical Steering Committee will be designed the CVS Administrator. That person will be responsible for giving CVS commit access to folks, updating the COMMITERS le, and other CVS related management. That person will need login access on the CVS server of course. Initially Steve Lime will be the CVS Adminstrator. CVS Commit Practices The following are considered good CVS commit practices for the MapServer project. Use meaningful descriptions for CVS commit log entries. Add a bug reference like (bug 1232) at the end of CVS commit log entries when committing changes related to a bug in bugzilla. Include an entry in the HISTORY le for any signicant change or bug x committed in the main MapServer source tree. Make sure it is placed under the correct version heading and include bug numbers in these messages too. Changes should not be committed in stable branches without a corresponding bug id and HISTORY entry. Any change worth pushing into the stable version is worth a bugzilla bug and good HISTORY notations. Never commit new features to a stable branch: only critical xes. New features can only go in the main development trunk. Only bug xes should be committed to the code during pre-release code freeze. Signicant changes to the main development version should be discussed on the -dev list before you make them, and larger changes will require a RFC approved by the TSC. Do not create new branches without the approval of the TSC. Release managers are assumed to have permission to create a branch. All source code in CVS should be in Unix text format as opposed to DOS text mode. When committing new features or signicant changes to existing source code, the committer should take reasonable measures to insure that the source code continues to build and work on the most commonly supported platforms (currently Linux and Windows), either by testing on those platforms directly, or by getting help from other developers working on those platforms. If new les or library dependencies are added, then the congure.in, Makele.in, Makele.vc and related documentations should be kept up to date.
Id $Id: ms-rfc-7.1.txt 8278 2008-12-23 21:34:31Z hobu $ Note: This RFC obsoletes MS RFC 7: MapServer CVS Commit Management. Purpose To formalize SVN commit access, and specify some guidelines for SVN committers. Election to SVN Commit Access Permission for SVN commit access shall be provided to new developers only if accepted by the MapServer Project Steering Committee. A proposal should be written to the PSC for new committers and voted on normally. It is not necessary to write an RFC document for these votes ... email to mapserver-dev is sufcient. Removal of SVN commit access should be handled by the same process. The new committer should have demonstrated commitment to MapServer and knowledge of the MapServer source code and processes to the committees satisfaction, usually by reporting tickets, submitting patches, and/or actively participating in the various MapServer forums. The new committer should also be prepared to support any new feature or changes that he/she commits to the MapServer source tree in future releases, or to nd someone to which to delegate responsibility for them if he/she stops being available to support the portions of code that he/she is responsible for. All committers should also be a member of mapserver-dev mailing list so they can stay informed on policies, technical developments and release preparation. Committer Tracking A list of all project committers will be kept in the main mapserver directory (called COMMITTERS) listing for each SVN committer: Userid: the id that will appear in the SVN logs for this person. Full name: the users actual name. Email address: A current email address at which the committer can be reached. It may be altered in normal ways to make it harder to auto-harvest. A brief indication of areas of responsibility. SVN Administrator One member of the Project Steering Committee will be designed the SVN Administrator. That person will be responsible for giving SVN commit access to folks, updating the COMMITTERS le, and other SVN related management. Initially Steve Lime will be the SVN Administrator. SVN Commit Practices The following are considered good SVN commit practices for the MapServer project. Use meaningful descriptions for SVN commit log entries.
531
Add a ticket reference like (#1232) at the end of SVN commit log entries when committing changes related to a ticket in Trac. Include changeset revision numbers like r7622 in tickets when discussing relevant changes to the codebase. Include an entry in the HISTORY le for any signicant change or x committed in the main MapServer source tree. Make sure it is placed under the correct version heading and include ticket numbers in these messages too. Changes should not be committed in stable branches without a corresponding ticket and HISTORY entry. Any change worth pushing into the stable version is worth a Trac ticket and good HISTORY notations. Never commit new features to a stable branch: only critical xes. New features can only go in the main development trunk. Only ticket defects should be committed to the code during pre-release code freeze. Signicant changes to the main development version should be discussed on the -dev list before you make them, and larger changes will require an RFC approved by the PSC. Do not create new branches without the approval of the PSC. Release managers are assumed to have permission to create a branch. All source code in SVN should be in Unix text format as opposed to DOS text mode. When committing new features or signicant changes to existing source code, the committer should take reasonable measures to insure that the source code continues to build and work on the most commonly supported platforms (currently Linux and Windows), either by testing on those platforms directly, or by getting help from other developers working on those platforms. If new les or library dependencies are added, then the congure.in, Makele.in, Makele.vc and related documentations should be kept up to date. Legal Commiters are the front line gatekeepers to keep the code base clear of improperly contributed code. It is important to the MapServer users, developers and the OSGeo foundation to avoid contributing any code to the project without it being clearly licensed under the project license. Generally speaking the key issues are that those providing code to be included in the repository understand that the code will be released under the MapServer License, and that the person providing the code has the right to contribute the code. For the committer themselves understanding about the license is hopefully clear. For other contributors, the committer should verify the understanding unless the committer is very comfortable that the contributor understands the license (for instance frequent contributors). If the contribution was developed on behalf of an employer (on work time, as part of a work project, etc) then it is important that an appropriate representative of the employer understand that the code will be contributed under the MapServer License. The arrangement should be cleared with an authorized supervisor/manager, etc. The code should be developed by the contributor, or the code should be from a source which can be rightfully contributed such as from the public domain, or from an open source project under a compatible license. All unusual situations need to be discussed and/or documented. Committers should adhere to the following guidelines, and may be personally legally liable for improperly contributing code to the source repository: Make sure the contributor (and possibly employer) is aware of the contribution terms. Code coming from a source other than the contributor (such as adapted from another project) should be clearly marked as to the original source, copyright holders, license terms and so forth. This information can be in the le headers, but should also be added to the project licensing le if not exactly matching normal project licensing (mapserver/LICENSE.txt). 532 Chapter 14. Development
Existing copyright headers and license text should never be stripped from a le. If a copyright holder wishes to give up copyright they must do so in writing to the foundation before copyright messages are removed. If license terms are changed it has to be by agreement (written in email is ok) of the copyright holders. When substantial contributions are added to a le (such as substantial patches) the author/contributor should be added to the list of copyright holders for the le. If there is uncertainty about whether a change it proper to contribute to the code base, please seek more information from the project steering committee, or the foundation legal counsel. Voting History Adopted on 2008/07/02 with +1 from PericlesN, DanielM, TamasS, JeffM, UmbertoN, SteveW, AssefaY, FrankW, TomK
New connection type PLUGIN New eld char* plugin_library in layerObj structure, this is the name of library to load for this layer. Function to get virtual table for requested layer. If the library isnt already loaded, it will be loaded on demand.
static const layerVTableObj * getCustomLayerVirtualTable(layerObj *layer)
where layerVTableObj is the virtual table and layer is a custom layer. In case of error, funtion will return NULL. Function to get a function pointer from dynamic loaded library. This function will also load the library.
msGetDynamicLibrarySymbol(const char *Library, const char *SymbolName)
This is implemented by GDAL project, and I have planned to use their implementation of this (CPLGetSymbol). Cache structure for already loaded libraries. This cache structure will consist of a full name/path of the library (provided by user via maple), and a function pointer to the virtual table initialization function. The size of cache will be xed and will be same as the maximum amount of layers (200 at the moment). This is the maximum number of different custom layers for MapServer which could be loaded at the same time. This cache implementation is internal, so if it has to be make dynamically allocated, it is possible to do later without breaking interface. New lock item (TLOCK_LAYER_VTABLE) to protect library cache structure. Files and objects affected This proposal will affect at least following les and objects: map.h layerObj will contain a new eld, char *plugin_library. New lock token TLOCK_LAYER_VTABLE New les and objects for custom layer handling. Backwards compatibility issues This change is binary incompatible, but maple backward compatible. It will add a new keyword which is unknown for old MapServers. Implementation Issues None Bug ID Bug 1477
534
Voting history Vote proposed by Jani Averbach on 10/26/2005, the initial result was +3 and after amending RFC, got +4 (3 non-voting members). Voting +1: Frank Warmerdam, Steve Lime, Yewondwossen Assefa, Daniel Morissette Proposal passed and will move forward. Open questions None Working Notes Plugin library has to implement function PluginInitializeVirtualTable
int (*pfnPluginInitVTable)(layerVTableObj *, layerObj *);
which is called during library loading. This function is responsible to populate layerVTableObj * virtual table. If this function leaves some function pointers to NULL in this virtual table, then default actions are used for these missing functions. The defaults are visible in function maplayer.c: populateVirtualTable(...). The function must not populate directly layerObj->vtable, it have to use layerVTableObj * argument for this. The MapServer is holding TLOCK_LAYER_VTABLE lock during this function call.
535
Implementation Details The item tag would have the following properties. name: the name of the attribute to be exposed format: a simple string containing the token(s) $value, default format is the result of any processing nullformat: string to return if value is NULL or empty (length=0) uc: convert string to upper case lc: convert string to lower case substr: perform a perl-like substring operation by providing offset, and optionally length (un-implemented as of 3/13/07) commify: add commas to a numeric string (12345 would become 12,345), note, supports only North American notation at the moment escape: what type of escaping to do (default is html), permissible values would be html, url, none precision: number of decimals to retain after the decimal point pattern: regular expression that must validate (against the column value) to process the tag We could add simple case statement support at a later date but the above would more than meet my needs at the moment. Examples Display no decimal places, and commify: [item name=foo commity=true precision=0] - 12345.6789 output as 12,345 Conditional display an item if its value contains bar: [item name=foo pattern=bar] Escape a value for inclusion in a URL, and convert to upper case: [item name=foo uc=true escape=url] - hello world output as HELLO%20WORLD Apply a custom format to an item, and display a message if the item is empty: [item name=foo format=foo=$value nullformat=foo is not found] Notes Item tags are processed after other column tags (e.g. [foo]) so you can include substitution strings within the item tag itself. Bug ID 1636 536 Chapter 14. Development
development and user communities, with the primary difference being that, where Apache started as a single project and then branched out, the OSGeo Foundation is attempting to weld together the overlapping but sometimes disparate interests of different projects with different communities. The Foundation will hopefully serve as an outreach and advocacy organization for the community; a forum for improving cross-project collaboration; a unied professional front for large government and corporate users; a source of shared infrastructure, like code and documentation repositories; and as a legal entity to help protect developers and users of Open Source geospatial software against greedy patent lawsuits or unscrupulous license infringements. In general, the object of the Foundation will be, in the words of Mark Lucas of OSSIM, to help us do what we love which, for most of us, is building useful tools for digital cartography and geospatial analysis, and solving interesting problems with them. Deciding to Join The MTSCs charter, specied in MS RFC 1, clearly states that it is only to concern itself with technical matters in the project. In our opinion, deciding to join OSGeo presents a special case in that it affects both the technical and non-technical. In this case we propose that the MTSC go through its decision process, and if approved, the community will be solicited to provide their input via a non-anonymous website poll. If both groups are in agreement - via the normal approval process from the MTSC and a majority from the community - the motion to join OSGeo will be considered passed. Considerations As MapServer joins the foundation some changes are anticipated in the project. There will need to be a copyright review of the existing code base, ensuring that it is all legitimately contributed under the existing license. All MapServer committers will need to sign some sort of committer agreement providing assurance they are not adding encumbered code. MapServer may have to consider moving its project infrastructure (CVS, website, lists, etc.) to the foundation at some point. We will also need to establish a MapServer Project Committee within the foundation. This may just be the MTSC or it may be broader, including other stakeholders. For the time being the MTSC will continue to operate under MS RFC 1: Technical Steering Committee Guidelines if the motion to join OSGeo is passed. Additional RFC(s) will address any changes in process deemed necessary as a result of joining the foundation. Voting history Passed +7. February 6th, 2005.
538
Overview One of the features most frequently asked for are labels that follow along linear features. This RFC describes an initial implementation of this feature. Technical Details The proposed solution has a couple of primary goals: isolate virtually all computations and data storage into a minimum number of functions and structures. integrates easily into the existing labelCacheObj structure and label cache processing routines. A single, new function- msPolylineLabelPath() serves as the sole computational function for this new functionality. Like the existing msPolylineLabelPoint() function it takes an input feature and annotation string and computes a labeling position. However, instead of computing a single point (and optionally, angle) it computes a label point and angle for each character in the annotation string. The computation results are returned in a new structure called a labelPathObj that looks like:
typedef struct { multipointObj path; shapeObj bounds; double *angles; } labelPathObj;
The function will return NULL if a curved label is not appropriate for the feature in question so traditional labeling can take place (for example, if the feature has only 2 points a curved label is not necessary). The curved labels bounding polygon will be calculated in this function as well and stored in the bounds member of the labelPathObj structure. In order to get the labelPathObj into the label cache it will be necessary to do 2 things: extend labelCacheMemberObj to optionally reference a labelPathObj extend the function msAddLabel to take a labelPathObj in addition to the parameters it already accepts Since each labelPathObj will contain the boundary for the curved label, it will be ready to use with the existing label cache rendering code. The only addition to the label cache rendering is code to detect when a text path should be rendered instead of a traditional label. Driver specic code to render a text path will have to be written but in general this is trivial and just involves calling the normal text rendering code once for each character in the path. Maple Implications It is proposed that we simply extend the labelObj ANGLE parameter. Currently it takes an angle (given in degrees) or the keyword AUTO. We suggest adding support for the keyword FOLLOW. This would set a new labelObj member, anglefollow, to MS_TRUE (and also angleauto to MS_TRUE as ANGLE FOLLOW implies ANGLE AUTO if a curved label is not appropriate). Support for Non-GD Renderers Presently all MapServer output renders use the contents of the label cache, which is basically render agnostic. This will not be the case any more. The placement computations necessary to support curved labels do leverage font metrics derived from the GD/Freetype interface. It may well be possible for the SWF, PDF and SVG renders to leverage 14.6. Request for Comments 539
even the GD-based curved labels, however it is probably best to consider this a raster-only output feature in this implementation. If font metrics support for other renderers is developed in the future then this feature can be easily extended to support them. Bug Tracking Bug 1620 has be setup to track this feature addition. Voting History +1: Lime, Assefa, Nacionales, Warmerdam, Morissette
Unit tests are placed in the cunit subdirectory of the MapServer source and distributed with all future releases. Unit tests les should be named with respect to the original MapServer source le they test plus the addition of the _tests sufx: for instance unit tests for the mappool.c le should be placed in a le called mappool_tests.c. The les can have an alphanumeric code added to the sufx to keep them conveniently short (like mappool_tests_1.c, mappool_tests_1b.c or mappool_tests_umberto.c). Usage recommendations Developers are not required to write unit tests but when they do we suggest to follow this checklist.
General
She will also use the usual preprocessor ags to ensure only the relevant tests for the current conguration context will be compiled and run. The example attached to issue #1664 already implements this feature. Testing specic functionalities Some aspects of MapServer like database connections and gd rendering are inherently difcult to test. This section provides guidance on how to deal with them in unit tests and will be expanded as new or better solutions are devised.
Database connections
Database connections generally require a specic setup so that expected tables, data and possibly other structures are in place. While this should be a long term goal in the short term unit tests could be limited to comparing the sql query against the expected one. This quite likely requires a refactoring of current PostGIS code. In the future a minimal setup script should be provided to create and populate the database for the user (if she desires to do so).
541
WFS/WMS support
Note: The author is not an expert here In this case unit tests can be used to verify that for certain requests (possibly using the test data supplied with MapServer) the string returned by MapServer equals the expected one. A refactoring of existing code could be necessary.
Mapscript
Unit tests should be developed by the MapScript mantainers by following the guidelines given here. Running unit tests and functional tests ( Continuos integration ) Not part of unit tests for now, but useful in perspective Effort should be put toward developing a build system capable of 1. testing the overall build/test of MapServer and of the various MapServers with different congure options 2. and integrating those results with the msautotest suite.
Sensor Model Language : Information model and XML encoding for discovering, querying and controlling Web-resident sensors. Sensor Planning Service : A service by which a client can determine collection feasibility for a desired set of collection requests for one or more mobile sensors/platforms, or a client may submit collection requests directly to these sensors/platforms. Transducer markup Language (TML) : General characterizations of transducers (both receivers and transmitters) Web Notication Service : Executes and manages message dialogue between a client and Web service(s) for long duration asynchronous processes. The intention here is to support the SOS mandatory operations. Please refer to the OGC site (http://www.opengeospatial.org/functional/?page=swe) for more details on the SWE initiatives. User Interface From the user perspective there will be an SOS interface will offer the three core operations (GetCapabilities, GetObservation and DescribeSensor). A full description of what could be available is presented in Annexe A : Sensor Observation System (SOS) support in MapServer. Changes in MapServer All the development will be localized into a mapogcsos.c le. There will be additions to the mapows.c/h le to integrate the dispatch of the requests. In mapgml.c (function msGMLWriteWFSQuery), extract the loop that writes features ( gml:featureMember) into a separate function so the the GetObservation can also use it to output the results. The SOS capability will be available when MapServer is built using the ag USE_SOS. Mapscript implications The are no special implication for the MapScript module Additional libraries There will be an attempt to use the libxml2 (http://xmlsoft.org/) library when generating the GetCapabilities document. Decision to go ahead will be based on ease to use and speed of output. Testing It is proposed that automatic tests with map/data/expected results be added into the msautotest project to test the GetCapbilities and GetObservation requests. Bug Tracking Bug 1710 : http://trac.osgeo.org/mapserver/ticket/1710
543
Voting History +1 : Assefa, Warmerdam, Nacionales +0 : Morissette -0 : Gillies Note: discussions, concerns are available in the mapserver-dev list (Feb 2006 RFC 13 : SOS support) Annexe A : Sensor Observation System (SOS) support in MapServer This is a rst attempt to dene what will be supported in MapServer to be able to deploy a Sensor Observation System (SOS) Specications and useful links used : Sensor Observation Service (SOS) (OGC 05-088r1, Version 0.1.1) Observation and Measurement (OGC 05-087r1, toward Version 1.0) Sensor ML : Sensor Model Language(ML) OGC 04-019r2 http://www.opengeospatial.org/functional/?page=swe svn link https://svn.opengeospatial.org:8443/ogc-projects/ows-3/schema4demo/ for members :
SOS provides several operations divided into core mandatory operations (GetCapabilities, DescribeSensor and GetObservation) and optional transactional and enhanced operations. The rst implementation of SOS in MapServer will only address the core operations 1. GetCapabilities Request The GetCapabilities request will use the following parameters : Request : xed at GetCapabilities Service : xed at SOS 2. GetCapabilities returned document Attached at the end of the document examples of a GetCapabilities document. The following elements are SOS items included in the capabilities document, with an equivalent MapServer implementation ServiceIdentication (all elements are extracted from metadata at the web level) Title : extracted from a metadata at web level ows/sos_title. Same concept as wms/wfs Abstract : metadata ows/sos abstract ServiceType : Fixed to SOS ServiceType version : Fixed to 0.3 Fees : metadata Ows/sos_fees Access Constrains : metadata : Ows/sos_constrain
ServiceProvider (all elements are extracted from metadata at the web level, using an equivalent name as the SOS element) ProviderName : ProviderSite IndividualName 544 Chapter 14. Development
PositionName Voice Facsimile DeliveryPoint City AdministrativeArea PostalCode Country ElectronicmailAdress EndAdress OnlineResource HoursOfService ContactInstructions
Operation Metadata : This part of the capabilities denes the operations that will be supported which are GetCapbilities and GetObservation. For more information refer to https://svn.opengeospatial.org:8443/ogcprojects/ows3/schema4demo/ows/1.0.30/owsOperationsMetadata.xsd Operation : GetCapabilities * Operation Name : Fixed at GetCapabilities * HTTP : Connect point URL extracted. Only the Get request method is supported * Parameter : includes name and version. We could use the parameters to propagate the name of the service SOS and the version. Other parameters may be added if needed. Operation : GetObservation * Operation Name : Fixed GetObservation * DCP (HTTP) : extracted from a metadata * Parameter : We could use this to propagate the parameters needed when doing a GetObservation request (Offering, eventTime) Operation : DescribeSensor Filter Capabilities The Filter Capabilities that will be supported are the same ones that are currently supported in MapServer (See WFS Filter Encoding for more info) : Spatial Capabilities, Logical Operators, Comparison Operators There is a mention in the specications of ogc lter temporal capabilities, but I could not locate the exact denition of it. In any case, SOS Contents (Observation Offerings) As explained in SOS specications (section 6.2) , ...An observation offering is also analogous to a layer in a Web Map Service because each offering is intended to be a non-overlapping group of related observations. Each Observation Offering is constrained by a number of parameters including sensor system that report observation, Time, phenomena, geographical region ... In MapServer an Offering will be represented by a group of layers using mapserers group parameter. The metadata associated with a group (offering will be taken from the rst layer of the group) The following properties would be set at a group level. Standard Properties * id : Unique Offering Identier. Mandatory * name : name used with the offering. Optional * description : description of the offering. Optional Bounded By : used to dene the geographical boundaries of the Offering. It should be extracted from a metadata. Mandatory 14.6. Request for Comments 545
EventTime : used to dene a valid time range for the offering. It should be extracted from a metadata. Mandatory Procedures : series of URLS reference to one or more systems that supply observations in the offering. It should be extracted from a metadata. Mandatory Observed property : Observables/Phenomena that can be requested in this offering. Two specializations are identied in the specications: Constrained : modies base phenomenon by adding a single constrains (ex surface water temperature add a constrain that depth is between 0, -0.3) Compound which is either a composite (a set of component phenomena that may or may not relate to each other)or a phenomenonSeries that applies one or more constrainstList to the base phenomenon) There is no clear cut indication which representation would be the more natural for MapServer but if we consider the group/layer/attribute combination, we can see that a group of layers could represent an offering, a layer would be an observed property (or phenomenon) and the attributes would be the composite phenomenon dening the phenomenon. The capabilities document will include CompositePhenomenonType element with an mandatory id element identifying the phenomenon and optional elements such as name and component. Feature Of Interest The denition given in the specication is : This is a single feature or a collection of features that represents the object on which the sensor systems are making observations. In case of in-situ sensor this may be a station to which the sensor is attached or the atmosphere directly surrounding it. For remote sensors this may be the area or volume that is being sensor. It is represented by GML feature type and is expected to include bounding box extents. In our case here, this would be equivalent to the bounded by element dened earlier. Note that in the implementation of MapServer, It is assumed that geographical information used to represent the individual sensors represent the feature of interest of the sensor. This is a requirement to be able to do spatial queries. Result Format MIME type of the result that will be returned to a GetObservation request. text/xml;subtype=om1.0.30 3. GetObservation Request The GetObservation request used to retrieve observation data will be supported using the Get method. Post method will not be supported in the rst implementation. Here are the parameters that will be supported and their denitions : Offering : Equivalent to the Offering Id identied in the capabilities (Mandatory) evetnTime : single time or time period. This will be used as a Time lter to do the queries using an identied time attribute. (Optional) observedProperty : Identies the layer in MapServer (Mandatory) featureOfInterest : Additional geographical lter using a bbox. (Optional) Result : Will be used to lter using the OGC Filter supported capabilities. 4. Get Observation Response An observation response should contain the following information : Information describing the Offering Valid time (instances or period) 546 Chapter 14. Development Fixed to
Description of the phenomenon (like the offering name) location and feature of interest for the offering The result associated with the offering In the case of MapServer implementation, what is proposed is to be returned an observation collection reecting the query results. Here is the different elements returned : name : The offering unique identier description : Description of the offering time : Valid time instance or period featureonterest : Geographical extents covered of the offering Member : This is repeated for all the observations returned. The following are the parameters included for each member observed property : the phenomenon observed location : geographical coordinates procedure result : Result of the observation. In the rst implementation It is proposed that the gml:feature member is returned. This gives the possibility to return one/more attribute values in an easily manipulated format. The will be equivalent to a gml:feature member returned in wfs.
5. Describe Sensor The Describe sensor request uses two parameter that are SensorId (Mandatory) and an optional outputFormat. In this phase the DescribeSensor will use a metadata of URL type set on the layer and relay the request. There wont be any SensorML output generation done in MapServer in this implementation. 6. Examples http://vast.uah.edu:8080/ows/weather?request=GetCapabilities http://vast.uah.edu:8080/ows/weather? request=GetObservation&offering=WEATHER_DATA&time=200404-01T05:00:00Z/2004-04-01T06:00:00Z&format=application/com-xml
C Structural Changes None. Existing structure, members and constants would be utilized. The position enumeration should probably be given a different starting value to avoid conict with variables like MS_TRUE and MS_FALSE. Maple Changes This functionality is really geared towards inline features. However, Id like to keep the door open to support features from any datasource. The proposed change would extend the use of the LAYER TRANSFORM parameter. Currently it takes values TRUE or FALSE (default is TRUE). I propose extending to also take any of the standard explicit position values. So for the typical inline feature use youd see a layer like:
LAYER NAME copyright TYPE POINT TRANSFORM LL FEATURE POINTS 10 -10 END TEXT Copyright © MNDNR END CLASS ... END END
Files affected map.h => change starting value of the positions enumeration maple.c => add detection of the additional TRANSFORM values mapprimitive.c => add a new offset shape function that would take the map hight, width and shapeObj as input. mapdraw.c => update shape drawing code to use the new function (basically an else condition for all the if (layer->transform) checks). Testing Python suite: none needed MsAutoTest suite: a maple testing all 9 positions would be developed Backwards compatabilty issues N/A, new functionality. A value for TRANSFORM of FALSE implies UL... It should be noted that by changing the starting value for the position enumeration there is the possibility of breaking scripts that refer position by integer (poor programming practice). I would expect this to be a remote possibility and worth the risk.
548
549
2.1 Not changing the code (Considering as safe without locks) Some of the process-wide global variables store invariant data - like enumerations - having been initialized at compilation time. Since these variables can be simultaneously read by multiple threads there is nothing to be done and even the locks should be removed - if exist - ensuring the thread isolation to be realized. Might be redeclared as static const. 2.2 Retaining the variable, but reconsidering the initialization code Some of the global variables store invariant data but the initial value is assigned at run time during the module initialization phase. In this situation we should ensure that the initialization will be done before the subsequent access is receivable to prevent from the possibility of race conditions. msSetup() is designated as a suitable place to make module level initialization of the variables. Mapscript language bindings are encouraged to provide calling msSetup automatically at module startup. The current locking strategy should be reviewed and the locks should be restricted to the initialization code. 2.3 Rewriting the code to eliminate the need of the global variable If the global variable could be eliminated by changing the code structure we will consider to make these changes. The locks related to these variables should be removed. 2.4 Using thread local variable instead of the global one When the usage of the global variable cannot be eliminated easily we will consider to use thread local variables instead. To implement thread local variables, theoretically we have at least 2 options to do: 1. By modifying the variable declaration we could use storage speciers like Microsoft specic __declspec(thread) or __thread on the POSIX environments. 2. By implementing the allocation of the thread local memory utilizing the platform dependent TLS APIs like the Windows TLS or the unix Pthreads implementation. The rst one is not applicable for Mapserver since the Microsoft implementation does not allow delay loading of the dll containing variables declared with __declspec(thread). The second approach is applicable, however rewriting the existing code may be more difcult. GDAL has a sample implementation for it might be taken over. 2.5 Not changing the code (Marking as safe with locks, will be reconsidered later) Some of the MapServer code and/or the related external libraries may not be modied easily and will be protected by locks in this phase of the realization. These issues will be kept open and the solution for the thread isolation might be reconsidered later. The open issues will be enumerated and documented along with the MapServer source les and the thread safety FAQ http://mapserver.gis.umn.edu/docs/faq/thread_safety 2.6 Not changing the code (Marking as unsafe, will be deprecated and unsupported) Having lack of support of portions of the existing code may keep from changing the code easily. These portions of the code will not be modied in this phase of the realization. These issues will be kept open and might be reconsidered later. The open issues will be enumerated and documented along with the MapServer source les and the thread safety FAQ. 550 Chapter 14. Development
3. Issues of the Mapserver/Mapscript code This chapter will enumerate the sections of the existing code should be reconsidered according to the options mentioned previously. The line numbers may slightly change according to the developers work.
epplib.c(47):static int REVERSE; /* set to 1 on bigendian machines */
This variable is set in eppreset using the following code { union { long i; char c[4]; } u; u.i=1; REVERSE=(u.c[0]==0); } should be set during the initialization or by the makele as a predened constant. Also the MapServer congure script may include byte order detection. This constant might be used by other modules. SDL: This constant is limited to epplib.c...
mapcpl.c(57):static char szStaticResult[MS_PATH_BUF_SIZE];
FrankW: In fact this code carried over from GDAL was later remodelled in GDAL. It looks like msGetBasename() is only used in a few places and we should remodel those to avoid using a static buffer.
maperror.c(110):static char *ms_errorCodes[MS_NUMERRORCODES] = {"", maperror.c(154): static errorObj ms_error = {MS_NOERR, "", "", NULL}; maperror.c(169):static te_info_t *error_list = NULL; maperror.c(552): static char version[1024]; maperror.c(651): static char nonblocking_set = 0;
TODO
mapfile.c(184):static char *msUnits[8]={"INCHES", "FEET", "MILES", "METERS", "KILOMETERS", "DD", "PI mapfile.c(185):static char *msLayerTypes[8]={"POINT", "LINE", "POLYGON", "RASTER", "ANNOTATION", "QUE mapfile.c(186):char *msPositionsText[MS_POSITIONS_LENGTH] = {"UL", "LR", "UR", "LL", "CR", "CL", "UC" mapfile.c(187):static char *msBitmapFontSizes[5]={"TINY", "SMALL", "MEDIUM", "LARGE", "GIANT"}; mapfile.c(188):static char *msQueryMapStyles[4]={"NORMAL", "HILITE", "SELECTED", "INVERTED"}; mapfile.c(189):static char *msStatus[5]={"OFF", "ON", "DEFAULT", "EMBED"}; mapfile.c(191):static char *msTrueFalse[2]={"FALSE", "TRUE"}; mapfile.c(193):static char *msJoinType[2]={"ONE-TO-ONE", "ONE-TO-MANY"};
The above are all const static data, being handled as 2.1.
mapgd.c(239):static unsigned char PNGsig[8] = {137, 80, 78, 71, 13, 10, 26, 10}; /* 89 50 4E 47 0D 0A mapgd.c(240):static unsigned char JPEGsig[3] = {255, 216, 255}; /* FF D8 FF hex */ mapgd.c(911): static gdPoint points[38]; mapgd.c(2428): static double last_style_size; mapgd.c(2719): static int styleIndex, styleVis; mapgd.c(2720): static double styleSize=0, styleCoef=0, last_style_size=-1; mapgd.c(2721): static int last_style_c=-1, last_style_stylelength=-1, last_styleVis=0;
TODO
mapgdal.c(141):static int bGDALInitialized = 0;
551
Imagemap support is not widely used, will be handled as 2.6 for now. Still waiting for comments.
mapio.c(67):static mapio.c(69):static mapio.c(70):static mapio.c(71):static mapio.c(73):static mapio.c(74):static mapio.c(75):static int is_msIO_initialized = MS_FALSE; msIOContext default_stdin_context; msIOContext default_stdout_context; msIOContext default_stderr_context; msIOContext current_stdin_context; msIOContext current_stdout_context; msIOContext current_stderr_context;
FrankW: Currently there is only one process wide set of io handlers for io. This will almost certainly need to change at some point to be thread local in some fashion. I hope to address this when I work on the redirectable OWS services accessable from MapScript this spring.
maplexer.c(220):static YY_BUFFER_STATE yy_current_buffer = 0; maplexer.c(230):static char yy_hold_char; maplexer.c(232):static int yy_n_chars; /* number of characters read into yy_ch_buf */ maplexer.c(238):static char *yy_c_buf_p = (char *) 0; maplexer.c(239):static int yy_init = 1; /* whether we need to initialize */ maplexer.c(240):static int yy_start = 0; /* start state number */ maplexer.c(245):static int yy_did_buffer_switch_on_eof; maplexer.c(306):static yyconst short int yy_accept[2442] = maplexer.c(579):static yyconst int yy_ec[256] = maplexer.c(611):static yyconst int yy_meta[52] = maplexer.c(621):static yyconst short int yy_base[2456] = maplexer.c(895):static yyconst short int yy_def[2456] = maplexer.c(1169):static yyconst short int yy_nxt[2776] = maplexer.c(1478):static yyconst short int yy_chk[2776] = maplexer.c(1787):static yy_state_type yy_last_accepting_state; maplexer.c(1788):static char *yy_last_accepting_cpos; maplexer.c(1886):static int yy_start_stack_ptr = 0; maplexer.c(1887):static int yy_start_stack_depth = 0; maplexer.c(1888):static int *yy_start_stack = 0;
According to Steves suggestions we will address this with newer versions ex and bison invoked appropriately.
mapmygis.c(245):static int gBYTE_ORDER = 0;
TODO
552
mapogcsos.c(1974):
TODO
mapogr.cpp(840):static int bOGRDriversRegistered = MS_FALSE;
TODO
mapparser.c(282):static mapparser.c(317):static mapparser.c(328):static mapparser.c(354):static mapparser.c(368):static mapparser.c(381):static mapparser.c(391):static mapparser.c(402):static mapparser.c(415):static mapparser.c(431):static mapparser.c(439):static mapparser.c(455):static mapparser.c(465):static mapparser.c(491):static mapparser.c(519):static const const const const const const const const const const const const const const const unsigned char yytranslate[] = unsigned char yyprhs[] = yysigned_char yyrhs[] = unsigned short yyrline[] = char *const yytname[] = unsigned short yytoknum[] = unsigned char yyr1[] = unsigned char yyr2[] = unsigned char yydefact[] = yysigned_char yydefgoto[] = short yypact[] = yysigned_char yypgoto[] = unsigned char yytable[] = yysigned_char yycheck[] = unsigned char yystos[] =
According to Steves suggestions we will address this with newer versions ex and bison invoked appropriately.
mappluginlayer.c(46):static VTFactoryObj gVirtualTableFactory = {MS_MAXLAYERS, 0, {NULL}};
TODO
mappool.c(206):static int connectionCount = 0; mappool.c(207):static int connectionMax = 0; mappool.c(208):static connectionObj *connections = NULL;
TODO
mapproject.c(889):static char *ms_proj_lib = NULL; mapproject.c(890):static char *last_filename = NULL; mapproject.c(918): static int finder_installed = 0;
TODO
mapscale.c(68):static char *unitText[5]={"in", "ft", "mi", "m", "km"}; mapscale.c(69):double inchesPerUnit[6]={1, 12, 63360.0, 39.3701, 39370.1, 4374754};
553
TODO
mapserv.c(1196): static int nRequestCounter = 1;
Considering safe without locks (2.1). The mapserv application does not involved in multiple threads.
mapshape.c(70):static int bBigEndian;
TODO
mapswf.c(97):static char gszFilename[128]; mapswf.c(98):static char gszAction[256]; mapswf.c(99):static char gszTmp[256];
TODO
TODO
mapwms.c(252):static char *wms_exception_format=NULL;
TODO
md5c.c(58):static unsigned char PADDING[64] = {
554
SDL: gdft and its contents are not part of MapServer distributions.
gdft\gdttf.c(712): gdft\gdttf.c(852): gdft\gdttf.c(853):
static gdCache_head_t *tweenColorCache=NULL; /****** set up tweenColorCache on fi static gdCache_head_t *fontCache=NULL; /****** initialize font engine on fir static TT_Engine engine;
SDL: gdft and its contents are not part of MapServer distributions.
gdft\jisx0208.h(7):static unsigned short UnicodeTbl[][94] = {
SDL: gdft and its contents are not part of MapServer distributions.
mapscript\csharp\csmodule.i(32): mapscript\csharp\csmodule.i(41): static $moduleHelper() static $moduleHelper the$moduleHelper = new $moduleHelper();
TODO
mapscript\php3\php_mapscript.c(789):static mapscript\php3\php_mapscript.c(790):static mapscript\php3\php_mapscript.c(791):static mapscript\php3\php_mapscript.c(792):static mapscript\php3\php_mapscript.c(793):static mapscript\php3\php_mapscript.c(794):static mapscript\php3\php_mapscript.c(795):static mapscript\php3\php_mapscript.c(796):static mapscript\php3\php_mapscript.c(797):static mapscript\php3\php_mapscript.c(798):static mapscript\php3\php_mapscript.c(799):static mapscript\php3\php_mapscript.c(800):static mapscript\php3\php_mapscript.c(801):static mapscript\php3\php_mapscript.c(802):static mapscript\php3\php_mapscript.c(803):static mapscript\php3\php_mapscript.c(804):static mapscript\php3\php_mapscript.c(805):static mapscript\php3\php_mapscript.c(806):static mapscript\php3\php_mapscript.c(807):static mapscript\php3\php_mapscript.c(808):static mapscript\php3\php_mapscript.c(809):static int int int int int int int int int int int int int int int int int int int int int le_msmap; le_mslayer; le_msimg; le_msclass; le_mslabel; le_mscolor; le_msrect_new; le_msrect_ref; le_mspoint_new; le_mspoint_ref; le_msline_new; le_msline_ref; le_msshape_new; le_msshape_ref; le_msshapefile; le_msweb; le_msrefmap; le_msprojection_new; le_msprojection_ref; le_msscalebar; le_mslegend;
555
mapscript\php3\php_mapscript.c(810):static mapscript\php3\php_mapscript.c(811):static mapscript\php3\php_mapscript.c(812):static mapscript\php3\php_mapscript.c(813):static mapscript\php3\php_mapscript.c(814):static mapscript\php3\php_mapscript.c(815):static mapscript\php3\php_mapscript.c(816):static mapscript\php3\php_mapscript.c(857):static mapscript\php3\php_mapscript.c(858):static mapscript\php3\php_mapscript.c(859):static mapscript\php3\php_mapscript.c(860):static mapscript\php3\php_mapscript.c(861):static mapscript\php3\php_mapscript.c(862):static mapscript\php3\php_mapscript.c(863):static mapscript\php3\php_mapscript.c(864):static mapscript\php3\php_mapscript.c(865):static mapscript\php3\php_mapscript.c(866):static mapscript\php3\php_mapscript.c(867):static mapscript\php3\php_mapscript.c(868):static mapscript\php3\php_mapscript.c(869):static mapscript\php3\php_mapscript.c(870):static mapscript\php3\php_mapscript.c(871):static mapscript\php3\php_mapscript.c(872):static mapscript\php3\php_mapscript.c(873):static mapscript\php3\php_mapscript.c(874):static mapscript\php3\php_mapscript.c(875):static mapscript\php3\php_mapscript.c(876):static mapscript\php3\php_mapscript.c(877):static mapscript\php3\php_mapscript.c(878):static mapscript\php3\php_mapscript.c(879):static mapscript\php3\php_mapscript.c(891):static mapscript\php3\php_mapscript.c(893):static
int le_msstyle; int le_msoutputformat; int le_msgrid; int le_mserror_ref; int le_mslabelcache; int le_mssymbol; int le_msquerymap; zend_class_entry *map_class_entry_ptr; zend_class_entry *img_class_entry_ptr; zend_class_entry *rect_class_entry_ptr; zend_class_entry *color_class_entry_ptr; zend_class_entry *web_class_entry_ptr; zend_class_entry *reference_class_entry_ptr; zend_class_entry *layer_class_entry_ptr; zend_class_entry *label_class_entry_ptr; zend_class_entry *class_class_entry_ptr; zend_class_entry *point_class_entry_ptr; zend_class_entry *line_class_entry_ptr; zend_class_entry *shape_class_entry_ptr; zend_class_entry *shapefile_class_entry_ptr; zend_class_entry *projection_class_entry_ptr; zend_class_entry *scalebar_class_entry_ptr; zend_class_entry *legend_class_entry_ptr; zend_class_entry *style_class_entry_ptr; zend_class_entry *outputformat_class_entry_ptr; zend_class_entry *grid_class_entry_ptr; zend_class_entry *error_class_entry_ptr; zend_class_entry *labelcache_class_entry_ptr; zend_class_entry *symbol_class_entry_ptr; zend_class_entry *querymap_class_entry_ptr; unsigned char one_arg_force_ref[] = unsigned char two_args_first_arg_force_ref[] =
TODO
mapscript\php3\php_proj.c(196):static zend_class_entry *proj_class_entry_ptr; mapscript\php3\php_proj.c(200):static int le_projobj; mapscript\php3\php_proj.c(294):static long _php_proj_build_proj_object(PJ *pj,
TODO
mapscript\swiginc\dbfinfo.i(40): static char pszFieldName[1000];
TODO
mapscript\swiginc\map.i(204): static int i=0;
556
4. Considerations for the future development Developers should keep in mind that their code may be called by multiple threads simultaneously. Using process-wide global variables modied at run time will be discouraged in the future. If the usage is inevitable the variables should be protected by using mutual exclusion properly depending on the USE_THREAD constant. 5. Backwards compatibility issues This is binary and source code level backward incompatible change. The compatibility of the mapscript interface might be kept. Bug ID The following bug is added as a primary source for collecting the developer and user response. Nevertheless the MapServer users and developers list will also be monitored and the RFC will be updated accordingly by the primary author. Bug 1764 Voting history Still not proposed for voting
557
Technical Solution GetCapabilities, GetFeatureInfo and GetMap calls for WMS callable from MapScript, and results capturable for processing. GetCapabilities, DescribeCoverage and GetCoverage calls for WCS callable from MapScript and results capturable for processing. GetCapabilities, DescribeFeatureType and GetFeature calls for WFS callable from MapScript and results capturable for processing. Any other OWS services dispatched through OWSDispatch (such as SOS) would also be accessable from MapScript. IO hooking to capture various output from MapServer services will be accomplished via mapio.c services, the same as is used to capture output for FastCGI services. All SWIG based MapScript languages will be supported (Perl, Python, Ruby, C#, Java). PHP (non SWIG) may be supported if the PHP MapScript maintainers do a similar implementation. A MapScript WxS HOWTO will be written, including simple examples of customized services. WxS Functions Add the following methods on the mapObj in mapscript/swiginc/map.i.
int OWSDispatch( OWSRequest *req );
We cant call the lower level functions, like msWMSGetCapabilities() directly very easily because these functions require some pre-processing done by msWMSDispatch(). Note that the OWSDispatch() recongures the map it is invoked on to match the request. Note that the results of the OWSRequest are still written out via the normal stdout stream handling, so separate msIO hooking is needed to capture the results. OWSRequest This object is already dened to MapScript in mapscript/swiginc/owsrequest.i but it seems to lack a means of setting it from cgi arguments or directly by parsing a provided url. I propose to add the following method on the OWSRequest:
loadParams();
Loads the parameters from the normal sources (QUERY_STRING env. variable for instance).
loadParams( const char * url );
Loads the parameters from the given url portion as would have appeared in QUERY_STRING if REQUEST_METHOD was GET.
558
IO Hooking Currently output from functions such as msWMSGetCapabilities() is directed through the msIO services (in mapio.c), such as msIO_printf(). In order to capture this output and make it available for further processing it will be necessary to provide a means for MapScript applications to insert their own IO handlers of some sort. Additionally, currently the msIO layer has a concept of io handlers, but they are global to the application. For nontrivial use of WxS MapScript services in Java, c# and other multithreaded environments it is desirable for it to be possible to insert per-thread IO handlers. Need to make at least current_stdin/stdout/stderr_context variables thread local. Possibly using the same approach as maperror.c. A new mutex will be required for this. Consider thread safe output to shared stdin/stdout/stderr handles for all threads? ie. protect with a mutex. We need to provide a convenent way to install to buffer and from buffer io handlers. We need to always use msIO redirection. Currently in the default case of not using FastCGI, USE_MAPIO is not dened in mapio.h and msIO_printf() and similar functions are actually just #deneed to printf(). But if we want to be able to capture output all the time for MapScript, we will actually always need the msIO layer. So USE_MAPIO will always have to be dened.
msIO_resetHandlers();
Resets msIO handlers to defaults (using stdin, stdout, stderr). Clears buffer data if buffered handlers were installed.
msIO_installStdoutToBuffer();
Fetch stdout buffer pointer and length. gdBuffer already provides language specic bindings to get byte data.
const char *msIO_getStdoutBufferString();
Fetch stdout buffer as a string. Appropriate for XML and HTML results for instance. 14.6. Request for Comments 559
The installed buffer handlers will manage their own buffer and concept of current read/write position. My objective is that folks should be able to do something like this in Python MapScript.
mapscript.msIO_installStdoutToBuffer() if map.OWSDispatch( req ) == mapscript.MS_SUCCESS: result = mapscript.msIO_getStdoutBufferString() mapscript.msIO_resetHandlers()
Questions: 1) Should we be pushing handlers instead of installing them and losing track of the previous handler? Then we could just pop them off. 2) Should we make the whole msIOContext thing more visible to MapScript? It seems like it would be complicated. gdBuffer The msIO_getStdoutBufferBytes() returns a gdBuffer since most language bindings already have a way of using this as a array of raw bytes buffer. It is normally used for fetched gdImage buffers. But because the msIO function returns a gdBuffer referring to an internally memory array not owned by the gdBuffer we need to add a owns_data ag.
typedef struct { unsigned char *data; int size; int owns_data; } gdBuffer;
Likewise, each of the language bindings needs to be modied to only call gdFree() on data if owns_data is true. This:
%typemap(out) gdBuffer { $result = PyString_FromStringAndSize($1.data, $1.size); gdFree($1.data); }
becomes this:
%typemap(out) gdBuffer { $result = PyString_FromStringAndSize($1.data, $1.size); if( $1.owns_data ) gdFree($1.data); }
And similarly for the other bindings. Files and objects affected
mapio.c mapio.h mapscript/mapscript.i mapscript/swiginc/owsrequest.i mapscript/swiginc/image.i
560
Backwards compatibility issues There are no apparent backward compatibility problems with existing MapScript scripts. Implementation Issues the gdBuffer stuff likely ought to be generalized. some MapScript languages lack gdBuffer typemaps (ie. perl). some performance testing should be done to verify that USE_MAPIO isnt going to slow down normal operations signicantly. This is specially a concern once the mapio.c statics are actually handled as thread local as each msIO call will need to search for the appropriate thread local context. the msIO buffer approach is predicated on streaming output results into a memory buffer. For very large return results this may use an unreasonable amount of memory. For instance a WFS request with a 250MB response document. But such results arent necessarily reasonable in web services context anyways. The set of functions will need to be exposed separately in the PHP bindings. Test suite The msautotest/mspython and python unit tests will be extended with at least rudimentary testing of a few of these services. As we have no automated tests for other MapScript languages, no automated tests will be added, but I will endevour to prepare simple scripts to test things. Currently this has been done for Python and Perl MapScript. Example This shows a very simple Python MapScript script that invokes a passed in OWSRequest passed via normal cgi means, but adding a text/plain content type ahead of the regular content type so we can see the results. The script could easily have done extra manipulation on the URL parameters, and on the map object. Example:
#!/usr/bin/env python import sys import mapscript req = mapscript.OWSRequest() req.loadParams() mapscript.msIO_installStdoutToBuffer() map.OWSDispatch( req ) print Content-type: text/plain print print mapscript.msIO_getStdoutBufferString()
561
Bug ID http://trac.osgeo.org/mapserver/ticket/1788 Voting history +1: FrankW, SteveW. Open questions None
14.6.18 MS RFC 17: Dynamic Allocation of layers, styles, classes and symbols
Date 2006/05/12 Author Frank Warmerdam, with edits from Daniel Morissette and Umberto Nicoletti Contact warmerdam at pobox.com, dmorissette at mapgears.com, umberto.nicoletti at gmail.com Last Edited 2007/07/18 Status Adopted (2007/07/18) - Implementation completed (2007/07/23) Version MapServer 5.0 Id $Id: ms-rfc-17.txt 8278 2008-12-23 21:34:31Z hobu $ Purpose Modify the MapServer core libraries so that lists of layers, classes and styles are dynamic, not xed to compile limits MS_MAXCLASSES, MS_MAXSTYLES, MS_MAXLAYERS and MS_MAXSYMBOLS. MS_MAXSYMBOLS Change symbolSetObj so that this:
int numsymbols; symbolObj symbol[MS_MAXSYMBOLS];
becomes:
int numsymbols; int maxsymbols; symbolObj **symbol;
Add the following function to ensure there is at least one free entry in the symbol array in the symbolSetObj. This function will only grow the allocated array of pointers if needed (if maxsymbols == numsymbols) and will then allocate a new symbolObj if symbol[numsymbols] == NULL. The new entries in the array will be set to NULL and the new symbolObj[numsymbols] will be all set to zero bytes.
symbolObj *msGrowSymbolSet( symbolSetObj * );
Modify all places that add new symbols to call msGrowSymbolsSet() to ensure there is space. These locations can be fairly easily identied by greping on MS_MAXSYMBOLS. 562 Chapter 14. Development
Modify all places that access symbols by index to use the proper way to reference symbols in the new array, possibly using a GET_SYMBOL() macro similar to the GET_LAYER() added in MS-RFC-24 for layers. mapsymbol.c: Modify msInitSymbolSet() to initially setup the symbol set with an array of just one symbol. There should be no swig MapScript changes required as it already uses msAppendSymbol(). MS_MAXLAYERS map.h: Since MS RFC 24: Mapscript memory management already converted the array of layers in a mapObj to an array of pointers, we only need to add int maxlayers; to mapObj to indicate the current allocation size of layers array. Note that this also determines the size of the mapObj layerorder array. mapdraw.c: Change msDrawMap() to use map->numlayers in place of current MS_MAXLAYERS for asOWSReqInfo array. mapobject.c: Add msGrowMapLayers(mapObj*) function to ensure there is room for at least one more layer on the map. This grows layers, and layerorder arrays. mapobject.c: modify msInsertLayer() and MapScript layer constructor code (see last item) to use msGrowMapLayers(). maple.c: set maxlayers to MS_MAXLAYERS and allocate layers accordingly in initMap(). GrowMapLayers() before calling loadLayer() and loadLayerValue() when parsing. Use ms-
mappluginlayer.c: make dynamic. Im not exactly sure what there is a static factory with entries dimensioned by the number of layers. It looks like swig MapScript already has an mapObj.insertLayer() method using msInsertLayer() which should be safe. Do MapScript applications sometimes just update the layers and numlayers directly? Answer: all layer manipulation is done by the layer constructor (when a not null mapObj is passed as only argument) or by msInsertLayer. Must modify the layer constructor as well. MS_MAXCLASSES map.h: Add maxclasses eld in layerObj (RFC-24 already converted the array of classes in a layerObj to an array of pointers). layerobject.c: Modify msInsertClass() and MapScript constructor code (like for layers) to use msGrowLayerClasses(). layerobject.c: Add msGrowLayerClasses() to ensure there is at least one extra class in the classes list. mapdraw.c: colorbuffer and mindistancebuffer in msDrawQueryLayer() will need to be dynamically sized and allocated on the heap. maple.c: initLayer() will need to initialize maxclasses to MS_MAXCLASSES, and allocate class list accordingly. mapogcsld.c: modify to use msGrowLayerClasses() instead of checking limit. MS_MAXSTYLES map.h: add maxstyles eld to classObj (RFC-24 already converted the array of styles in a classObj to an array of pointers).
563
maple.c: set maxstyles to MS_MAXSTYLES and allocate accordingly in initClass(). ClassStyles() as apppriate. classoject.c: Add msGrowClassStyles() to ensure there is an unused class. classobject.c: Use msGrowClassStyles() in msInsertStyle() and in the style constructor. Files and objects affected
map.h mapfile.c mapsymbol.c mapdraw.c mapobject.c mappluginlayer.c layerobject.c mapogcsld.c classobject.c mapscript/swiginc/layer.i mapscript/swiginc/class.i mapscript/swiginc/style.i
Use msGrow-
Backwards compatibility issues None. Test suite Python unit test entries will be added to exceed the builtin maximums for all of layers, classes, styles and symbols. An msautotest entry with a large number of classes will also be added. Bug ID 302: https://trac.osgeo.org/mapserver/ticket/302 Voting history Vote completed on 2007-07-19: +1 from DanielM, SteveL, FrankW, SteveW, UmbertoN, TamasS, AssefaY Comments/Questions from the review period Has the following issue already been dealt with by RFC-24 since the code already allocates less than MS_MAX_LAYERS in initMap()? Did RFC-24 make it a formal requirement to use the proper insert/add methods to add layers, styles and classes? Answer: the implementation adopted with MS RFC 24: Mapscript memory management tries to save memory by only allocating the number of layers that are effectively needed. A map with 5 layers will allocate exactly 5 layers, a map with 50 layers will allocate 50, and so on up to the hard-coded limit of MS_MAX_LAYERS. This is also true for classes and style. 564 Chapter 14. Development
The arrays of pointers are for obvious reasons always allocated to MS_MAX_LAYERS size, but memory usage is reduced anyway because arrays of pointers are much smaller that arrays of structs. This represents a substantial change from before, when MS_MAX_LAYERS blank layers where always allocated causing a sure waste of memory in small maps. MS RFC 17: Dynamic Allocation of layers, styles, classes and symbols should then invoke the various msGrow*() methods to grow the arrays when numlayers == maxlayers-1. Id suggest to grow the array to a sensible size (like half of the current size) as the impact on memory allocation is going to be mitigated by the dynamic allocation approach introduced by MS RFC 24: Mapscript memory management MS RFC 24: Mapscript memory management did not make a formal requirement to use the proper insert methods as those and the object constructors are the only way to add a layer, class or style to a map. I do not know if this is also true for symbols. Because MapScript application often explicitly initialize blank layers, classes and styles directly, and then increment the count, we cant depend on all access going through the proper insert/add methods. For this reason we preserve the old MS_MAX values to establish the initial allocation. This should mean that existing applications will continue to work at some cost in unused memory. But well behaved MapScript applications using insert methods to increase sizes will be able to grow beyond the initial allocation. Im not aware of any MapScript way to bypass the insert or the constructors (i.e. with direct manipulation of the arrays). It there was such way (which I doubt) I suggest that we forbid it by explicitly changing the MS_MAX_* names and making required elds immutable in swig. Comment from Tamas: The mappluginlayer stuff should be concretized a bit. That static repository of the vtables would prevent from loading the same library twice. That array should also be allocated dynamically since I dont think we will ever have MS_MAXLAYERS number of different plugin layers.
OGR The Tiny Encryption Algorithm (TEA) at http://www.simonshepherd.supanet.com/tea.htm will be used for the encryption/decryption functions. The implementation details follow... Encryption key In order to safely protect the encrypted information, an encryption key will be required by this mechanism. The key will NOT be stored in the maple: it will be stored in a separate le on the server and should be kept in a safe area by the server administrator (especially outside of the web servers document directories). The location of the encryption key can be specied by two mechanisms, either by setting the environment variable MS_ENCRYPTION_KEY or using a CONFIG directive:
CONFIG MS_ENCRYPTION_KEY "/path/to/mykey.txt"
New msencrypt command-line utility A msencrypt command-line utility will be provided to create an encryption key and to encrypt passwords (or any string) for use in a maple. To create an encryption key:
msencrypt -keygen /path/to/mykey.txt
If the MS_ENCRYPTION_KEY environment variable is set then the -key argument does not need to be specied. Encoding of encrypted strings Since the result of encryption is binary data that is not suitable for inclusion directly in a MapServer maple, hex encoding will be used for the encrypted strings in the maple as well as for storing the encryption key to disk. The { and } characters will be used as delimiters for encrypted strings inside database CONNECTIONs. This will allow the use of either plain text or encrypted passwords in maples without any backwards compatibility issues. e.g.
CONNECTIONTYPE ORACLESPATIAL CONNECTION "user/{MIIBugIBAAKBgQCP0Yj+Seh8==}@service"
Any part of a CONNECTION string can be encrypted and not just the password. This will allow protecting other information such as login name, hostname or port numbers if necessary. For reference, here are examples of typical connection strings for the layer types that will be affected:
CONNECTIONTYPE POSTGIS CONNECTION "host=yourhostname dbname=yourdatabasename user=yourdbusername password=yourdbpassword por CONNECTIONTYPE SDE
566
CONNECTION "sdemachine.iastate.edu,port:5151,sde,username,password" CONNECTIONTYPE ORACLESPATIAL CONNECTION "user/pwd@service" CONNECTIONTYPE OGR CONNECTION "OCI:user/pwd@service"
Modications to the source code A msDecryptString() function will be created, it will take a CONNECTION string as input and decrypt any encrypted component that it may nd in it. This function will be called by the various msXXXLayerOpen() methods before opening the connection to the database.
char *msDecryptString(mapObj *map, const char *string)
The rst time that msDecryptString() is called for a given maple, it will load the encryption key from the le and store the key in a new private member of the mapObj (char * encryption_key). To reduce the chances of false matches in long CONNECTION strings such as OGR VRT data sources, msDecryptString() function will look for a pair of { + }, and then verify that all chars in the block are valid hex encoding chars (0-9,A-F) before proceeding with decryption. Note that the decrypted string will never be stored in the layerObj, it will be kept local to the function that opens the connection and destroyed as soon as the function is done with it. This is to prevent exposing the decrypted information in error messages or in calls to msSaveMap(). Files affected
map.h mapfile.c maporaclespatial.c mappostgis.c mappostgresql.c mapsde.c mapogr.cpp
Backwards compatibility issues None. Bug ID 1792: http://trac.osgeo.org/mapserver/ticket/1792 Voting history Adopted on 2006/06/01. +1: FrankW, DanielM, HowardB, YewondwossenA, SteveW
567
Comments from the review period There were concerns about the use of the {...} delimiter to indicate encrypted strings inside CONNECTIONs. Since there was not a better alternative we will stick to that. There was a suggestion to use an ENCRYPTION_KEY maple keyword instead of CONFIG MS_ENCRYPTION_KEY. Since there was no strong argument either way we decided to stick to CONFIG MS_ENCRYPTION_KEY. There was a suggestion to consider the Blowsh algorithm (http://www.schneier.com/blowsh.html) instead of TEA. The sample implementations of Blowsh would require much more work to integrate than TEA, and since TEA is public domain and so much simpler (simpler is better!), well stick to TEA for now and can always change the underlying algorithm at a later time if we nd that TEA is too weak (which doesnt appear to be an issue). Will the encryption methods be made available to MapScript? No plan to do so at this time, but this could easily be added later on. Since the user running the web server (and MapServer) needs to have permissions to read the key, any web server process or user with permissions to read the key can decrypt the passwords using a trivial program. It should be made very clear in the documentation that this is just simple obfuscation and is by no means secure and that users should not place valuable passwords in maples encrypted or not.
Several new enumerations would then dene what properties could be bound:
#define MS_STYLE_BINDING_LENGTH ... #define MS_STYLE_BINDING_ENUM { MS_STYLE_BINDING_SIZE, MS_STYLE_BINDING_ANGLE, ... }; #define MS_LABEL_BINDING_LENGTH ... #define MS_LABEL_BINDING_ENUM { MS_LABEL_BINDING_SIZE, MS_LABEL_BINDING_ANGLE, ... };
568
Several elements would be removed from layerObj and styleObj. For example, angleitem, angleitemindex and similar members would be removed. styleObjs and labelObjs would each take on 2 new members:
char hasBindings; attributeBindingObj bindings[MS_STYLE_BINDING_LENGTH];
Maple/MapScript Changes Options like SIZEITEM and ANGLEITEM would go away. Instead a more logical syntax such as:
STYLE SIZE [mySizeItem] ANGLE [myAngleItem] COLOR 255 0 0 SYMBOL square END
Square brackets have been used in MapServer templates and expressions to bind to attributes so they are a natural choice to denote attribute bindings in this case. Similarly MapScript would loose the ability to set/get the xxxITEM properties. Instead the style and label objects would get setBinding and deleteBinding methods:
(in Perl) $style->setBinding($mapscript::MS_STYLE_BINDING_SIZE, mySizeItem); $style->deleteBinding($mapscript::MS_STYLE_BINDING_COLOR);
Files Affected map.h => structure changes, enum and dene additions maputil.c => add msStyleBindAttributes();
void msStyleBindAttributes(shapeObj *shape, styleObj *style) { if(style->bindings[MS_STYLE_BINDING_SIZE].item) style->size = atoi(shape->values[style->bindings[MS_STYLE_BINDING_SIZE].index]); if(style->bindings[MS_STYLE_BINDING_ANGLE].item) style->angle = atoi(shape->values[style->bindings[MS_STYLE_BINDING_ANGLE].index]); ... }
maplabel.c => add msLabelBindAttributes(); maplayer.c => x msWhichItems() to populate the binding indexes mapdraw.c => remove references to the xxxITEM properties, if a style or label has bindings then call msStyleBindAttributes or msLabelBindAttributes maple.c => x parsing to hangle strings in addition to numbers for all supported bindings (symbols already allow this), if a binding is dened ip the hasBindings ag, remove all references to xxxITEM properties, alter style and label writing code to honor bindings as part of output mapcopy.c => x style and labeling copying 14.6. Request for Comments 569
maplexer.l/maple.h => remove xxxITEM denes and lexer references, and to dene a new raw type (similar to MS_STRING) called MS_BINDING mapscript/swiginc/style.i => add setBinding and deleteBinding methods (similar for PHP/MapScript) Testing Python suite: need tests to set and delete bindings MsAutoTest suite: a maple testing various bindings would be developed (DNR tests have one example for labels) Backwards compatabilty issues This does affect a number of parameters, however they are lightly used so this is probably worth the risk. The primary risk is breaking maples as opposed to scripts. Given that this will denitely break some stuff I think it is most appropriate as a 5.0 change. Bug ID 2100 Voting history +1 Lime, Morissette, Woodbridge
570
PROCESSING "LUT_<color#>=<lut_specification>"
for a LUT applied only to one band. The <lut_specication> can be the name of a le containing a LUT, or an inline lut denition. The inline lut denition looks like:
<lut_specification>=<in_value>:<out_value>,<in_value>:<out_value>[,<in_value>:<out_value>]*
The text le takes the same form, except that it may be multiline (lines will be implicitly joined by commas). So some common forms would be:
PROCESSING "LUT=0:0,128:150,255:255" PROCESSING "LUT_2=green_lut.txt"
Note that the LUT specication les will be searched for relative to the map le if a relative path is provided. The LUT will be applied in LoadGDALImage(), after any scaling to 8bit. So currently only 8bit (0-255) input and output values are supported. Optionally we could consider non-8bit inputs, and allow the LUT to apply scaling to 8bit but this would be somewhat complicated to do in a computationally efcient manner. A 256 entry LUT will be created by linear interpolation between the LUT control points. Note this is different than a true curve based approach where some form of curve tting is done to the control points. For a signicant number of control points the difference will be very slight, but it could be noticable for LUTs with only a few control points (ie. 3). Optionally we could compute a proper curve t, but this will require extra research and development. If no control points exist for input values 0 and 255 a mapping of 0:0 and 255:255 will be assumed. Other Curve Formats The GIMPs ascii curve format will also be supported directly. Exact details of this are to be determined, and since a GIMP curve le contains several curves (for different bands) it may be necessary to select which is to be used in the PROCESSING statement. Perhaps something like:
PROCESSING "LUT_2=GIMP_red:gimp.crv"
Maple Implications All new options are selected via new PROCESSING options. There is no change in the maple syntax. There should be no compatibility problems with old maples. MapScript Implications There are no additions or changes to the MapScript API. The new options are controlled via PROCESSING information on the layers which I believe is already manipulatable from MapScript. Documentation Implications The new processing options will need to be documented in the Raster Access HOWTO (and possibly the maple reference).
571
Test Plan New test cases for each mode will be incorporated in msautotest/gdal. Stafng / Timeline The new feature will be implemented by Frank Warmerdam and completed by November 30th, 2006, for inclusion in the MapServer 5.0 release. Funding provided by the Information Center of the Ministry of Agriculture and Forestry (Finland). Tracking Bug http://trac.osgeo.org/mapserver/ticket/1943
14.6.22 MS RFC 22a: Feature cache for long running processes and query processing
Date 2007/06/24 Author Tamas Szekeres Contact szekerest at gmail.com Last Edited 2007/06/24 Status Discussion Draft Version Mapserver 5.0 Id $Id: ms-rfc-22a.txt 8278 2008-12-23 21:34:31Z hobu $ 1. Overview Currently the various query operations involve multiple accesses to the data providers which may cause a signicant performance impact depending on the providers. In the rst phase all of the features in the given search area are retrieved and the index of the relevant shapes are stored in the result cache. In the second phase the features in the result cache are retrieved form the provider one by one. Retaining the shapes in the memory we could eliminate the need of the subsequent accesses to the providers and increase the overall performance of the query. Implementing the cache requires a transformation of the data between the data provider and the client. From this aspect it is desirable to provide a framework to implement this transformation in a higher level of abstraction. 2. Purpose The main purpose of this RFC is to implement a feature cache and retain the shapes in the memory for the further retrievals during a query operation. However I would also want to create a mechanism so that a layer could use another layer as a data source. This outer layer could apply transformations on the shapes coming from the base layer or even retain the shapes in the memory for the subsequent fetches. Here are some other examples where this framework would provide a solution: 1. Constructing geometries based on feature attributes 2. Modifying the geometries or the feature attribute values 3. Geometry transformations (like GEOS operations) 4. Feature cache 572 Chapter 14. Development
5. Providing default layer style based on external style information, or attribute based styling 6. Providing custom data lters Setting up a proper layer hierarchy one can solve pretty complex issues without the need of creating additional (eg. mapscript) code. Later on - as a live example - Ill show up the solution of the following scenario: 1. The user will select one or more shapes in one layer (by attibute selection in this case). 2. Cascaded transformations will be applied on the selected shapes (Ill use the GEOS convexhull and buffer operations) 3. In another layer the features will be selected based on the transformed shapes as the selection shapes. In this proposal to ensure the better readability Ill avoid embedding much of the code inline. However most of the implementation patches are available at the tracking ticket of this RFC (see later). 3. General principles of the solution This proposal involves writing additional data providers. These providers will use another layer as the source of the features. To set up this hierarchy of the layers, the CONNECTION parameter of these layers will contain the name of the source layer. In some cases the source layer doesnt participate in the renderings and should be kept internal to the original layer. Therefore we will establish the support for nesting the layers into each other. In this regard the CONNECTION parameter will contain the full path of the layer it refers to. The path contains the layer names in the hierarchy using the slash / as the separator between the names. We can specify the pathnames relative to the actual layer or relative to the map itself. 1. Specify a reference relative to the map:
LAYER NAME "roads" CONNECTIONTYPE OGR CONNECTION "roads.tab" ... END LAYER NAME "cache" CONNECTIONTYPE CACHE CONNECTION "/roads" ... END
573
The main difference between these 2 options is that in the rst case the referred layer is contained by the layers collection of the map, so the layer will participate in the drawings. In the second case the referred layer is internal to the outer layer. It is supported that 2 or more layers connect to the same base layer so that the features will be served from the same cache repository. The base layer can reside in any place of the layer hierarchy. In any case, the exension layer can also be implemented as a pluggable external layer. (CONNECTIONTYPE PLUGIN) To achieve the desired functionality the following 3 providers will be implemented: 3.1 Feature caching provider The purpose of this provider is to retain the features from the source layer in the memory so the subsequent fetches on the feature caching provider will be served from the internal cache. With the current implementation Im planning to retain the shapes of last extent. When the subsequent shape retrieval refers to the same extent (or within that extent) the features will be served from the cache. At the moment I will not address caching features from multiple non overlapping extents and implement more sophisticated cache management (like size limit/expiration handling) but it might be the object of an enhancement in the future. All of the provider specic data will be placed in the layerinfo structure of the provider. The shapes in the cache will be stored in a hashtable. This provider will be implemented in a separate le (mapcache.c). 3.1.1 Shape retrieval options This provider will be capable to populate the cache with all of the shapes in the given extent or only with the shapes in the resultcache of the source layer. The rst one is the default option and the latter can be selected by the following PROCESSING directive:
PROCESSING "fetch_mode=selection"
The cache will be populated upon the WhichShapes call of the caching provider when the given rect falls outside of the previous one. We can also specify that the provider will retieve all the shapes of the current map extent regardless to the search area using the following setting:
PROCESSING "spatial_selection_mode=mapextent"
3.1.2 Items selection The feature caching provider will store all of the items available regardless of which items have been selected externally (by using the WhichItems call). However the iteminfo will contain the indexes only of the requested items. The GetShape and the NextShape operations will copy only the requested subset of the items to the caller. This solution will provide the compatibility with any other existing provider so theres no need to alter the common mapserver code from this aspect. 3.1.3 Support for the STYLEITEM AUTO option By using the STYLEITEM AUTO option the provider can retrieve the classObj of every shapeObj from the data source. So as to keep on supporting this option the caching provider will be capable to cache these classObj-s as well as the shapeObj-s in a separate hashtable. When the STYLEITEM AUTO option is set on the feature caching provider the style cache will also be populated by calling the GetAutoStyle function to the source layer. The subsequent GetAutoStyle calls on the feature caching provider will retrieve the classObj-s from the style cache and provide a copy to the caller.
574
3.1.4 Support for the attribute lter The feature caching provider will be compatible with the existing query operations (implemented in the msQueryBy[] functions in mapquery.c). For supporting the msQueryByAttributes the NextShape will use msEvalExpression before returning the shapes to the caller. 3.2 Geometry transformation provider The geometry transformation provider (implemented in mapgeomtrans.c) will support transparent access to the source layer. Every vtable operations will be dispatched to corresponding vtable operation of the source layer. In addition some of the other layer properties might require to copy between the connected layers. 3.2.1 Items selection This provider will serve the same subset of the items as the source layer provides. Therefore the InitIteminfo will copy the items and the numitems of the external layer to the source layer, like:
int msGeomTransLayerInitItemInfo( layerObj *layer ) { /* copying the item array an call the subsequent InitItemInfo*/ return msLayerSetItems(((GeomTransLayerInfo*)layer->layerinfo)->srclayer, layer->items, layer->nu }
And upon the GetItems call these values will be copied back to the external layer, like:
int msGeomTransLayerGetItems(layerObj *layer) { /* copying the item array back */ int result; GeomTransLayerInfo* layerinfo = (GeomTransLayerInfo*)layer->layerinfo; result = msLayerGetItems(layerinfo->srclayer); msLayerSetItems(layer, layerinfo->srclayer->items, layerinfo->srclayer->numitems); return result; }
3.2.2 Applying the transformations The proposed implementation will support most of the GEOS transformations supported by mapserver (buffer, convexhull, boundary, union, intersection, difference, symdifference). The transformations will be applied right before retrieving a shape to the caller. The desired transformation can be selected using a PROCESSING option, like:
PROCESSING "transformation=buffer"
Some of these operations will use 2 shapes to create the transformed shape. The reference shape of these transformations can be set externally using the WKT representation of a processing option:
PROCESSING "ref_shape=[WKT of the shape]"
575
Im also planning to support retrieving this shape from the features collection of the layer and from an external layer as well. 3.3 Layer lter provider The layer lter provider (implemented in maplter.c) will provide the shape retrieved from the source layer and will not apply any transformation on that. However some of the shapes will be skipped in the NextShape operations depending on the spatial and the attribute selection options. This provider ensures transparent access to the source layer (just as the previous one) but uses a cache for storing the selection shapes. The selection shapes will be retrieved from another layer which can be specied in the following processing option:
PROCESSING "selection_layer=[path to the layer]"
When populating the selection cache Ill support to retrieve all of the shapes or only the shapes in the result cache as for the caching provider mentioned before:
PROCESSING "fetch_mode=selection"
4. Putting the things together (example) In this chapter Ill describe the solution of the scenario have been mentioned earlier. Ill start with a simple map le denition with 2 layers the counties and the citypoints of the country:
MAP NAME "Hungary" STATUS ON EXTENT 421543.362603 47885.103526 933973.563202 367180.479761 SIZE 800 600 IMAGETYPE PNG IMAGECOLOR 255 255 255 PROJECTION "proj=somerc" "lat_0=47.14439372222222" "lon_0=19.04857177777778" "x_0=650000" "y_0=200000" "ellps=GRS67" "units=m" "no_defs" END SYMBOL Name point Type ELLIPSE POINTS 1 1 END FILLED TRUE END LAYER PROJECTION "AUTO" END
576
NAME "Hun_Counties" CONNECTIONTYPE OGR CONNECTION "Hun_Megye.TAB" STATUS default TYPE POLYGON LABELITEM "name" CLASS TEMPLATE "query.html" LABEL SIZE medium COLOR 64 128 64 END STYLE COLOR 208 255 208 OUTLINECOLOR 64 64 64 END END END LAYER PROJECTION "AUTO" END NAME "Hun_CityPoints" CONNECTIONTYPE OGR CONNECTION "Hun_CityPoints.TAB" STATUS default TYPE POINT CLASS STYLE COLOR 255 0 0 SYMBOL "point" SIZE 2 END END END END
This map will look like this: http://trac.osgeo.org/mapserver/attachment/ticket/2128/sample.png 4.1 Adding the feature cache for the layers Any of the layers might be cached by using the CACHE layer provider. The original provider might be nested inside the cache. The parameters related to the drawing should be specied for the outer layer, like:
LAYER PROJECTION "AUTO" END NAME "Hun_Counties_cache" CONNECTIONTYPE CACHE CONNECTION "Hun_Counties" STATUS default TYPE POLYGON LABELITEM "name" CLASS
577
TEMPLATE "query.html" LABEL SIZE medium COLOR 64 128 64 END STYLE COLOR 208 255 208 OUTLINECOLOR 64 64 64 END END LAYER PROJECTION "AUTO" END NAME "Hun_Counties" CONNECTIONTYPE OGR CONNECTION "Hun_Megye.TAB" TYPE POLYGON END END
The Hun_Counties_cache layer is queryable and all of the existing methods are available to populate the resultcache. In my example Ill use the mapscript C# drawquery example (implemented in drawquery.cs) to execute an attribute query and use the drawquery afterwards. The following command will be used along with this sample:
drawquery sample.map "([Name]=Tolna)" sample.png
Which passes the ([Name]=Tolna) query string to the queryByAttributes of the rst layer. The result of the rendering will look like: http://trac.osgeo.org/mapserver/attachment/ticket/2128/sample1.png The corresponding maple can be found here: http://trac.osgeo.org/mapserver/attachment/ticket/2128/sample1.map 4.2 Applying transformations on the counties In the next step Ill apply a cascaded GEOS convexhull and buffer operations on the rst layer. The results will be rendered in a separate layer using the following denition:
LAYER NAME "selectionshape" CONNECTIONTYPE GEOMTRANS CONNECTION "simplify" STATUS default TYPE POLYGON TRANSPARENCY 50 CLASS STYLE COLOR 64 255 64 OUTLINECOLOR 64 64 64 END END PROCESSING "transformation=buffer" PROCESSING "buffer_width=0.2"
578
LAYER NAME "simplify" TYPE POLYGON CONNECTIONTYPE GEOMTRANS CONNECTION "/Hun_Counties_cache" PROCESSING "transformation=convexhull" END END
The result of the rendering will look like: http://trac.osgeo.org/mapserver/attachment/ticket/2128/sample2.png The corresponding maple: http://trac.osgeo.org/mapserver/attachment/ticket/2128/sample2.map Which is not the desired result since all of the polygons were transformed. So as to transform only the selected shape an additional cache should be specied by using the fetch_mode=selection processing option:
LAYER NAME "selectionshape" CONNECTIONTYPE GEOMTRANS CONNECTION "simplify" STATUS default TYPE POLYGON TRANSPARENCY 50 CLASS STYLE COLOR 64 255 64 OUTLINECOLOR 64 64 64 END END PROCESSING "transformation=buffer" PROCESSING "buffer_width=0.2" LAYER NAME "simplify" TYPE POLYGON CONNECTIONTYPE GEOMTRANS CONNECTION "selectioncache" PROCESSING "transformation=convexhull" LAYER NAME "selectioncache" TYPE POLYGON CONNECTIONTYPE CACHE CONNECTION "/Hun_Counties_cache" PROCESSING "fetch_mode=selection" END END END
And here is the result of the drawing: http://trac.osgeo.org/mapserver/attachment/ticket/2128/sample3.png The corresponding maple: http://trac.osgeo.org/mapserver/attachment/ticket/2128/sample3.map
579
4.3 Using the transformed shape as the selection shape My nal goal is to select the features of the point layer using the transformed shape as the selection shape. Therefore Ill have to use the layer lter provider on the point layer and setting the selection_layer to the transformed layer:
LAYER TYPE POINT CONNECTIONTYPE LAYERFILTER CONNECTION "Hun_CityPoints" NAME "selectedpoints" STATUS default PROCESSING "selection_layer=/selectionshape" CLASS STYLE COLOR 255 0 0 SYMBOL "point" SIZE 2 END END LAYER PROJECTION "AUTO" END NAME "Hun_CityPoints" CONNECTIONTYPE OGR CONNECTION "Hun_CityPoints.TAB" TYPE POINT END END
Here is the result: http://trac.osgeo.org/mapserver/attachment/ticket/2128/sample4.png The corresponding maple: http://trac.osgeo.org/mapserver/attachment/ticket/2128/sample4.map Note1: Without altering the map conguration I can modify the selection externally and the rendered image will reect the changes automatically. For example I can select 2 counties using the query string: ([Name]=Tolna or [Name]=Baranya) The resulting image can be found here: http://trac.osgeo.org/mapserver/attachment/ticket/2128/sample4a.png Note2: If theres no need to render the selection layer I can specify that conguration inline:
LAYER TYPE POINT CONNECTIONTYPE LAYERFILTER CONNECTION "Hun_CityPoints" NAME "selectedpoints" STATUS default PROCESSING "selection_layer=selectionshape" CLASS STYLE COLOR 255 0 0 SYMBOL "point" SIZE 2 END
580
END LAYER PROJECTION "AUTO" END NAME "Hun_CityPoints" CONNECTIONTYPE OGR CONNECTION "Hun_CityPoints.TAB" TYPE POINT END LAYER NAME "selectionshape" CONNECTIONTYPE GEOMTRANS CONNECTION "simplify" STATUS default TYPE POLYGON TRANSPARENCY 50 CLASS STYLE COLOR 64 255 64 OUTLINECOLOR 64 64 64 END END PROCESSING "transformation=buffer" PROCESSING "buffer_width=0.2" LAYER NAME "simplify" TYPE POLYGON CONNECTIONTYPE GEOMTRANS CONNECTION "selectioncache" PROCESSING "transformation=convexhull" LAYER NAME "selectioncache" TYPE POLYGON CONNECTIONTYPE CACHE CONNECTION "/Hun_Counties_cache" PROCESSING "fetch_mode=selection" END END END END
Here is the result: http://trac.osgeo.org/mapserver/attachment/ticket/2128/sample5.png And the corresponding maple: http://trac.osgeo.org/mapserver/attachment/ticket/2128/sample5.map And recall that because Ive used a cache on the counties layer all of these renderings require to retrieve the shapes only once from the original provider. That was the primary objective of this RFC. 5. Modifying the mapserver core To achieve the desired fuctionality the following major steps should be done in the mapserver core. The details of the proposed changes can be found here: http://trac.osgeo.org/mapserver/attachment/ticket/2128/common.patch 14.6. Request for Comments 581
5.1 Hashtable implementation The current hashtable implementation (in maphash.c) will be generalized to be capable to store objects as well as strings. Currently the hashtable can store only string values. In addition the we will provide support for specifying the hashsize upon the construction of the hashtable. The objects will be stored in the hashtable by reference and the destroy function of the objects can also be specied externally. The following functions will be added to maphash.c
int initHashTableEx( hashTableObj *table, int hashSize ); void msClearHashItems( hashTableObj *table ); struct hashObj *msInsertHashTablePtr(hashTableObj *table, const char *key, const char *value); struct hashObj *msFirstItemFromHashTable( hashTableObj *table); struct hashObj *msNextItemFromHashTable( hashTableObj *table, struct hashObj *lastItem ); int msGetHashTableItemCount(hashTableObj *table);
initHashTableEx can be called to specify the hash size externally. Actually the original initHashTable will be implemented as calling initHashTableEx with MS_HASHSIZE. msClearHashItems will clear all of the elements of the hashtable but does not clear the items array. msInsertHashTablePtr provides the support for adding object by reference to the hashtable. msFirstItemFromHashTable and msNextItemFromHashTable will provide the iteration of the elements efciently and will be called by the NextShape of the feature caching provider. msGetHashTableItemCount will retrieve the actual number of the hashtable items. 5.2 Extending the layerObj structure to support nesting the layers (map.h) The sublayers in the layerObj structure will be stored as an array of layers.
typedef struct layer_obj { ... #ifndef SWIG struct layer_obj **layers; int numlayers; /* number of sublayers in layer */ #endif /* SWIG */ ... } layerObj;
582
5.3 Adding a new built in data connection types (map.h) A new data connection type is established for the new providers.
The lexer will be modied to interpret the new connection types. 5.4 Support for destroying the persistent data of the providers (map.h, maplayer.c) The providers would keep persistent data between the various Connection/Close operations on that layer so we should establish a mechanism to destroy this provider specic data by adding a new method to the layervtable:
void (*LayerDestroy)(layerObj *layer);
583
7. Backwards compatibility issues These changes will retain maple and mapscript backward compatibility. 8. Bug ID The ticket for RFC-22a can be found here. Bug 2128 9. Voting history None
Detailed Process Proposals are written up and submitted on the mapserver-dev mailing list for discussion and voting, by any interested party, not just committee members. Proposals need to be available for review for at least two business days before a nal decision can be made. Respondents may vote +1 to indicate support for the proposal and a willingness to support implementation. Respondents may vote -1 to veto a proposal, but must provide clear reasoning and alternate approaches to resolving the problem within the two days. A vote of -0 indicates mild disagreement, but has no effect. A 0 indicates no opinion. A +0 indicate mild support, but has no effect. Anyone may comment on proposals on the list, but only members of the Project Steering Committees votes will be counted. A proposal will be accepted if it receives +2 (including the author) and no vetoes (-1). If a proposal is vetoed, and it cannot be revised to satisfy all parties, then it can be resubmitted for an override vote in which a majority of all eligible voters indicating +1 is sufcient to pass it. Note that this is a majority of all committee members, not just those who actively vote. Upon completion of discussion and voting the author should announce whether they are proceeding (proposal accepted) or are withdrawing their proposal (vetoed). The Chair gets a vote. The Chair is responsible for keeping track of who is a member of the Project Steering Committee (perhaps as part of a PSC le in CVS). Addition and removal of members from the committee, as well as selection of a Chair should be handled as a proposal to the committee. The Chair adjudicates in cases of disputes about voting. When is Vote Required? Any change to committee membership (new members, removing inactive members) Changes to project infrastructure (e.g. tool, location or substantive conguration) Anything that could cause backward compatibility issues. Adding substantial amounts of new code. Changing inter-subsystem APIs, or objects. Issues of procedure. When releases should take place. Anything dealing with relationships with external entities such as OSGeo Anything that might be controversial.</li>
585
Observations The Chair is the ultimate adjudicator if things break down. The absolute majority rule can be used to override an obstructionist veto, but it is intended that in normal circumstances vetoers need to be convinced to withdraw their veto. We are trying to reach consensus. It is anticipated that separate committees will exist to manage conferences, documentation and web sites. That said, it is expected that the PSC will be the entity largely responsible for creating any such committees. Committee Membership The PSC is made up of individuals consisting of technical contributors (e.g. developers) and prominent members of the MapServer user community. There is no set number of members for the PSC although the initial desire is to set the membership at 9.
Adding Members
Any member of the mapserver-dev mailing list may nominate someone for committee membership at any time. Only existing PSC committee members may vote on new members. Nominees must receive a majority vote from existing members to be added to the PSC.
Stepping Down
If for any reason a PSC member is not able to fully participate then they certainly are free to step down. If a member is not active (e.g. no voting, no IRC or email participation) for a period of two months then the committee reserves the right to seek nominations to ll that position. Should that person become active again (hey, it happens) then they would certainly be welcome, but would require a nomination. Membership Responsibilities
Guiding Development
Members should take an active role guiding the development of new features they feel passionate about. Once a change request has been accepted and given a green light to proceed does not mean the members are free of their obligation. PSC members voting +1 for a change request are expected to stay engaged and ensure the change is implemented and documented in a way that is most benecial to users. Note that this applies not only to change requests that affect code, but also those that affect the web site, technical infrastructure, policies and standards.
586
questions on the developer mailing list, however they are expected to provide their thoughts and opinions on user level requirements and compatibility issues when RFC discussions take place. Bootstrapping Prior to the TSC anointing itself the PSC this RFC must be distributed before the MapServer community via MapServer-Users for comment. Any and all substantive comments must be discussed (and hopefully, but not necessarily, addressed via MapServer-Dev. All members of the existing Technical Steering Committee will form the initial Project Steering Committee. Steve Lime is declared initial Chair of the Project Steering Committee. Initial members are: Steve Lime Daniel Morissette Frank Warmerdam Assefa Yewondwossen Howard Butler Steve Woodbridge Perry Nacionales There are two open committee positions at the initial formation of the PSC. Updates 29 May 2007 The following members were were added to the PSC after discussion and consensus: Tom Kralidis Jeff McKenna Umberto Nicoletti Tamas Szekeres
14.6.24 MS RFC 25: Align MapServer pixel and extent models with OGC models
Date 2007/10/23 Author Steve Lime Contact steve.lime at DNR.STATE.MN.US Status Draft Version Id $Id: ms-rfc-25.txt 8278 2008-12-23 21:34:31Z hobu $
587
Overview At present MapServer uses different pixel and extent model than dened by OGC services such as WCS and WMS. MapServer uses the center of a pixel to represent its unique coordinate value. An extent is interpreted as the bounding box that runs from the center of the UL pixel in an image to the center of the LR pixel in an image. Why? Well, it goes back to companion software that existed along side MapServer to display satellite data stored in ERDAS that used the center to center extent model. The math is simple and there is a certain logic in having the extent actually represent pixel values - that is, if you render the extent as a polygon you get the exact edge of the image as one might expect. On the other hand, OGC service specications dene an extent (BBOX) to refer to the dimensions of the outside edges of the image being requested. This appears to be a far more common means of expressing an area of interest. Ive not been able to ascertain where the coordinate of an individual pixel is located from various OGC specications. MapServer could retain a center-based pixel model. That does add complexity to the map <=> image coordinate transformations since you have to offset things by one-half cellsize. Since that computation is done many times I would expect a performance hit. We could optimize things by computing and storing the one-half cellsize value once (as cellsize is now), but that complicates the C APIs and requires huge amounts of change. I propose moving to a upper-left-based pixel model to simplify these conversions. Note: In looking at the code there were past efforts to go to the OGC extent in 4.8 and 4.10, but it was not universally applied. This RFC would ensure that the same extent and pixel model is in use throughout MapServer and that it is consistent with OGC. model diagram: http://maps.dnr.state.mn.us/mapserver_docs/rfc25_extent.pdf Technical Details Affected les (relative to what is in main development trunk): map.h: change denition of MS_CELLSIZE
#define MS_CELLSIZE(min,max,d) ((max - min)/d)
map.h: change coordinate conversion macros (no change just add comments)
/* ** These macros work relative to the UL corner of the UL pixel of a map exent. Pixel ** model is (as of 5.0) the UL corner of a pixel. UL pixel = minx,maxy. */ #define MS_MAP2IMAGE_X(x,minx,cx) (MS_NINT((x - minx)/cx)) #define MS_MAP2IMAGE_Y(y,maxy,cy) (MS_NINT((maxy - y)/cy)) #define MS_IMAGE2MAP_X(x,minx,cx) (minx + cx*x) #define MS_IMAGE2MAP_Y(y,maxy,cy) (maxy - cy*y)
mapwcs.c: remove code to convert between MapServer extent and OWS extent mapwms.c: remove code to convert between MapServer extent and OWS extent mapwmsclient.c remove code to convert between MapServer extent and OWS extent 588 Chapter 14. Development
various raster layer handlers: Need Franks comments here. mapscript ...zoom functions: I dont believe these will need any change. The affect of these changes on end-users should be minimal since it is unlikely they the are aware of differences in extent interpretation. The larger impact may be on 3rd party applications like dBox, Chameleon and QGIS that manage extents and call MapServer. Efforts must be made to make those folks aware of the change. Maple Implications None, these are internal changes only. MapScript Implications None, these are internal changes only. Documentation Implications The models for a pixel and an extent need to documented in a couple of places: maple reference, the related OWS service how-tos and perhaps a new how-to pertaining to just this topic. Test Plan Need to develop some tests to somehow validate the math. The WCS interface or output drivers using GDAL are excellent candidates since they produce georeferenced output. Some testing has already been done to verify the existence of the issue (rst discovered via WCS) and the proposed x. Mini-images (e.g. 7x7) can be used to verify rendering makes sense. For example, if you draw the extent as a polygon you would expect to see lines for the left and top edges, but not for the bottom and right. That is because the maxx,miny extent values wont represent a pixel in the output (rather the next tile to the right and/or below). Stafng / Timeline Changes to maputil.h, map.h, mapwcs.c and mapwms.c would be done by Steve Lime. Changes to other portions of MapServer would be coordinated with the various component owners. This RFC would be completed for the 5.0 release.
589
Mapserver terminology is mostly good and consistent, with a few exceptions. The two that generate the most confusion and TRANSPARENCY (layerObj) and various scale referencing parameters (e.g. MINSCALE). Another change would be changing the symbolObj STYLE parameter to PATTERN instead. This would be simply to avoid confusion with the classObj STYLE. The The purpose of this proposal is to make Mapserver even easier to use, removing confusion that can arise in cases of inconsistent terminology. TRANSPARENCY 1. Overview TRANSPARENCY is used in the Mapserver maple layer object for what is in fact opacity (as is also pointed out in the current documentation). 2) Technical details To achieve more consistent terminology, the following should be done: Changing the keyword TRANSPARENCY to OPACITY The old maple layer keyword TRANSPARENCY will be deprecated, but shall be supported in future versions of Mapserver as an alias for OPACITY. The new maple layer keyword OPACITY should replace TRANSPARENCY. There will be no changes in type or semantics, only a change of keyword name. The internal structure member name in the layerObj will change from transparency to opacity. 1. Maple Implications The parser will have to support both OPACITY and TRANSPARENCY (for backward compatibility). The type will not change. At debug level 1 a warning will be issued that the TRANSPARENCY parameter is deprecated and OPACITY should be used instead. 1. MapScript Implications Since the layerObj will no longer contain a transparency member this will break old scripts. The x will be evident. 1. Documentation Implications Documentation should be updated, introducing OPACITY as a new layer keyword with documentation similar to the current transparency. The layer keyword TRANSPARENCY should be documented as deprecated. All other documentation that references TRANSPARENCY will have to be updated (simple search-replace with a manual check of all occurences of the word transparency?) SCALE 1. Overview SCALE and MAXSCALE/MINSCALE is a case where Mapserver terminology is not in line with mainstream map terminology. In proper usage, scale is a representative fraction. The scale 1:50000 tells us that one meter on the map corresponds to 50000 meters in the terrain. 1:1000 (0.001) is a larger scale than 1:50000 (0.00002). The current use of MAXSCALE and MINSCALE is therefore not consistent with proper terminology. 590 Chapter 14. Development
1. Technical details To achieve more consistent terminology, the following could be done with limited consequences: Change all occurrences of SCALE in keywords to ScaleDenom. MinScale 10000 Maxscale 1000000 will become: MinScaleDenom 10000 MaxScaleDenom 1000000 This will apply to the following occurences of SCALE in mapserver keywords: Map object: SCALE -> ScaleDenom Web object: MAXSCALE/MINSCALE Layer object: MAXSCALE/MINSCALE LABELMAXSCALE/LABELMINSCALE SYMBOLSCALE Class object: MAXSCALE/MINSCALE 1. Maple Implications The parser would have to accept the new keywords. The old keywords will be unique prexes of the new keywords, and could be accepted by the parser (in a transition period or for eternity). At debug level 1 a warning will be issued that the ...SCALE parameter is deprecated and ...SCALEDENOM should be used instead. 4) MapScript Implications For all scale variables, scale should be changed to scaledenom (for consistency reasons). The type (double) will not change. Like opacity above this could break old scripts. 1. Template Implications The [scale] substitution should be deprecated (but still supported) and [scaledenom] added. 1. CGI Imaplications The scale CGI parameter would continue to be supported (e.g. users often dene a map extent using a center point and a scale value). Scaledenom would also be supported. 1. Documentation Implications All occurences of scale keywords in the documentation will have to be changed to reect the new names. The old style keywords could be included, but should marked as deprecated. PATTERN 1. Overview Currently both the symbolObj and classObj contain STYLE parameters. The symbolObj style stores dash patterns used for line symbols. The name is derived from GD terminology. To avoid confusion with the classObj STYLE the symbolObj STYLE should be renamed to more concisely reect its purpose. 14.6. Request for Comments 591
1. Technical details In the symbolObj structure denition the member style will be renamed pattern. All references to the style in the code will also be updated. 1. Maple/symbol le Implications The parser would have to accept the new keywords. The old keywords will be unique prexes of the new keywords, and could be accepted by the parser (in a transition period or for eternity). At debug level 1 a warning will be issued that the STYLE parameter is deprecated and PATTERN should be used instead. 1. MapScript Implications As above the symbolObj structure would be altered and so MapScript scripts that set a symbol style programatically would break. They would need to reference the patter parameter instead. 1. Template Implications None 1. CGI Implications None 1. Documentation Implications The symbolObj reference guides would need to updated to reect the name change.
592
Technical Solution PRIORITY is a new LABEL parameter that takes an MS_MAX_LABEL_PRIORITY (highest). The default value is 1. integer value between 1 (lowest) and
MS_MAX_LABEL_PRIORITY is dened and can be altered in map.h, its default value is 10. The prioritization is handled by maintaining an array of MS_MAX_LABEL_PRIORITY cache lists in the label cache. When a label is added to the label cache, its priority index is used to decide in which cache list it should be added. Then at rendering time, we loop through the cache lists, starting with the highest priority list. Specifying an out of range PRIORITY value inside a map le will result in a parsing error. An out of range value set via MapScript or coming from a shape attribute will be clamped to the min/max values in msAddLabel(). There is no expected impact on performance for using label priorities. Support for attribute binding The PRIORITY parameter can also be bound to an attribute using the attribute bindings mechanism dened in RFC-19. This means two ways to set LABEL PRIORITY:
... LABEL PRIORITY 5 ... END ...
or
... LABEL PRIORITY [someattribute] ... END ...
Modications to the source code PRIORITY will be added to the LABEL object in map.h, in the maple parser/writer (maple.c) and in MapScript A MS_IS_VALID_LABEL_PRIORITY() macro will be dened to validate priority ranges in a consistent way everywhere. The label cache code (maplabel.c) will be modied to work with an array of MS_MAX_LABEL_PRIORITY cache lists instead of a single list The various msDrawLabelCacheXX() functions will be modied to replace the current loop on cache items with two nested loops: the outer loop will iterate on cache lists (from highest to lowest), and the inner loop will iterate on the cache items inside each list. msBindLayerToShape() will be updated to support binding PRIORITY to a shape attribute eld. MapScript Implications The labelObj will have a new priority property of type integer. 14.6. Request for Comments 593
Files affected
map.h mapfile.c maplabel.c maputil.c mapgd.c mapimagemap.c mappdf.c mapsvg.c mapswf.c mapagg.cpp
Backwards compatibility issues None. Bug ID 1619: https://trac.osgeo.org/mapserver/ticket/1619 Bug 206 also made mention of label priority but has been closed as duplicate of 1619: https://trac.osgeo.org/mapserver/ticket/206 Voting history Vote completed on 2007-05-25: +1 from DanielM, SteveW, SteveL, YAssefa, UmbertoN and FrankW Questions/Comments from the review period Q: Why use an array of cache lists instead of doing a quicksort on all cache entries? A: Mainly for performance reason, but it was also pointed out that quicksort is not stable and could result in different orderings depending on the set of labels.
594
Overview MapServer 4.10 and older used to have multiple LOG/DEBUG output mechanisms that did not play well together. In order to improve the usability of the software this RFC proposes a new LOG/DEBUG output mechanism with more control on the output location (logle or stderr) and that works under all supported web servers. Inventory of existing mechanisms MapServer 4.10 and older support the following LOG/DEBUG systems: LOG [lename] in the WEB object: From the documentation: File to log MapServer activity in. Must be writable by the user the web server is running as. More specically, the function writeLog() in mapserv.c logs information about the mapserv CGI request results at the end of its execution. This option has no effect with MapScript. MS_ERRORFILE environment variable: If set then all calls to msSetError() are logged to this le. msDebug() with DEBUG ON/OFF at the MAP and LAYER level: There are msDebug() calls in various areas of the code that generate information that may be useful in tuning and troubleshooting apps. The DEBUG ON/OFF statements in the MAP and LAYER objects are used to enable/disable the msDebug() calls. The msDebug() mechanism is also disabled by default and enabled only by the -DENABLE_STDERR_DEBUG compile-time option. Users could benet from easier access to this and more debug information. The output of msDebug() is sent to stderr and cannot be redirected. In addition to not being very exible, this is a problem under IIS where stderr output goes to stdout and the msDebug() output corrupt MapServers output. Questions Q: Is the mapserv-specic LOG option really used by anyone? Do we need to maintain it, should we get rid of it, or perhaps extend it? At a minimum this option should be better documented to avoid confusion with the other mechanisms described in this RFC. A: The LOG option will be left untouched by this RFC. Technical Solution We will essentially merge the MS_ERRORFILE and DEBUG/msDebug() mechanisms. The variable MS_ERRORFILE will specify the location of the output, with possible values being either a le path on disk, or one of stderr or stdout. The current DEBUG ON/OFF mechanism that controls msDebug() output will also be extended to support multiple DEBUG levels. In order to keep the implementation relatively simple and efcient, the output le handle will be kept open with a reference to it in a global variable in the context of the current request and will be closed only in msCleanup(). This means that if two maples are loaded in the same request with different MS_ERRORFILE settings then errors/debug statements for both will go to the same le (and the output le will change when the second maple is read). Note: the output le handle will be global in the context of the current request only and not global across threads, this will be done using the same mechanism currently used by msGetErrorObj() in maperror.c.
595
Setting MS_ERRORFILE The variable MS_ERRORFILE will specify the location of the output, with possible values being either a le path on disk, or one of the following special values: stderr to send output to standard error. Under Apache stderr is the Apache error_log le. Under IIS stderr goes to stdout so its use is discouraged. With IIS it is recommended to direct output to a le on disk instead. stdout to send output to standard output, combined with the rest of MapServers output windowsdebug to send output to the Windows OutputDebugString API, allowing the use of external programs like SysInternals debugview to display the debug output. It will be possible to specify MS_ERRORFILE either as an environment variable or via a CONFIG directive inside a maple:
CONFIG "MS_ERRORFILE" "/tmp/mapserver.log"
or
CONFIG "MS_ERRORFILE" "stderr"
If both the MS_ERRORFILE environment variable is set and a CONFIG MS_ERRORFILE is also set, then the CONFIG directive takes precedence. If MS_ERRORFILE is not set then error/debug logging is disabled. During parsing of a maple, error/debug logging may become available only after the MS_ERRORFILE directive has been parsed. DEBUG levels The current DEBUG ON/OFF mechanism, at the layer and map level will be extended to support multiple debug levels as follows. The default is DEBUG OFF (Level 0): Level 0: Errors only (DEBUG OFF, or DEBUG 0) In level 0, only msSetError() calls are logged to MS_ERORFILE. No msDebug() output at all. This is the default and corresponds to the original behavior of MS_ERRORFILE in MapServer 4.x Level 1: Errors and Notices (DEBUG ON, or DEBUG 1) Level 1 includes all output from Level 0 plus msDebug() warnings about common pitfalls, failed assertions or non-fatal error situations (e.g. missing or invalid values for some parameters, missing shapeles in tileindex, timeout error from remote WMS/WFS servers, etc.) Level 2: Map Tuning (DEBUG 2) Level 2 includes all output from Level 1 plus notices and timing information useful for tuning maples and applications Level 3: Verbose Debug (DEBUG 3) All of Level 2 plus some debug output useful in troubleshooting problems such as WMS connection URLs being called, database connection calls, etc. Level 4: Very Verbose Debug (DEBUG 4) Level 3 plus even more details... Level 5: Very Very Verbose Debug (DEBUG 5) Level 4 plus any msDebug() output that might be more useful to the developers than to the users. 596 Chapter 14. Development
The MS_DEBUGLEVEL environment variable Debug level can also be set using the (optional) MS_DEBUGLEVEL environment variable. When set, this value is used as the default debug level value for all map and layer objects as they are loaded by the maple parser. This option also sets the debug level for any msDebug() call located outside of the context of a map or layer object, for instance for debug statements relating to initialization before a map is loaded. If a DEBUG value is also specied in the maple in some map or layer objects then the local value (in the maple) takes precedence over the value of the environment variable. This option is mostly useful when tuning applications by enabling timing/debug output before the map is loaded, to capture the full process initialization and map loading time, for instance. MapScript Implications No direct implication. Setting MS_ERRORFILE will enable debug output in MapScript as well. Note that output to stderr or stdout may not work as expected in some scripting environments and we do not plan to make any special efforts to support those special cases as part of this RFC. However, logging to a le on disk will work with all MapScript avours. Files affected
map.h mapfile.c maperror.c
Several source les with msDebug() calls in them may also need to be edited to adjust the debug level at which the various msDebug() calls kick in. Backwards compatibility issues The MapServer 4.x and older MS_ERRORFILE continues to work as before by default The DEBUG ON/OFF mechanism continues to work as before. However some msDebug() output from previous versions of MapServer may require a higher debug level in order to be enabled. Bug ID 709: https://trac.osgeo.org/mapserver/ticket/709 1333: https://trac.osgeo.org/mapserver/ticket/1333 1783: https://trac.osgeo.org/mapserver/ticket/1783 2124: http://trac.osgeo.org/mapserver/ticket/2124 Voting history Vote completed on 2007-06-29: +1 from DanielM, TomK, FrankW, TamasS, JeffM, SteveL and AssefaY.
597
Questions/Comments from the review period Q: Can we catch the output of OGR/GDALs CPLDebug calls, perhaps when the map-level debug level is >= 3? A: Frank suggests that we keep this for a later phase.
598
STYLE SIZE [v1007] COLOR 255 217 191 END END CLASS NAME "Population Age 40-59" STYLE SIZE [v1008] COLOR 255 186 140 END END END
In the example above, if for a given shape we have v1006=1000, v1007=600 and v1008=400 then the actual pie slices for each class will be respectively 50%, 30% and 20% of the total pie size. If we produced bar charts then the values would represent the relative height of the bars with the largest value (highest bar) being 100% of the chart height. The following attachment to ticket 1800 contains a sample map produced by the layer denition above: https://trac.osgeo.org/mapserver/attachment/ticket/1800/chart-test.jpg The layers legend behaves as usual and produces one color sample per class. Issues and limitations The initial implementation supports only GD output formats. However Thomas Bonfort has offered to implement an AGG version once support for it is available. This is considered a future enhancement outside of the scope of this RFC. Update 2007/09/06: chart rendering is supported by the AGG renderer too. Should we use special keywords instead of PROCESSING parameters to specify the chart type and size? The values of each class are taken from the SIZE of the corresponding STYLE, which is semantically awkward (but that saves us from creating new keywords) MapScript Implications The new CHART type (constant) would be exposed via MapScript. There are no other MapScript implications. Files affected
map.h mapfile.c maplexer.l mapdraw.c mapchart.c maplegend.c Makefile.in makefile.vc (new MS_LAYER_CHART constant) (new CHART keyword) (hooks to call chart rendering code) (implementation of chart rendering) (add case for chart layer type) (addition of mapchart.o) (addition of mapchart.obj)
Note: The patch from ticket 1800 also contains changes to mappostgis.c and mapmygis.c to treat layer type CHART the same way as POLYGON but Im not exactly sure why or if the same needs to be done for other data sources. This will need further review before being released.
599
Backwards compatibility issues None. This is a new feature. Bug ID 1800: https://trac.osgeo.org/mapserver/ticket/1800 Future enhancements: 2136: https://trac.osgeo.org/mapserver/ticket/2136 2145: https://trac.osgeo.org/mapserver/ticket/2145 Documentation http://mapserver.gis.umn.edu/docs/howto/dynamic-charting Voting history Vote completed on 2007/07/05: +1 from DanielM, SteveW, AssefaY Questions/Comments from the review period Q: Does this assume a POLYGON data type input only? Can LINE and POINT data sources also be supported? A: The current implementation works only for polygon data sources. I could extend it to work on point data sources as well fairly easily I think. Im not sure about line data sources though. I guess we could do like we do for ANNOTATION layers and use msPolylineLabelPoint() to determine the location of the chart. Ticket #2145 has been opened to track this enhancement: https://trac.osgeo.org/mapserver/ticket/2145 Q: Could we support attribute binding in CHART_SIZE = [size]? This would allow you to show the relative size of hits at a point and have the chart show the percentage contributions in the wedges. A: While this would be a nice feature, we will keep it as a potential enhancement for a future release. See ticket #2136: https://trac.osgeo.org/mapserver/ticket/2136
Overview This RFC documents the changes required in order to upgrade MapServers OGC WMS support to version 1.3.0 of the specication. MapServer already includes mechanisms to support multiple WMS versions (and already supports WMS versions 1.0.0, 1.1.0 and 1.1.1) so in theory this upgrade should be straightforward and shouldnt require a RFC. Unfortunately, WMS 1.3.0 contains some tricky changes that while they are not exactly backwards incompatible are likely to make the life of users of WMS miserable. This RFC is mostly to document those changes and the way MapServer deals with them. Coordinate Systems and Axis Orientation The main issue introduced by WMS 1.3.0 is the change in the way it handles axis order for several SRS. This has an impact on the way the BBOX is specied in WMS requests and in Capabilities documents and in how the CONNECTIONTYPE WMS code interacts with remote servers. In previous versions of WMS, for any SRS the rst axis was the easting (x or lon) and the second axis was the northing (y or lat). Starting with WMS 1.3.0, some SRS such as the very popular EPSG:4326 have their axis reversed and the axis order becomes lon, lat instead of lat, lon. This change in WMS 1.3.0 was done in order to align with the denitions from the EPSG database (a requirement to make WMS an ISO specication). This change is sure to confuse simple clients that used to treat all SRS the same way. MapServer and PROJ will need to be extended to carry information about the axis order of all EPSG SRS codes and treat them using the correct axis order. New CRS codes such as CRS:xxxx and AUTO2:xxxx have also been added by WMS 1.3.0 that will need to be supported by MapServer. Note the wo types of Layer CRS identiers are supported by the specication: label and URL identiers. The intention is to support at this point the label types CRS. List of CRS planned to be supported are: CRS:84 (WGS 84 longitude-latitude) CRS:83 (NAD83 longitude-latitude) CRS:27 (NAD27 longitude-latitude). AUTO2:42001 AUTO2:42002 AUTO2:42003 AUTO2:42004 AUTO2:42005 CRS:1 (pixel coordinates) would not be supported at this point (there is a ticket discussing this issue http://trac.osgeo.org/mapserver/ticket/485) EPSG codes: when advertising (such as BoundingBox for a layer elemnt) or using a CRS element in a request such as GetMap/GetFeatureInfo, elements using epsg code >=4000 and <5000 will be assumed to have a reverse axes. All the above need to be done in a way that allows continued support for older versions of the WMS specication (1.0.0 to 1.1.1) and will have the least impact on existing WMS services. Implementation for the reverse axis will follow closely to what was already done for WCS1.1 support (http://mapserver.org/development/rfc/ms-rfc-41.html) WMS and SLD All references to SLD support has been removed from the WMS 1.3.0 specications. It has been replaced by two specications: Styled Layer Descriptor prole of the Web Map Service 14.6. Request for Comments 601
Symbology Encoding Implementation Specication The Styled Layer Descriptor prole allows: to extend the WMS to support additional operations (DescribeLayer, GetLegendGraphic) addtional parameters related to the SLD for the GetMap support advertise SLD support. This specication will be supported in the current implementation. Note that the GetStyles operation (available in WMS 1.1.1) might not be supported in the rst phase The Symbology Encoding Implementation represent basically the denitions for the different symbolizers. We need to upgrade the current SLD support to support this specication. HTTP Post support HTTP Post support is optional and currently supported by Mapserver WMS 1.1.1. WMS 1.3.0 denes that if POST is supported, the the request message is formulated as an XML document. Although this is highly deirable, the rst implemenation of the WMS 1.3.0 might not support the XML Post requests. OCG compliance tests The OGC Compliance and Interoperability Testing Initiative (CITE) http://cite.opengeospatial.org/test_engine/wms/1.3.0/ provides automatic tests to validate the implementation. The short term intention is to use this service as a rst validation tool. The longer term goal is to have Mapserver WMS 1.3.0 fully compliant. Other Notes GetCapabilities advertises only the text/xml format. During a request we do not parse the optional Format paramater. It is always set to text/xml MapScript Implications None. This affects only the WMS server interface and WMS CONNECTION type. Files affected
mapwms.c mapwmslayer.c mapfile.c mapows.c/h mapogcsld.c
Backwards compatibility issues The change in the way the axis order is handled is likely to cause lots of confusion.
602
Bug ID 473: http://trac.osgeo.org/mapserver/ticket/473 Voting history Passed with +1 from: TomK, Woodbridge, Assefa, Morissette Questions/Comments from the review period Q: Can libxml2 be used to generate XML responses to continue the work started in mapowscommon.c? A: Ill keep libxml2 in mind during the implementation, but I do not plan to refactor and risk breaking any code to convert it to libxml2 as part of this upgrade. Since WMS 1.3.0 doesnt implement OWS common, it wont benet from any of the code thats already using libxml2. It will actually mostly reuse existing printf-based code thats already well tested and working. I think the right time to switch to libxml2 for WMS would be when it will support OWS common and then there will be real benets by reusing functions from mapowscommon.c.
3. call loadObject (e.g. loadLayer) In effect this would be a way to load an empty object or update a new one. The loadObject functions would need minor changes: 1. Each function would need to remove restrictions for duplicate properties. That is setting a parameter twice should not generate an error as is does now. 2. Properties with allocated memory (e.g. char * ) should be freed if they already have values and are being updated. 3. the object main keyword (e.g. LAYER or CLASS) should be allowed as a token within that object loader. When parsing a le the object identier (e.g. LAYER) is stripped off with the parent object. For example, a CLASS is recognized by loadLayer so that token never is encountered by loadClass. It makes the most sense to pass entire object denitions including the object identier for ease of use. MapScript Im open to suggestions but I think the easiest thing to do would be to add an updateFromString method to all major objects. It would simply take a string snippet and would wrap the ...LoadFromString methods mentioned above. They would return MS_SUCCESS or MS_FAILURE. Might consider adding a clear method to (freeObject then initObject) so that users could clean things out and reload from a string. Im not sure about the effects on reference counting here. URL I propose removing all the loadObjectValue (e.g. loadLayerValue) functions in favor of entire object loading. So, instead of doing something like: ...map_scalebar_units=meters&map_scalebar_intervals=5&map_scalebar_size=300+2... You would do: ...map_scalebar=UNITS+METERS+INTERVALS+5+SIZE+300+2... The major objects would still be referenced by map_scalebar or map_legend or map_layername, but all other properties would be loaded through snippets. The function msLoadMapParameter would become msUpdateMapFromURL and it would set the lexer state, acquire a thread lock and then call the appropriate loadObject function. One issue is that the loadObject functions have traditionally worked just from les so there are no limitations on what can be altered. Obviously from a URL you cant allow just anything to be altered (e.g. CONNECTION, DUMP and so on). So, we would create a new lexer state, MS_TOKENIZE_URL, that would only recognize the parameters that we want. In that state the lexer would not return tokens like DUMP or CONNECTION so the loadObject functions would not handle those cases. This is a simple addition to the lexer. Any parameter exposed to URL modication will have the relevant loading block examined so that there are no memory leaks or buffer overow possibilities. In addition, it was pointed out that URL conguration should not be a default behavior but should be enabled explicitly. Enabling this feature would happen by way of a new parameter within the webObj- URLCONFIG [pattern], with a default of NULL. The pattern would be a regular expression that would be applied against any map_* variables. So, one could limit changes to just the scalebar object with URLCONFIG scalebar or allow more with URLCONFIG .. The default would not to be allow any URL conguration.
604
Backwards Compatibility The URL change will break backwards compatibility but I feel this is a relatively lightly used option and this change will be very benecial. Post Implementation Notes Apparently a number of folks are having trouble with porting applications to use the new url conguration. Below are more examples and lists of supported keywords by object type. Rule of thumb one: when there is the opportunity for more than one of a particular object (e.g. layers, classes and styles) the syntax must uniquely identify the object in question in the variable name (e.g. map.layer[lakes]) and then the maple snippet to modify the object is given as the variable value. We have no way to modify 5 styles at once because the maple syntax is so freeform. Rule of thumb two: any parameters or objects that hang off the mapObj must be referenced in the variable name (e.g. map.imagetype). Example 1, changing a scalebar object:
...&map.scalebar=UNITS+MILES+COLOR+121+121+121+SIZE+300+2&...
605
angle,backgroundcolor,color,outlinecolor,size,symbol,width
More to come... Bug IDs http://trac.osgeo.org/mapserver/ticket/2143 Voting history +1 from SteveL, SteveW, TomK, FrankW, AssefaY, PericlesN +0 from JeffM
14.6.31 MS RFC 32: Support for Anti-Grain Geometry (AGG) Rendering Engine
Date 2007/07/09 Author Steve Lime, John Novak Contact Steve.Lime at DNR.State.MN.US Status Pending Id $Id: ms-rfc-32.txt 8278 2008-12-23 21:34:31Z hobu $ Overview Presently MapServer supports GD (www.libgd.org) as its primary raster rendering backend. While GD is sufcient in many instances it is not capable of high quality output especially with regards to anti-aliased line work. MapServer does support pseudo anti-aliased wide lines using variable opacity fuzzy buffers, but the results are not as good as they could be. AGG has emerged as one of the premier software-only rendering solutions and it holds the promise of superior output quality with little or no apparent loss in performance. In fact, AGG may well be faster than GD in some instances even with the higher quality output. That said, we are still heavily vested in GD for many things. Text positioning and raster rendering in particular use GD functions directly. On the other hand, AGG does not have built in functions to read or write popular graphics formats such as GIF, JPEG or PNG. It makes sense then to consider a hybrid solution wherein we can take advantage of aspects of GD that make sense such as buffer management and I/O capabilities, and let AGG worry about rendering features. Thats exactly what is proposed- AGG rendering into a GD managed image buffer. A secondary benet is that AGG functionality can be added incrementally as time and resources permit. For example, since an AGG imageObj is really just a gdImagePtr we can use current code that renders to a GD image along side any AGG routines. Note: See AGG Rendering Specics for more information. Technical Solution The goal of this initial implementation is to be able to render the symbol and style denitions the same way as GD does. That is, the AGG renderer should produce output similar to GD but of a higher quality. No attempts are made at 606 Chapter 14. Development
this stage to introduce rendering capabilities specic to AGG unless otherwise noted. As a result no additions to the MapServer symbolObj or styleObj are necessary at this point. For the most part, the AGG renderer can ingest processed shapeObjs, styleObjs and symbolObjs just as GD. That said, since AGG uses sub-pixel computations to render features it does not want feature coordinates rounded to integer values, so a special AGG-only map to image coordinate conversion function msTransformShapeAGG. Note, that it may be that GD could also make use of the non-rounded features and could just cast the doubles to ints when passing xs and ys to GD (in fact the code already does this), but further testing will be necessary. C API Changes In reality adding a new renderer has little or no effect on the MapServer core. The following les are to be modied to add AGG specic processing blocks that are basically straight copies of GD support: mapdraw.c mapdrawgdal.c maperror.c maplegend.c mapoutput.c mapraster.c mapresample.c maputil.c No new functionality is added to these les, rather just else-if blocks. The bulk of the AGG functionality can be found in a new source le, mapagg.cpp. For better or worse it mimics the rendering API found in mapgd.c. So, for example msDrawLineSymbolGD has a counter part in msDrawLineSymbolAGG. Various helper functions/methods can also be found in that le. MapScript No changes. Maples An output block like this will trigger AGG rendering:
OUTPUTFORMAT NAME AGG_PNG24 DRIVER AGG/PNG IMAGEMODE RGB END
607
Issues and Caveats The AGG driver only supports RGB output at this time. A fundamental difference in how GD and AGG interpret alpha channel values (GD is backwards) means that AGG cannot write to a GD alpha channel and have the output interpreted correctly. This really shouldnt be a deal breaker though since vector rendering in MapServer does not write to the alpha channel except when dealing with layer transparency, otherwise alpha blending occurs. In addition, GD is back under active development and there are plans to dene a proper RGBA buffer. Text and raster layers are drawn using GD. While text placement could certainly benet from sub-pixel placement there are not enough resources to complete that support at this time. Hopefully it can be addressed soon. Raster layer rendering doesnt appear to benet from AGG and will remain a GD function at this time. The following symbol, style combinations do not work under AGG: TODO The AGG license was changed between versions 2.4 (BSD style) and 2.5 (GPL) (http://www.antigrain.com/license/index.html). MapServer should use version 2.4 of the library until all implications of this change are claried. Bug ID None assigned Voting history None
608
Technical Solution As mentioned earlier msLayerWhichItems() does a couple of things. Some of these functions would need to be retained somehow and are described below. 1. Layer items array: this array normally would be populated by the msLayerWhichItems() call. Instead it should be populated as a layer is opened in msLayerOpen. (makes sense?) 2. Index references: linking a attribute name to an index value would have to happen during the course of rendering or querying instead of ahead of time. Basically code that uses attributes would have to rst check if the parameter is not NULL, and then if the index reference is not set it would have to call a function like that shown below. While this affects a good number of places in the code base the change is relatively minor. The use of attribute binding isolates much of this code so this change is smaller for version 5.0 that it otherwise would have been.
int msGetItemIndex(char **itemlist, int numitems, char *item) { int i; if (!itemlist || numitems <= 0 || !item) return -1; for (i=0; i<numitems; i++) if(strcasecmp(itemlist[i], item) return i; return -1; /* failure */ }
1. Logical expression handling: expressions maintain their own individual list of items to process so like 2 above this list would have to be created during processing. The code to do this exists as part of msLayerWhichItems() and would be retained under some other name. Note: this RFC does not address single pass queries, but rather sets the stage for them. Subsequent drawing, query and template output processes would remain unaltered. General C API Changes maplayer.c - msLayerWhichItems() goes away. msLayerOpen() now sets the layer->items array. maputil.c - Binding functions now must assign index references when executed. Same goes for the functions to assign a classObj to a feature. mapdraw.c - Layeritemindex and classitemindex must now be dynamically assigned values. Input Driver Changes It is unclear how each driver made use of the output of msLayerWhichItems(). It may be as easy as calling msLayerGetItems() instead of using msLayerGetItemInfo() in msLayerOpen() in which case wed loose the msLayerGetItemInfo() function for each driver too (and the main wrapper function). TODO... mapshape.c - mapsde.c - mapogr.cpp - mappostgis.c - maporaclespatial.c - mapmygis.c MapScript No changes.
609
Maples No changes anticipated. Backwards Compatibility Issues None. This is a new feature. Bug ID None assigned. Voting History None
610
Setup and maintain the Release Plan section of the website for this release Coordinate with the developers team Coordinate with the QA/testers team Coordinate with the docs/website team Keep track of progress via Trac (make use of Trac milestones and ensure tickets are properly targeted, push some tickets to a later release if required, etc.) Organize regular IRC meetings (including agenda and minutes) Tag source code in SVN for each beta, RC and release Branch source code in SVN after the nal release (trunk becomes the next dev version) Update map.h and HISTORY.TXT for each beta/RC/release Package source code distribution for each beta/RC/release Update appropriate website/download page for each beta/RC/release Make announcements on mapserver-users and mapserver-announce for each release Produce/coordinate bugx releases as needed during the 6 months period that follows the nal release (i.e. until the next release) Any of the above tasks can be delegated but they still remain the ultimate responsibility of the release manager. The MapServer Release Process (Credit: Inspired by the Plone release process at http://plone.org/documentation/manual/plone-developerreference/overview/release-process) MapServer uses a time-based release cycle, trying to aim for one release every 6 months. The normal development process of a MapServer release consists of various phases. Development phase The development phase usually lasts around 4 months. New features are proposed via RFCs voted by the MapServer PSC. RFC freeze date For each release there is a certain date by which all new feature proposals (RFCs) must have been submitted for review. After this date no features will be accepted anymore for this particular release. Feature freeze date / Beta releases By this date all features must have been completed and all code has to be integrated. Only non-invasive changes, user interface work and bug xes are done now. We usually plan for 3-4 betas and a couple of release candidates over a 6 weeks period before the nal release. Release Candidate Ideally, the last beta that was bug free. No changes to the code. Should not require any migration steps apart from the ones required in the betas. If any problems are found and xed, a new release candidate is issued. Final release / Expected release date Normally the last release candidate that was issued without any show-stopper bugs. Bug x releases No software is perfect. Once a sufcient large or critical number of bugs have been found for a certain release, the release manager releases a new bug x release a.k.a. third-dot release (for example 4.10.2). 14.6. Request for Comments 611
MapServer Version Numbering MapServers version numbering scheme is very similar to Linuxs. For example, a MapServer version number of 4.2.5 can be decoded as such: 4: Major version number. We release a major version every two to three years. The major version number usually changes when signicant new features are added or when major architectural changes or backwards incompatibilities are introduced. 2: Minor version number. Increments in minor version number almost always relate to additions in functionality and correspond to the 6 months release process described in this RFC. MapServer uses the same even/odd minor version number scheme as Linux. Even minor version numbers (0..2..4..6) relate to release versions, and odd minor versions (1..3..5..7) correspond to developmental versions. For instance development version 4.1 was released as version 4.2.0, there was never any formal release of 4.1. 5: Revision number. Revisions are bug xes only. No new functionality is provided in revisions. Voting history Vote completed on 2007/07/19. +1 from DanielM, SteveL, SteveW, FrankW, TamasS, AssefaY, JeffM, PericlesN, UmbertoN and HowardB.
612
also be supported in the usual fashion for OWS metadata (ie. wms_compliance, wfs_compliance, wcs_compliance, sos_compliance). If this keyword value is permissive, then when practical and unambiguous MapServer may attempt to be forgiving of missing or otherwise non-compliant requests and input in the interest of increasing MapServers usability in real life interoperability scenarios. This may include things such as allowing protocol parameters to be omitted in requests that are required by the OGC specications, allowing services to operate even if metadata is missing from the maple to ll required elds in capabilities. If this keyword value is pedantic, then to the extent practical MapServer will attempt to generate an error if its input (WxS protocol requests, maple incomplete, etc) is not in full compliance with the requirements of the OGC specications. It is foreseen that users wishing to encourage good standards compliance behavior in clients, and to ensure they dont accidentally put up web services with incomplete metadata will use the pedantic mode. It is anticipated that pedantic mode will also be used when MapServer is run through OGC CITE and similar test suites. It is foreseen that permissive mode will be used by those wishing to ensure their service is accessable by the broadest set of possible clients, even if they are not strictly operating to the standards. Developers should keep in mind that adding more exceptions in the permissive mode should not be taken lightly as this encourages misuse of the specs and bloats the code with unnecessary exceptions. msOWSLookupMetadata() In actual code, the compliance keyword might be tested using msOWSLookupMetadata() in a manner similar to this:
if (stylesfound == 0 && sldfound == 0) { if( strcasecmp(msOWSLookupMetadata(&(map->metadata),"MO","compliance"), "pedantic") == 0 ) { msSetError(MS_WMSERR, "Missing required parameter STYLES", "msWMSLoadGetMapParams()"); return msWMSException(map, nVersion, "MissingParameterValue"); } else { msDebug( "WMS request missing STYLES parameter, permissively ignoring." ); } }
MapServer 5.0.1 For MapServer 5.0.1 the only change anticipated to be made in the code is the above example, requiring the STYLES parameter only in pedantic mode. If other standards enforcement issues are discovered to be unnecessarily interfering with use of MapServer in real life interoperability they may also be changed in 5.0.x to be based off this keyword. MapServer 5.1 In MapServer 5.1, and the future, if other standards enforcement issues are discovered to be unnecessarily interfering with use of MapServer in real life interoperability scenarios they may also be changed to be based off this keyword. Once again, developers should keep in mind that adding more exceptions in the permissive mode should not be taken lightly as this encourages misuse of the specs and bloats the code with unnecessary exceptions. As part of implementation of this RFC the authors will review all WARNING: entries emitted in capabilities documents in places like mapwms.c to see if they ought to be turned into fatal errors when operating in pedantic mode. 14.6. Request for Comments 613
Documentation The ows_compliance keyword will be added to the MapServer 5 reference documentation. Implementation The described changes will be made in MapServer 5.0 and MapServer 5.1 by Frank Warmerdam and/or Daniel Morissette with the MapServer 5.0 changes in time for a 5.0.1 release. It is hoped that all OWS service developers will apply the permissive/pedantic tests in OWS services in the future as required and as issues come up. MapScript No changes are anticipated in mapscript as it already has metadata setting methods. Backwards Compatibility Issues Implementation of this feature should restore backward compatible default behavior in MapServer 5 with MapServer 4.x. No other compatability issues are anticipated. Bug ID http://trac.osgeo.org/mapserver/ticket/2427 Voting History There was a rst vote around 2007/11/08 which was vetod... and after further discussion the RFC has been withdrawn in favor of simply restoring the behavior of MapServer 4.10 with respect to the STYLES= parameter (i.e. make it optional again). See ticket #2427 about this.
1. Use output format objects to dene formats that can be used to output query results in addition to drawing images. For example:
OUTPUTFORMAT NAME gml3 DRIVER GML3 MIMETYPE text/xml; subtype=gml/3.2.1 END
Might need to extend that object to discriminate between map rendering and query formatters but that can happen in mapdraw.c and mapserv.c too. That is, drivers are explicitly referenced in those places so if someone tries to draw a map with a GML3 driver it would throw an error. 1. Use the webObj QUERYFORMAT property to reference formats: QUERYFORMAT gml3. Right now that property carries a mime-type but it could be used to reference a format too. 2. Also allow applicable modes (i.e. WFS, WMS, SOS), to utilize DRIVER/TEMPLATE type formats (i.e. advertise in GetCapabilities responses, support through API [e.g. request=GetFeature&outputFormat=text/xml; subtype=gml/3.2.1]), mapped from OUTPUTFORMAT/MIMETYPE. Presently the WCS driver requires the developer to explicitly dene supported output formats, other services could do the same and could reference templated output. 3. Dene a TEMPLATE driver. Basically this would just invoke the normal query templating scheme. For example:
OUTPUTFORMAT NAME kml DRIVER TEMPLATE MIMETYPE application/vnd.google-earth.kml+xml TEMPLATE myTemplate.kml END OUTPUTFORMAT NAME geojson DRIVER TEMPLATE MIMETYPE application/json; subtype=geojson TEMPLATE myTemplate.js END
1. Note that in the above examples we reference a le, so Im thinking of supporting a single template system for queries in addition to the current mechanism. To do this Id propose 4 new template tags: [resultset], [feature], [join] (for one-to-many joins), and [include] (to support code sharing between templates). All but the include tag would be blocks. An example might be:
[include src="templates/header.html"] [resultset name=lakes] ... old layer HEADER stuff goes here, if a layer has no results this block disappears... [feature] ...repeat this block for each feature in the result set... [join name=join1] ...repeat this block for each joined row... [/join] [/feature] ...old layer FOOTER stuff goes here... [/resultset] [resulset name=streams]
615
... old layer HEADER stuff goes here, if a layer has no results this block disappears... [feature] ...repeat this block for each feature in the result set... [/feature] ...old layer FOOTER stuff goes here... [/resultset] [include src="templates/footer.html"]
<?xml version="1.0" encoding="ISO-8859-1"?> [resultset layer=mums] <MapServerUserMeetings xmlns="http://localhost/ms_ogc_workshop" xmlns:xlink="http://www.w3.org/1999/x <gml:description>This is a GML document which provides locations of all MapServer User Meeting that <gml:name>MapServer User Meetings</gml:name> <gml:boundedBy> <gml:Envelope> <gml:coordinates>-93.093055556,44.944444444 -75.7,45.4166667</gml:coordinates> </gml:Envelope> </gml:boundedBy> [feature] <gml:featureMember> <Meeting> <gml:description>[desc]</gml:description> <gml:name>[name]</gml:name> <gml:location> <gml:Point srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"> <gml:pos>[x] [y]</gml:pos> </gml:Point> </gml:location> <year>[year]</year> <venue>[venue]</venue> <website>[url]</website> </Meeting> </gml:featureMember> [/feature] <dateCreated>2007-08-13T17:17:32Z</dateCreated> </MapServerUserMeetings> [resultset]
616
This would allow for relatively complex text les of any sort to be built from multiple layers. All the normal template tags would still be supported but those normally available for query results would only be valid inside a [feature]...[/feature]. These tags would work with existing system too but just wouldnt be as useful as with the 1 template idea. Note: It is often a problem to have trailing record separator characters after the nal record. For example, in the JSON template above the trailing comma in the [feature] block causes problems with Internet Explorer. So I propose supporting a trim attribute that tells the template processor to remove that string from the end of the output for the last feature processed. Note: A resultset could be applied to multiple layers so the name attribute will take a comma delimited list of layers. The order listed is the order they results will be presented. Its possible that groups could be used as well but at this point that seems like a fairly rare use case. Note: A resultset will also take a maxresults attribute so that the number of features processed can be limited. Additional Maple Changes By moving templates out of a layer we lose the ability mark layers as queryable. Dan proposed adding a QUERYABLE TRUE/FALSE option to layerObjs. That could be put in place as part of this RFC, although it is not required. We could continue to leverage dummy template values. Adding it would require the normal changes to support a new keyword, and a small change to function in mapquery.c that tests to see if a layer is queryable. Basically a layer would be queryable if: 1) it has a template or 2) QUERYABLE is TRUE (default would be FALSE). Documentation Documentation detailing the new templated output capabilities will be added to the maple reference guide (OUTPUTFORMAT and WEB objects) and to the template reference guide (new [resultset], [feature], [join] and [include] tags). Implementation mapoutput.c: No changes necessary (I think), no need to dene a default format, nor do I think we need to extend the outputFormatObj structure. maple.c/maplexer.l: Allow changing webObj QUERYFORMAT from a URL. (todo: add support for setting a layer as queryable) maptemplate.c: Add processor functions for the new tags. Update process line to recognize the [resultset] and [join] tags (the [feature] tag would only be valid within a [resultset] block. Write a new single template processing function similar to msReturnQuery() in that same source le, something like msReturnSingleTemplateQuery(). mapserv.c: Add code at the end of the query processing switch statement to look at the value of web->queryformat. If
617
it references an existing output format by name then use the le the format points to with msReturnSingleTemplateQuery(), otherwise process as currently done. Caveats: to simplify tag parsing (at least initially) I propose requiring that start and end tags exist on their own lines in the template le (is this a requirement for legend templates?). Depending on the legend template block parsing this requirement could be removed once some implementation work is done. MapScript No changes are anticipated in MapScript at this time although we may choose to expose templated output as an option at a later date. Backwards Compatibility Issues No other compatibility issues are anticipated. The current templating mechanism would continue to function. In the event the QUERYFORMAT does not reference an outputFormatObj the current system would kick in. In fact, the current system can use several of the new proposed tags, specically [join] and [include] tags. Bug ID None assigned. Voting History None
618
The History of Spatial References in MapServer MapServers spatial reference support is quite anemic by many standards. While most of the data sources MapServer interacts with support describing the spatial reference of contained layers, MapServer has historically dropped the information on the oor or completely ignored it. MapServers reprojection machinery keys off the fact that a LAYERs PROJECTION is different than the MAPs. When this is the case, MapServer reprojects the LAYERs data to the MAPs spatial reference during a map draw. OGC services also interact here, and when a spatial reference is specied as available using the METADATA mechanism, a client can request maps in a different spatial reference than is specied by default, which starts the reprojection machinery.
Denition
MapServer has historically used two different approaches for dening the spatial reference of its data EPSG/ESRI codes in the form:
PROJECTION "init=epsg:4326" END
A third, and rather unknown option is available exclusively to WMS the EPSG AUTO denition, where MapServer attempts to determine the spatial reference from the data itself. This method currently only works for OGR and GDAL data sources, and it is only available when GDAL/OGR is linked into MapServer.
Performance Observations
MapServers current spatial reference story is focussed on two things simple description and ensuring that unnecessary data reprojection doesnt happen. MapServer currently uses proj4 directly to do its data reprojection, and this is the impetus for dening coordinate systems in proj4 format. For people wanting the best performance but still requiring data reprojection, dening your spatial references in proj4 format is a must. Alternatively, the EPSG/ESRI code denition of MapServers spatial references allows MapServer to ofoad the lookup of proj4 descriptions to proj4 itself, with a simple le-based lookup table. This mechanism is currently a bottleneck, however, as each lookup requires trolling through a le to match the given identier and returning the proj4 denition. Note: This penalty was lessened in early 2009 by the addition of a caching mechanism in proj4 that allows subsequent lookups to be fast.
619
Usability
The usability of these two mechanism can be a nightmare for users. First, most of the spatial reference descriptions that people work with are of the WKT variety not proj4. While it is straightforward to set the PROJECTION information for data with a known EPSG value, custom projections or those not generally available in the EPSG database require the user to somehow translate their WKT into proj4 format and paste it into their maple. Additionally, http://spatialreference.org exists to help ease this pain, but it is ultimately a stopgap, and not a permanent solution to the problem. It is not practical to be downloading the spatial reference for each and every layer in a maple on every map draw from a website. spatialreference.org does provide some conversion utilities to allow a user to paste in WKT and have it return MapServer PROJECTION blocks, but this approach still foists pain and misery on the users. Specication Features MapServer will continue to behave as before, assuming the inputted projection is either an EPSG code or proj4 denition. The user will also have the ability to optionally add a TYPE enumeration that will hint the processing of the projection object.
PROJECTION TYPE TYPEENUM "A definition" END
The following optional TYPE enumerations would be supported: AUTO PROJ4 EPSG FILE OGCWKT ESRIWKT See below for some examples:
# Use the what the layer defines as the projection definition. # This may not be available for all data sources or layer types # (shapefile, SDE, OGR, etc.). PROJECTION AUTO END
620
# Read the definition from a file PROJECTION TYPE FILE VALUE "../myfile.prj" END
# Use an OGC WKT definition (escaping may be required) PROJECTION GEOGCS["WGS 84", DATUM["WGS_1984", SPHEROID["WGS 84",6378137,298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich",0, AUTHORITY["EPSG","8901"]], UNIT["degree",0.01745329251994328, AUTHORITY["EPSG","9122"]], AUTHORITY["EPSG","4326"]] END
# Use an ESRI WKT definition (escaping may be required) PROJECTION TYPE ESRIWKT GEOGCS["GCS_WGS_1984", DATUM["D_WGS_1984", SPHEROID["WGS_1984",6378137,298.257223563]], PRIMEM["Greenwich",0], UNIT["Degree",0.017453292519943295]] END
Implementation Details It is important that MapServers previous spatial reference denition behavior be preserved. First, drastically changing the PROJECTION denitions would mean a lot of unnecessary maple churn. Second, continuing to dene spatial references in proj4 format as before will be the most performant. Implementation of this RFC will encompass four items: 1. Additional spatial reference type enumerations will be added. 2. Addition of a method to the LAYER virtual table so layers can support returning the spatial reference in a variety of formats (OGCWKT, ESRIWKT, proj4, EPSG). 3. Additional methods will be added to operate with the MapScript projectionObj to support setting the projectionObj of a TYPE with a denition.
TYPE Enumerations
The following TYPE enumerations will be added to support SRS denition types:
621
projectionObj
Two methods will be added to set the projectionObj using various denition types and to return denitions in various avors.
int msSetProjectionByType(projectionObj *p, int type, const char *value) char* msGetProjectionByType(projectionObj *p, int type)
Driver-specic implementations
The following drivers will have implementations provided to support TYPE AUTO spatial reference denitions: Shapele OGR GDAL Raster ArcSDE PostGIS
MapScript
msSetProjectionByType and msGetProjectionByType will be exposed to MapScript via the projectionObj:
setByType(char* definition, int type) getByType(int type)
Files Affected
mapserver.h mapfile.c mapscript/swiginc/projection.i maplayer.c mapproject.h mapproject.c mapsde.c mapogr.cpp
622
mapraster.c mappostgis.c . . .
Backward Compatibility Issues All work described in this RFC will provide optional capabilities to MapServer and no backward compatibility issues are expected. Documentation This RFC will stand as primary documentation for the feature until such time as the methods and practices described in this document are integrated into the regular MapServer documentation framework.
14.6.37 MS RFC 38: Native Microsoft SQL Server 2008 Driver for MapServer
Author Howard Butler Contact hobu.inc at gmail.com Revision $Revision: 8278 $ Date $Date: 2008-12-23 13:34:31 -0800 (Tue, 23 Dec 2008) $ Status Implemented Version 5.2 Id $Id: ms-rfc-38.txt 8278 2008-12-23 21:34:31Z hobu $ Purpose To provide a read-only, native MapServer driver that connects to Microsoft SQL Server 2008 (henceforth called SQL Server) on Windows as a PLUGIN datasource driver. Background I.S. Consulting has donated a native driver modeled on the PostGIS driver to support SQL Server 2008s newly added spatial capabilities. This new driver will only be available on the Windows platform, and it will only be available as a PLUGIN datasource driver. No additional enumerations or conditional includes will be added to the MapServer codebase to support this driver. Usage Details The driver is a PLUGIN layer, and uses the PLUGIN syntax described in RFC 8 [1] to dene relevant layer information:
LAYER NAME "Roads" CONNECTIONTYPE PLUGIN PLUGIN "C:\ms4w\plugins\msplugin_mssql2008.dll"
623
DATA "the_geom from roads" TYPE LINE STATUS ON PROJECTION "init=epsg:4326" END CLASS STYLE COLOR 0 0 255 WIDTH 8 END END END
Files Affected A single le, mapmssql2008.c will be added to subversion. It will only be compiled on windows using the nmake /f makele.vc plugins command when options describing the ODBC libraries are switched on. Backward Compatibility Issues All work described in this RFC will provide optional capabilities to MapServer and no backward compatibility issues are expected. Documentation This RFC will stand as primary documentation for the feature until such time as the methods and practices described in this document are integrated into the regular MapServer documentation framework. Intellectual Property This work will become a regular part of MapServer and will be released under MapServers open source license. [1] http://mapserver.gis.umn.edu/development/rfc/ms-rfc-8/
624
Overview When WMS and SLD support was added in MapServer few years back, one of features that was not integrated was the ability to specify named styles through WMS GetMap request using the STYLES parameter or through the <NamedStyle> parameter in an SLD document. Using named styles, the WMS client has the ability to render a specied layer using styles predened by the WMS server. Example of this would be:
http://..../mapserv.cgi?Request=GetMap&....&LAYERS=Rivers,Roads,Houses&STYLES=CenterLine,CenterLine,O
<StyledLayerDescriptorversion="1.0.0"> <NamedLayer><Name>Roads</Name> <NamedStyle> <Name>Casing</Name> </NamedStyle> <NamedStyle> <Name>CenterLine</Name> </NamedStyle> </NamedLayer> </StyledLayerDescriptor>
The main reason this functionality is not yet supported is that It is not currently possible to dened in MapServer several mutually exclusive styles on a layer The intention of this RFC is to introduce a simple mechanism that would allow MapServer to dene mutually exclusive Styles. This would then allow for MapServer to advertise and support named styles through the WMS interface Proposed Changes The MapServer architecture (layer. class, styles) does not t well the SLD model where it assumes that you can dene mutually exclusive styles on a layer and be able to switch between them. One possible solution which is reasonably non disruptive would be to introduce the concept of group names at the class object level and have at a layer level a parameter that can be used to specify the classes to use. Something like this is what is proposed:
LAYER ... CLASSGROUP "group1" ... CLASS NAME "name1" GROUP "group1" ... END CLASS NAME "name2" GROUP "group2" ... END CLASS NAME "name3" GROUP "group1" ...
625
END ...
This introduces two new keywords, CLASSGROUP at the layer level and GROUP name in the class object. These parameters are optional If the CLASSGROUP parameter is set, only classes that have the same group name would be considered at rendering time. If it is not set, all classes (current behavior) would be used. Note that CLASSGROUP is acting as the default style if there are classes within the same LAYER with different GROUPs dened. The idea is that STYLES parameter through a wms request (or cgi URL variable) would override the value of the CLASSGROUP. In the example above, only classes name1 and name3 would be considered for rendering (if STYLES= or STYLES=default), unless the client overrides this value using STYLES=group2. Affected/Added functionalities in MapServer 1. MapServer vector rendering (function msShapeGetClass) would use the setting of the classgroup if it is available 2. Raster rendering (function msGetClass) : would use the setting of the classgroup if it is available 3. Possibility to use the URL variables to modify the value of the classgroup (something like this would be valid : ...&map.layer[layername]=classgroup+group2. This would allow through the cgi to switch representation of a layer if needed 4. WMS related functionalities: Advertise STYLES through the GetCapabilities: styles would be based on the different group names of the classes dened in the layer. If all classes do not have the GROUP set, the current behavior (returning the STYLE element with the default name) will be kept. If one or more classes have the GROUP set, It is proposed to output something like this for each group:
<Style> <Name>group1</Name> <Title>group1</Title> <LegendURL width="20" height="10"> <Format>image/png</Format> <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="h </LegendURL> </Style>
Support Named Styles in SLD. This would have the effect of setting the layer level CLASSGROUP. We throw an exception if an invalid style is passed. Support style names in the STYLES parameter for the WMS GetMap request. We would still support the empty style names as well as the default keyword used for STYLES. We throw an exception if an invalid style is passed. GetLegendGraphic would be extended to support names in the STYLES parameter. The if STYLE parameter is present and the value is not empty, we would throw an exception is the style passes is not valid.
626
GetStyles : the current behavior is to return all the classes as UserStyle elements. the sld 1.0 specication does not seem to be clear on how to deal when multiple styles are available : section 13.1 species ...All requested styles that can in fact be described by SLD will be returned as UserStyle elements, and styles that cannot be will returned as NamedStyle elements. .... The proposed approach is to keep the current beahviour if the CLASSGROUP is not set and if set, to return UserStyle elements on specied classes only. 1. Legend drawing would need to use the setting of the classgroup if it is available Other Considerations Does this apply to all types of layers such as chart layers ? Files Affected
maplexer.l mapserver.h mapfile.h mapfile.c mapogcsld.c mapwms.c maplegend.c mapcopy.c php_mapscript.c
MapScript Need to update set function (at least in the php MapScript) to set the two new parameters at the layer and class level. Need to check if there is anything to be done for swig MapScript. Backwards Compatibility All work described in this RFC will provide optional capabilities to MapServer and no backward compatibility issues are expected. Documentation SLD, WMS Server, and Maple documents will be upgraded. Testing Addition of a test in msauto to validate the support of names STYLES parameter through a GetMap request Bug ID http://trac.osgeo.org/mapserver/ticket/2431 Voting History +1: Assefa, TomK, FrankW +0, DanielM, SteveW 14.6. Request for Comments 627
loop through text lines to nd the line with the most characters l_max pad all the other lines with (l_max - l_cur)/2 space characters A more advanced implementation will be to use the exact line lengths as returned by the renderers with the msGetLabelSize function: compute the size in pixels of the string (two spaces, accounts for kerning): l_2space loop through text lines to longest line of length pix_l_max pad all the other lines with (pix_l_max - pix_l_cur)/2 * 1/(2*l_2space) space characters Limitations: aligning text to the right will produce ugly results using this method, unless using a monospace font. Modications to the source code MAXLENGTH and ALIGN will be added to the LABEL object in map.h, in the maple parser/writer (maple.c) and in MapScript msTransformLabelText() in maplabel.c will be updated to support the modications proposed. No other modications should be required as the text itself is modied to t the users request (i.e. it is padded with spaces, and/or newlines are added to it) MapScript Implications The labelObj will have new maxlength property of type integer and align property (ms_align_*). Files affected
map.h mapfile.c maplabel.c maplexer.l maplexer.c
Backwards compatibility issues None. Bug ID 2383: https://trac.osgeo.org/mapserver/ticket/2383 Voting history +1: SteveL, SteveW +0: FrankW, TomK
629
Questions/Comments from the review period SteveW: allow preciser computation of line offsets when padding with spaces: done. The precise size of each line is calculated in pixels, and the closest number of space characters required for alignment is computed accordingly DanielM: allow multiple characters to be used when wrapping lines: not addressed. Space characters can be replaced by a newline, while the hyphen character should generally be kept. Any idea how we can specify that some wrapping characters are to be kept while others are just markers for potential linebreaks?
request. The following table indicates which WCS metadata items are mapped to what coverage XML elements in WCS 1.0 and WCS 1.1:
MapServer --------<x>_formats <x>_keywordlist <x>_label <x>_description <x>_abstract (new) <x>_metadatalink_href <x>_nativeformat <x>_rangeset_name <x>_rangeset_label <x>_bands_name WCS 1.1 ------SupportedFormat ows:Keywords (unused) ows:Title ows:Abstract (unused) (unused) Field.Identifier Field.Title Axis.identifier WCS 1.0 ------formats keywords label description (unused) metadataLink nativeFormat RangeSet.name Rangeset.label AxisDescription.name
URNs / Coordinate Systems and Axis Orientation WCS 1.1 uses URNs like urn:ogc:def:crs:EPSG::4326 or urn:ogc:def:crs:OGC::CRS84. In addition the WCS protocol is required to honour EPSG axis conventions when using coordinate systems within the EPSG authority space. This means, for instance, that any coordinates in the urn:ogc:def:crs:EPSG::4326 coordinate system must be provided in lat,long ordering instead of the conventional long,lat. In order to implement these requirements, several changes are planned: msLoadProjectionString() will be updated to expand URNs in the EPSG and OGC name spaces. msLoadProjectionString() will add the +epsgaxis=ne parameter for URNs for GCS codes in the EPSG name space. New msAxisNormalizePoints() and msAxisDenormalizePoints() will be added for converting between normalized (easting,northing) axis orientation and EPSG preferred (denormalized) axis orientation (sometimes northing,easting). These functions will scan the p->args[] list for the +epsgaxis=ne to decide. msOWSCommonBoundingBox() will be modied to use these axis denormalization function to denormalize axis ordering for EPSG GCS URNs. the WCS 1.1 GetCoverage call will use msAxisNormalizePoints() to x up orientation of request axes when needed. MapScript No changes to MapScript are anticipated. Backwards Compatibility No alterations to WCS 1.0 support are expected, and it is not expected that the mechanisms for specifying services metadata will be changed though it is possible a few metadata items used only in WCS 1.1 will be added. Documentation The WCS Server will be extended to discuss WCS 1.1 related issues.
631
Implementation Resources Implementation will be done by Frank Warmerdam with nancial support from Noetix Research Inc. and the Geoconnections program of the Canadian Government. Preliminary implementation is already operational in svn trunk, and work completion is anticipated by March 1st. Testing Tests will be added to msautotest/wxs for the WCS 1.1 protocol. Additional assistance with WCS 1.1 validation from other contributors would be welcome. Bug ID None Yet. Voting History FrankW(+1), AssefaY(+1), TomK(+1), DanielM(+1), PerryN(+1)
LAYER ... METADATA "ows_http_cookie" "forward" # This will forward the cookie sent to MapServer END ...
The user can also pass direct cookie values instead of the cookies behing passed to MapServer. To pass multiple cookies, use the following syntax:
LAYER ... METADATA "ows_http_cookie" "cookie1=my_value; cookie2=myvalue; " # This will forward the metadata value END ...
By using the metadata conguration, a MapScript application will be able to forward a HTTP Cookie by setting the correct metadata. Currently only WMS and WFS code will use this since they are the only places where MapServer request an outside webserver. Implementation Issues It was pointed out during the RFC review period that passing and storing the cookie data using an http_cookie_data metadata is a poor use of MapServers metadata mechanism. Since MapServer currently lacks a mechanism to associate application state information to a mapObj, there is currently no better mechanism in place to store the cookie data received from the client and pass it to the rendering code that calls the remote WMS. Due to lack of a better solution, for the time being we will use the http_cookie_data metadata as proposed in this RFC, with the knowledge that this is a poor use of metadata and that we as soon as a better mechanism is in place to store and pass application state in a mapObj then this metadata will be deprecated and replaced by this new mechanism. Developers of MapScript applications setting this http_cookie_data metadata should be aware of this and be prepared to change their code in future revisions of MapServer. Another issue is that no encoding currently is planned to be made with the http_cookie_data metadata. Poorly formated metadata could break the HTTP header of a request. If it is found that Curl doesnt encode the cookie value, only character with a value between 32 and 126 (printable ascii characters) will be allowed. Modications to the Source Code The HTTP Cookie data will need to be stored in cgiRequestObj in a new member variable to be able to pass it to the maple. If HTTP Cookies are present the cookies will always be stored there. The mapserv.c main function will then be responsible of the HTTP Cookies in the maple just after the loadMap() function and before msOWSDispatch() if the ows_http_cookie metadata is set. The WMS and WFS code will set the newly created variable in the httpRequestObj when it prepares the URL for a server request. The WMS/WFS msPrepareWMSLayerRequest function will check for the ows_http_cookie metadata in the layer and the map objects. If the value is set to forward, the content of the http_cookie_data metadata will be forwarded as HTTP Cookie to the WMS/WFS server. Curl as an option in the curl_easy_setopt() function when doing a request called CURLOPT_COOKIE to send cookies with a request.
633
MapScript By storing the HTTP Cookie data in a maple metadata MapScript will be able to use this new functionality. Heres an example of a PHP/MapScript use of HTTP Cookie:
foreach($_COOKIE as $szKey => $szValue) { $szHTTPCookies .= "$szKey=$szValue; "; } $oMap->setMetadata("http_cookie_data", $szHTTPCookies); $oMap->setMetadata("ows_http_cookie", "forward"); $oMap->draw();
File Affected
cgiutil.h cgiutil.c maphttp.c mapows.h mapserv.c mapwmslayer.c mapwfslayer.c (add http_cookies in cgiRequestObj) (read and store the http cookies data in cgiRequestObj) (send cookies with the request via curl option) (add http_cookies to httpRequestObj) (store cookies in mapfile metadata) (set cookies in httpRequestObj) (set cookies in httpRequestObj)
Backwards Compatibility None. Bug ID http://trac.osgeo.org/mapserver/ticket/2566 Voting History Adopted on 2008/04/01 with +1 from FrankW, DanielM, TomK and AssefaY, and +0 from JeffM and PericlesN.
14.6.42 MS RFC 43: Direct tile generation for Google Maps and Virtual Earth API
Date 2008/04/08 Author Paul Ramsey Contact pramsey at cleverelephant.ca Last Edited 2008/05/02 Status Adopted on 2008/04/29 - Completed Version MapServer 5.2 Id $Id: ms-rfc-43.txt 8278 2008-12-23 21:34:31Z hobu $
634
Overview Providing a simple access API in the mapserv CGI can make using Mapserver with the Google Maps and Virtual Earth user interfaces dramatically easier for new users. Technical Solution The GMaps API denes a GTileLayer which can be used as an overlay or base map. The GTileLayer supports a GTileLayerOption, tileUrlTemplate, which allows the TileLayer to be accessed using a simple URL pattern that substitutes Googles x/y/z coordinates into the request:
http://host/tile?x={X}&y={Y}&z={Z}.png
See http://code.google.com/apis/maps/documentation/reference.html#GTileLayer For MapServer, the simple URL pattern will be:
http://host/cgi-bin/mapserv?map=/the.map&layers=foo,bar&mode=tile&tilemode=gmap&tile={X}+{Y}+{Z}
The change will add in new handling in the loadForm function for the mode, interface, version, x, y and z parameters. Like the WMS interface, GMaps API will require PROJ to be specied, and the existence of PROJECTION denes for all layers being accessed. Google X/Y/Z coordinates will be converted to spherical mercator coordinates and fed into the extent. The result will make a Google-with-Mapserver map as easy as:
var url = "http://host/cgi-bin/mapserv?"; url += "map=/the.map&"; url += "layers=parcels&"; url += "mode=tile&"; url += "tilemode=gmap&"; url += "tile={X}+{Y}+{Z}"; var myLayer = new GTileLayer(null,null,null, { tileUrlTemplate:url, isPng:true, opacity:0.5 } ); var map = new GMap2(document.getElementById("map")); map.addOverlay(new GTileLayerOverlay(myLayer));
635
A request with tilemode of gmap implies the following: The tile parameter will be of the form: x y zoom The output CRS will be set to spherical mercator (EPSG:900913) The service bounds be global in extent. The top zoom level (0) will have 1 tile. The zoom levels will run from 0 upwards The y axis of the tile coordinates will run from top to bottom The x axis of the tile coordinates will run from left to right The output tiles will be 256x256 in size Each zoom level will be related to parent and children by powers of two A request with tilemode of ve implies the following: The tile parameter will use the VE tile numbering scheme, http://msdn.microsoft.com/en-us/library/bb545006.aspx for more details. The output CRS will be set to spherical mercator (EPSG:900913) The service bounds be global in extent. The top level will have 4 tiles (0, 1, 2, 3). The output tiles will be 256x256 in size Each zoom level will be related to parent and children by powers of two The MapServer tile mode API will not explicitly attempt to address issues of meta-tiling or cross-tile labeling. However, the following steps will be taken to try to minimize these issues: Future phases will render into a target slightly larger than the tile and then clip off the extra border pixels. MapScript Implications None. This affects only the CGI interface and mapserv CGI. Files Affected
mapserv.c maptile.c <new> maptile.h <new>
See
Documentation will be updated to reect the new feature Mapserver CGI Reference Mapserver Tile HOWTO <new> Test suite will be updated to exercise the new features Frank Warmerdam has volunteered to do this
636
Backwards Compatibility Issues None. This functionality is net new and requires no changes to existing behavior. Bug ID http://trac.osgeo.org/mapserver/ticket/2581 Voting History Adopted on 2008/04/29 with +1 from SteveL, DanielM, JeffM, SteveW, TomK, PericlesN and AssefaY. References http://msdn.microsoft.com/en-us/library/bb545006.aspx http://code.google.com/apis/maps/documentation/reference.html#GTileLayer http://www.worldwindcentral.com/wiki/TileService
duplication in cases where a maple contains similar layers and the same data validation pattern applies to all. The logic would simply be: look for validation pattern in layer, if not found then look for validation pattern at map level, if not found then no modications are allowed.
VALIDATION data my pattern filter another pattern ... END
The validation would only be invoked if the token source is a URL. Maple le or string-based processing would be unaffected. An example of how this would work can be seen in maple.c near line 2683 with the DATA/DATAPATTERN parameters. Files Affected maplexer.l: all parameters (a few will never be modiable, like VALIDATION) will be changed to be recognized in the URL_VARIABLE lexer state; VALIDATION token needs to be added maple.h: add VALIDATION token maple.c: all non-value checked parameters will require regex validation before changes will be allowed via URL; recognize validation token; write validation hash with maple mapserv.c: update code for runtime substitution and qstring validation to check the validation hash as well A complete list of parameters affected will be attached to this document in the post-implementation notes below. Maple Changes New VALIDATION token will be recognized. MapScript Changes None. MapScript already has a general class for hashTableObj management. Backwards Compatibility Issues The parameters DATAPATTERN and TEMPLATE pattern will become deprecated though. The objects in question (LAYER and CLASS) already contain validation blocks that can be used for this. URL runtime substitution and qstring validation are currently supported through metadata, This would become deprecated as well. The runtime variables and the word qstring can be used as keys in the validation block instead. Post-Implementation Notes A HowTo will be developed that covers this topic and run-time substitutions. Bug ID http://trac.osgeo.org/mapserver/ticket/2699
638
CENTER/ORIGIN [x y]
Denes the centre of the symbol using decimal pixels (x axis increasing to the right, y axis increasing downwards). Is used for placing a point symbol on the map or on a decorated line Denes the center of rotation if an ANGLE is specied for point symbols. Default value is the centre of the symbols bounding box. Applies to TYPE ellipse, vector, pixmap, truetype.
Modes of operation
DEFAULT reference direction to the right (east), counter-clockwise direction of rotation. CLOCKWISE reference direction to the right (east), clockwise direction of rotation. COMPASS reference direction to the north, clockwise direction of rotation (compass directions).
Behavior
For symbols of Type HATCH, this is the angle of the hatched lines. For points, this species the rotation of a symbol around its dened CENTER. For point symbols on lines, this species the rotation of the symbol relative to the direction of the line (0 - the symbols x-axis is oriented along the line), or a xed compass direction for the symbols orientation (COMPASS). For polygon lls this species the rotation of the pattern given by its dening symbol. For its use with hatched lines, see Example#8 in the SYMBOL examples.
640
polygon ll symbols
give hatches and vector lls a stable geographical coordinate origin (0,0) to better support tiling and continuous rendering of neighbouring polygons
labeling
TODO Keywords moved from SYMBOL to STYLE
more to come?
add MINSCALEDENOM/MAXSCALEDENOM parameters to styleObj this would allow doing things like removing outlines or the hollow portions of tube line work based on scale. add LABELMETHOD to layerObj (or perhaps just method to labelObj?) this would allow users to choose label placement algorithms that meet their needs. For example, in D2 below improving label placement will come with a reduction in performance. In some situations simply using a shapes bounding box center is perfectly adequate. The default would be the improved placement in D2. 14.6. Request for Comments 641
add LABEL to layersObj so that a default can be dened for all classes (sort of like templates). A class label would take precedent. add OUTLINEWIDTH to styleObj eg for drawing road lines with a cached outline It is currently impossible to have scale dependant road networks with a xed width outline, this addition will remedy this. This would also be a shorthand to be able to specify an outline for linear networks, without having to specify two style blocks. add TYPE to styleObj for line and polygon types modies how the current shape is interpreted. Applies to line and polygon layers (for now: any ideas for applying this to point layers?) TYPE BBOX : use the style to render the bounding box of the current shape TYPE CENTROID : render a single pointObj at the centroid of the feature TYPE VERTEXES : render a pointObj at each vertex of the shape. - how to specify angle (follows line direction, xed, ....) - need to specify a way to ignore the start and/or end points of the feature TYPE START/END : render a pointObj at the start/end of the feature. would be used for example to add arrowheads to lines - default angle is direction of rst/last segment Files Affected maplexer.l: C4, C5 mapgd.c: B1, C2, C3, C4 mapagg.cpp: B1, C2, C3, C4 maple.c: B1, C1, C2, C3, C4, C5, C6, D1 mapdraw.c: C1, C5, C6, D1 mapprimitive.c: C5, D2 Bug IDs Individual modications will be tracked with their own tickets which will be listed here. B1: http://trac.osgeo.org/mapserver/ticket/2766
642
Have a gallery that works better Move off of UMN computing and integrate within OSGeos infrastructure Make it easy for folks to nd the docs Some people have complained that it is difcult to nd documents on the website unless you know the exact place in the hierarchy. Because our mind-reading webpage nding software isnt quite up to snuff, the new website should make it easy enough for documenters to organize and reorganize information in logical and interlinked ways. It seems the strictly-enforced hierarchy causes more problems than it solves in this regard. Stay the out of developers way The current website is quite slow. Slow to edit, slow to view, and slow to change. Theres lots of pointing and clicking involved to do the simplest tasks. So much so, that folks will only update the website when they absolutely have to. Developers have subversion access by denition of being developers. They should be able to edit the website through text les in subversion and have the website be updated automatically. Allow documenters to get their job done The website fails documenters in a number of ways, but the most important failure is the inability to tie documents to specic MapServer versions. A new iteration of the MapServer website must allow this to happen. Luckily, we already have tools to version documents (our source code repository), so we should just leverage that to accomplish this goal. Allow limited user-contributed information in the form of wiki pages From time to time, users do contribute signicant documentation describing how to accomplish a particular task with MapServer. Our new infrastructure must still allow this to happen without too much friction. MapServers Trac instance already provides this capability (along with single-signon), and we can take advantage of it to accomplish this goal. Have a gallery that works better The OpenLayers Gallery works better than the current MapServer gallery, and it works much easier from a management/administrative standpoint. A benet of using OpenLayers gallery software is both projects can enjoy the benets of improving it, which is not possible with the current MapServer gallery. Move off of UMN computing and integrate within OSGeos infrastructure Just recently (Sept 15th Sept 16th, 2008), the server that houses the site was having power supply unit issues (they have been resolved), but it is a fact that the site is running on a very old Solaris machine that could be decommissioned at any point without much of a heads up. MapServer no longer brings grant monies to the UMN, and while they have been gracious to continue hosting us, we need to move somewhere where we have more control over our destiny. Reasons like this are exactly why OSGeo exists, there are resources there for us to use, and we should move the website there at the same time.
644
Implementation We are going to unabashedly rip off OpenLayers web infrastructure. This includes the gallery, static website, and Trac integration. OpenLayers web infrastructure meets a lot of the goals above, it stays out of the way of the developers and does a good job of serving the users documentation needs. The mechanics of how this transition will take place are described below: 1. Migrate everything in http://mapserver.gis.umn.edu/development to Trac and add redirects of /development to a landing page on the Trac wiki. 2. Migrate everything in http://mapserver.gis.umn.edu/community to Trac and add redirects of /community to a landing page on the Trac wiki. 3. Migrate everything in http://mapserver.gis.umn.edu/download to Trac and add redirects of /download to a landing page on the Trac wiki. 4. Stand up an Apache instance for MapServer on OSGeo infrastructure. Howard will coordinate with OSGeos System Administration Committee to get this done. Our new URL will be http://mapserver.osgeo.org 5. Stand up an instance of the OpenLayers Gallery at http://mapserver.osgeo.org/gallery and port over our existing gallery entries. Any culling of these entries must be done by some volunteer effort. 6. Migrate existing documents (notice of when to be given) in /docs to Subversion http://svn.osgeo.org/mapserver/trunk/docs/ All subsequent editing on major MapServer documents from that point forward should happen in svn, and the documents on the Plone website will be considered frozen. 7. Stand up a cron process that takes the docs in Subversion and generates a static HTML website from them. This website will be what exists at http://mapserver.osgeo.org
645
globally for a map le As well, the option to fail on a missing layer will be added to the WMS client code, which currently defaults to ignore on a missing layer. All changes will preserve the current default behavior in cases where new behavior is not requested by the user: missing data in tileindexes will continue to cause failure and missing WMS layers will continue to be ignored, unless Mapserver is compiled with ignore-missing-data. A map-level conguration option will be added, CONFIG ON_MISSING_DATA [ACTION], with the following valid actions: IGNORE, LOG, FAIL. The default map-level behavior will be FAIL, unless MapServer is compiled with ignore-missing-data, in which case it will be LOG. This will preserve the current behavior for all legacy maples and compile set-ups. In the case of LOG behavior, the logging will only occur if the maple is set up for logging: DEBUG is set and MS_ERRORFILE is set. Documentation must note that DEBUG and MS_ERRORFILE need to be set. At the same time, this ticket (#2722) can probably be tracked down and resolved. Mapscript Implications None. Files Affected
mapshape.c mapogr.c mapraster.c maprasterquery.c
Documentation will be updated to reect the new feature Mapserver Maple Reference Backwards Compatibility Issues None. Legacy maples and compile setups should retain existing behavior in the presence of this new code. Bug ID http://trac.osgeo.org/mapserver/ticket/2785 Voting History N/A References N/A
646
to treat the underlying geometry as a point rendered on the rst vertex current feature. The directive to activate this behavior is the GEOMETRYTRANSFORM keyword, that initially belongs to the STYLE object. Further developments could be to enable the keyword at the LAYER level. Usages of this parameter include drawing bounding boxes of underlying geometries, or adding arrowheads/tails to lines. Further developments would allow complex expressions to be passed to the keyword, allowing nested transformations to the underlying geometry, eg:
GEOMETRYTRANSFORM "difference([geom],buffer([geom],10))"
Detailed functionality The GEOMETRYTRANSFORM keyword initially accepts a shortcut version of these parameters : bbox : render a shapeObj representing the bounding box of the underlying geometry. start/end : render a point symbol at the rst/last vertex of the underlying geometry. By default, the symbol is oriented to match the orientation of the corresponding geometry segment. This would be used to add arrowheads/tails to linestrings. vertices : render a point symbol at each vertex of the geometry. The default orientation matches the half angle of the corresponding segments. The start and end vertices are not included in the transformation. These transforms are not initially implemented, but could be supported in the future: buffer([geom],distance) : render a shapeObj representing the buffered geometry. distance species the buffer distance, in layer units. 14.6. Request for Comments 647
centroid([geom]) : render a pointObj at the location of the centroid of the geometry labelpoint([geom]) : render a pointObj at the location of the at the point where the geometry will/would be labelled. convexhull([geom]) simplify([geom]) Implementation Details Apart from the parsing and internal storage of which type should be used, the modications of this RFC only affect the high-level rendering functions in mapdraw.c . There are three main modications: AUTO is added to the ANGLE parser for the STYLE block. styleObj has an autoangle member added accordingly. inside msDrawVectorLayer, a copy of the shape before being clipped by the current extent must be kept, as the whole shape must be used for all but the VERTICES type. Then, when looping through the different styles that can be applied, we switch off to the type-specic function if a GEOMETRYTRANSFORM keyword is set. inside mapgeomtransform.c, the type-specic drawing function is added. Depending on the current style type, it either computes a new shape from the original shape (types bbox, convexhull or buffer) and passes it to the msDrawShadeSymbol, or calls msDrawMarkerSymbol for points of the original shape (types start, end, vertices, centroid) after having adjusted the orientation accordingly. Affected Files mapdraw.c maplexer.c/.l maple.c mapserver.h mapgeometrytransform.c is added, for the parsing of the transform expression, the transformation itself, and the calling of msDrawMarkerSymbol / msDrawShadeSymbol functions Limitations For line layers, the transformations do not t in with the current cache mechanism that draws the rst style of each class in a rst pass for all shapes, and the remaining styles in a second pass. MapScript implications Getters and setters will have to be added to the different mapscripts. A possible enhancement could also be to expose the transformation function to MapScript. Documentation completed 648 Chapter 14. Development
Backwards Incompatibility Issues none expected. Bug ID http://trac.osgeo.org/mapserver/ticket/2825 Voting History Vote completed on 2008/12/08: +1: Lime, Szekeres, Woodbridge, Nacionales, Morissette +0: Nicoletti
649
OUTLINEWIDTH on line layers It is currently impossible to draw a outlined line with a scale-dependant width. We propose to add the OUTLINWIDTH keyword to the STYLE block, that indicates the width in pixels that should be rendered around the main line color. The implementation of this lies in mapdraw.c. When a lines style block has an outlinewidth, the underlying shape is actually drawn twice: once with its width adapted to account for the outlinewidth, and once normally. The current caching mechanism for lines is preserved. example usage:
LAYER TYPE LINE SIZEUNITS meters CLASS STYLE COLOR 255 0 0 OUTLINECOLOR 0 0 0 OUTLINEWIDTH 1 WIDTH 25 #this is in meters (ground units) MINWIDTH 1 #minimal width (in pixels) for far zoomed maps MAXWIDTH 20 #maximal width (in pixels) for close zoomed maps END END END
whatever the map extent or scale, this line layer would always be rendered by a red line with a one pixel black outline. http://trac.osgeo.org/mapserver/ticket/2865 add LABEL to layersObj Note: This feature has not yet been implemented so that a default can be dened for all classes (sort of like templates). A class label would take precedent. http://trac.osgeo.org/mapserver/ticket/XXX Affected Files maple.c mapdraw.c (outlinewidth on lines, scale on styleobj) mapserver.h maplabel.c (scale on labels) Documentation The documentation for the keywords will be aded to the main maple syntax docs. Mapscript Getters and Setters for the keywords will be added for mapscript availability
650
Backwards Incompatibility None Expected Comments from Review period the LABELMETHOD proposal is withdrawn fractional values also for pattern,gap, offset: a good candidate for 6.0 (when pattern and gap would be moved to the styleObj?) there was concensus for adding parametered scaling, usefull for thematic mapping (eg size proportional to a feature attribute) by allowing simple expressions, eg SIZE ( 18 + [poptotal] * (( 43-18)/(5000-30000)) ) or by adding pseudoitems at the layer level:
PSEUDOITEM mySize (mrange([itemname], mininput, maxinput, minoutput, maxoutput)) myText (commify(round([itemname], 2)) + ac) END LABELITEM myText CLASS STYLE COLOR 255 0 0 SIZE [mySize] END LABEL ... END END
this enhancement will be addressed in a specic rfc. Voting History +1 : SteveW, UmbertoN, TamasS, SteveL, DanielM (,AlanB)
651
Overview This RFC proposes the addition of an Opengl Rendering module to MapServer for faster rendering of images. Presently MapServer supports AGG rendering for high quality anti-aliased images. Although AGG is capable of high quality images, and is signicantly faster than GD rendering, it is still not fast enough to suit desirable use cases such as live on-demand rendering. Opengl is seen as a solution that can provide high performance rendering by making use of hardware specially designed for real-time rendering. Current Opengl prototypes are capable of rendering maps an order of magnitude faster than AGG with similar image quality. Technical Solution The Opengl rendering module interface and path will be very similar to the current AGG rendering module. Like AGG, the Opengl module will make use of GD for I/O of the results. However due to the nature of Opengl there are a few key implementation differences that are worth noting. Opengl can make use of pre-rendered textures. All symbols can be pre-rendered and stored as an Opengl texture, when they are used in rendering a map, the rendered texture is simply copied onto the image buffer with transformations. This can hugely increase the performance of complex and heavily repeated symbols, such as train tracks, because not only do they need to be only rendered once, Opengl also handles the repetition and transformations which it has been heavily optimised for. Labels also benet from this method greatly, as an entire alphabet can be pre-rendered and stored as textures. When a curved label is to be drawn, the Opengl module simply places the rotated textures of the characters. Pre-rendered textures of symbols can also be shared between different map rendering instances. For this reason it is suggested that the rendering path be modied slightly, such that when a maple with opengl rendering is rst loaded, all the symbols are pre-rendered and stored on the map object. This drastically increases the performance of batch rendering. Another notable difference between AGG and Opengl is that Opengl is incapable of rendering into main memory, and instead renders into a inaccessible buffer in video memory. This means the image must be rendered into video memory in OpengGL, then copied to the GD image buffer before saving the result. C API Changes As the Opengl module follows very closely to the AGG implementation, very little change has to be made to the core of MapServer. Minor changes are made to the following les to add a rendering path for Opengl: mapdraw.c mapdrawgdal.c maperror.c maplegend.c mapoutput.c mapraster.c mapresample.c maputil.c No new functionality is added to these les, rather just else-if blocks. The bulk of Opengl functionality will be found in mapogl.cpp. 652 Chapter 14. Development
Issues The guts of opengl rendering occurs inside of opengl drivers. Opengl drivers vary from hardware and operating system, and the rendering techniques vary with them. What this means is that maps rendered on different computers can have different results, such as color shades, anti-aliasing quality and performance. Although Opengl is cross platform, each operating system has a different method of setting up an Opengl context to render into. Currently we have an implementation for pre-vista windows. Documentation TBD Backwards Incompatibility No issues expected. Bug ID Not assigned.
Technical Solution It was decided that for the time being we should develop a XML schema and a XSLT to convert from XML to text maple. If the new XML format takes off then we may consider implementing support for it directly in MapServer in a future release. Maples An example of XML maple layer denition (prototype):
<Layer> <name>popplace</name> <type>POINT</type> <debug>5</debug> <status>ON</status> <Metadata> <item name="DESCRIPTION">Cities</item> <item name="TEST">TESTING</item> <item name="RESULT_FIELDS">NAME</item> </Metadata> <data>popplace</data> <labelItem>Name</labelItem> <classItem>Capital</classItem> <Class> <name>Cities</name> <expression>1</expression> <template>ttt_query.html</template> <symbol>2</symbol> <size>8</size> <Label type="TRUETYPE"> <colorAttribute>[COULEUR]</colorAttribute> <font>sans</font> <angle>0</angle> <size>8</size> <outlineColor red="255" green="255" blue="255"/> </Label> <color red="0" green="255" blue="0"/> </Class> <Class> <name>Cities</name> <expression>/2|3/</expression> <template>ttt_query.html</template> <tolerance>5</tolerance> <Label type="TRUETYPE"> <colorAttribute>[COULEUR]</colorAttribute> <font>[FONT]</font> <angle>[ANGLE]</angle> <size>8</size> <outlineColor red="255" green="255" blue="255"/> <position>AUTO</position> <partials>FALSE</partials> </Label> <Style> <symbol>7</symbol> <size>6</size>
654
Future Enhancement In the future, some enhancement could be good to added: Special tags for all WMS options (including styles) Reusable xml block with ID Documentation TBD Backwards Incompatibility No issues expected. Bug ID http://trac.osgeo.org/mapserver/ticket/2872
655
Technical Solution There are a number of potential solutions: 1. One could cache the returned shapes in memory. While this wouldnt result in a true single-pass, you wouldnt have to go back to the original driver twice. However, it could lead to large memory consumption with even moderatelysized datasets. Multiple clients accessing services at the same time would only compound the problems. 2. Another solution would be fold much of the query pre- and post-processing code into the msLayerWhichShapes() and msLayerNextShapes() functions so that the access paradigm used in drawing layers could be used. Subsequent research has let us to conclude that a true single pass is not possible in some cases. For example, GML requires a result set envelope be written out before writing individual features. Theres no way to get that initial envelope without a pass through the features. Its simply not worth the investment in time... 3. A nal solution would be to change how the msLayerGetShape() function behaves. We prepose changing the behavior of that function to provide random access to a result set (as dened by msLayerWhichShapes()) rather than the entire data set. This removes most of the overhead currently incurred by referencing the results already returned by the data driver in the intial query. Under this last solution data drivers would need to do two things: update the population shapeObj index property (long int) with a value that will allow msLayerGetShape() to randomly access a result update the driver-specic version of msLayerGetShape() to retrieve a shape from the results created in msLayerWhichShapes() The query functions would need to: not close the layer when nished with a query (we assume that users will want to do something with the results) allow msLayerWhichItems() to retrieve ALL items so that the retreived shapes are presentation-ready (draw, template, or ...) Backwards Compatability Issues This solution preserved 95% of the current functionality. Because we are proposing to change the behaviour of msLayerGetShape() to be specic to query processing. While this has always been the intentional use, theres nothing to stop a user from using that method (in MapScript) in other ways. A typical MapScript query and process results operation would be unchanged. One casualty would be the query save/read functions. Since the processing of a set of results would be specic to dataset result handle it wont be possible to get back to a result once a layer is ultimately closed. Files Impacted driver les: changes to shape fetching code maptemplate.c: dont open/close a layer mapgml.c: dont open/close a layer mapdraw.c: dont open/close a layer IF if drawing a query map maputil.c: refactor msLayerWhichItems() 656 Chapter 14. Development
657
Voting History Adopted on 2009/03/12 with +1 from DanielM, UmbertoN, TomK, SteveW, TamasS, HowardB, AssefaY, PericlesN, JeffM and SteveL.
658
struct renderer{ // configuration parameters // image creation functions // raster handling functions (input and output) // image saving functions (only for the renderers that cannot export a // raster format) // low level rendering functions lines and polygons symbology vector // ellipse pixmap truetype text handling label size calculation label // rendering // // // // support for using an image cache for symbology creation of a tile representing a cached symbol vector ellipse ... placement of a cached tile at a point using a tile as a fill pattern on lines and polygons
Conguration parameters
Each renderer can inform the higher level calling code of what functionality it supports or implements. This will primarily allow us to support vector and raster renderers. More details on each conguration parameter will be given when appropriate in the rest of this document.
Note: Renderer specic creation options would be extracted by each renderer from the outputFormatObj passed to it. (This would be used eg by the PDF renderer for page layout options).
659
// pointers to the start of each band in the pixel buffer unsigned char *a,*r,*g,*b; // step between one component and its successor (inside the same band) unsigned int pixel_step //step between the beginning of each row in the image unsigned int row_step; // pointer to the actual pixels (should not be used by the high-level // code) // TODO: as this memeber is actually private, it should probably be // a void* so that any internal representation can be used unsigned char *pixelbuffer; } rasterBufferObj;
A renderer must provide a function to initialize a rasterBuffer where the pixel alignment and the order of the bands best ts its internal representation of a raster array.
void (*initializeRasterBuffer)(rasterBufferObj *buffer, int width, int height);
Handling Raster Layers Depending on the renderers capabilities, there are two possibilities here, that are determined by the supports_pixel_buffer parameter: if the renderer supports a pixel buffer, then the raster layer code is given a handle to the memory buffer used by the renderer, and direclty sets individual pixels where needed. Such a renderer will thus implement a function to export a rasterBufferObj pointing to its internal pixel buffer:
void (*getRasterBuffer)(imageObj *img,rasterBufferObj *rb);
if the renderer does not use an internal representation that can be directly lled by the raster layer code, it must provide two functions that will allow the higher level code to merge the created raster:
void (*mergeRasterBuffer)(imageObj *dest, rasterBufferObj *overlay, double opacity, int dstX, int dstY)
TODO: exporting to a buffer for mapscript getBytes() 660 Chapter 14. Development
Lines simple stroke: is passed a pattern (dashes) and line style (caps, joins) pattern ll: is passed a tile
void (*renderLine)(imageObj *img, shapeObj *p, strokeStyleObj *style); void (*renderLineTiled)(imageObj *img, shapeObj *p, void *tile);
Markers
void (*renderVectorSymbol)(imageObj *img, double x, double y, symbolObj *symbol, symbolStyleObj *style); void (*renderPixmapSymbol)(imageObj *img, double x, double y, symbolObj *symbol, symbolStyleObj *style); void (*renderEllipseSymbol)(imageObj *image, double x, double y, symbolObj *symbol, symbolStyleObj *style); void (*renderTruetypeSymbol)(imageObj *img, double x, double y, symbolObj *symbol, symbolStyleObj *style); void (*renderTile)(imageObj *img, void *tile, double x, double y, double angle);
Labels and Text label size calculation: If passed an advances pointer, also calculates individual advances for each glyphs (for anlge foloow text)
int (*getTruetypeTextBBox)(imageObj *img,char *font, double size, char *string, rectObj *rect, double **advances);
661
void (*renderGlyphs)(imageObj *img, double x, double y, labelStyleObj *style, char *text); void (*renderGlyphsLine)(imageObj *img,labelPathObj *labelpath, labelStyleObj *style, char *text);
Tiles and Caches For some symbols and renderer combinations, it might be bencial to use a cache so as not to have to render a complicated symbol over and over again. This behavior would probably have to be deactivated when using attribute binding (on size, angle, color...) as there would be too many cache misses and no real gain. TBD: use a renderer specic format for a tile (passed back as a void*), or would a simple imageObj created by normally by the renderer sufce ? Second solution is much simpler as wed use the same functions for rendering a symbol than for rendering a tile. First solution is more exible, as the renderer can cache anything. Miscelaneous functions
void (*transformShape)(shapeObj *shape, rectObj extend, double cellsize);
Cleanup functions
void (*freeImage)(imageObj *image); void (*freeSymbol)(symbolObj *symbol); void (*freeShape)(shapeObj *shape);
Note: The freeSymbol and freeShape functions are added here as we will be adding a void* pointer to the symbolObj and shapeObj objects where a renderer can store a private cache containing an implementation specic representation of the object. High Level Usage of the rendering API
Image Creation
nothing special. just pass on to the renderer.
Image Saving
Depending on whether the renderer can export a raster buffer or not: supported: get a raster buffer, eventually apply formatoptions (quantization) and pass the buffer to the MapServers saving functions unsupported: call the renderers saving function
662
Raster Layers
MapServers Raster layer handling will be modied so that it can write to a rasterBufferObj and not only to a gdImage. Note: TODO (FrankW) add some detail here about the changes induced here
if(renderer->supports_pixel_buffer) { rasterBufferObj buffer; renderer->getRasterBuffer(img,&buffer); msDrawRasterLayer(map,layer,&buffer); } else { rasterBufferObj buffer; renderer->initializeRasterBuffer(&buffer,width,height); msDrawRasterLayer(map,layer,&buffer); renderer->mergeRasterBuffer(img,&buffer,0,0); renderer->freeRasterBuffer(&buffer); }
Line Rendering
simple stroke: call the renderer directly marker symbols:
663
compute positions and orientations along the geometry render a marker symbol with the renderers marker functions for each of these positions. It probably isnt a good idea to use a tile cache if the symbols have to follow line orientation, as rotating a cached tile will produce poor results. pattern: create the patterns tile (with the renderers marker functions) pass the tile to the renderer
Polygon Rendering
simple ll pattern ll: create the pattern tile eventually cache the tile for future use on another geometry pass the tile to the renderer hatch ll: - compute the lines corresponding to the hatch - use the renderers simple stroking function
Text Rendering
Nothing special to add here, except that the basic preliminary tests (if the font is dened, or if the string to render is NULL) and the lookup of the system path of the truetype font le will be done once by the high level code before calling the renderer drawing function. Note: Raster fonts will not be supported (at least in a rst phase) by this rendering API. Only truetype fonts are implemented. Image I/O Currently all image I/O is done through the GD library. To raise this dependency, the RFC proposes to have mapserver implement image loading and saving by directly interfacing the libpng / libjpeg / giib libraries. The corresponding code will be added to a new le mapimageio.c, and will produce or read rasterBufferObjs. These functions will implement the formatoptions that are currently supported. Adding new formatoptions would be done by adding the code to these i/o functions, and would thus add the support for all the renderers that use this rendering API architecture: jpeg: quality: 0 - 100 png: interlacing: will be set to OFF by default, as the creation is costlier, produces heavier images, and is incompatible with TileCaches metatiling functionality. compression: could be added to select the quality of zlib compression quantization: produce palette-based pngs from rgb or rgba imagemodes. palette: produce palette-based pngs given a precomputed palette. Further enhancements could include automatically producing a palette by looping through the input maple to extract the colors and ensure they end up in the nal image (this would only be supported for RGB, not RGBA) 664 Chapter 14. Development
gif: TBD Note: The initial implementation of this RFC will not include support for writing GIF images. Note: The initial implementation of this RFC will not include image loading functions by direct usage of the libjpeg/libpng/giib libraries. It will instead fallback to GD loading and convert the created gdImage to a rasterBuffer. This can be added in a second phase as it is lower priority, and does not induce a major architectural change. Miscelaneous
Legend
The legend rendering code will have to be refactored, as it currently produces a gdImage. Legend rendering will be handled like a normal imageObj. Note: TODO: embed mode is problematic. If postlabelcache is on, then the created imageObj can easily be added to the main image using the renderTile function (for the renderers that support it. the others will probably have noe embedded legend support) If postlabelcache is off we have a problem, as the created legend is passed as a pixmap symbol to the main map rendering. This is incompatible with the vector renderers, as the imageObj they have created isnt an array of pixels.
Scalebar
TBD
Reference Map
TBD. Should we even still be supporting this ? Affected Files maprendering.c , mapimageio.c, mapcairo.c (added) maple.c (defaults, and keywords moved from symbolObj to styleObj) mapoutput.c (renderObj creation) mapdraw.c (msDrawXXX functions moved to maprendering.c) mapserver.h .... lots more 14.6. Request for Comments 665
Documentation No end documentation needed aside from the migration guide. Mapscript TBD Backwards Incompatibility Symbology should be better behaved between renderers, but does imply some backwards incompatible changes in how some symbols can be rendered (although this can probably seen as xing bugs rather than backwards incompatibilities) reverse orientation of rotation for vector symbols. currently vector symbols are rotated in the opposite direction of the other symbols. for line geometries , the given pattern (dashes...) will be scaled by the actual width of the line. A dotted line will therefore be dened as PATTERN 1 1 END whatever the width of the line. More to come ? Comments from Review period Voting History
666
Technical Solution A new optional DEFRESOLUTION keyword will be added in the mapObj with a default value if 72 if not set. DEFRESOLUTION is the reference or default resolution for which all symbology sizes are dened in the maple. At rendering time, if RESOLUTION is set to something different from DEFRESOLUTION, then the symbology in the layer denitions will be adjusted by a factor corresponding to RESOLUTION/DEFRESOLUTION. More specically, this is done by multiplying the layer->scalefactor value by the resolution/defresolution ratio in msPrepareImage(). The following rendering parameters will be affected: size (symbols and labels) width (lines) The following rendering parameters which were not impacted by scaling in the past will also be xed to follow the scaling from now on: offsets (line, point, polygon) pattern (line) gap (line) outlinewidth (labels) shadowsize, background-shadow-size (labels) buffer around labels (collision) minfeaturesize, mindistance (labels) The case of outlinewidth for line styles is a bit different: it ignores the scalefactor so that we get a xed outline width no matter what we use for size units, but we want it to follow the resolution/defresolution factor. For this case the line drawing code will need to have a reference to the mapObj passed to msDrawLineSymbol() so that it can access the resolution and defresolution parameters and do the right thing. In the case of pixmap symbols, they will be scaled only if a size is set. If no size is set then no scaling happens. Usage example Example 1: Lets say weve got a maple that we use to produce a 400x400 pixels image for use on the Web, with both defresolution and resolution set to 72.
MAP ... RESOLUTION 72 DEFRESOLUTION 72 SIZE 400 400 ... END
In order to produce a 300dpi image for printing, the application code should request an image of 1667 x 1667 pixels (400*300/72=1667) and set resolution=300. MapServer will automagically scale all symbology sizes by a factor of 300/72=4.1667.
667
The new values of size and resolution for printing will likely be passed as URL parameters or set via MapScript in most applications, but for the purpose of this example, expressed in maple syntax then wed use the following mapObj settings for printing:
MAP ... RESOLUTION 300 DEFRESOLUTION 72 SIZE 1667 1667 ... END
Example 2: An application is using a maple developed for map.resolution=96 with MapServer 5.x. In order to take advantage of the new feature, one should set DEFRESOLUTION=96 in the maple, and at rendering time, setting RESOLUTION=300 will result in all symbology being scaled by a factor of 300/96=3.125. Backwards Compatibility Issues Existing apps or maples that set RESOLUTION to a value other than 72 without setting DEFRESOLUTION will end up with their symbology scaled. This change in behavior is more likely to be considered as a feature than as a bug in most cases, but in case this is a problem for an existing app then the x will be to simply add a DEFRESOLUTION to the maple which matches the resolution for which all maple classes and styles are dened. The rendering parameters listed above that did not follow scaling in the past will be xed to follow the scaling. Documentation notes In addition to documenting the new feature, a note should be added somewhere in the mapserver docs that as of this change, the size values will reect valid sizes (according to the SIZEUNITS settings, MS_PIXELS by default) only when the RESOLUTION is set to the default 72 or equal to the DEFRESOLUTION setting. Files Impacted mapserver.h: new defresolution member in mapObj maple.c, maplexer.l, etc: new DEFRESOLUTION maple keyword mapdraw.c: adjust scalefactor as needed in msPrepareImage() mapscript/php3/php_mapscript.c: expose new defresolution member Ticket Id http://trac.osgeo.org/mapserver/ticket/2948 Voting History No vote yet. Adopted on 2009/03/16 with +1 from DanielM, HowardB, SteveW, TamasS, PericlesN and AssefaY.
668
669
The rst line of the template le will automatically be stripped from the template and will not be included in the MapServer output. If the magic string is not found then the template will be rejected by MapServer. HTML template example:
<!-- MapServer Template --> <html> <head>...</head> <body> ... </body> </html>
MS_MAP_PATTERN Environment Variable The optional MS_MAP_PATTERN environment variable, set via mod_env or other web server equivalents, can be used to specify a Regular Expression that must be matched by all maple paths passed to the mapserv CGI. 670 Chapter 14. Development
If MS_MAP_PATTERN is not set then any .map le can be loaded. Example, use Apaches SetEnv directive to restrict maples to the /opt/mapserver/ directory and subdirectories:
SetEnv MS_MAP_PATTERN "^/opt/mapserver/"
MS_MAP_NO_PATH Environment Variable The optional MS_MAP_NO_PATH environment variable can be set to any value via mod_env or other web server equivalents to forbid the use of explicit paths in the map=... URL parameter. Setting MS_MAP_NO_PATH to any value forces the use of the map=<env_variable_name> mechanism in mapserv CGI URLs. If this variable is not set then nothing changes and the mapserv CGI still accepts explicit le paths via the map=... URL parameter. Example, set set MS_MAP_NOPATH and some maple paths in Apaches httpd.conf:
SetEnv MS_MAP_NO_PATH "foo" SetEnv MY_MAPFILE "/opt/mapserver/map1/mymapfile.map"
... and then calls the mapserv CGI must use environment variables for the map=... parameter:
http://localhost/cgi-bin/mapserv?map=MY_MAPFILE&mode=...
Backwards Compatibility Issues The MAP and SYMBOLSET keywords must be added to any maple and symbolset that did not contain them already. All MapServer templates must be updated to contain the MapServer Template magic string on the rst line. The new environment variables are optional and will have no impact on existing applications that dont use them. Files Impacted mapserver.h maptemplate.c mapserv.c Ticket Id Related security tickets: http://trac.osgeo.org/mapserver/ticket/2939 http://trac.osgeo.org/mapserver/ticket/2941 http://trac.osgeo.org/mapserver/ticket/2942 http://trac.osgeo.org/mapserver/ticket/2943 http://trac.osgeo.org/mapserver/ticket/2944
671
Voting History Adopted on 2009-03-26 with +1 from DanielM, TomK, PericlesN, JeffM, SteveW, AssefaY, SteveL and TamasS.
Table of Contents VIM Syntax General remarks Installation Folding Closing Remarks
General remarks vi (vim) resides in: /usr/share/vim/current (vim_root). Syntax denitions are in vim_root/syntax/*.vim les. Linking le types to extensions is done in vim_root/ftdetect/*.vim. (The the star denotes the extension and would be replaced with map to dene highlighting of MapServer cong les). Installation The installation process requires two steps: 1. Copy the map.vim syntax le to the syntax directory Copy map.vim to the vim syntax directory (on Suse: /usr/share/vim/current/syntax) 2. Register the syntax le in the custom letype directory If absent, create a new directory called ftdetect in vim_root (on Suse Linux: /usr/share/vim/current). Create a new le called map.vim in ftdetect according to the example shown below:
" MapServer config file au BufNewFile,BufRead *.map setf map
Now restart vim and open a map le .... 672 Chapter 14. Development
Folding
Introduction
Vim code folding can be an extremely handy way to simplify the task of editing complex MapServer maples inside the Vim editor. A Vim command le called map_fold.vim is attached to this document, which denes a folding mode for maples. This le also lives at http://iconocla.st/code/dot/map_fold.vim.
Installation
In Vim 6, you can copy map_fold.vim as-is to your $VIMROOT/ftplugin/ directory, and it should more or less work. To use locally, create a ~/.vim/ftplugin directory, copy map_fold.vim to it, and then add the following to your ~/.vimrc:
autocmd BufRead *.map set filetype=map
map_fold.vim is totally compatible with the map.vim syntax highlighter, and their combined use is even recommended.
Use
The Vim folding tutorial (at least the rst two or three sections) is highly recommended. The Vim folding reference may also be helpful.
Conclusion
Hope this helps! Please let me know if you nd it useful, or if you nd ways to improve it. Thanks! Closing Remarks The keywords are based on the TextPad Symbol Map_40.syn le contributed by Christopher Thorne, which can also be found on the MapServer utility page. I hope the le is somehow useful to anybody out there. If there are any questions or suggestions, please feel free to contact me.
673
674
CHAPTER
FIFTEEN
DOWNLOAD
15.1 Source
15.1.1 Current Release(s)
2009-4-22 mapserver-5.4.0.tar.gz Changelog
15.2 Binaries
15.2.1 Windows
OSGeo4W OSGeo4W is a binary distribution of a broad set of Open Source geospatial software for Win32 environments (Windows XP, Vista, etc). OSGeo4W includes GDAL/OGR, GRASS, MapServer, OpenEV, uDig, as well as many other packages (about 70 as of summer 2008). MS4W MapServer for Windows from MapTools.org. If you are a beginner looking for a complete MapServer solution on the Windows platform, or an advanced user looking to avoid compiling your own, this is what youre looking for. MS4W is a complete Web Server/MapServer/MapScript package. MS4W includes several avors 675
of MapScript (PHP, C#, Python, Java), and additional dlls for SDE and Oracle support. Several popular Web applications are also available for download, which are pre-congured for MS4W. FWTools A collection of Open Source GIS tools provided by Frank Warmerdam. This goes beyond your basic web mapping tools and include many useful utilities for creating, manipulating, and serving geo-spatial data.
15.2.2 Linux
FGS The FGS Linux Installer is a self-extracting le that will install MapServer with PHP/MapScript and all of their dependencies on your Linux system. It provides a stand-alone environment with all the required software (incl. Apache and PHP) to run PHP/MapScript webmapping applications. The bundled version of Apache can be congured to run on any port so it will not interfere with previous installations of Apache or other web servers on your system. DebianGIS DebianGIS provides a number of packages including MapServer, PostGIS, GDAL, QGIS, and GEOS. It sometimes lags a little bit behind the absolute latest release, but DebianGIS provides a solid integration environment for a giant slug of Open Source GIS software.
15.2.3 Mac OS X
Kyng Chaos William Kyngesburye provides excellent, up-to-date packages for Mac OS X. Most of the Open Source GIS stack is provided, including GEOS, GDAL, QGIS, and PostGIS.
676
CHAPTER
SIXTEEN
GLOSSARY
AGG Anti-Grain Geometry A high quality graphics rendering engine that MapServer 5.0+ can use. It supports subpixel anti-aliasing, as well as many more features. CGI Wikipedia provides excellent coverage of CGI. EPSG EPSG codes are numeric codes associated with coordinate system denitions. For instance, EPSG:4326 is geographic WGS84, and EPSG:32611 is UTM zone 11 North, WGS84. The WMS protocol uses EPSG codes to describe coordinate systems. EPSG codes are published by the OGP Surveying and Positioning Committee. A list of PROJ.4 denitions corresponding to the EPSG codes can be found in the le /usr/local/share/proj/epsg. PROJECTION describes how to use these in your Maple. See Also: http://spatialreference.org for a listing of spatial references and an interface to search for spatial references. Filter Encoding Filter Encoding is an OGC standard which denes an XML encoding for lter expressions to allow for spatial and attribute querying. See Also: WFS Filter Encoding FreeType FreeType is a font engine that MapServer uses for accessing and rendering TrueType fonts. GD GD is a graphics library for dynamic generation of images. It was the rst graphics renderer that was available for MapServer, and it is required by MapServer to operate. GDAL GDAL (Geospatial Data Abstraction Library) is a multi-format raster reading and writing library. It is used as the primary mechanism for reading raster data in MapServer. It is hosted at http://www.gdal.org/ GEOS Geometry Engine Open Source is a C/C++ port of the Java Topology Suite. It is used for geometric algebra operations like determining if a polygon is contained in another polygon or determining the resultant intersection of two or more polygons. MapServer optionally uses GEOS for geometric algebra operations. GML Geography Markup Language is an OGC standard which denes an abstract model for geographic features See Also: WFS Server GPX GPS eXchange Format is an XML Schema for describing GPS data. OGR can be used to transform and render this data with MapServer. Map Scale A treatise of mapping scale can be found on about.com. Maple Maple is the declarative language that MapServer uses to dene data connections, map styling, templating, and server directives. Its format is xml-like and hierarchical, with closing END tags, but the format is not xml.
677
MapScript MapScript is an alternative the the CGI application of mapserv that allows you to program the MapServer object API in many languages. Mercator Wikipedia provides excellent coverage of the Mercator projection. OGC The Open Geospatial Consortium is a standards organization body in the GIS domain. MapServer supports numerous OGC standards. See Also: WMS Server and WMS Time and WMS Client and WFS Server and WFS Client and WCS Server and Map Context and SLD and WFS Filter Encoding and SOS Server OGR OGR is the vector data access portion of the GDAL library. It provides access to a multitude of data formats. See Also: OGR OM Observations and Measurements is an OGC standard which denes an abstract model for sensor based data. See Also: SOS Server OpenLayers OpenLayers is a JavaScript library for developing draggable, slippy map web applications. Proj.4 Proj4 is a library for projecting map data. It is used by MapServer and GDAL and a multitude of other Open Source GIS libraries. Projection A map projection is a mathematical transformation of the surface of a sphere (3D) onto a 2D plane. Due to the laws of the universe, each type of projection must make tradeoffs on how and what features it distorts. Raster A raster is a rectangular grid of pixels. Essentially an image. Rasters are supported in MapServer with a layer type of RASTER, and a variety of formats are supported including GeoTIFF, JPEG, and PNG. Shapele Shapeles are simple GIS vector les containing points, lines or areas. The format was designed and published by ESRI and is widely supported in the GIS world. It is effectively the native and highest performance format for MapServer. See Also: Wikipedia SLD SLD is an OGC standard which allows for custom symbolization for portrayal of data. See Also: SLD SOS SOS is an OGC standard which provides an API for managing deployed sensors and retrieving sensor and observation data. See Also: SOS Server Spherical Mercator Spherical Mercator is a term used to describe the PROJECTION used by many commercial API providers. SVG Scalable Vector Graphics is an XML format that MapServer can output. It is frequently used in browser and mobile devices. See Also: SVG
678
SWF Shockwave Flash format that MapServer can generate for output. See Also: Flash Output SWIG Simplied Wrapper Interface Generator is the library that MapServer uses for generating the language bindings for all languages other than C/C++ and PHP. MapScript describes these bindings. Tileindex A tileindex is a Shapele or other Vector data source that contains footprints of Raster data coverage. MapServer can use a tileindex to render a directory of raster data. The tileindex allows MapServer to only read the data that intersects the requested map extent, rather than reading all of the data. See Also: Tile Indexes Vector Geographic features described by geometries (point, line, polygon) on a (typically) cartesian plane. WCS WCS is an OGC standard that describes how to systematically produce structured Raster cartographic data from a service and return them to a client See Also: WCS Server and WCS Use Cases WFS WFS is an OGC standard that describes how to systematically produce structured Vector cartographic data from a service and return them to a client. See Also: WFS Server and WFS Client WMC Web Map Context is an OGC standard which allows for sharing of map views of WMS layers in multiple applications. See Also: Map Context WMS WMS is an OGC standard that describes how to systematically produce rendered map images from a service and return them to a client. See Also: WMS Server and WMS Client
679
680
CHAPTER
SEVENTEEN
ERRORS
17.1 drawEPP(): EPPL7 support is not available
Error displayed when not using EPPL7 data. This is a confusing error for users who are not even trying to view EPPL7 layers (EPPL7 is a raster format). The full error displayed may appear as follows:
msDrawRaster(): Unrecognized or unsupported image format ... drawEPP(): EPPL7 support is not available.
17.1.1 Explanation
When MapServer tries to draw a layer, it will attempt to use all of the drivers it knows about, and the EPPL7 driver is the very last driver it will try. This means that if a layer fails to draw for any reason, you will see this error message. There are other possible instances when this error can appear however, here are a few: the server is returning either a ServiceException (which MapServer does not yet detect and parse into a reasonable error message) or it is returning an image in an unrecognized format ... for instance it is returning a GIF image and MapServer is not built to support GIF images. WMS servers often advertise multiple image formats but dont respect them in the getmap request.
681
Ogrinfo gives the les extent in the form of (minx, miny),(maxx, maxy), therefore the EXTENT in a maple would be:
EXTENT -2340603.750000 -719746.062500 3009430.500000 3836605.250000
Note: The EXTENT in a maple must be in the same units as the MAP -level PROJECTION.
682
Example Template:
<tr> <td>[lrn]</td> <td>[PIN]</td> </tr>
The [lrn] is a special keyword that indicates the resulting line number which starts at 1. [PIN] is the name of a feature attribute.
683
Note: This limitation was corrected in MapServer 5.0 and should no longer be a problem.
684
685
3. Set an environment variable through your web server. Apache has a SetEnv directive that can set environment variables. Add something like the following to your Apache httpd.conf le:
SetEnv PROJ_LIB C:/somedir/proj/nad/
686
The query feature requires a TEMPLATE object in the CLASS object of your LAYER denition. The value points to a html fragment using MapServer template syntax. Example MapFile fragment:
LAYER NAME "Parcel9" TYPE POLYGON STATUS OFF DATA "Parcels/area09_parcels" CLASS STYLE OUTLINECOLOR 128 128 128 COLOR 153 205 255 END TEMPLATE "templates/Parcels/area09_parcels.html" END HEADER "templates/Parcels/area09_parcels_header.html" FOOTER "templates/Parcels/area09_parcels_footer.html" END
Example Template:
<tr> <td>[lrn]</td> <td>[PIN]</td> </tr>
The [lrn] is a special keyword that indicates the resulting line number which starts at 1. [PIN] is the name of a feature attribute.
687
688
CHAPTER
EIGHTEEN
FAQ
18.1 Where is the MapServer log le?
See MS RFC 28: Redesign of LOG/DEBUG output mechanisms
A: Generally, no (but see the next question). Many components of MapServer use static or global data that could potentially be modied by another thread. Under heavy load these unlikely events become inevitable, and could result in sporadic errors. Q: Is it possible to safely use any of MapServer in a multi-threaded application? A: Some of it, yes, with care. Or with Python :) Programmers must either avoid using the unsafe components of MapServer or carefully place locks around them. Pythons global interpreter lock immunizes against MapServer threading problems; since no mapscript code ever releases the GIL all mapscript functions or methods are effectively atomic. Users of mapscript and Java, .NET, mod_perl, or mod_php do not have this extra layer of protection. A: Which components are to be avoided? Q: Below are lists of unsafe and unprotected components and unsafe but locked components. Unsafe: OGR layers: use unsafe CPL services Cartoline rendering: static data Imagemap output: static data SWF output: static data and use of unsafe msGetBasename() SVG output: static data WMS/WFS server: static data used for state of dispatcher Forcing a temporary le base (an obscure feature): static data MyGIS: some static data Unsafe, but locked: Map cong le loading: global parser Setting class and and layer lter expressions (global parser) Class expression evaluation (global parser) Setting map and layer projections (PROJ) Raster layer rendering and querying (GDAL) Database Connections (mappool.c) PostGIS support Oracle Spatial (use a single environment handle for connection) SDE support (global layer cache) Error handling (static repository of the error objects) WMS/WFS client connections: potential race condition in Curl initialization Plugin layers (static repository of the loaded dll-s) Rather coarse locks are in place for the above. Only a single thread can use the global parser at a time, and only one thread can access GDAL raster data at a time. Performance is exchanged for safety.
690
691
Select 24bit output. This might be as easy as IMAGETYPE JPEG in your MAP section. Enable dithering (PROCESSING DITHER=YES) to produce a better color appearance. Preprocess your image to 8bit before using it in MapServer with an external application like the GDAL rgb2pct.py script. For more information review the Raster Data.
(results based on an average 630x396 map with various colours, symbols, labels/annotations etc.) Although GIF shows a quantitative as well as qualitative advantage over PNG when generating maps that contain full coloured remote sensing imagery, PNG is the clear quantitative winner in terms of generated le sizes for maps with or without additional monochrome imagery and should therefore been the preferred image format. If the mapping application however can also display fullcolour aerial or satellite imagery, the output le format can be changed dynamically to either GIF or even PNG24 to achieve the highest possible image quality.
693
694
18.17.2 Result
18.18 How do I have a polygon that has both a ll and an outline with a width?
How do I have a polygon that has both a ll and an outline with a width? Whenever I put both a color (ll) and an outlinecolor with a width on a polygon within a single STYLE, the outline width isnt respected. For historical reasons, width has two meanings within the context of lling polygons and stroke widths for the outline. If a polygon is lled, then the width denes the width of the symbol inside the lled polygon. In this event, the outline width is disregarded, and it is always set to 1. To acheive the effect of both a ll and an outline width, you need to use two styles in your class.
STYLE # solid fill COLOR 255 0 0 END STYLE # thick outline (could use a circle symbol with size too) OUTLINECOLOR 0 0 0 WIDTH 3 ANTIALIAS TRUE END
18.18. How do I have a polygon that has both a ll and an outline with a width?
695
Note: The bdry_counln2 shapele referenced in the counties layer is a line shapele. A polygon shapele could be substituted with roughly the same results, though owing to the nature of shapeles each border would be rendered twice and the resulting output line would likely appear to be slightly thicker. Alternatively, one could use a polygon shapele, set TYPE to POLYGON, and use OUTLINECOLOR in place of COLOR in the STYLE element. Note: You can tweak the combination of STYLE->WIDTH and SYMBOLSCALE to modify line widths in your output images. See Also: Cartoline symbols can be used to achieve fancier effects.
Web Coverage Service (OGC:WCS) 1.0.0, 1.1.0 Geography Markup Language (OGC:GML) 2.1.2, 3.1.0 Level 0 Prole Web Map Context Documents (OGC:WMC) 1.0.0, 1.1.0 Styled Layer Descriptor (OGC:SLD) 1.0.0 Filter Encoding Specication (OGC:FES) 1.0.0 Sensor Observation Service (OGC:SOS) 1.0.0 Observations and Measurements (OGC:OM) 1.0.0 SWE Common (OGC:SWE) 1.0.1 OWS Common (OGC:OWS) 1.0.0, 1.1.0
LAYER NAME "hillshade" TYPE RASTER STATUS OFF TRANSPARENCY 70 CONNECTIONTYPE WMS CONNECTION "http://gisdata.usgs.net:80/servlet19/com.esri.wms.Esrimap/USGS_WMS_NED?reaspect=false PROJECTION
697
"init=epsg:4326" END METADATA "wms_srs" "EPSG:4326" "wms_title" "US_NED_Shaded_Relief" "wms_name" "US_NED_Shaded_Relief" "wms_server_version" "1.1.1" "wms_format" "image/png" END END
18.23 Why do my WMS GetMap requests return exception using MapServer 5.0?
Before upgrading to MapServer 5.0, I was able to do quick GetMap tests in the form of: http://wms.example.com/wms?service=WMS&version=1.1.1&request=GetMap&layers=foo Now when I try the same test, MapServer WMS returns an XML document saying something about missing required parameters. Whats going on here? This was a major change for WMS Server support in MapServer 5.0. MapServer WMS Server GetMap requests now require the following additional parameters:
698
srs bbox width height format styles Note: These parameters were always required in all versions of the WMS specication, but MapServer previously had not required them in a client request (even though most OGC WMS clients would issue them anyway to be consistent with the WMS spec). The request below now constitutes a valid GetMap request:
http://wms.example.com/wms?service=WMS&version=1.1.1&request=GetMap&layers=foo&srs=EPSG:4326&bbox=-18
Which is consistent with the WMS specication. More information on these parameters can be found in the WMS Server and the OGC WMS 1.1.1 specication For more detailed information, see ticket 1088 Warning: STYLES, though a required WMS parameter, is now optional again in MapServer. For more detailed information, see ticket 2427
Since my data already had a projection dened, I did not need to explicitly state a source projection. This command uses the EPSG denition for NAD83 Rhode Island (32130) and performs the feet to meters conversion. Now say my data wasnt already projected? Heres how we deal with that:
699
Lets examine what is going on here: The -s_srs parameter explicitly denes a projection for the data. The parameters used here were taken out of the EPSG denition (in this case, 32130) in the epsg le(see the projection FAQ for more details on locating EPSG denitions). The entry for RI in the epsg le is as follows:
# NAD83 / Rhode Island <32130> +proj=tmerc +lat_0=41.08333333333334 +lon_0=-71.5 +k=0.999994 +x_0=100000 +y_0=0 +ellps=GRS80
You can see how the denition in the initial command is formulated. Notice that the +units=m parameter has been changed to +to_meter=0.3408. This is important for the conversion. Where did the value of 0.3408 come from you ask? From the EPSG le! It has many goodies buried in it so by simply running grep to_meter epsg you can refresh your memory if you need to. The next parameter in the command is -t_srs EPSG:32130. This command tells ogr2ogr to transform the data to the EPSG code of 32130. After this is declared, all you need to do is declare a le name for your new shape le and to set which le is being used as the input (note: make sure you dont confuse the order of these two). Hit enter, bombs away, and enjoy your new data in meters!
700
CHAPTER
NINETEEN
LICENSE
Copyright (c) 1996-2008 Regents of the University of Minnesota. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation les (the Software), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies of this Software or works derived from this Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
701
702
CHAPTER
TWENTY
CREDITS
Major funding for development of MapServer has been provided by NASA through cooperative agreements with the University of Minnesota, Department of Forest Resources. Additional enhancements have been made by the State of Minnesota, Department of Natural Resources and the Land Management Information Center. MapServer and MapScript have been developed by Stephen Lime. Raster access module developed by Pete Olson and Stephen Lime. PHP/MapScript module was developed by DM Solutions and is maintained by MapGears. Portions copyright (c) 1998 State of Minnesota, Land Management Information Center.
703
704
BIBLIOGRAPHY
[FW1] Frank Warmerdam on the mapserver-dev: Message-Id: <[email protected]> Date: Wed, 17 Aug 2005 22:31:09 -0400 Subject: Re: Mapserver Plug-in Infastructure: RFC and PATCH
705
706
Bibliography
INDEX
A
AGG, 677 ANTIALIAS LABEL, 82 SYMBOL, 103
C
CGI, 58, 677 CLASS DEBUG, 65 EXPRESSION, 65 GROUP, 66 KEYIMAGE, 66 MAXSCALEDENOM, 66 MINSCALEDENOM, 67 CLASSITEM, 85 EXPRESSION, 68 cloning LAYER, 228 maple, 228 CONFIG MAP, 92
GDAL, 677 GEOS, 677 GML, 677 GPX, 677 GROUP CLASS, 66
I
IIS, 58 INCLUDE MAP, 75 install Oracle, 60 installation php, 46 introduction php, 178
J
Join, 78
K
KEYIMAGE CLASS, 66
D
DEBUG CLASS, 65 LAYER, 86 download php, 47
L
LABEL, 82 ANTIALIAS, 82 LABELMAXSCALEDENOM LAYER, 87 LABELMINSCALEDENOM LAYER, 87 LAYER cloning, 228 DEBUG, 86 LABELMAXSCALEDENOM, 87 LABELMINSCALEDENOM, 87 MAXSCALEDENOM, 88 MINSCALEDENOM, 88 SYMBOLSCALEDENOM, 89 LEGEND, 91
E
EPSG, 677 EXPRESSION CLASS, 65 CLASSITEM, 68
F
Filter Encoding, 677 FreeType, 677
G
GD, 677
707
M
MAP CONFIG, 92 INCLUDE, 75 SCALEDENOM, 94 Map Scale, 677 Maple, 677 maple cloning, 228 MapScript, 227 saving, 228 MapScript, 677 maple, 227 php, 190 python, 222 MAXSCALEDENOM CLASS, 66 LAYER, 88 WEB, 137 Mercator, 678 MINSCALEDENOM CLASS, 67 LAYER, 88 WEB, 138
S
saving maple, 228 SCALEDENOM MAP, 94 Shapele, 678 SLD, 678 SOS, 678 Special options, 89 Spherical Mercator, 678 SVG, 678 SWF, 678 SWIG, 679 SYMBOL ANTIALIAS, 103 SYMBOLSCALEDENOM LAYER, 89
T
Tileindex, 679
V
Vector, 679
O
OGC, 678 OGR, 678 OM, 678 OpenLayers, 678 Oracle, 281 install, 60
W
WCS, 679 WEB MAXSCALEDENOM, 137 MINSCALEDENOM, 138 WFS, 679 WMC, 679 WMS, 679
P
php, 58 constants, 191 download, 47 installation, 46 introduction, 178 MapScript, 190 PROCESSING, 89 Proj.4, 678 Projection, 678 python MapScript, 222
Q
QUERYMAP, 99
R
Raster, 678 Raster options, 89 Regular expressions, 69
708
Index