What Is MapX? - DaaS (Data as a Service) offering
Transcription
What Is MapX? - DaaS (Data as a Service) offering
MapX Developer’s Guide MapInfo Corporation Troy, NY 2 MapX Developer’s Guide Information in this document is subject to change without notice and does not represent a commitment on the part of the vendor or its representatives. No part of this document may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying without the written permission of MapInfo Corporation, One Global View, Troy, New York 12180–8399. ©1992–1999 MapInfo Corporation. ALL RIGHTS RESERVED. MapInfo Help ©1992–1999 MapInfo Corporation. ALL RIGHTS RESERVED. MapInfo, MapInfo Professional, MapBasic, MapXtreme and the MapInfo Logo are registered trademarks of MapInfo Corporation. Contact MapInfo Corporation on the Internet at: http://www.mapinfo.com MapInfo Corporate Headquarters: MapInfo Europe Headquarters: Voice: (518) 285–6000 England Germany Fax: (518) 285–6060 voice: +44 (0)1753 848 229 voice: +49 6196 6700 0 Sales Info Hotline: (800) 327–8627 fax: +44 (0)1753 621 140 fax: +49 6196 6700 11 Federal Sales: (800) 619–2333 Technical Support Hotline: (518) 285–7283 Technical Support Fax: (518) 285–6080 For international customers, please use the Technical Support Fax number. WARNING: This software uses patented LZW technology for .GIF image compression and/or decompression. (Unisys United States patent No. 4,558,302 and corresponding patents in Canada, France, Germany, Italy, Japan and the United Kingdom). GIF images compressed or decompressed for transmission via the Internet or via any other on–line communication capability may not be sold or licensed for revenue, or used by an Internet Service Provider or in paid advertisements unless the user first enters into a written license agreement with Unisys. For information concerning licensing, please contact: Unisys Corporation Welch Licensing Department C1SW19 Township Line & Union Meeting Roads P.O. Box 500 Blue Bell PA 19424 Fax: 215–986–3090 HAHTsite is a registered trademark of HAHT Software Inc. in the United States. Portions of the data are the proprietary information of Roadnet Technologies, Inc., a United Parcel Service Company, and are Copyright 1993. Roadnet Technologies, Inc. Monotype and Century Gothic are trademarks of Monotype Topography Limited registered in the U.S. Patent and Trademark Office and certain other jurisdictions. Portions of this publication are Copyright 1998, HAHT Software Inc. All Rights Reserved. Portions of the software are derived from the Standard C Library, ©copyright 1992, by P.J. Plauger, published by Prentice–Hall, and are used with permission. HyperHelp copyright© Bristol Technology Inc. 1991, 1992, 1993 HIL© Media Cybernetics, Inc. 1993, Halo Imaginf Library is a trademark of Media Cybernetics, Inc. EHelp® is a registered trademark of Foundation Solutions, Inc., ©copyright, 1992, 1993. MrSID® is a trademark of LizardTech, Inc. and is used under license. Products named herein may be trademarks of their respective manufacturers and are hereby recognized. Trademarked names are used editorially, to the benefit of the trademark owner, with no intent to infringe on the trademark. This documentation reflects the contributions of almost all of the women and men who work for MapInfo Corporation. It was specifically produced by Tony Maritato and Max Morton , with the help of Jim Regan, David Smith, Brian Bloniarz, and Larry Strianese. Colleen Cox, Editor. These members of the Documentation Department are indebted to MapInfo’s Quality Assurance Department and, of course, to all the members of the Engineering team who labored on this project. MapInfo welcomes your comments and suggestions. MapX v4.0 September 1999 4 MapX User’s Guide Table of Contents Chapter 1: Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Mapping at a Glance. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Making MapX Work for You. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Overview of Key Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Who Should Read This Book. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 2 3 3 5 Chapter 2: Getting Started With MapX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Getting Started with MapX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 What Is MapX? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 System Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 What's Included With MapX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Before Installing MapX. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 Installing MapX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 Adding the Map Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 Upgrading Visual Basic Applications From an Earlier Version of MapX . . . . . . . . . . . . . . . . 13 Upgrading C++ Applications From an Earlier Version of MapX . . . . . . . . . . . . . . . . . . . . . . . . 14 Getting Started with Visual Basic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 Getting Started with Visual C++. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 Getting Started with PowerBuilder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 Getting Started With Delphi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 Getting Started with Lotus Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 MapX Documentation Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 Where to Go Next . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 Chapter 3: New in MapX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 New in MapX. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . New in MapX v4.0. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Enhancements and Additions to MapX v3.5.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Enhancements and Additions to MapX v3.5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Enhancements and Additions to MapX v3.0. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Upgrading MapX v2.0 Applications to MapX Version 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 30 36 37 41 43 Chapter 4: Mapping Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 Mapping Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Organizing Your Data and Maps: An Overview of Tables. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . What Are GeoSets? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Map Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Putting Your Data on the Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . The Power of MapX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 46 47 53 54 56 Chapter 5: MapX Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 MapX Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Map Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Property Page. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Layers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . GeoSets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . DataSets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Annotations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 58 61 63 64 67 68 70 Chapter 6: Mapping in Layers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 Mapping in Layers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Maps as Layers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . The Layers Collection: Building Blocks of Your Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Some Properties of the Layers Collection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Some Methods of the Layers Collection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . The Layer Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Layer Order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Examining Layers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Checking a Layer’s Feature Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Zoom Layering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generating Labels For a Layer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Annotations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Raster Images. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Animation Layers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Drawing Layers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 74 74 77 78 82 84 85 86 87 89 92 92 94 95 Chapter 7: Features and Selections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 Features and Selections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 Using the Features Collection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 Selection Collection. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 Feature Editing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 Chapter 8: Finding Features on a Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 Finding Features on a Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 Find Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 FindFeature Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 Chapter 9: Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 Creating a Custom Tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 Creating Polygon Drawing Tools (Polytools) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 2 MapX Developer’s Guide Chapter 10: Putting Your Data on the Map . . . . . . . . . . . . . . . . . . . . . . . . . .131 Putting Your Data on the Map. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 What is Data Binding?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 The Power of Adding Your Data to a Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 How to Add Your Data to a Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 DataSet Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 DataSets Collection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 DataSets.Add Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135 Fields.Add Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140 Displaying Your Data as a Layer of Points (BindLayer) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 Making Your New Layer of Points a Permanent Layer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 How Data Binding Uses the GeoDictionary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 The Different Types of Data Sources. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 Chapter 11: Accessing Data from a DBMS. . . . . . . . . . . . . . . . . . . . . . . . . .159 Accessing Data from a DBMS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159 Accessing Remote Spatial Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 Using the Layers.Add Method with a LayerInfo Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 Accessing Remote Tables through a .tab File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 Mapping DBMS Data with X/Y Columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 Oracle8i Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164 DBMS LayerInfo Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166 Accessing Attribute Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 Performance Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 Caching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 The MapInfo Map Catalog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 Using MapInfo Professional to Manage a Map Catalog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 Loading Spatial Data to DBMS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 Manually Creating a MapInfo Map Catalog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 Making a DBMS Table Mappable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173 Symbol, Pen, Brush Clause Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 Specifying Point Styles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 Specifying Line Styles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176 Specifying Fill Styles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176 Troubleshooting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176 Chapter 12: Thematic Mapping and Analysis . . . . . . . . . . . . . . . . . . . . . . . .179 Theme Mapping and Analysis. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . What Is Thematic Mapping? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Planning Your Thematic Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Types of Thematic Mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Manipulating a Theme Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Customizing a Thematic Legend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . MapX Developer’s Guide 179 180 182 188 203 206 3 Chapter 13: Using Coordinate Systems. . . . . . . . . . . . . . . . . . . . . . . . . . . . 207 Using Coordinate Systems. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Basic Concepts of Coordinate Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Obtaining a Coordinate System Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Querying the Properties of a CoordSys Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Displaying a Map in a Different CoordSys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Specifying X-Y Coordinates in a Different CoordSys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Displaying the Choose Projection Dialog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using Settings From MAPINFOW.PRJ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Applying an Affine Transformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Defining Custom Datums . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Datum Conversion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . For More Information... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207 208 208 209 210 211 212 213 216 219 221 222 Chapter 14: Using Drilldown Layers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223 Using Drilldown Layers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . What Is a Drilldown Layer?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Terms and Concepts You Should Know . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . How to Develop a Drilldown Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Preparing a Drilldown Layer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating a Drilldown Tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Resetting the Drilldown Layer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Drilldown Layer Limitations and Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . For More Information... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223 224 225 227 228 232 242 242 243 Chapter 15: Exporting Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 Exporting Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Exporting Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ExportSelection Property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Printing Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 246 247 248 Chapter 16: Working With Visual C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249 Working With Visual C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Understanding the Sample Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Upgrading C++ Applications from an Earlier Version of MapX . . . . . . . . . . . . . . . . . . . . . . . Accessing MapX Properties and Methods in C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Including MapX.cpp in Your Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating a MapX Control Using C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating Menu Items Using C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Handling MapX Events Using C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using Custom Tools (C++ example) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Data Binding Using C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Adding a Shortcut Menu Using C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 249 250 251 252 255 256 257 259 261 263 265 MapX Developer’s Guide Using the Built-In Helper Dialogs from C++. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266 Handling MapX Exceptions Using C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267 Creating a Map in a C++ Dialog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 Chapter 17: Distributing Your MapX Application. . . . . . . . . . . . . . . . . . . . .273 Distributing Your MapX Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . MapX Customer Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Installing the MapX OCX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Installing Raster Format Handlers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Installing Maps and Geosets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Adding Keys to the Windows Registry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Passing in the MapX License String . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273 274 275 279 281 282 283 Appendix A: Managing MapX Data. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .285 Appendix A: Managing MapX Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285 Data Sources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286 Appendix B: Geoset Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .299 Appendix B: The Geoset Manager. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299 Appendix C: Using the Geodictionary Manager . . . . . . . . . . . . . . . . . . . . .313 Appendix C: Using the Geodictionary Manager. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313 User Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316 Command Line Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321 Appendix D: Custom Dataset Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . .323 Appendix D: Custom Dataset Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323 Static Dataset Object Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323 Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325 MapX Developer’s Guide 5 6 MapX Developer’s Guide Chapter 1: Introduction Introduction Welcome to the MapInfo family of products. As the field of enterprise 1 Chapter ➤ Introduction mapping continues to expand, MapInfo leads the way with new ➤ Mapping at a Glance products that are designed to fulfill users’ desktop and enterprise ➤ Making MapX Work for You mapping needs from our flagship product, MapInfo Professional, to the ➤ Overview of Key Features most specialized with MapMarker, our premier address-matching product. MapInfo MapX is a mapping ActiveX (OCX) control that lets you easily add powerful mapping capabilities to your applications. With maps, you can display information in a format that's easy for everyone to understand. Maps are more informative than simple charts and graphs, and can be interpreted more quickly and easily than spreadsheets. MapX is based on the same mapping technology used in other MapInfo products, such as MapInfo Professional and Microsoft Map. If you have created or purchased MapInfo map data (tables) for use with MapInfo Professional or Microsoft Map, you can use those same files with MapX. ➤ Who Should Read This Book Chapter 1: Introduction Mapping at a Glance Huge quantities of information are available today, far more than ever before. Data abounds in spreadsheets, sales records, and marketing files. Paper and disks store masses of information on customers, stores, personnel, equipment, and resources. Nearly all of it has a geographic component. An estimated 85 percent of all databases contain some sort of geographic information such as street addresses, cities, states, ZIP Codes, or even telephone numbers with area codes and exchange numbers. MapX can help you sort through all of this information, and, using the geographic components in your data, display your results on a map. This lets you see patterns and relationships in the mass of information quickly and easily without having to pore over your database. 2 MapX Developer’s Guide Chapter 1: Introduction Making MapX Work for You With MapX, the power to add powerful mapping capabilities to your applications is at your complete disposal. You can display your data as points, as thematically shaded regions, as pie or bar charts, etc. Unleash MapX’s analytical features by grouping and organizing data, performing searches, or selecting map features within a specific radius, rectangle, or specific points. For example, MapX can show which branch store is the closest to your biggest customers. It can calculate the distances between customers and stores; it can show you the customers who spent the most last year; it can color-code the store symbols by sales volume. What makes it all come together is a visual display of your data on the map. Overview of Key Features MapX is much more than a "map viewer." With MapX, you can analyze and visualize your business data, create or edit map features, and display the results geographically. Key features of MapX are listed below. • Thematic mapping Visualize your data with thematic mapping. Associate data with each feature on the map, then use color-coding (or other styles) to present your data visually. With thematic mapping, you can see your data, using any of six different styles (colored ranges, dot-density, individual values, graduated symbols, pie charts, or bar charts). • Drill-down mapping Explore your data with point-and-click simplicity. For OLAP/DSS, you can allow the user to drill down into a region on the map by pointing and clicking. • Data binding Your map can incorporate data from the container in which the OCX is embedded, an ODBC, or a DAO data source such as MSAccess. MapX provides several different types of data binding, including ZIP Code-level geocoding. • Annotations Provide orientation, highlight specific data, and make your map mor informative by adding text, symbols, and labels. MapX Developer’s Guide 3 Chapter 1: Introduction 4 • Layering Display and control the display of a map layer so it displays only when a map's zoom level falls within a preset distance. Also use or create a seamless map layer to treat a group of base tables as if they were one. Special types of applications are supported by special layer types, such as Animation Layer (for real-time tracking) and UserDraw layer (for drawing special map elements, such as logos, on top of the map). • Raster Images Include a raster image underlay to give your map an attractive, detailed background. • Automatic Labeling Add labels to your maps automatically, as well as control their attributes and display. • Selections Unleash MapX’s analytical features by grouping and organizing data. Select map features within a specific radius, rectangle or specific points. • Feature Factory The FeatureFactory object allows you to create, combine, buffer, or erase point, line, and region features. • Tools Your users interact with the map directly, by clicking and dragging. Use MapX's built-in navigation, selection, and labeling tools, or create custom tools tailored to suit your own application. • Map Editing You can give your users the power to add, modify, or delete features on the map. • Projections and Coordinate Systems With full support of coordinate systems and map projections, MapX allows you to fine-tune the map's display and process X-Y data in native coordinates. • Remote Spatial Server Connectivity Connect to live data stored in Oracle8i Spatial and MapInfo SpatialWare running on Oracle 8.0.5, Informix, or other supported SpatialWare databases. Spatial servers allow companies to host their map data in their enterprise databases for central management and security. Spatial servers like SpatialWare and Oracle8i Spatial offer advanced query processing, and increased performance on the server for an organization’s spatial data. Storing spatial data in an RDBMS is also necessary for applications that will require a great deal of map editing and deals with large data sets. MapX Developer’s Guide Chapter 1: Introduction Who Should Read This Book This book is written for anyone who wants to easily add mapping capabilities to their applications using MapX and object-oriented programming languages, such as Visual Basic, Visual C++, PowerBuilder, or Delphi, or into Lotus Notes using LotusScript. Learning About MapX If you are upgrading from an earlier version of MapX, see chapter: "What's New in MapX". If you are using MapX for the first time, here are some pointers for how to learn about MapX: • Read chapter: "Getting Started with MapX". • Examine the sample applications and use them as a template for your own creations. When you install MapX, sample applications are installed on your computer; look under <Path to MapX>\ Samples40. Note: The MapX CD provides additional sample programs that are not automatically installed on your computer. Look for those sample programs on the CD, under the \Samples directory. You can also find the latest sample applications on the MapX web site <http://www.mapx.com>. For tips on using MapX with a specific development environment, see one of these topics in the "Getting Started with MapX" chapter: • Getting Started with Visual Basic • Getting Started with Visual C++ • Getting Started with Lotus Notes • Getting Started with PowerBuilder • Gettind Started with Delphi MapX Developer’s Guide 5 Chapter 1: Introduction 6 MapX Developer’s Guide Chapter 2: Getting Started With MapX Getting Started with MapX This chapter presents the information you need to install MapX 2 Chapter ➤ Getting Started with MapX successfully and gives you a quick overview of MapX. First-time users ➤ What is MapX should read this chapter. ➤ System Requirements ➤ What's Included With MapX ➤ Before Installing MapX ➤ Installing MapX ➤ Adding the Map Control ➤ Upgrading Visual Basic Applications From an Earlier Version of MapX ➤ Upgrading C++ Applications From an Earlier Version of MapX ➤ Getting Started with Visual Basic ➤ Getting Started with Visual C++ ➤ Getting Started with PowerBuilder ➤ Getting Started with Delphi ➤ Getting Started with Lotus Notes ➤ MapX Documentation Set ➤ Where to Go Next Chapter 2: Getting Started With MapX What Is MapX? MapX is a tool for application developers. It offers the easiest, most cost-effective way to embed mapping functionality into new and existing applications. MapX is an OCX component that can be quickly integrated into client side applications using Visual Basic, PowerBuilder, Delphi, Visual C++ or other object-oriented languages and in Lotus Notes (v4.5) using Lotus Script. Developers can work in the environments they're familiar with, and end users can access mapping through their familiar business applications. System Requirements Because MapX is a 32-bit OCX, it requires a 32-bit version of Windows (Windows 95/98 or Windows NT 4.0). MapX applications cannot run on Windows 3.1. MapX works with object-oriented programming languages (such as Visual Basic, Visual C++, PowerBuilder, or Delphi) or with Lotus Notes using Lotus Script. What's Included With MapX The MapX software package includes the components listed below. Note: If you clear options when installing MapX, some of these files will not be installed on your system. By default, files are installed within or underneath the folder: \<Path to MapX>\MapInfo MapX 4.0\ MapX Contents Program Files The MapX OCX, along with an assortment of DLLs and other support files. 8 MapX Developer’s Guide Chapter 2: Getting Started With MapX Sample Maps A collection of map files (in MapInfo table format) of different regions around the world. The number of sample maps included with MapX depends on which version of MapX you install; the full version of MapX includes more maps than the 30-day evaluation software. Sample Data A Microsoft Access database containing sample demographic data. Sample Applications Program examples in various languages, showing you MapX in action. Tip: For the latest sample programs, visit the MapX web site: http://www.mapx.com Utilities The MapInfo Geodictionary Manager (GeoDictionaryManager40.exe), which allows you to register tables for use with MapX, and the GeosetManager, which allows you to easily create Geosets. MapX Documentation Customers who purchase MapX receive a Reference Guide describing all objects, methods, properties, events, and constants used by MapX. (Not included with 30-day evaluation copy of software.) Customers who purchase MapX receive the MapX Developer’s Guide. It is a detailed work on mapping concepts and how to use MapX effectively. MapX’s comprehensive Online Help system is an electronic combination of both the Reference and Developer’s guides. It provides quick access to the information you need to learn and use MapX. Spatial Server Access With Spatial Server Access, you can display map data from remote data sources, such as Oracle and Informix. MapX Developer’s Guide 9 Chapter 2: Getting Started With MapX Before Installing MapX Before installing MapX, you should record your serial number in an easy-to-remember place, such as a manual title page. Be sure to fill out the postage-paid registration card provided and return it to MapInfo Corporation. Note: We strongly recommend that you remove all previous versions of MapX and exit from all Windows programs before beginning the installation. Uninstalling older versions of MapX Uninstalling an older version of MapX is a relatively simple procedure. The steps are: 1. Select Start > Programs > MapInfo MapX v.X > Uninstall MapX v.X 2. The Uninstall Shield screen will appear and a dialog will confirm that you would like to remove MapX and all of its components. Click OK. Installing MapX The MapX installation procedure is described below. If your Windows configuration does not have a MapX program group, the installation process will create such a group. If your Windows configuration already has a MapX program group, the installation process will create a new MapX icon within that group. To install MapX: 1. Place the MapX CD in the CD drive (such as D:). Click on the Windows Start button and select Run. 2. Type or select [ CD Drive Letter ]\Setup.exe (e.g., D:\Setup.exe) in the Open dropdown list and click OK. The Welcome screen displays. Choose Next to continue the installation process. 3. The Software License screen displays. Choose YES to accept the terms of the agreement and to continue the installation process. 4. The Choose Destination Location screen displays. Specify the directory where MapX will be installed. If you do not have MapX currently installed, the default location is: Program Files\MapInfo MapX 4.0\ 10 MapX Developer’s Guide Chapter 2: Getting Started With MapX If you already have MapX installed, the default is the current installation directory. Note: We strongly recommend that you remove all previous versions of MapX and exit from all Windows programs before beginning the installation. To designate a different location, choose the Browse button, and specify the destination. Click Next to continue the installation process. 5. Specify the product components you want to install. Disk space requirements for selected components display. When you select a component, a description of that component displays. If the Change button is enabled, the component has subcomponents. Click the Change button to display a list of those components and their space requirements. Check the sub-components you wish to install. For example, if you select the Exporting/Importing Formats component, five sub-components display (GIF, JPG, TIF, PSD, and PNG) with the disk space required for each. You can choose to install any or all of these sub-components. If you want to install support for Lotus Notes databases, make sure the Lotus Notes option is checked when you install MapX. (The Lotus Notes option is a subcomponent, within the Data Drivers option.) See, Installing and Setting Up Visual Basic drivers for Lotus Notes, later in this chapter. 6. The Select Program Folder screen displays; designate the program folder. 7. The Start Copying Files screen displays. Check the information presented. If it is correct, choose Next to install MapX. A progress bar indicates the status of the installation. If you want to change information, choose Back to return to previous screens. Adding the Map Control After installing MapX, you may need to add the Map control. MapX Developer’s Guide 11 Chapter 2: Getting Started With MapX For Visual Basic Users Install the Map control on the Visual Basic toolbox. Do the following with an open Visual Basic project: If you are using Visual Basic 4: 1. Right-click on the Visual Basic toolbox, and choose Custom Controls from the shortcut menu. 2. In the Custom Control dialog, look for "MapInfo MapX V4" in the list. If this item is not checked, check it. Click OK. If you are using Visual Basic 5 or later: 1. Right-click on the Visual Basic toolbox, and choose Components from the shortcut menu. 2. In the Components dialog, click on the Controls tab and look for "MapInfo MapX V4" in the list. If this item is not checked, check it. Click OK. The Map control appears on the toolbox. To place a map on your Visual Basic form, select the Map control and draw a box on the form. If you save your project, the next time you re-load your project the Map icon will appear in the toolbox automatically. For C++ Users You will want to include MapX.cpp and MapX.h in your project. They contain the class definitions and method implementations for access to the MapX control. The MapX.h and MapX.cpp files can be found in the Samples40\CPP subdirectory where MapX is installed. Using Visual C++ version 4 From the Insert menu, choose Files Into Project. Choose MapX.cpp as the file to insert. Note: Do not choose the Insert > Component command. Doing so would create a .cpp file, but it would be incomplete. 12 MapX Developer’s Guide Chapter 2: Getting Started With MapX Using Visual C++ version 5 and 6 From the Project menu, choose AddTo Project > Files. Choose MapX.cpp as the file to add. Note: Do not choose Project > Components And Controls command. Doing so would create a .cpp file, but it would be incomplete. Upgrading Visual Basic Applications From an Earlier Version of MapX If your Visual Basic project uses an earlier version of MapX, use the following procedure to convert your application to the current version. 1. Open the project of the application you want to upgrade to the current version. 2. Delete the map object from the form. Make a note of the name of the map control and of any map properties that may have been modified from their defaults. 3. From the Tools menu, choose Custom Controls. 4. In the Available Controls list, uncheck the MapInfo MapX Control and click OK. 5. Go back into the Tools > Custom Controls dialog and check the MapInfo MapX Version x Control (where x is the number of the current version) and click OK. 6. Place the new MapX Map control on your form, and give it the same name (e.g. "Map1") that you used with your earlier version’s control. After the new OCX is added into the project, you will need to restore any custom properties. MapX Developer’s Guide 13 Chapter 2: Getting Started With MapX Upgrading C++ Applications From an Earlier Version of MapX If you wrote a C++ application using an earlier version of MapX, you will need to use the new MapX wrapper classes (mapx.h and mapx.cpp) to upgrade your application to the current version of MapX. You may need to modify the strings that you pass to CreateDispatch. With an earlier version of MapX , you may have used a string to specify an object name; for example: Flds.CreateDispatch("MapX.Fields") With the current version of MapX, you need to specify a different string: Flds.CreateDispatch("MapX.Fields.4") To make your code more compatible with future versions of MapX, you may want to use GetClsid instead of a string. The result returned by GetClsid will work in current and future versions of MapX. For example: Flds.CreateDispatch(Flds.GetClsid()) This change applies to all creatable objects. To learn more about creatable objects, search for "Create, Objects" in the Online Help Index of in the Creating Objects section of the "MapX Basics" chapter.) Getting Started with Visual Basic Creating a Simple Map With MapX, it's easy to add a map to your application. In fact, you can add a working map to a Visual Basic form without writing a single line of code. 1. Select the Map control from the Visual Basic toolbox. (If the Map control does not appear on the toolbox, see Adding the Map Control in this chapter. 2. Draw a box on your form, representing the area where you want the map to appear. MapX displays a preview of your map. 14 MapX Developer’s Guide Chapter 2: Getting Started With MapX 3. Right-click on the Map control, and choose Properties from the shortcut menu. The MapInfo MapX Properties dialog box appears. 4. Locate the Current Tool option, which is near the bottom of the General tab. Set the Current Tool to "1003 - Zoom In" and click OK. 5. Run your program to view the map. Notice that whenever the cursor is over the map, it changes to a magnifying glass with a plus sign. 6. Click on the map. MapX zooms in on the map location where you clicked. You can click repeatedly, to zoom in more and more.You can also draw a marquee to specify the exact area that you want to zoom in on. As you zoom in closer and closer, you will notice that more map features become visible. This is because individual map layers have been set up with Zoom Layering (a feature that automatically displays map layers within a preset zoom range ). To zoom back out, hold down the CTRL key and click the map again. Note that while you're holding down the CTRL key, the cursor changes to a magnifying glass with a minus sign. One way to learn MapX is to study sample applications. Look for sample applications in the folder: \<Path to MapX>\MapInfo MapX 4.0\Samples40 MapX Developer’s Guide 15 Chapter 2: Getting Started With MapX Understanding ASIA.VBP (Visual Basic 4 project) This project displays a simple form with a map. Buttons on the map allow the user to select various tools -- a Select tool, a Pan tool, Zoom In and Zoom Out tools. A TextBox at the upper right lets the user read or set the map's zoom distance. Highlights The Main form contains a Map object (Map1). This object was placed on the form using the Map control. If the Visual Basic toolbox does not show you this control, you need to add the control to the toolbox. This application displays Asian data because the programmer chose the "Asia" geoset.You choose the geoset at design-time, by right-clicking the Map object and choosing Properties. The Properties dialog also allows you to set many other map properties. 16 MapX Developer’s Guide Chapter 2: Getting Started With MapX When the user clicks one of the buttons at the upper left, the application uses the Map.CurrentTool property to change which tool is in use. For example: Private Sub Command4_Click() map1.CurrentTool = miSelectTool End Sub The text box at the upper right allows the user to type in a desired zoom distance (distance across the map), in miles. The application uses the Map.Zoom property to apply the new zoom distance: Private Sub Text1_LostFocus() map1.Zoom = Text1.Text End Sub When the user zooms in or out (using the Zoom In or Zoom Out buttons), the map's zoom distance changes. The application automatically updates the text at the upper right by using the MapViewChanged event. Private Sub map1_MapViewChanged() Text1.Text = map1.Zoom End Sub MapX Developer’s Guide 17 Chapter 2: Getting Started With MapX Understanding VBsample.VBP (Visual Basic 5 project) This project displays another simple form with a map. However, it will only run if you are using Visual Basic 5 or 6 with MapX. This map defaults to United States data, but it is designed to handle any specified geoset. You may select a different geoset at design-time by right-clicking the map object and selecting properties. This project uses three types of data binding. They are: • Point Reference • XY Coordinate • Normal If you choose Point Reference or XY, a layer will be created. For more information on layers, see chapter: "Mapping in Layers." 18 MapX Developer’s Guide Chapter 2: Getting Started With MapX Tools The tool bar is located on the left side of the screen. Drag the cursor over an icon to identify what it is and click the desired tool.You may also access tools using the Tools menu. Arrow tool: Acts as the default pointer/cursor tool. Zoom In: Gets a closer area view of the map. Zoom Out: Gets a wider area view of the map. Pan: Repositions the map within the window Ruler: Measures distance between two defined points. Select: Selects objects on the map. Select Rectangle: Selects objects within a given rectangle. Select Radius: Selects objects within a given circular region. Select Polygon: Selects objects within a given region. Label: Labels objects with information from a given database. Annotation Tool: Places point symbols on the map. Add Text Annotation: Adds titles or labels to the map. Insert Data and Themes You can insert data in this map using the the Insert Data feature in the Map menu. When selected, the Add Dataset dialog appears. Choose the data you wish to add. To create or modify a theme, select Create or Modify Theme in the Map menu and their respective dialog boxes will appear. For more information on thematic mapping, see chapter: "Theme Mapping and Analysis". Find Feature The Find Feature command is located in the Map menu. When selected, the Find Dialog appears. The user will define which layer, object, and value of object to use in the search. Optional refinements are available. For more information on the Find feature, see chapter: "Finding Features on a Map". MapX Developer’s Guide 19 Chapter 2: Getting Started With MapX The code used in this application is: For Each ftr In lyr.Selection ' The children of the layer are the individual ' features Set ftrNode = QueryTree.Nodes.Add(lyrNode, tvwChild,lyr.Name _ & ftr.Name & Str$(ftr.FeatureID), ftr.Name) For Each fld In ds.Fields ' Each feature has data attached to it; add ' this data as a child of the feature lyr.KeyField = fld.Name QueryTree.Nodes.Add ftrNode, tvwChild, , lyr.KeyField _ & ": " & ftr.KeyValue Next Next Select Within Distance To select within distance, the user must first use one of the select tools to select the area he wishes to search. Then he must choose Select Within Distance from the Map menu. The Select Within Distance dialog appears. The user will specify which layers, the distance, the units of measure, and the feature(s) to select. For more information on the Select Within Distance feature, see chapter: "Features and Selections". The code used in this application is: ' There's just one layer for which we have to select Set ToBeSelectedLayer = _ fMainForm.Map1.Layers(ToBeSelectedLayerCombo.Text) For Each ftr In SourceFeatures ' For each feature, select everything within the distance Set FeaturesToSelect = _ ToBeSelectedLayer.SearchWithinDistance(ftr, _ SearchDistance, SelectionUnit, _ miSearchTypePartiallyWithin)_ ToBeSelectedLayer.Selection.Add FeaturesToSelect Next Query Selection Use a selection tool to select the area for query. The Query Selection feature can access data associated with a map. It is located in the Map menu. 20 MapX Developer’s Guide Chapter 2: Getting Started With MapX Getting Started with Visual C++ One way to learn MapX is to study sample applications. Look for sample applications in the folder: <Path to MapX>\Samples40 As you study the sample C++ application mapxsamp.cpp, refer to chapter: "Working With Visual C++", to help you understand how to use MapX with C++. Note: These topics assume that you are using Microsoft’s Document/View model (standard MFC AppWizard app.) The sample application can be built in Developer Studio with mapxsamp.mdp. Getting Started with PowerBuilder Creating a Simple Map These steps will create a new project and place a Map control into the application. 1. Create a new application to hold your Map by opening the Application Painter and choosing New from the File menu. Pick a file for the Application Library and a name for the new application. ChooseYes when asked whether to generate an Application Template. 2. Open the main document window (for the Application Template, it is called w_genapp_sheet). Select it in the Application Painter and click the return key to open the Window Painter. 3. Select OLE from the Controls menu. 4. Select the Insert Controls tab from the Insert Object dialog, and pick MapInfo MapX V4 from the list box. Click OK to return to the Window Painter 5. Click in the document window to insert a new Map object. MapX Developer’s Guide 21 Chapter 2: Getting Started With MapX Getting Started With Delphi Adding the Map Control These steps install MapX into a Delphi package. This process only needs to be done once. 1. Open Delphi with a new, empty project. 2. Select Import ActiveX Control from the Components menu. 3. Select MapInfo MapX V4 from the list box, and click Install. In the Install dialog box, install into the default package, which should be Borland User’s Components. Press Yes to recompile the package, then close and save the Package window. The MapX icon should appear in the Controls palette, under the ActiveX tab. 4. Close the Delphi program. In Windows, locate the file <Path to MapX>\Samples40\Delphi\DelphiWrappers\DelphiFix.exe. Run this executable to correct several errors in the MapX source files generated by Delphi. Creating a Simple Map These steps can be used to create a new project which includes MapX. 1. Select the MapX icon from theTools palette, under the ActiveX tab. 2. Draw a box on the form representing where you want the Map to appear. Delphi will then show a preview of the Map on the form. 3. Select Run from the Run menu to run the new application. Getting Started with Lotus Notes Introduction To embed a MapX control into Lotus Notes, you need the Notes client version 4.5 or later. Notes client applications cannot call DataSets.Add with type miDataSetUnbound. This restriction is due to a bug in Notes 4.5 (related to type conversion for booleans) which prohibits using the MapX RequestData method for unbound data sets through LotusScript. Lotus plans to fix this problem in an upcoming release of Notes. 22 MapX Developer’s Guide Chapter 2: Getting Started With MapX Installing and Setting Up Drivers for Lotus Notes If you want to install support for Lotus Notes databases, make sure the Lotus Notes option is checked when you install MapX. (The Lotus Notes option is a sub-component, within the Data Drivers Install option.) MapX accesses Lotus Notes by using the support files MNotesDataset.dll and MMapXColumnInfo.dll, which are stored in the MapX Program directory. If you check the Lotus Notes Data Driver option at install time, the MapX installer attempts to register these dlls. Note: If the file nnotes.dll (which is part of Lotus Notes) is not in your path, the MapX installer will not be able to register these dlls, and an error message will be displayed during installation. To correct this error, modify your SYSTEMPATH to include your Lotus Notes directory. Then register the dlls manually (by running regsvr32.exe) or re-run the MapX installer with the Lotus Notes data driver option checked. Note: To access a database on a Notes server, there must be at least one database from that server located on your Notes desktop (desktop.dsk). Accessing Data through a Notes View Access to a Notes View is provided using a NotesViewInfo object. This object has three properties: Server, Database, and View • The Server property specifies the name of the Notes server. If the file is being accessed locally, this can be set to the null string. • The Database property is used to specify the path to the database file. On a Server, this path would be relative to the Notes data directory; locally, this would be a full path beginning with a drive letter. NOTE: Because UNC path specifications are not supported by the Notes API, drive mappings must be used for accessing a database across a network. • The View property represents the name of the Notes View being referenced. Notes View will typically be used with a MapX Fields object to define specifically which columns of the View are to be used. The MapX Fields object is used in the normal way, although it is important to note that column title references are case specific. MapX Developer’s Guide 23 Chapter 2: Getting Started With MapX Example: Using a Notes View from Visual Basic The following Visual Basic example shows the code used to generate a simple thematic map using "state" and "value" columns from a Notes View named "State Info" in a database named "states.nsf". The example assumes that the database exists on a server named NS1 in a "samples" subdirectory off of the Notes data directory. Dim ds as DataSet Dim flds As New MapXLib.Fields Dim NDO As New NotesViewInfo flds.Add "state", "BindField", 4, 0 flds.Add "value", "ValueField", 1, 1 NDO.Server = "NS1" NDO.Database = "samples\states.nsf" NDO.View = "State Info" Set ds = Map1.Datasets.Add(miDataSetNotesView, NDO, _ "NotesThematic", "BindField", , , flds) Map1.Datasets("NotesThematic").Themes.Add 0, "ValueField", _ "NotesThematic" Example: Using a Notes View from LotusScript In the preceding Visual Basic example, the datatypes MapXLib.Fields and NotesViewInfo, and the DatasetType constant miDataSetNotesView were obtained by Visual Basic through the MapX dlls and type library. In an environment such as LotusScript where the type library is not available, handles to these objects are obtained somewhat differently,as illustrated below: Dim Dim Dim Dim Dim Dim uiws as New NotesUIWorkspace uidoc as NotesUIDocument ds as Variant flds As Variant NDO As Variant Map1 as Variant 'if the Map is embedded on a form, get the handle as follows... set uidoc = uiws.currentDocument set Map1 = uidoc.getobject("Map1") 'otherwise, create a new map object... 24 MapX Developer’s Guide Chapter 2: Getting Started With MapX set Map1 = createobject("MapX.Map.3") set flds = createobject("MapX.Fields.3") set NDO = createobject("MapX.NotesViewInfo.3") flds.Add "state", "BindField", 4, 0 flds.Add "value", "ValueField", 1, 1 NDO.Server = "NS1" NDO.Database = "samples\states.nsf" NDO.View = "State Info" Set ds = Map1.Datasets.Add(7, NDO, "NotesThematic", _ "BindField", , , flds) Map1.Datasets("NotesThematic").Themes.Add 0, "ValueField", _ "NotesThematic" Accessing Notes Through a Notes Function Query Accessing Notes data through a function query is accomplished using a NotesQueryInfo object. The NotesQueryInfo object has Server and Database properties which behave exactly as described for the NotesViewInfo object. In addition, the NotesQueryInfo object has a third property named Query which represents the text of a query to be performed. The syntax of this query is that of a standard Notes formula. Notes function queries are generally used in conjunction with MapX Fields objects to define specifically which fields of the database record are to be used. Unlike Notes View column titles, references to record field names are not case-sensitive. Example: Using a Notes Query from Visual Basic Revisiting the preceding Visual Basic example, suppose that the database records have fields for state and value, and that the analysis you want to perform requires a thematic to be created based on database records whose state field is one of NY, TX, CA, or FL. The code can be written as follows: Dim ds as DataSet Dim flds As New MapXLib.Fields Dim NDO As New NotesQueryInfo flds.Add "state", "BindField", 4, 0 MapX Developer’s Guide 25 Chapter 2: Getting Started With MapX flds.Add "value", "ValueField", 1, 1 NDO.Server = "NS1" NDO.Database = "samples\states.nsf" NDO.Query = "@IsMember(state;""NY"":""TX"":""CA"":""FL"")" Set ds = Map1.Datasets.Add(miDataSetNotesQuery, NDO, "NotesThematic", "BindField", , , flds) Map1.Datasets("NotesThematic").Themes.Add 0, "ValueField", "NotesThematic" As in the first example, this can be easily adapted to LotusScript or other environments. When the type library is not available, miDataSetNotesQuery can be replaced by its numeric equivalent: 8. MapX Documentation Set In addition to the Developer’s Guide, MapX’s documentation set includes the MapX Reference and Online Help. MapX Reference The MapX Reference is a complete guide to the object, properties, methods, events, error codes, and expressions, associated with MapX. Alphabetically organized, most entries include a purpose, cross-references to other entries, and in many cases, sample code written in Microsoft Visual Basic and C++. 26 MapX Developer’s Guide Chapter 2: Getting Started With MapX Online Help MapX’s comprehensive Online Help system provides the information you need to learn and use MapX more effectively. It is essentially an electronic merging of ALL information contained in the printed Reference Guide and Developer’s Guide. You can reach the information in several ways: • Use the Help Contents screen to choose topics from books. Click on a book to display its topics, and choose a topic from the list. • Use the Find feature to search on a specific word. Select: Start menu > Programs > MapInfo MapX > MapX Online Help. Then, click index and go to the FindTab . Type the word you want to search for, and click Rebuild. MapX displays a list of words to help narrow your search. Click on a word, and a list of topics displays that contain the selected word. Double-click on the topic you want or click Display to display the topic. You my customize your serch by clicking Options to make your find more specific. • Use the Index feature to find a topic quickly.Type the first few letters of the word you are looking for. The topic that most closely matches what you typed is highlighted. Click the index entry you wish to display. • See Also information: Click on the green underlined text in any Help window to bring up information on related tasks or key words and phrases. Online Help has been designed to display in part of your window so that you can view your maps, Browser windows, and dialogs alongside the Help window. Of course, you can always change the size of the Help window to work the way you are most comfortable. Choose Help > Always On Top to keep the Help window on your screen so you can continue to work in MapX. Or use Alt–Tab to toggle between the Help screen and the MapX desktop. Tips on Using Online Help Using Code Examples You can easily copy code examples from the Help window. To copy text, highlight the text, and press CTRL-C; to paste the text into your development environment, press CTRL-V. You can also use Drag and Drop to drag highlighted text from Help into other applications. MapX Developer’s Guide 27 Chapter 2: Getting Started With MapX Download the Latest Help Files MapInfo Corporation regularly updates the MapX Online Help. To download the latest version of this Help file, visit the MapX web site at: http://www.mapx.com The MapX web site also provides sample applications, as well as a Discussion Area where you can post questions and interact with other MapX users. Where to Go Next This chapter has provided a very quick overview of MapX. Other sections of this documentation describe specific features of MapX in greater detail. Before you read any further, take a moment to view the MapX OLE Automation object model diagram. This poster is included with MapX and is useful for giving you the big picture. Use it as a reference as you learn about MapX. 28 MapX Developer’s Guide Chapter 3: New in MapX 3 Chapter New in MapX This chapter summarizes the improvements and enhancements made to MapX for version 4.0, 3.5.1, 3.5, and 3.0. If you are upgrading from MapX version 2, you will want pay close attention to the features added in version 3.0., and how to upgrade your existing MapX version 2 applications. ➤ What’s New in MapX Version 4.0 ➤ Enhancements and Additions to Map Version 3.5.1 ➤ Enhancements and Additions to Map Version 3.5 ➤ Enhancements and Additions to Map Version 3 ➤ Upgrading MapX Version 2 Applications to MapX Version 3 Chapter 3: New in MapX New in MapX v4.0 New Features • Grid Display & Transparent Rasters: MapX opens grids and 24-bit transparent rasters. • Raster Auto Registration: MapX can open a raster file (not a .tab file) directly and auto-register it using the info stored in the raster file. • ADO & RDO Support: MapX supports both ADO & RDO as data sources for databinding. • True color support: MapX uses 24-bit color by default. • DB2 Support: MapX supports the opening of remote layers from DB2 databases. • Faster Layer Access: Performance has been improved for repeated layer and dataset operations. • Vector Symbol Support: MapX now displays vector symbols (MapInfo 3.0 compatible). • Object Creation and Editing Tools: The select tool now allows for dragging, resiezing, and deleting features in editable layers. Four new creation tools added. They are: (1) miAddPointTool (2) miAddLineTool (3) miAddPolylineTool (4) miAddRegionTool. • Oracle 8i Database support: MapX supports Oracle 8i Data. Feature Enhancements • 30 User-Defined Cursors for Custom Tools : Now in MapX, a programmer can use CreateCustomTool to associate his Tooled with a built-in drawing behavior and a built-in cursor. Optionally, a programmer can specify cursors to use when the shift or control keys are held down while the tool is being used. If the ControlCursor or ShiftCursor is not specified, the DefaultCursor will be used (whether it is stock or custom). MapX Developer’s Guide Chapter 3: New in MapX • Remove Requirement for the Geodictionary: MapX now isolates the use of the Geodictionary so that it is only required for automatching. The Geodictionary key in the registry now: (1) Could contain a full file spec for the Geodictionary file. The effect is that the data directory is set to be the path leading to the Geodictionary file named by thiskey. The in-memory geodictionary is initialized from the Geodictionary file and layers contained in the Geodictionary can be automatically matched against it too. Layers added to the map are still added to the in-memory geodictionary so they can be auto matched against. (2) Could contain just a path specification. The data directory is set to be the path named by this key. The in-memory geodictionary is initialized empty. Layers added to the map are still added to the in-memory geodictionary so they can be auto matched against. (3) Could not exist at all. The in-memory geodictionary is initialized empty. Layers added to the map are still added to the in-memory geodictionary so they may be auto matched. • Faster access to a features Nodes data: MapX exposes the node data in such a way that the user can query for all the nodes in an object with one pass, then have them returned in a SafeArray containing the node data (See Feature.Nodes). • Path handling: MapX is more consistent in the way that it handles file paths. Enhancements to Properties, Methods, and Events • AddFeatureToolUsed Event: This event is called whenever the user uses one of the standard object creation tools (miAddPointTool, miAddLineTool, miAddPolylineTool, or miAddRegionTool). The behavior of this event is similar to the PolyToolUsed Event. • Feature.CenterX & Feature.CenterY This now returns the true center of a text feature. • Layer.Add: Now, the first parameter is a VARIANT which can be either a LayerInfo object or a string. See LayerInfo object. Note: AddServerLayer is no longer the preferred way of opening a remote layer via Layer.Add. Calling the LayerInfo object is more efficient. • Map.InfotipPopupDelay: This allows the programmer to specify the duration of time the user needs to have the mouse icon over an object before the InfoTip (if specified) appears. • Map.InfoTipSupport: This allows the programer to specify whether or not MapX should display pop-up InfoTips. MapX Developer’s Guide 31 Chapter 3: New in MapX • Map.MouseIcon property: This lets the programer specify a custom cursor to use as the default mouse cursor in MapX. (See the Map.MousePointer property) • MapDraw event: This event will be called once before a draw, and once after a draw is completed. There is one parameter which states whether a draw is beginning or ending. • ResolveDataBindingEx event: This event has the same function as the ResolveDataBind event, but it passes a collection of ResolveObjects instead of a string array. Additional Objects • FindResult object: This will return information about the FindRC in the form of properties to make it easier to access the result of the find. Note: This object was renamed from FindResults object. • LayerInfo object: The LayerInfo object stores parameters to be passed to the Layers.Add method and specifies type from the LayerInfoTypeConstants. Note: AddServerLayer is no longer the preferred way of opening a remote layer via Layer.Add. Calling the LayerInfo object is more efficient. • RowValue object and RowValues collection: The RowValue object represents a single value for a field in a dataset. RowValues collection is a group of RowValue objects. These objects are used with Layer.InsertFeature, Layer.UpdateFeature, Feature.Update, and Dataset.RowValues to read/update attribute fields in a MapInfo table. Additional Properties • BindLayer.ReferenceLayerField: This specifies what field (by number, starting at 1) in the mapinfo table to bind to. If not specified, MapX will sample the source data for the column and choose the column with the highest match rate. If none match, then the first column is chosen. • Dataset.RowValues: • Feature.FeatureKey: Returns the Key of the feature. Each feature in a layer contains a unique key within the layer. This is a string value and is read-only. This is a replacement for Feature.FeatureID (which still works as it did before, but it is recommended that you use the new FeatureKey property). • Feature.Nodes property: This read-only property exposes the node data in such a way that the user can query for all the nodes in an object with one pass, then have them returned in a single, contiguous block of memory • Find.CloseMatchesMax: This returns the maximum number of close matches loaded in FindResult from SearchEx. 32 • LabelProperties.PartialSegments property: Setting this value to true enables MapX to label polylines, even if only a small part of the polyline is currently visible. However, this will not work for other features/objects, as it only applies to autolabels. • Layer.DataSets property: This read-only property is a DataSets collection that is bound to the map layer it is associated with. This collection is a subset of the full MapX Developer’s Guide Chapter 3: New in MapX DataSets collection (Map.DataSets). The objects within Layer.DataSets are the same as the objects within Map.DataSets. • Layer.Editable: This property allows a selection in the layer to be edited (moved, resized, or deleted). • LayerInfo.Type property : This is a read/write property whose value is one of the LayerTypeConstants. • Map.MatchThreshhold: This is the minimum threshold percentage required for matching a map layer with a data source. It is used to control auto-matching during Datasets.Add. • Map.PanAnnimationLayer: This property controls whether the animation layer (if there is one) is drawn into the backing store when the pan tool is in use so that the contents of the layer are dragged around with the rest of the map. The default is FALSE. • RowValue.Dataset: This property is used to specify which dataset the value is for. • RowValue.Field: This property is used to specify the field in the dataset that the value is for. • RowValue.ReadOnly: This property determines whether or not the properties can be set on the object. • RowValue.Value: This property is used to specify the value for the field. • RowValues.Count: This read-only property specifies the number of rows in the RowValues collection. • RowValues.ReadOnly: This read-only property specifies whether or not properties can be set on the collection. • Style.MaxVectorSymbolCharacter: This read-only property returns the maximum valid code for a vector symbol. • Style.MinVectorSymbolCharacter property: This read-only property returns the minimum valid code for a vector symbol. • ThemeProperties.ApplyAttribute: This controls which of the theme category’s style attributes are actually applied to the theme. It can be used to selectively modify either the color or the size of the categories of the theme, without affecting the other’s appearance. • ThemeProperties.BarFrameStyle: The style of the frame of the bar chart. • ThemeProperties.BarGraduatedStack: Specifies if the stacked bars should be graduated. • ThemeProperties.BarIndependentScale: This property replaces the ThemeProperties.Independent property. • ThemeProperties.BarStacked: Specifies whether to draw stacked bar charts. • ThemeProperties.BarWidth: This property replaces the ThemeProperties.Width • ThemeProperties.BorderStyle: The style of the border of a pie or bar chart. MapX Developer’s Guide 33 Chapter 3: New in MapX • ThemeProperties.ColorMethod: This specifies the method used to interpolate between the top and bottom range colors to get the colors of the intermediate ranges. • ThemeProperties.DotColor: The color of the dots in a dot density theme. • ThemeProperties.GraduateSizeBy: Controls the graduation method used for graduated pies, bars, or symbols. • ThemeProperties.InflectionColor: This is an OLE_COLOR value. It indicates the color of the inflected range. • ThemeProperties.InflectionRange: This controls which range takes on the color specified in InflectionColor. The ranges above and below the InflectionRange will have a mixture of InflectionColor and the top and bottom range colors, respectively. • ThemeProperties.InflectRanges: In a ranged theme, an inflection point can be used to separate the ranges into two sections. When InflectRanges is true, the colors in the ranged theme will spread from the top range color to the InflectionColor, then from the InflectionColor to the bottom range color. • ThemeProperties.NegativeSymbolStyle: The style of the negative symbol in a graduated symbol theme. • ThemeProperties.PieClockwise: Controls whether the pie wedges are drawn in clockwise order. • ThemeProperties.PieGraduated: This property replaces the ThemeProperties.Graduated property. • ThemeProperties.PieHalfPies: Specifies whether to draw half pies instead of whole pies. • ThemeProperties.PieStartAngle: The start angle that the first pie wedge is drawn. • ThemeProperties.PositiveSymbolStyle: This property replaces the ThemeProperties.SymbolStyle property. • ThemeProperties.RoundBy: This specifies the interval to round the ranges to. • ThemeProperties.RoundRanges: This controls whether the boundaries of the ranges are rounded off. • ThemeProperties.ShowNegativeValues: This property specifies whether to show negative values in the graduated symbol theme. Additional Methods • Coordsys.Clone method: This returns a copy of a CoordSys object.. • DataSet.AddField method: This allows a field ('column') to be added to a dataset that is an expression containing functions, operators, and datasets fields (from the current dataset only). • Features.Clone method: This clones a features collection. • Find.SearchEx method: This extends the functionality of the search method. It enables the search engine to look for the closest matches returned in a collection. 34 MapX Developer’s Guide Chapter 3: New in MapX • Layer.BeginAccess method: This method will open and lock the table for read or write access. This improves the performance for repeated layer and dataset operations. You must call EndAccess once for each call to BeginAccess method. • Layer.EndAccess method: This method unlocks map tables. You must call EndAccess once for each call to BeginAccess method. • Layer.Refresh: This method flushes the cache from the layer. This is useful for server layers that have caching turned on. • Layer.Search method: This method exposes the power of SQL queries. The expression (the "where-clause" portion of the statement) is evaluated for each row in the Layers table, and a Features collection is returned. • LayerInfo.AddParameter method: Is the set of parameters required for a given call to the Layers.Add method, and is determined by the type of LayerInfo object passed. • RowValues.Add: This property adds a RowValue object to a specified RowValues collection. • RowValues.Clone: This method clones specified row values from a dataset and returns a new RowValues object. The clone is not read-only or read/write. • RowValues.Item: This returns a specific RowValue object from the RowValues collection. • RowValues.Remove: This method removes a specified RowValue object from the collection. • RowValues.RemoveAll: This method removes all RowValue objects from a RowValues collection. • Style.SymbolVectorColor method: This method determines the color of the vector symbol. • Style.SymbolVectorSize method: This method determines the point size of the vector symbol. MapX Developer’s Guide 35 Chapter 3: New in MapX Enhancements and Additions to MapX v3.5.1 36 • Write capability, inserts and updates, directly to SpatialWare layers: If you have added a SpatialWare layer through the AddServerLayer method, any edits or changes to that map layer will be committed to the SpatialWare table. See Feature.Update, Layer.UpdateFeature, Layer.AddFeature, and Accessing Remote Spatial Data. • Export Style Samples: The Style object has four new methods that allow you to export symbol, region, line and text style samples. The methods are ExportSymbolSample, ExportRegionSample, ExportLineSample, and ExportTextSample. • Rotating Text objects: The new TextFontRotation property of the Style object allows you to control the number of degrees to rotate (clockwise) a Text object. Currently valid only for Feature objects. • AllOthers Range Category: The new AllOthersCategory property of the RangeCategories collection and the new AllOthersCategory property of the IndividualValueCategories collection allow you to define a category for all ranges not in a ranged or individual categories theme. The text that appears in the legend for the AllOthersCategory range category object can be set with the LegendTexts.AllOthersText property. • Returning the Feature Id From a Feature Name: Given a name, the new FeatureIDFromFeatureName property of the Layer object returns the ID of the feature with that name. • Select a Feature by FeatureID: The new SelectByID method of the Selection collection allows you to select a feature by FeatureID. • Add a Feature by FeatureID: The new AddlByID method of the Features collection allows you to a add a Feature object with the specified FeatureID to the Features collection. • Remove a Feature by FeatureID: The new RemoveByID method of the Features collection allows you to a remove a Feature object with the specified FeatureID from the Features collection. • Control the Wait Cursor: The new WaitCursorEnabled property of the Map object allows you to turn the Wait Cursor on or off manually. • Added New Parameter to Layers.AddServerLayer: Takes a LayerCacheConstants value. MiLayerCacheOn, which is the default, will keep attributes and objects that have been read in memory; if you zoom in they do not need to be fetched from the database. Since MapX looks in memory for a record, you will not see the latest updates. If MiLayerCacheOff, all data will be fetched from the database; it will give the most up to date data but will be less efficient. MapX Developer’s Guide Chapter 3: New in MapX • Added a new Dataset type, the safe array dataset: It is a COM dataset (needs to be registered via regsvr32.exe before it can be used) that implements only IMMapXStaticDataset (it does not do dynamic binding). A new DatasetTypeConstant has been added, miDataSetSafeArray = 9. To use this dataset, the data reference (SourceData parameter to the Datasets.Add method) should be aVARIANT that contains a safearray full of the data to be bound. Enhancements and Additions to MapX v3.5 The following overview summarizes the improvements made to MapX for version 3.5. Performance Enhancements • Improved XY and PointRef Binding speed. • Improved speed of the Lotus Notes datasets. • Improved map drawing speed. • Support for more raster import formats including GIF, JPEG, and PNG. • New Delphi Native Dataset for Delphi 3.0. Feature Enhancements • Create Themes Faster for Server and Drilldown Layers: When creating a theme with Themes.Add, computing ranges for layers with large numbers of rows, such as drilldown or server layers, can take some time. The new ComputeTheme parameter of the Add method lets you create a non-compute theme for any theme type. A noncompute theme gives you the ability to create a theme without having the ranges automatically calculated for you. You can then create the ranges yourself. This is a faster way for drilldown and server layers. See Themes.Add, DataMin, DataMax, ComputeTheme, and Value. This feature also works in conjunction with IndividualValueCategories, MultivarCategories, and RangeCategories. • NADCON Support: Beginning with MapX 3.5, the NADCON algorithm is used to convert coordinates between NAD 27 and NAD 83 if those coordinates lie within the areas covered by NADCON (United States, Puerto Rico, and the Virgin Islands). If the coordinates lie outside those areas, or if they use datums other than NAD 27 or NAD 83, MapX uses the Molodensky or Bursa-Wolfe conversion methods. See Datum Conversion. MapX Developer’s Guide 37 Chapter 3: New in MapX • Intellimouse Support: The Intellimouse provides a wheel as a third (middle) button on the Microsoft mouse. The Mousewheel will zoom the map when rolled, scroll the map up and down when the wheel is rolled with the control key down, and ”AutoScroll” when the middle button is held down and moved away from the mouse click point. A property, MouseWheelSupport, will describe the level of Intellimouse support: None, Zoom/Scroll only (no AutoScroll), or Full. A MouseWheel event allows you to override the built-in behavior. Note that for use in Visual Basic for Windows 95, you need to have a third party .OCX in order to get the mouse events on a Visual Basic form. • Incremental Drawing of Map: Currently, the map is drawn to an offscreen bitmap; when the offscreen map is complete, it is bit block transferred to the screen. The Map.RedrawInterval property determines how often to transfer the map to screen as is it being drawn in memory. • Matching on Numeric columns: This property controls matching on numeric fields. This property appears on the Data (design time) property page. If MatchNumericFields is true, then numeric fields are considered candidate keys (along with the alphanumeric fields) when MapX is auto matching. If it is false, then numeric columns are not considered when doing auto matching. See Data Binding overview. • Interleaved Line Styles: The ability to create intersections on your maps that really look like intersections and specify Line Widths in measured units, rather than pixels. This makes it much easier to determine what your printed maps will look like. See the Style.LineInterleaved property. • Pen Styles: New mapx.pen file contains many new pen styles. • Node Limit: The maximum number of nodes for regions and polylines has been increased to 1,048,572 nodes for a single polygon region or polyline. The limit drops by seven nodes for every two additional polygons. If an object with more than 32K nodes is saved and the table is read in a version of MapX prior to version 3.5, the object(s) will not be visible. Objects in the table that do not exceed the 32K limit will be visible. • Support for spatial predicates and functions in SQL queries submitted to SpatialWare: Previously, you were limited to non-spatial SQL as in: SELECT SW_GEOMETRY, SW_MEMBER, CUSTOMER_NAME FROM CUSTOMER WHERE CUST_ID > 100000; Now, you can include spatial operates as in: SELECT SW_GEOMETRY, CUST_ID, ST_AREA (SW_GEOMETRY) FROM CUSTOMER, ZIPCODE WHERE ST_OVERLAPS(CUSTOMER.SW_GEOMETRY, ZIPCODE.SW_GEOMETRY) AND ZIPCODE = ’12345’; 38 MapX Developer’s Guide Chapter 3: New in MapX Enhancements to Properties, Methods, and Events • The new ComputeTheme parameter of the Theme.Add method lets you create a noncompute theme. A non-compute theme gives you the ability to create a theme without having the ranges automatically calculated for you. You can then create the ranges yourself. This is a faster way for drilldown and server layers. See also DataMin, DataMax, and ComputeTheme. • There are new ColorConstants for system colors such as miColorWindowBackground. • The DLG option of the ConnectString property controls the display of the connection dialog box: • You can now pass a Rectangle object to the CreateRegion method which creates a region using the four corners of the rectangle. Additional Properties, Methods, and Events • The ActiveAnnotation method returns the currently selected annotation (or NULL if no annotation is selected). • The BackColor property controls what color the background of the map is ’erased’ with before drawing the map. • The Border property controls whether or not to draw the title’s border. • The ComputeTheme, DataMin, and DataMax properties control whether themes are computed and the minimum and maximum values to set the range for computed themes. • The DrawLabelsAfter property allows for better control over where labels are in the drawing order. • The LineInterleaved property is used to make a pen style interleaved if that pen style supports being interleaved with the LineSupportsInterleave property. • The LineSupportsInterleave property is a read-only boolean property which denotes whether a given pen style supports interleave or not. • The LineWidthUnit property controls the unit of measurement for the line width. The width is specified in either pixels (default) or tenths of points, by specifying a StyleUnitConstants value. • The MapInitialized event is called immediately after map initialization is complete. It serves to notify the container application of the best time to do any necessary run-time configuration. • The MapScreenWidth and MapScreenHeight properties make it easier to position legends. • The MouseWheelSupport property controls the level of Intellimouse support: None, Zoom/Scroll only (no AutoScroll), or Full. MapX Developer’s Guide 39 Chapter 3: New in MapX • The PaperHeight and PaperWidth properties contain the paper height and width of the legend in Map.PaperUnit units. • The PrintLegend method prints the legend in the specified rectangle to the specified device context. • The RegionBorderWidthUnit property controls the unit of measurement for the region border width. The width is specified in either pixels (default) or tenths of points, by specifying a StyleUnitConstants value. • The Datasets.RemoveAll method removes all Dataset objects from the collection. • The Fields.RemoveAll method removes all Field objects from the collection. • The Layers.RemoveAll method removes all Layer objects from the collection. • The Parts.RemoveAll method removes all Parts objects from the collection. • The Points.RemoveAll method removes all Point objects from the collection. • The Themes.RemoveAll method removes all Theme objects from the collection. • The SearchPath property allows the user to set the Search Path dynamically. This property is available at run-time only. • The ShowCount property controls whether or not to show on the legend the count portion of the ranges. • The Value property gets or sets the value used in an individual value theme. • The Visible property controls whether ranges are visible for the legend. Note: The following section summarizes the improvements made to MapX for version 3.0. If you are upgrading directly from MapX version 1, you also might want to read about features added in version 2. 40 MapX Developer’s Guide Chapter 3: New in MapX Enhancements and Additions to MapX v3.0 The following overview summarizes the improvements made to MapX for version 3.0. • MapX now provides support for coordinate systems and map projections, including support for custom datums and affine transformations. For details, see the discussion of Coordinate Systems. • A new type of map layer, the Drilldown layer, allows users to explore the map by pointing and clicking. If you want to see more detail about a particular region, click on that region; the region is replaced by smaller, more detailed features. • Spatial Server Access (SSA) is a powerful new feature that allows developers to connect to live data stored in spatial servers, such as MapInfo's SpatialWare running on Oracle and Informix databases. Spatial servers allow companies to host their map data in their enterprise database for central management and security. Spatial servers like SpatialWare offer advanced query processing and increased performance on the server for an organization's spatial data. For details, see Accessing Remote Spatial Data. • A new Dynamic Data Binding feature improves performance when you use ODBC to access live data on a large database server. Ordinarily, when you bind data, MapX makes a static copy of data when the database is opened. A new, optional argument of the Datasets.Add method lets you specify that the data binding should be dynamic, in which case MapX grabs data in a live mode, only copying data as it is needed. Dynamic data binding is also supported if you develop your own custom dataset support. • New object processing capabilities allow you to combine, buffer, intersect, or erase point, line and region features. For details, see the new FeatureFactory object. • The list of standard tools now includes a polygon select tool. This tool allows the user to draw a polygon, and then selects features inside the polygon. Also, the CreateCustomTool method now takes additional, optional parameters, allowing you to specify different cursors that should be used if the user holds down SHIFT or CTRL while using the tool. • You now can display point features using either TrueType font symbols (as in earlier versions of MapX) or bitmap symbols. TrueType font symbols now support a new Style.SymbolFontRotation property, which allows you to rotate symbols. Also, the Style object now supports a new LineStyleCount property, and a new RegionTransparent property that lets you create transparent fill patterns. MapX Developer’s Guide 41 Chapter 3: New in MapX • MapX now includes a new utility, GeosetManager.exe, which makes it easier to create your own geosets. You can run this utility from the Start menu. Note: MapX 3.0 also provides source code for a sample Visual Basic 5 project called GeosetManager, which provides functionality very similar to GeosetManager.exe. However, you do not need to install this sample VB project to run the GeosetManager.exe utility. 42 • The BindLayer object has several new properties: The CoordSys property specifies a coordinate system when you create a layer in xy or pointref binding. The Filespec property allows you to create a permanent layer instead of a temporary one. The KeyLength property specifies the length of the character column in the resulting layer. • A new Bounds property returns a rectangle that represents the minimum bounding rectangle. Several objects—the Map object, Layers collection, Layer object, Features collection, and Feature object—all support the Bounds property. The Bounds property is useful when you need to determine the geographic extents of one or more features on the map (e.g. so you can zoom out far enough to see all of the features). For an example see Zooming to Show an Entire Layer. • The Map object supports a new SaveMapAsGeoset method, which creates a new Geoset based on the current status of the map (layer settings, zoom level, etc.). • The Theme object supports a new Fields property, which returns a Fields collection. • Thematic ranges can be calculated using two new methods: Natural Break and Standard Deviation. See ThemeProperties.DistMethod. • Two new properties —ThemeProperties.AllowEmptyRanges and Legend.ShowEmptyRanges — give you more control over "empty" ranges (ranges that do not contain any features). • Two new properties — Map.SelectionStyle and Map.ExportSelection — allow you to control the display and exporting of the selection highlighting style. • Even if you cannot access your data sources through the standard MapX data binding techniques, you can create your own custom dataset support. MapX version 3 provides a run-time extensible architecture, allowing you to plug in custom dataset types through a COM based dataset interface. See Custom Dataset Support. • Enhancements to the Layer object: A new GetFeatureByID method retrieves a feature, given its ID. The SearchWithinFeature method can now search within a stand-alone feature. The SearchWithinDistance method now allows you to specify either a Point object or a Feature object as the starting location for the search; earlier versions did not allow you to specify a Feature object. • The Layers property page now includes additional buttons—Add, Remove, Up and Down—that allow you to add, remove, or change the order of the layers in the map. • The Feature object's Bounds, Length, Perimeter, and Area properties can now work on stand-alone features. MapX Developer’s Guide Chapter 3: New in MapX • If a MapInfo table contains an arc, circle, rectangle, or rounded rectangle feature, and a MapX application modifies that feature, MapX automatically converts the feature into a line or region when updating the feature. See Automatic Conversion of Special Features. Users can press the ESC key to interrupt the drawing of the map (provided that the application in which MapX is embedded has the focus). Upgrading MapX v2.0 Applications to MapX Version 3 Some of the changes in MapX 3.0 might interfere with applications that were written using version 2. If your MapX version 2 application does not run correctly under version 3, try the following: • In version 2, the standard labeling tool (miLabelTool) had a value of 1010. In version 3, the labeling tool's new value is 1011; the new miPolygonSelectTool has the value 1010. If you used the label tool's literal value (1010) instead of its define, you will need to update your code to use the new value. • The PolyToolUsed event now takes additional parameters (added to provide support for modifier keys, and to allow you to cancel a tool's action). • The DrawUserLayer event now takes an additional parameter (added to address problems when drawing to a metafile). • The SearchWithinDistance method now expects an additional Units parameter, which explicitly specifies the map units that apply to the search distance. • Stand-alone features must be "attached to the map," so that a coordinate system is associated with the feature. You can explicitly attach a feature to the map through the new Feature.Attach method. Note that you do not need to use the Attach method with objects that were created through the new FeatureFactory object; FeatureFactory methods create features that are already attached to the map. • The Map.MBR property has been renamed to Map.Bounds, and the Feature.MBR property has been renamed to Feature.Bounds. • If you modify a feature in a layer (not a stand-alone feature), and you have not yet performed an Update to save the changes, then the Feature object's Bounds, Length, Perimeter and Area properties return values that are based on the "modified" version of the object (the object as it exists in memory). In earlier versions of MapX, the values returned by these properties did not reflect modifications made to the feature. • The Title.Position and Graphic.Position properties behave differently in version 3; as a result, titles and text annotations may be positioned differently than they were in version 2. For example, suppose you assign the value miPositionTL ("Top Left") to the MapX Developer’s Guide 43 Chapter 3: New in MapX Graphic.Position property. MapX version 3 positions the text annotation so that the text is above and to the left of the anchor location; MapX version 2 used the opposite orientation (placing the anchor location at the top left corner of the text). Also, changing the Position property on the title (or an annotation) will keep the object's (X, Y) properties constant and reposition the object using the new position value. (In version 2, MapX left the object in place, and changed (X,Y) to reflect the new position value.) • The ODBC library used in version 2 (mideodbc.dll) has been replaced by a new library: MODBCDataset.dll. ODBC access also requires a new library: MMapXColumnInfo.dll. • The Lotus Notes library used in version 2 (midenote.dll) has been replaced by a new library: MNotesDataset.dll. Lotus Notes access also requires a new library: MMapXColumnInfo.dll. • MapX version 3 includes an updated set of DLLs that provide support for exporting images. The new DLLs have slightly different names to reflect the new version (e.g. the GIF export DLL has been renamed from lfgif60n.dll to lfgif70n.dll). • If you have created your own installer to install MapX version 2, you may need to modify the part of the installation script that creates registry keys. Instead of registry keys that end in "2.0", MapX version 3 uses registry keys that end in "3.0". See Distributing Your MapX Application. • If you wrote a Delphi, PowerBuilder or LotusScript application using MapX version 2, and your application creates stand-alone, creatable objects, you may need to modify your syntax to make your application work with MapX version 3. For example, you might need to change "MapX.Style.2" to read "MapX.Style.3". See Creatable Objects. • The ThemeCategories object has been replaced by three new collection objects: RangeCategories, IndividualValueCategories, and MultivarCategories. For example, in version 2, you might have written code like this: DIM categories AS ThemeCategories SET categories = Map1.Datasets(1).Themes(1).ThemeProperties.RangeCategories With MapX version 3, you would modify the code to use the new object name, like this: DIM categories AS RangeCategories SET categories = Map1.Datasets(1).Themes(1).ThemeProperties.RangeCategories 44 MapX Developer’s Guide Chapter 4: Mapping Concepts 4 Chapter Mapping Concepts Now that you have installed MapX and been enticed by the wide variety of features and functionality in the What’s New chapter, you are probably anxious to get mapping. But, first, take a few minutes to read this ➤ Mapping Concepts ➤ Organizing Your Data and Maps: An Overview of Tables ➤ What Are GeoSets? chapter, especially if you are new to MapX. This chapter ➤ Map Features gives you a solid understanding of the concepts for ➤ Putting Your Data on the Map successful mapping with MapX. ➤ The Power of MapX Chapter 4: Mapping Concepts Organizing Your Data and Maps: An Overview of Tables To use MapX, you need the files that contain your records and maps that come from MapInfo. MapX organizes all its underlying information in the form of MapInfo tables; each table is a group of MapInfo files that is used to build a layer in a map. How Files Make Up a Table All MapInfo tables will have the following files: • <Somefile>.tab: This file describes the structure of the MapInfo table. It is a small text file describing the format of the file containing the data. • <Somefile>.dat(.mdb, .aid, or .dbf): These files contain the tabular data. • <Somefile>.map: This file describes the graphic objects (will not exist if the table has no map objects). • <Somefile>.id: This file is a cross reference file that links the data with the objects (will not exist if the table has no map objects). • <Somefile>.ind: This is an index file. The index file allows you to search for map objects using the Find object. MapInfo Tables and MapX Layers Each mappable MapInfo table can be displayed as a layer in a map. For example, you can display a table of customers, a table of streets, and a table of county boundaries. Think of these layers as transparencies where each layer contains a different part of the map. The layers are stacked one on top of the other and allow you to see all aspects of the map at the same time. 46 MapX Developer’s Guide Chapter 4: Mapping Concepts What Are GeoSets? A geoset keeps a collection of map layers and their settings easily available to you. Geosets are data sets made up of standard MapInfo format map files (.tab) of the same geographic region, hence the name geoset. Geosets help you to avoid the time consuming task of opening and displaying layers individually each time you want to work with them as a sample map. The extension for a geoset is .gst. A .gst is a text file that contains several metadata keys that tell MapX what tables to display and how to display them. When a geoset is opened, it automatically opens all of the files included in the geoset to a default display. The developer can change the default display to meet their individual needs. A geoset's settings include projection, default zoom, auto-labeling of objects, zoom layering and whether the table is visible when opened. MapX will also open any single (.tab) map file the developer specifies. Geosets are provided for convenience and are not required for MapX to function. MapX will not open a MapInfo workspace (.wor file type). MapX Developer’s Guide 47 Chapter 4: Mapping Concepts Geosets Available with MapX 48 Geosets Layers in Geoset Argentina Geoset Argentina Major Cities Argentina Cities Argentina Country Boundary South America Country Boundaries World Ocean (Lat / Long) Asia Geoset Asia Asia Major Cities Asia Capitals World Ocean (for Asia) European Country Boundaries Australia Geoset Australia State Boundaries Australia State Capital Cities Australia Major Cities Australia Cities Australia Highways World Ocean (Lat / Long) Brazil Geoset Brazil Major Cities Brazil Cities Brazil Country Boundary South America Country Boundaries World Ocean (Lat / Long) Canada Geoset Canadian Province Boundaries Canadian Province Capital Cities Canada Major Cities Canada Cities Canada Highways World Ocean (Lat / Long) US State Boundaries China Geoset China Major Cities China Cities China Country Bdy China Highways World Ocean (for Asia) Asia Major Cities Asia Country Boundaries MapX Developer’s Guide Chapter 4: Mapping Concepts Geosets Layers in Geoset Dallas, TX Geoset Dallas Major Highways A Dallas Major Highways B Dallas Streets A Dallas Streets B Dallas Streets C Dallas City Boundary A Dallas City Boundary B Dallas Water Rivers Dallas Water Bodies Dallas, TX Raster Dallas Locations Crime Demo Map Crime County Map DC Geoset DC Landmarks DC Roads DC State Roads DC Interstate Roads DC Highways DC Zips Dc Area Landmarks Dc Water Layer Dc City Boundaries Europe Geoset European Country Boundaries European NUTS 1 Level Boundaries European NUTS 2 Level Boundaries European Capitals European Highways European Major Cities European Cities World Ocean (Lat / Long) Asia France Geoset France NUTS 2 Level Administrative Boundaries France Major Cities France Cities France Highway Map World Ocean (Lat / Long) European Country Boundaries MapX Developer’s Guide 49 Chapter 4: Mapping Concepts 50 Geosets Layers in Geoset Germany Geoset Germany NUTS 2 Level Bdys Germany Major Cities Germany Cities Germany Highways World Ocean (Lat / Long) European Country Boundaries India Geoset India State Bdys India District Bdys India Minor Cities India Major Cities India Capital Cities Asia World Ocean (for Asia) Israel Geoset Israel Major Cities Israel Cities Israel Country Boundary World Ocean (Lat / Long) Africa Country Boundary Asia Italy Geoset Italy Major Cities Italy Cities Italy Highways Italy NUTS 2 Level Bdys World Ocean (Lat / Long) European Country Boundaries Japan Geoset Japan Country background Japan Cities Japan Major Cities Japan Cased Roads Japan Highways Japan Rivers and Lakes World Ocean (Lat / Long) Mexico Geoset Mexico State Boundaries Mexico Cities Mexico State Capital Cities Mexico Highways Mexico Major Cities World Ocean (Lat / Long) US State Boundaries MapX Developer’s Guide Chapter 4: Mapping Concepts Geosets Layers in Geoset Mid-Atlantic Geoset Mid-Atlantic Capitals Mid-Atlantic Counties Mid-Atlantic Highway Mid-Atlantic Major Cities Mid-Atlantic Cities Mid-Atlantic States World Ocean (Lat / Long) US State Boundaries North American Geoset Canadian Province Boundaries Canadian Province Capital Cities Canada Major Cities Canada Cities Canada Highways Mexico State Boundaries Mexico Cities Mexico State Capital Cities Mexico Highways Mexico Major Cities US Cities US Major Cities US Highways US State Boundaries US State Capitals World Ocean (Lat / Long) Portugal Geoset Portugal Major Cities Portugal Highways Portugal NUTS 2 Level Boundary World Ocean (Lat / Long) European Country Boundaries South Korea Geoset South Korea Major Cities South Korea Cities South Korea Country Boundary Asia World Ocean (for Asia) Spain Geoset Spain Highways Spain Major Cities Spain Cities Spain NUTS 2 Boundaries World Ocean (Lat / Long) European Country Boundaries MapX Developer’s Guide 51 Chapter 4: Mapping Concepts 52 Geosets Layers in Geoset UK Geoset United Kingdom Cities United Kingdom Standard Regions United Kingdom Class A Roads United Kingdom Motorways World Ocean (Lat / Long) European Country Boundaries US Detail Geoset US Cities US top 20 Cities US Major Cities US Highways US State Boundaries US State Capitals World Ocean (Lat / Long) Mexico State Boundaries Canadian Province Boundaries US County Boundaries US Zipcode Boundaries Landmark Map US Geoset US Cities US top 20 Cities US Major Cities US Highways US State Boundaries US State Capitals World Ocean (Lat / Long) Mexico State Boundaries Canadian Province Boundaries US County Boundaries World Detail Geoset World Countries World Capitals WorldTop 25 Cities World Ocean (Robinson) World Graticule World Major Cities World Minor Cities World Geoset World Countries World Capitals WorldTop 25 Cities World Ocean (Robinson) World Graticule MapX Developer’s Guide Chapter 4: Mapping Concepts Geosets Layers in Geoset Other Files US 5-Digit Zipcode Points US 5-Digit Zipcode Points (compressed point file) Dallas Major Highways from MapXsite Streets 1.0 Dallas Streets from MapXsite Streets 1.0 Dallas City Boundary from MapXsite Streets 1.0 Dallas Water Rivers from MapXsite Streets 1.0 Dallas Water Bodies from MapXsite Streets 1.0 The MapStats.mdb This is not a geoset, rather, an access database containing demographic information that matches many of the geosets that in MapX. MapStats.mdb • Demographics for Australia • Demographics for Asia • Demographics for the World • Demographics for DC • Demographics for Mid-Atlantic States • Demographics for US • US Customer Database • US County Age Demographics • US County Age Demographics by Gender • US County Household demographics by Age, Income • US County Household demographics • US County Household Income • US County Housing Values • US County Population Demographics Map Features We mentioned earlier that maps in MapX are made up of layers of map objects. These map objects are accessed in MapX through the Feature object. There are four basic types of features: • Regions: closed objects that cover a given area. These include polygons, ellipses, and rectangles. For example, country boundaries, postal code boundaries, sales territories. • Point objects: represent single locations of data. For example, customer locations, restaurants, parking meters. MapX Developer’s Guide 53 Chapter 4: Mapping Concepts • Line objects: open objects that cover a given distance. These include lines, polylines, and arcs. Examples are streets, rivers, powerlines. • Text objects: text that describes a map or another object, such as labels and titles. You can have each type of object in a separate layer (most common), or you can combine objects in the same layer. MapX lets you create, edit, customize, and display these objects to make maps that meet your needs. Putting Your Data on the Map Datasets enable you to bind data your maps. For example, if you have a Microsoft Access database of sales by county, you could bind that data and display it on a counties map in order to spot trends in sales patterns by county that are not easily identified in the tabular data alone. There are many different types of databases in businesses today; therefore, MapX lets you bind to several different types of DataSources. The first argument to the Datasets.Add method lets you specify a DatasetTypeConstants value, which dictates the type of data binding you wish to perform. Types of data sources you can bind to include: 54 Datasource Description ADO This type of databinding uses the MS Active data objects ADO recordset. DAO A DAO Recordset object. You can get one from a Visual Basic data control, an Access form, or by creating one in Visual Basic, Access, or C++. Delphi This type uses the Borland BDE datasources. Global Handle This type of data binding lets you pass in a block of tab-delimited data. Layer This type of data binding lets you create a dataset that uses fields from a MapInfo table. Notes View/ NotesQuery These types of data binding deal specifically with Lotus Notes. ODBC MapX can use ODBC to retrieve data from any ODBC data source. OLE Data This is for containers such as PowerBuilder. MapX Developer’s Guide Chapter 4: Mapping Concepts Datasource Description Oracle Express Objects This allows access to the datacube as a dataset. RDO This uses MS Remote Data Objects and RDO Resultset object. SafeArray A COM dataset that allows static binding of data from a safearray. Unbound If you cannot support one of the other formats, MapX provides a ‘back door’. With this type of data binding, you can set up an event loop whereby MapX asks the container for data values, one cell at a time. Tools to Get the Job Done Most mapping applications provide an assortment of toolbar buttons (tools) to aid with common drawing tasks (such as drawing a line on the map) and navigation tasks (such as zooming in). MapX provides several common mapping tools, plus you can also create your own custom tools. Standard Tools With MapX, you can easily incorporate common tools into your application, without reinventing the wheel. MapX provides built-in support for several common mapping tools, including: • Navigation tools (Zoom-In, Zoom-Out, Pan, Center) that let the user change the scale and placement of the map. • A Labeling tool that lets the user click a map feature to label it. • A set of Selection tools that give the user various ways to select map features. • Annotations (symbols and text). Custom Tools If you need a type of toolbar button that MapX does not provide, you can simply create a custom tool by using the CreateCustomTool method. MapX Developer’s Guide 55 Chapter 4: Mapping Concepts The Power of MapX Now that you have an overview of tables, layers, geosets, map features, datasets and tools, you are ready to bring the full capabilities of MapX into play. With MapX, you can search a layer in a map and locate a specific feature within the layer. For instance, you could use it to find the closest dealer to Lackawaxen, PA. Or, you can calculate distances between health care providers and their patients, then get counts on how many patients live within a given radius of a particular hospital. Or, you could shade boundaries (counties, towns, states, countries) according to the total number of customers in each one or according to the number of customers who purchased within the last year. MapX refers to this as thematic mapping. As you become better acquainted with MapX, you will find that its applications are limited only by your imagination. 56 MapX Developer’s Guide Chapter 5: MapX Basics 5 Chapter MapX Basics In the Getting Started chapter, we created a simple MapX ➤ MapX Basics ➤ Map Object map using the MapInfo MapX Control, and in the ➤ Property Page previous chapter we introduced you to some MapX ➤ Layers mapping concepts. This chapter is an overview of the ➤ GeoSets major components behind MapX map creation and manipulation within an application. Selected topics will be discussed in detail in subsequent chapters. ➤ DataSets ➤ Annotations ➤ Creating Objects Chapter 5: MapX Basics Map Object Looking at the partial MapX object hierarchy in the following diagram, you see that the map object itself is at the top. Every MapX object, property, and method is derived from the Map object. Every property and method shown underneath the map object will somehow contribute to building the overall Map object. Primarily DataSets, Layers, and Annotations objects define each Map object. 58 MapX Developer’s Guide Chapter 5: MapX Basics Partial MapX Object Model Note: This is not a complete MapX object model. The following table shows some of the Map object properties that are represented by numeric values. These properties may be changed at design time, or at runtime using the following code samples: Property Description Code Sample Zoom Sets the number of miles (default unit of measure) displayed in the map. Map1.Zoom = 500 Rotation Rotates the map a specified number of degrees. Map1.Rotation = 179 MapX Developer’s Guide 59 Chapter 5: MapX Basics Property Description Code Sample CenterX Sets the x and y coordinates which Map1.CenterX = -79.4458 may be Longitude or Latitude. This is dependent upon the projection of the map. CenterY Sets the x and y coordinates which Map1.CenterY = 44.9932 may be Longitude or Latitude. This is dependent upon the projection of the map. With the Map object, you can control how a map is displayed by manipulating several methods and properties of the map. There are some properties represented by other objects. For instance, when you see a MapX map, you are seeing a collection of individual layers, represented by the Layers collection. The Layers collection is a property of the Map object. Now let’s take a look at altering the properties of our map. The Property Page allows us to manipulate many properties of the map object. 60 MapX Developer’s Guide Chapter 5: MapX Basics Property Page The Property Page is an extremely useful place to alter the properties of the map while you are designing and testing an application. To access the Property Page in your Visual Basic project: 1. Click on Custom from the Properties Window. 2. Click the button on the MapX Developer’s Guide Custom row. 61 Chapter 5: MapX Basics Additionally, the Property Page can be accessed during design time by right clicking on the Map object within the form and selecting "Properties..." You may also view the Property Pages during run time. To do this, add the following code to the Map.Mouse_Up event. If Button = 2 Then Map1.PropertyPage This will test to see if the user clicked the right mouse button and then show the Property Page at runtime. Use the right mouse button, as it will not interfere with the normal use of tools (left button). Note: You should only use this code during designing and testing as it may give the user too much control over the map. However, if you want your finished product to display a dialog box for your end users, you may want to use the Layers.LayersDlg method instead of the PropertyPage method, because the LayersDlg dialog is more user-friendly. This method is discussed in the next chapter. 62 MapX Developer’s Guide Chapter 5: MapX Basics Layers Let’s consider a database of points on a map represented by black stars. By itself, this map is not very useful, but when you overlay the point map on top of a line map and a region map, you have a very useful map. Each individual map is referred to as a layer, and MapX stores a map as a collection of layers. MapX Developer’s Guide 63 Chapter 5: MapX Basics The layers may be altered at design-time through the MapX Properties dialog box, or programmatically during run-time. In the section above, the Properties dialog box allows the designer to manipulate the layers simply by changing the settings. In the next chapter, we will take a look at the code that can be used to change the layers properties and methods at any time within the program. Adding new layers, removing layers, and changing the visibility or style of a layer are among some of the actions you can perform on a layer. Layers Collection The Layers collection is made up of (0 - n) Layer objects. The Layer object is made up of a collection of features, with each feature having its own properties and styles. A collection of features is made up of Feature objects, which correspond to a feature on the map such as a point, line, or region.You can create stand-alone Feature objects, or you can obtain a collection of Feature objects. Features will be discussed in chapter: "Features and Selections". GeoSets A GeoSet is a collection of map layers and their settings. The GeoSet determines the collection of MapInfo table(s) used within a Map object and their settings. A GeoSet can be specified at design time. If this is set during run time, it will first remove all loaded layers and datasets, then load the new GeoSet. The default GeoSet that is loaded is US.GST. If you are familiar with MapInfo Professional, a workspace is similar to a GeoSet in MapX. Specifying an alternative GeoSet to load at run-time, adding a layer to the map object, or manipulating the look of a layer can be done through the Property Page, as discussed earlier, or through the MapX Geoset Manager program that ships with MapX and is found in the MapX Program Group. 64 MapX Developer’s Guide Chapter 5: MapX Basics Below is a map of the United Kingdom with specified Geosets. When you are satisfied with your map, you may save it. This will write the GeoSet (*.GST) file to your drive. When you open that GeoSet file, all of your map layers and settings will be returned as you have saved them. The GeoSet Manager lets you modify layers, manage zoom levels, labels, and other properties. For more information on the GeoSet Manager, see appendix: "Using the Geoset Manager". GeoDictionary The GeoDictionary is used when trying to match a data source and a map layer for databinding or creating a theme map. The GeoDictionary is a file (typically named geodict.dct) that maintains information about which map layers can be matched, and which fields can be used as match fields. Files need to be registered in the Geodictionary if you wish to take advantage of automatching/autobinding. For example, if you have data that has sales by state, the GeoDictionary may determine that that data should be matched against the “USA” map layer. MapX Developer’s Guide 65 Chapter 5: MapX Basics You can specify programatically or explicitly the column(s) to match from the map against which column in your data file/table, or you can let MapX reference the GeoDictionary to try and find a match. Modifying the GeoDictionary Registering a MapInfo table in the GeoDictionary is necessary if you wish to take advantage of automatching when doing data binding. Data binding will be covered in chapter: "Putting Data on the Map". The MapX GeoDictionary Program ships with MapX and allows you to register a new MapInfo table into the GeoDictionary. Additionally, within the MapX GeoSet Manager there are options under the Tools menu. Within the MapX GeoDictionary, click on the Register button, and simply select the table you wish to register, set the table properties and enter a description for the table. If you wish to automatically load the table to a GeoSet, click the Add button and select the existing GeoSet you wish to add the table to. 66 MapX Developer’s Guide Chapter 5: MapX Basics If the path for the new table you have registered is not listed within the MapX search path, the Map Manager program will then ask if you wish to copy the data into the MapX data directory or simply add the path to MapX’s search path. Something to keep in mind when distributing your application and associated data is that there are copyright laws involving many types of data. Make sure that you have the rights to distribute the data. If you are not sure, contact your data provider For more information on the GeoDictionary, see Appendix: Using the GeoDictionary Manager. DataSets DataSets enable you to bind data to your maps. For example, if you have an MSAccess database of sales by county and a map of counties you could bind that data to the county map and spot trends in sales patterns by county not easily highlighted in the tabular data. As indicated above, if MapX is required to specify the match between your data and a map, the match is determined through a process called automatching/autobinding. You must first register the map into the GeoDictionary to take advantage of automatching/autobinding. Once the data is bound to the map, you can view pertinent information geographically. The visual representation of data enables the creation of a theme map. A theme is the color-coding of the map to geographically represent trends in data. Data Binding is discussed in chapter: "Putting Your Data on the Map". Theme mapping is discussed in chapter: "Theme Mapping and Analysis". MapX Developer’s Guide 67 Chapter 5: MapX Basics Annotations The Annotations collection is an easy way to get text and symbols onto a map. The annotations sit “on top” of all other layers and are not linked to any data. If you are familiar with MapInfo software, the annotations are similar in purpose to a map’s cosmetic layer. Listed below are methods and properties for the Annotations collection object: Annotations Collection Methods 68 Method Description Code Sample AddSymbol Adds a symbol to the Annotation collection. A default style is used (as specified in Map.DefaultStyle). Map1.Annotations.AddSymbol _ X, Y AddText Adds text to the Annotation collection. The fourth parameter is the initial position of the text relative to the coordinates given. Map1.Annotations.AddText _ “Developer Services”, _ 79.44, 46.8889, _ miPositionTL Remove Removes a specific Annotation from the collection. Map1.Annotations.Remove 1 RemoveAll Removes all Annotations from the collection. Map1. Annotations.RemoveAll MapX Developer’s Guide Chapter 5: MapX Basics Annotation Collection Properties Property Description Code Sample Editable Specifies whether or not the annotation will be editable. Map1.Annotations.Editable _ = True Type Specifies the Annotation object type. If Map1.Annotations(2).Type_ = miTextAnnotation Then _ Print “It is text” Graphic This contains a Graphic object, which has properties for the Annotation. See the Graphic object description in the Online Help. Notice that there is no property for position, symbol style, or text in the annotation object. The annotation’s graphic property contains a graphic object containing this information. To modify the annotation, modify the annotation’s graphic object. The following code adds a symbol to a specified location: 'Add a symbol at location Map1.Annotations.AddSymbol X1, Y1 MapX Developer’s Guide 69 Chapter 5: MapX Basics Creating Objects In the MapX object model, you can create stand-alone objects using the following object classes. BindLayer ODBCQueryInfo BitmapSymbols Parts Feature Point Fields Points NotesQueryInfo Rectangle NotesViewInfo Style The following examples show how to create a stand-alone style object, display a styleselection dialog box, and use the new style to set the override style of a layer. Note that Delphi and PowerBuilder require you to specify the MapX version number after the object name (e.g., "MapX.Style.4"). This arrangement allows you to have multiple versions of MapX installed on your computer simultaneously. If you develop a MapX version 4 application, and then install a later version of MapX on the same computer, the new version of MapX will not interfere with the MapX version 4 application. Visual Basic Example Dim s as new MapXLib.Style s.PickRegion set Map1.Layers(1).Style = s C++ Example CMapXStyle style; style.CreateDispatch(style.GetClsid()); // can also use style.CreateDispatch("MapX.Style.4"), // but above is more portable between versions of MapX style.PickRegion(); m_ctrlMapX.GetLayers().Item(1).SetStyle(style); 70 MapX Developer’s Guide Chapter 5: MapX Basics Delphi Example Var s : variant; begin s := CreateOleObject('MapX.Style.4'); s.PickRegion; MapObject.Layers.Item(1).Style := s; end PowerBuilder Example OLEObject s long oleStatus s = CREATE OLEObject oleStatus = s.ConnectToNewObject("MapX.Style.4") ole_1.Object.Layers.Item(1).Style = s MapX Developer’s Guide 71 Chapter 5: MapX Basics 72 MapX Developer’s Guide Chapter 6: Mapping in Layers 6 Chapter Mapping in Layers This chapter presents the relationship between tables and maps, and shows how they are layered to create the level of detail you want. ➤ Mapping in Layers ➤ Maps as Layers ➤ The Layers Collection: Building Blocks of Your Map ➤ Properties of the Layers Collection ➤ Methods of the Layers Collection ➤ The Layer Object ➤ Layer Order ➤ Examining Layers ➤ Checking a Layer’s Feature Type ➤ Zoom Layering ➤ Generating Labels for a Layer ➤ Annotations ➤ Raster Images ➤ Animation Layers ➤ Drawing Layers Chapter 6: Mapping in Layers Maps as Layers You have already been introduced to the concept of computer maps as a collection of layers in the previous chapter. Each MapInfo table that contains graphic objects can be displayed as a layer in a Map window. For example, you can display a table of customers, a table of streets, and a table of county boundaries. Think of these layers as transparencies where each layer contains a different part of the map. The layers are stacked one on top of the other and allow you to see all aspects of the map at the same time. For example, one layer may contain country boundaries, a second layer may have symbols that represent capitals, and a third layer might consist of highways. Laying these transparencies one on top of the other builds a complete map. Now let’s get into the specifics of creating a map. The Layers Collection: Building Blocks of Your Map The Layers collection is a property of the Map control and contains Layer objects. These Layer objects, which are built from MapInfo tables, make up your map. Each layer contains different map features, such as regions, points, lines or text. The Layers collection has properties and methods used to perform operations such as adding and removing Layer object(s) from the collection. How to Get a Layers Collection One way to get a Layers collection is to load a geoset at design-time. As we said in the previous chapter, a geoset defines a collection of map layers and their settings.When you add a Map contol to a form, by default MapX loads the United States Geoset (US.GST). In other words, you start with the Layers collection as defined in the United States Geoset. 74 MapX Developer’s Guide Chapter 6: Mapping in Layers Let’s say you want to write an application that begins with a map of World Countries, that is, a collection of Layers that together make up a map of theWorld.You can do this by specifying the World Countries Geoset at design time: 1. Click Geoset from the Properties Window. 2. Click the drop-down arrow found on the Geoset row. 3. Select World Countries from the list of available Geosets. The Layers collection as defined in the World Countries Geoset will be loaded when you run your application. The World Countries map will appear in your Map control. The Property Page A quick way at design-time to see all the Layer objects that comprise a Layer collection is through the Property Page. The Property Page is an extremely useful place to alter the properties of a map while you are designing and testing an application. In this case, we will use it to see the Layers in the World Countries collection. 1. Click Custom from the Properties Window. 2. Click found in the Custom row. The Property Page will appear. MapX Developer’s Guide 75 Chapter 6: Mapping in Layers 3. Click on the Layers tab to view a list of the Layers in the collection. You can use this page to modify many properties of Layer objects in the collection, reorder Layers, or add and remove Layers in the collection. For example, you can make a layer of the map invisible when the map is displayed by highlighting the layer and clearing the Visible check box. When the map is displayed, that layer will not be visible. Of course, you can reset the layer to visible programmatically during run-time, for example: Map1.Layers.Item(2).Visible = True We’ll work a lot more with layers programmatically, in the following section. 76 MapX Developer’s Guide Chapter 6: Mapping in Layers Some Properties of the Layers Collection Each Map has a collection of layers. The Layers collection is made up of Layer objects. The Layers collection has methods and properties used to add and remove Layer objects from the collection. Note: The MapX Reference manual and Online Help have a complete listing of Layers Collection methods and properties. Get the Number of Layers in a Collectio A very useful property of any collection is the Count property. This will tell you the number of items, in this case the number of layers, in a collection. This is used if you want to cycle through each item in the collection, for example, getting the names of each item: Dim x as integer For x = 1 to Map1.Layers.Count Print Map1.Layers(x).Name Next Get a Layer from the Collection The Item property gets a specific Layer object from the collection. The Item property returns one of the layers as an object and is the default method for the Layers collection. You can reference layers by index value, such as 1, 2, and so on, but you can also reference layers by their names, such as Highways or Cities: Dim lyr as Layer Set lyr = Map1.Layers.Item(“Highways”) -orDim lyr as Layer Set lyr = Map1.Layers.Item(3) In your application you will be frequently referencing objects, properties, and methods through the Layers collection. You can use the fact that Item is the default method to abbreviate your code. For example, each of these lines of code makes an identical assignment. Map1.Layers.Item(3)Visible = False Map1.Layers(3).Visible = False Map1.Layers.Item(“Highways”).Visible = False Map1.Layers(“Highways”).Visible = False MapX Developer’s Guide 77 Chapter 6: Mapping in Layers Get the Geographic Extent of a Collection The Bounds property returns a Rectangle object representing the geographic extents of all layers in the collection (except the UserDraw layer). This property is useful if you want to zoom the map out far enough to show all objects in all layers: 'This sets the map bounds to the geographic extents of all layers in 'the collection effectively bringing the entire map into view. On Error Resume Next Set Map1.Bounds = Map1.Layers.Bounds End Sub Some Methods of the Layers Collection The Layers Collection has several methods that control which layers are in the collection and how they are displayed. There is also a method that will enable the user to call the Layer Control dialog allowing users to manipulate the methods and features of a layer. The methods may also be set at design-time using the Property Page, as discussed earlier in this chapter. 78 MapX Developer’s Guide Chapter 6: Mapping in Layers Note: The MapX Reference manual and Online Help have a complete listing of Layers Collection methods and properties. Using the Layer Control Dialog The LayersDlg method presents a dialog where the user can add layers, remove layers, change layer ordering, and change layer properties. If the user clicks OK, the changes made within the dialog will immediately be applied to the map. Map1.Layers.LayersDlg MapX Developer’s Guide 79 Chapter 6: Mapping in Layers Display Options of the Layer Control Dialo The Display Options dialog enables you to customize the display for each layer in a Map window. In Layer Control, the user can select a layer and click on the Display button to bring up the Display Properties dialog. There, the user can change the default styles for the layer and set the zoom at which a layer displays For example:. Display Mode When a user first opens a map, boundaries, lines, points, and text are all displayed using defaults in the map’s Geoset file. The user can change how objects display by using the Display Mode section of the Display Options dialog. For example, the user wants to change the display of streets to a dashed red line. In Layer Control the user would choose the street layer and click the Display button. This brings up the Display Options dialog. The user would check the Style Override box to activate the Style Override button (large gray button). MapX displays the override buttons that are appropriate for the type of objects in the layer. For example, if the layer contains streets, a line style 80 MapX Developer’s Guide Chapter 6: Mapping in Layers override button displays. Clicking on it to will access the Line Style dialog where the user can change the width, style, and color of the streets. For boundary layers, the style override button brings up the Region Style dialog where the user can change both the fill and borders of boundaries. The Symbol Style dialog displays when the user wants to override the style for layers containing symbols or points. The Style Override is only in effect during the current work session, as are the other display settings. To make them permanent,you would have to modify the geoset. Create a Layer Allows you to create a new temporary or permanent MapInfo table layer. The method returns a Layer object—the Layer object that was added to the collection. dim lyr as layer set lyr = Map1.Layers.CreateLayer (“Temporary”) Add a Layer Adds an existing layer to the collection and displays it on the map. When adding a layer, you can specify the position of the layer in the collection with the optional Position parameter. If no Position parameter is specified, the layer is positioned automatically with respect to other layers in the map. For example, a layer with points is placed above a layer with regions. Map1.Layers.Add “C:\Data\Counties.tab” -orPrivate Sub mnuAddLayers_Click() 'This uses the common dialog to open a MapInfo Table and add it as a layer. Dim sFile As String With dlgCommonDialog .DialogTitle = "Add Layer" .Filter = "MapInfo Tables (*.tab)|*.tab" .ShowOpen If Len(.filename) = 0 Then Exit Sub End If sFile = .filename End With On Error Resume Next Map1.Layers.Add sFile End Sub MapX Developer’s Guide 81 Chapter 6: Mapping in Layers Remove a Layer The Remove method removes a specified layer from the map. Map1.Layers.Remove 3 Remove All Layers The RemoveAll method removes all layers from the map. Private Sub btnLayersRemoveAll_Click() Dim nLayers As Integer nLayers = Map1.Layers.Count ' remove all of the layers Map1.Layers.RemoveAll nLayers = Map1.Layers.Count Reposition a Layer The Move method repositions a layer in the Layers collection. The first parameter is From position (the top layer = 1) and the second parameter is the To position. Map1.Layers.Move 1,2 The Layer Object The Layer object represents vector mapping data in the form of a collection of map features having a predominant feature type, such as regions, lines or symbols. Typically, a Layer object corresponds to the geographic objects from one MapInfo table. Each of the Layer objects in a Layer collection behaves independently of the others. Their styles may be changed, their zoom layering altered, etc., on an individual basis, without affecting any of the other layers. You may manipulate the layer object at any time within a program. You can also use the Property Page to set layer properties at design-time, as discussed above. The Layer object has many properties and methods. The methods used to get features from a Layer are discussed in chapter: Features and Selections. 82 MapX Developer’s Guide Chapter 6: Mapping in Layers Some Layer Properties Note: The MapX Reference manual and Online Help have a complete listing of Layer object methods and properties. Name Name of the layer. MsgBox Map1.Layers(4).Name Visible Whether or not a layer is visible. Map1.Layers.Item(2).Visible = False OverrideStyle Whether to override this layer’s default display characteristics. Map1.Layers(9).OverrideStyle = True Style The layer style to use if OverrideStyle is True. Map1.Layers(9).Style = newstyleobject ZoomLayer Sets zoom layering on or off. Map1.Layers(“States”).ZoomLayer = True MapX Developer’s Guide 83 Chapter 6: Mapping in Layers ZoomMin Sets the minimum zoom level at which a layer will be visible. Map1.Layers(“States”).ZoomMin = 45 ZoomMax Sets the maximum zoom level at which a layer will be visible. Map1.Layers(“States”).ZoomMin = 580 Selectable Sets MapX to recognize when a user clicks on this layer. Map1.Layers(“States”).Selectable = True AutoLabel Controls whether the layer is automatically labeled. Map1.Layers(“States”).AutoLabel = True The MapX Reference manual and Online Help have a complete list of Layer properties. Layer Order Map layers in a Layers collection display in increasing index order (i.e., Layers(1) is the top layer, Layers(2) is the layer underneath Layer(1), etc.), with the bottom layer drawn first and the top layer drawn last. It is important to order your layers correctly. For example, suppose that you have a layer of customer points and a layer of census tracts. If the layers are incorrectly ordered in the Layers collection, MapX will draw the customer points first and then display the census tract layer second. Your points would be obscured by the census tract layer You can reorder how layers are displayed in a Map at design time. From the Layers tab of the Property Page, discussed earlier, use the Up and Down buttons. Select the layer(s) you want to reorder and choose either the Up or Down button to move the layer(s) to a position above or below its current position. 84 MapX Developer’s Guide Chapter 6: Mapping in Layers To allow the user to reorder layers at runtime, use the LayersDlg method to present the Layer Control dialog, as discussed earlier. Layer order is also important when you use the Select tool. The Select tool selects objects from the topmost Selectable layer. If you have several objects at the same location, it is difficult to select the exact one you want. You can reorder your layers so that the layer you want to select from is the new topmost layer. Tools are discussed in Chapter: "Tools". Examining Layers There are many instances where you might want to examine layers in a collection. Here’s a simple code fragment to iterate through a Layers collection to determine what types of layers are present, and to display a message in a dialog box indicating the layer type. Dim lyr as Layer For Each lyr in Map1.Layers Select Case lyr.Type Case miLayerTypeNormal MsgBox “Layer ” & lyr.Name & “ is a normal layer” Case miLayerTypeRaster MsgBox “Layer ” & lyr.Name & “ is a raster layer” Case miLayerTypeSeamless MsgBox “Layer ” & lyr.Name & “ is a seamless layer” Case miLayerTypeUnknown MsgBox “Layer ” & lyr.Name & “ is an unknown layer” Case miLayerTypeUserDraw MsgBox “Layer ” & lyr.Name & “ is a user draw layer” Case miLayerTypeDrilldown MsgBox “Layer ” & lyr.Name & “ is a drilldown layer” Next In the code fragment we are using MapX-defined constants for all the layer types. These constants are collectively known as LayerTypeConstants. All MapX constants are listed in the MapX Online Help and Reference Guide. MapX Developer’s Guide 85 Chapter 6: Mapping in Layers Checking a Layer’s Feature Type This code fragment iterates through the Layers collection by index. It examines each Layer object in the collection and determines the type of features present in the layer. Features are discussed at length in chapter. Dim i as Integer For i = 1 To Map1.Layers.Count Select Case Map1.Layers(i).PredominantFeatureType Case miFeatureTypeRegion MsgBox “Layer ” & lyr.Name & “ contains regions” Case miFeatureTypeLine MsgBox “Layer ” & lyr.Name & “ contains lines” Case miFeatureTypeSymbol MsgBox “Layer ” & lyr.Name & “ contains symbols” Case miFeatureTypeMixed MsgBox “Layer ” & lyr.Name & “ contains mixed features” Case miFeatureTypeUnknown MsgBox “Layer ” & lyr.Name & “ contains unknown _ features” Case miFeatureTypeText MsgBox “Layer ” & lyr.Name & “contains text features” Next The Layers collection has a one based index, so we iterate from an index value of one through the count of the Layers collection. We also evaluated the PredominantFeatureType property of each layer in the collection, using the FeatureType constants for evaluating the PredominantFeatureType. 86 MapX Developer’s Guide Chapter 6: Mapping in Layers Zoom Layering Sometimes you want a map layer to display only at certain zoom levels. Zoom layering allows you to view a map layer when the map's zoom level falls within a preset distance.You can set a different zoom layering level for each layer. For example, if your map includes a street map layer, you may find that the streets become illegible when the user zooms out too far. MapX Developer’s Guide 87 Chapter 6: Mapping in Layers Using zoom layering, you might set up your map so that MapX automatically hides the streets whenever the user zooms out to show an area larger than 5 miles. The follwing sample code adds a layer to the map using the Layers collection Add method and sets up zoom layering by modifying the Layer object’s properties. Dim lyrStreets As Layer `Creates the layer object `Sets the Streets table as the layer object and orders the layer in `the map as number 3. Set lyrStreets = Map1.Layers.Add(“Streets.tab”, 3) lyrStreets.ZoomLayer = True `Sets zoom layering to true lyrStreets.ZoomMin = 0 `Sets minimum zoom to 0 miles lyrStreets.ZoomMax = 5 `Sets maximum zoom to 5 miles Once you set zoom layering for a layer, when you zoom within the minimum and maximum zoom levels, the layer will display on the map. You can zoom in on your map with the zoom tools (discussed in Chapter 7) or the ZoomTo method of the Map object. With the ZoomTo method you specifiy a zoom level and the x and y coordinates to center the map. Map1.ZoomTo 3, -70.26, 44.05 Since the zoom value of 3 miles is within the the minimum and maximum zoom levels, the Streets layer will center around the point -70.26, 44.05 and display 3 miles of the map across the width of the map control. Different layers in the same Map window can be displayed at different zoom levels. For example, you have a layer of streets, a layer of county boundaries, and a layer of state 88 MapX Developer’s Guide Chapter 6: Mapping in Layers boundaries. You want the streets layer to be visible only when the zoom level is less than eight miles. You want the county boundary layer to display when the zoom level falls between 20 miles and 200 miles. You want the states boundary layer to be visible only when the zoom level is greater than 100 miles. You can set a different zoom level for every layer in your map. Generating Labels For a Layer MapX provides many ways to label attributes of geographic objects in a map layer. Their drawn location is based on the location of the geographic object’s centroid and additional information such as anchor point and offset. As attributes, labels are dynamically connected to their map objects. If the layer is closed or is made invisible, the labels no longer display. If the data or geographic information changes, the labels change. If you create an expression for your labels and change the expression, the current labels are dynamically replaced with new ones. MapX Developer’s Guide 89 Chapter 6: Mapping in Layers Whether you label your map automatically, or interactively using the Label tool or the LabelAtPoint method, the content of the label is determined by the data associated with the geographic object. In addition to label content, you control the position, display, and look of automatic labels by using properties in the LabelProperties object. You can set conditions for displaying labels, in the style in which will display, and in what position for all the objects in the layer. Controlling Label Display To automatically generate labels for a layer, set the layer's AutoLabel property to True. Each Layer object has a LabelProperties object, which controls many aspects of labels. For example, to hide all of a layer's labels, set the LabelProperties.Visible property to False. To specify the maximum number of labels you want to display on your map, set the LabelMax property. The Duplicate property controls whether features with the same name can have separate labels on the map simultaneously. The Overlap property controls whether labels are allowed to overlap; setting Overlap toTrue can cause more features to be labeled, but you may find that overlapping labels are harder to read. Zoom-layering Labels You can configure labels to display only within a specific zoom range, much the same way that you display map layers within a certain zoom range. To specify a zoom range for labels, set the LabelZoom, LabelZoomMax, and LabelZoomMin properties of the LabelProperties for the layer. Label Position To control label positions, set the Position property (which controls whether labels are above, below, or to the side of the feature's centroid), and the Offset property (which controls how far the label is offset from the feature). The default anchor point depends on the layer's predominant feature type. For example, a layer of region features defaults to having labels centered over region centroids. For line/polyline features (such as street maps), you can make labels run parallel to the line features -- set the Parallel property to True. 90 MapX Developer’s Guide Chapter 6: Mapping in Layers Creating Callouts Callouts are labels with lines pointing to the objects they are labeling. They are very useful when there are many labels in a relatively small area. For example, you are labeling a map of Asia. There are many small countries that are relatively close together. If you tried to label all the countries, the labels would overlap and be difficult to read. To display callout lines, set the LabelProperties.LineType property to miLineTypeSimple (1) or miLineTypeArrow (2) for the layer that you want to label. Label Styles To make style changes for all the labels set the Style. You can also set the appropriate style options. Make the style changes you want. When you return to the map, the selected labels display with the style changes you specified. There are also background options. Set the appropriate options to have no background, or halo to create a halo effect around the text. This puts the text into relief from whatever it covers (e.g., part of a region, or a street, etc.). Interactive Labeling Although you will probably do most of your labeling automatically, in some cases you may want to create labels one at a time, using a Label tool. The Label tool is one of the standard tools built into MapX. To activate the tool, set the Map.CurrentTool property to miLabelTool (1010); the user will be able to label a map feature by clicking on the feature. The easiest way to remove all labels in a layer is to use the Visibility setting. It will disable the display of all the labels in that layer, both automatic and custom labels. To clear only the custom labels (those labels placed using the Label tool), use the ClearCustomLabels method. Dim Dim Dim Dim Set DS As Object DB As Object RS As Object Temp As Object DB = Workspaces(0).OpenDatabase("Mapstats.mdb") Set Set Set Set Set RS = DB.OpenRecordset("USA") DS = Map1.Datasets.Add(miDataSetDAO, RS) Map1.Layers("usa").LabelProperties.Dataset = DS Temp = DS.Fields("GEONAME") Map1.Layers("usa").LabelProperties.DataField = Temp MapX Developer’s Guide 91 Chapter 6: Mapping in Layers Annotations Although the labeling feature takes care of most of your text needs, you may still need to create text objects to annotate your map. Unlike labels, text annotations are not connected to data— you can place an annotation anywhere on the map, even if there are no features at that location. To add text or symbol annotations to your map, use the methods and properties in the Annotations collection and object. Each Map has a collection of Annotations (Map.Annotations property). Annotations are either symbol or text objects, and are drawn on top of the map. Annotations are typically used to add text messages to a map, or to put symbols on a map. These annotations scale with the map as you zoom in and out. Annotations are not tied to a particular map layer. Annotations are always on top. Note that the Annotation object has no properties for setting the position, symbol style, or text. To control these aspects of an annotation, you use the Annotation.Graphic property to obtain a Graphic object, then modify the Graphic object. Raster Images Raster images are a type of computerized picture consisting of row after row of tiny dots (pixels). Raster images are sometimes known as bitmaps. Aerial photographs and satellite imagery are common types of raster data found in GIS. 92 MapX Developer’s Guide Chapter 6: Mapping in Layers Displaying Raster Images as Map Layers With MapX you can display raster images (bitmaps) as backdrops to the maps you create.However, the raster image must first be part of a MapInfo table. You then can overlay additional data, such as street maps and customer locations, on top of the image. Although a raster image can be a picture of a map, the image cannot have data attached to it. The image is for viewing, as a backdrop or "underlay." How to Display a Raster Image Each raster image must have a corresponding '.TAB' file which stores the image's geographic coordinates. The .TAB file is created by using MapInfo Professional to 'register' the image. Note: When you display a raster image as a map layer, MapX automatically sets the rotation and projection of all the vector map layers, so that they match the rotation and projection of the raster image. MapX Developer’s Guide 93 Chapter 6: Mapping in Layers Animation Layers The Animation layer is useful where map features need to be updated frequently, such as in real-time applications. For example, you can develop a fleet-management application that represents each vehicle as a point object. You can receive current vehicle coordinates by using GPS (Global Positioning Satellite) technology, and then update the point objects to show the current vehicle locations on the map. In this type of application, where map objects are constantly changing, the map redraws much more quickly if the objects being updated ar stored in the animation layer instead of a conventional layer. Initially AnimationLayer is set to null. You can assign a Layer object to the property to make that Layer the animation layer (it can be a regular layer or user draw layer). When a layer is assigned to the AnimationLayer property, it is drawn on top of all layers, including the Annotations layer and selections. The layer is still in the same position in the Layers collection. Floating objects like legends are still displayed on top of the animation layer, although they don't have to be re-drawn each time because they are clipped out. If a normal layer is used as the animation layer, selections and labeling will still work. Example Set Map.Layers.AnimationLayer = Layers(3) The property can be used to identify what layer is currently the animation layer (if any): for each lyr in Map.Layers if Map.Layers.AnimationLayer = lyr the ... end if next To turn off the animation layer, you assign null to it: Set Map.Layers.AnimationLayer = nothing This turns the layer back into a normal layer, which is still positioned in the same place in the layer list. 94 MapX Developer’s Guide Chapter 6: Mapping in Layers Drawing Layers The AddUserDraw Layer method of the Layers collection gives developers the ability to draw layers on a map. It is used in conjunction with the DrawUserLayer event, which is fired when the layer needs to get drawn. The method returns a newly created Layer object. There can be any number of user draw layers. How It Works First, you add a user draw layer to your layers collection: ' this sets the UserDraw Layer to “My Layer” Dim lyr as Layer Set lyr = Map1.Layers.AddUserDrawLayer("My Layer", 1) Then you put the code to do the drawing on the layer in the DrawUser Layer event. When the application creates a UserDraw layer using the AddUserDrawLayer method of the Layers collection, an event is fired to the application when the window needs updating. A complete example is shown below. ' API DEFS should be declared in a separate module Declare Function MoveToEx Lib "gdi32" Alias "MoveToEx" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, lpPoint As POINTAPI) As Long Declare Function LineTo Lib "gdi32" Alias "LineTo" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long Declare Function SetMapMode Lib "gdi32" Alias "SetMapMode" (ByVal hdc As Long, ByVal nMapMode As Long) As Long Type POINTAPI x As Long y As Long End Type Public Const MM_TWIPS = 6 ' this sets the UserDraw Layer to “My Layer” Dim lyr as Layer Set lyr = Map1.Layers.AddUserDrawLayer("My Layer", 1) ' this example draws a line between the corners of Wyoming Private Sub Map1_DrawUserLayer(ByVal Layer As Object, ByVal hDC As Long, ByVal RectFull As Object, ByVal RectInvalid As Object) Dim pt As POINTAPI SetMapMode hDC, MM_TWIPS dim PX as single dim PY as single X1 = -111.0542 Y1 = 45.0009 X2 = -104.0528 MapX Developer’s Guide 95 Chapter 6: Mapping in Layers Y2 = 41.0018 if map1.ClipLine(X1,Y1,X2,Y2) then map1.ConvertCoord(PX, PY, X1,Y1, miMapToScreen) MoveToEx hDC , PX, -PY, pt ' win api call map1.ConvertCoord(PX, PY, X2,Y2, miMapToScreen) LineTo hDC, PX, -PY ' win api call end if End Sub 96 MapX Developer’s Guide Chapter 7: Features and Selections Features and Selections The methods of the Selections and Features objects allow you to “mark” or choose features that meet certain criteria. A point on a map representing New York City is an example of a Featur 7 Chapter ➤ Features and Selections ➤ Using the Features Collection object. Say you need to find all of the potential clients within 5 ➤ Selection Collection miles of Sheep’s Head Bay, Brooklyn. Once you create this ➤ Feature Editing collection of data, you may cycle through the collected data, print it out, take averages, count how many met that criteria, save them to a file, or perform other tasks. In this chapter we will take a detailed look at features and selections. Chapter 7: Features and Selections What Is a Map Feature? A map feature is a geographic object on a map such as a point, line or region. For example, a map of the United States could contain regions as states, lines as highways, and points as cities. In MapX, a map feature is represented as a Feature object. For example, New York state could be a Feature object of type region, interstate 95 a Feature object of type line, and New York City a Feature object of type point. What Is a Features Collection? In MapX, the different layers that make up your map usually have the same feature type within each layer. For example, the “US States” layer has region features to represent each state, the “US Highways” layer has line features to represent major U.S. highways, and the “US Capitols” layer has point features to represent each state capitol city. In MapX, all the features in a map layer or any subset of all the features in a map layer is represented as a Features collection. Many Layer object methods return a Features collection from a layer. The features in a Features collection are not highlighted on your map. For this, you use a Selection collection. What Is a Selection Collection? Like the Features collection, the Selection collection is also a collection of Feature objects. However, the Selection collection represents the Feature objects that are currently selected (either selected when the user clicks on the map with a selection tool, or selected by means of the various Select methods listed below). Each Layer object has its own Selection collection (Layer.Selection). MapX automatically highlights all the features in a Selection collection, considering them selected features. 98 MapX Developer’s Guide Chapter 7: Features and Selections Using the Features Collection The Features collection is similar to the Selection collection, in that both collections are collections of Feature objects. However, the Features collection has a different set of methods and properties than the Selection collection, and the two collection types behave differently. Selected features are automatically highlighted and features in a Features collection are not. Getting Features in a Layer Before you can do anything to a Features collection, you must first create the collection. The Layer object methods create a collection of Feature objects. The Following methods of the Layers collection provide various ways to get a Features collection. Code Sample (Dim fs as Features ‘this creates a collection of Features) Method Description AllFeatures Returns a Features collection with all features from the layer. NoFeatures Returns an empty Features collection for the layer. Set fs = Map1.Layers(9).NoFeatures SearchWithinDistance Returns a Features collection made up of features within a specified distance of a point object. Set fs = Map1.Layers(3). _ SearchWithinDistance (objPoint, _ 36.5, miUnitMile, _ miSearchTypeCentroidWithin) SearchWithinFeature Returns feature object made up of features within another specified region feature. Set fs = Map1.Layers(3). _ SearchWithinFeature _ (ftr, miUnitMile, _ miSearchTypeCentroidWithin) SearchWithinRectangle Returns features collection within bounds of specified rectangle. Set fs = Map1.Layers(3). _ SearchWithinRectangle(miRect, _ miUnitMile, _ miSearchTypePartiallyWithin) MapX Developer’s Guide Set fs = Map1.Layers(2) _ .AllFeatures 99 Chapter 7: Features and Selections SearchAtPoint Returns features collection made up of features at specified point. Set fs = Map1.Layers(3) .SearchAtPoint(objPoint) Search Type Constants MiSearchTypeCentroidWithin Include in search if the feature’s centroid is within the region. MiSearchTypeEntirelyWithin Include in search if the feature is contained by the region. MiSearchTypePartiallyWithin Include in search if any part of the feature is within the region. The follow code is a tool used event, which creates a collection of features at a point the user clicks. Private Sub Map1_ToolUsed(ByVal ToolNum As Integer, ByVal X1 As Double, ByVal Y1 As Double, ByVal X2 As Double, ByVal Y2 As Double, ByVal Distance As Double, ByVal Shift As Boolean, ByVal Ctrl As Boolean, EnableDefault As Boolean) Dim ftr As Feature'creates a Feature object Dim fs As Features'creates a collection of features Dim pt As New Point 'creates a new point 'the new point created has coordinate values set when the user clicks on a feature pt.Set X1, Y1 'If the tool used is the custom info tool then create a collection of features from the States layer 'and print the State Name feature into a message box. If ToolNum = InfoTool Then 'create the collecton of features at the point the user clicked Set fs = Map1.Layers("USA").SearchAtPoint(pt) 'print the State Name feature into a message box. For Each ftr In fs MsgBox ftr.Name Next End If 100 MapX Developer’s Guide Chapter 7: Features and Selections Manipulating a Features Collectio The following methods allow you to manipulate the Features collection by adding, removing, cloning, etc. a feature object to the collection: Method Description Add Add a Feature object or an entire Features collection into the collection. Clone Make a copy of the collection as another Features collection object. Common Combine this collection and another Features collection so that this collection contains only features that are in both (INTERSECT set operation). Remove Remove a Feature object or all features from a Features collection from this collection (SUBTRACT set operation). Replace Replace the contents of the collection with a Feature object or all features from a Selection collection object. Feature Object A Features collection is made up of a collection of Feature objects. A Feature object corresponds to a feature on a map like a symbol, line, or region. A Feature object corresponds to features (actual entities) in a layer, such as New York, Chicago, Louisiana, Cortland County, or Highway I-10. Stand-Alone Features The Feature object methods allow you to create and manipulate stand-alone feature objects. When you create a stand-alone feature object, you must attach that feature object to the map before you reference any of its methods or properties. Attaching a feature to the map associates the map's coordinate system with the feature. The following Visual Basic example shows how to create a stand-alone Text feature, then modify its caption. Dim f As New Feature Dim fNew As Feature ' Add a new text object to layer 1 f.Attach Map1 MapX Developer’s Guide 101 Chapter 7: Features and Selections f.Type = miFeatureTypeText f.Point.Set Map1.CenterX, Map1.CenterY f.Caption = "This is a text object" Set fNew = Map1.Layers(1).AddFeature(f) ' Change the text caption fNew.Caption = "Changed Text" fNew.Update The following Visual Basic example demonstrates how to attach a stand-alone feature object. Dim f as new Feature f.Attach Map1 f.Type = miFeatureTypeSymbol f.Point.Set Map1.CenterX, Map1.CenterY Map1.Layers(1).AddFeature f 102 MapX Developer’s Guide Chapter 7: Features and Selections Feature Object Properties The following properties define a feature object: Property Description Code Sample CenterX Contains the X centroid of the feature. Print ftr.CenterX CenterY Contains the Y centroid of the feature. MsgBox ftr.CenterY FeatureID Contains the ID of the feature. Each feature in a layer contains a unique ID within the layer. This is an Integer value. IVar = ftr.FeatureID Length Contains the length of the feature. Print ftr.Length Perimeter The length is the perimeter of the feature. If ftr.Perimeter > 500 Then Print “Too Long” End If Name Contains the name of the feature. MsgBox ftr.name Type Contains the type of the feature (point, line, etc.). ftr.Type = miFeatureTypeSymbol Selection Collection A fundamental function of MapX is selecting features on the map, so that you can perform additional tasks on them. Users can click on the map to select one or more features (points, lines, regions, etc.). MapX highlights all selected features. To examine the list of selected features, use the Selection collection, which is a collection of Feature objects. The Selection collection also provides various methods (such as SelectByRadius) that allow you to perform various types of selection, for example, selecting all of the features within a certain radius of a city. The selected features will show up highlighted on the map. Each layer has a collection of selected feature objects (Layer.Selection). MapX Developer’s Guide 103 Chapter 7: Features and Selections The Selection collection has methods to add and remove features to and from the collection. Also, if you have an existing Selection or Features collection, you may append, remove, copy, or find the intersection of the two collections. The following table lists some of the Selection collection methods. For a complete listing, see the Reference Guide or Online Help: 104 Method Description Code Sample ClearSelection Unselects all features in this layer. Use Layers.ClearSelection to clear the selection from all layers. Map1.Layers(“SalesReps1997”). Selection.ClearSelection Clone Make a copy of the collection as another Selection collection object. Map1.Layers(2).Selection.Clone ftrs Common Combine this collection and another Selection object so that this collection contains only features that are in both (INTERSECT set operation). Map1.Layers(2).Selection.Comm on Map1.Layers(4).Selection Remove Map1.Layers(2).Selection.Remo Remove a Feature object or all ve fs features from a Selection object from this collection (SUBTRACT set operation). Replace Replace the contents of the collection with a Feature object or all features from a Selection collection object. SelectAll Selects all features within a layer. Map1.Layers(“Cargo”).Selection .SelectAll SelectByPoint Selects the feature at a specified point within the layer. Map1.Layers(5).Selection.Select ByPoint 75.14, 42.9, miSelectionAppend SelectByRadius Selects features from the layer within a specified radius around a point. Map1.Layers(4). Selection.SelectByRadius X, Y, Radius, miSelectionnew Map1.Layers(“Boston”).Selectio n.Replace lyr.AllFeatures MapX Developer’s Guide Chapter 7: Features and Selections Method Description Code Sample SelectByRectangle Selects features from the layer within a rectangle. Map1.Layers(5).Selection.Select ByRectangle –98.7, 31.56, -75.14, 42.9, miSelectionRemove SelectByRegion Selects features from the layer within a region. Selection.SelectByRegion Layer, FeatureID, Flag Search Type Constants The following constants determine what to do with the results of your selection. MiSelectionNew Creates a new selection. MiSelectionAppend Adds to the current selection. MiSelectionRemove Removes from the current selection. The following code creates a new selection at a specific point: Private Sub Command1_Click() Map1.Layers(5).Selection.SelectByPoint -98, 31.56, miSelectionNew End Sub SelectionChanged Event This event is called whenever the selection changes. It enables the container to react to a selection made on the map. The selection can change as a result of a user using a selection tool, or by using one of the Selection methods from the Layer object. Private Sub Map1_SelectionChanged() '*********************************************************** 'Any time the selection changes, update the listbox with 'the currently selected records '*********************************************************** Dim ftr As Feature'Create a feature object Dim lyr As Layer'Create a layer object 'Within the current layer the user is selecting from, print out a message For Each lyr In Map1.Layers For Each ftr in lyr.Selection MsgBox (“found: ") ftr.name MapX Developer’s Guide 105 Chapter 7: Features and Selections Next Next End Sub Feature Editing MapX allows you to create, modify, or delete the features (points, lines, regions, etc.) that make up a map layer. Any layer that is based on an ordinary MapInfo table (.tab) file can be edited. Note: MapX does not provide transaction support. In other words, when you update the feature, after you add/delete/change a feature, it happens immediately.You don't need to save any changes later, and you can't undo the operation. How to Create New Map Features There are two ways to create new map features. You can create a feature by allocating a new Feature object, or create features by performing operations (such as buffering) on existing features by using the methods of the FeatureFactory property of the Map object. These types of features are called stand-alone features. Stand-alone features have some restrictions: they can't be added to any collections, and only the methods and properties that are used to define the feature are allowed. For example, you cannot use the Area property on a stand-alone feature, and a stand-alone feature has no value for the Feature.Layer property. A feature that comes from a layer is not a stand-alone feature, and all properties and methods work on it. Allocating a New Feature Object Example in Visual Basic The following Visual Basic example creates a symbol object. Dim newobj as new MapXLib.Feature 'stand-alone object Dim obj as MapXLib.Feature 'to hold feature added to layer newobj.Type = miFeatureTypeSymbol 'Use the map's default symbol style newobj.Style = map1.DefaultStyle ' specify the x- and y-coordinates (long, lat) newobj.Point.Set -104.3452, 34.91234 106 MapX Developer’s Guide Chapter 7: Features and Selections 'now add the object to a layer ' obj will be the newly added object ' you can still use newobj to add more objects set obj = map1.Layers(1).AddFeature(newobj) Example in C++ The following C++ sample creates a symbol object: void CSampleProjectView::CreateSymbol() { CMapXFeature newobj; // Standalone object CMapXFeature obj; // to hold object added to layer // Create the new object and attach it to the map’s coordinate system if(!newobj.CreateDispatch(newobj.GetClsid())) { TRACE0("Failed to Create Feature object"); return; } try { newobj.Attach(m_Map.GetDispatch()); newobj.SetType(miFeatureTypeSymbol); // Use the map’s default symbol style newobj.SetStyle(m_Map.GetDefaultStyle()); newobj.GetPoint().Set(-104.3452,34.91234); // Now add the object to the layer // obj is the newly added object // you can still use newobj to add more objects obj = m_Map.GetLayers().Item(1).AddFeature(newobj); } catch (COleDispatchException *e) { e->ReportError(); e->Delete(); } catch (COleException *e) { e->ReportError(); e->Delete(); } } To create other feature types, just set the type to miFeatureTypeRegion, miFeatureTypeLine, or miFeatureTypeText and then set the properties that apply to that feature type. MapX Developer’s Guide 107 Chapter 7: Features and Selections FeatureFactory Methods The methods of the FeatureFactory object let you create new map features, or create features by performing operations (such as buffering) on existing features. These are the methods of the FeatureFactory object: • BufferFeatures • CombineFeatures • CreateArc • CreateCircularRegion • CreateEllipticalRegion • CreateLine • CreateRegion • CreateSymbol • CreateText • EraseFeature • IntersectFeatures • IntersectionPoints • IntersectionTest Most of these methods return stand-alone feature objects. These feature objects are automatically attached to the map (i.e., they already have an associated coordinate system). In other words, you do not need to use the Attach method on the features returned by these methods. To obtain a FeatureFactory object, reference the Map.FeatureFactory property. Dim f As MapXLib.Feature Dim p As New MapXLib.Point ' Use the map's current center as the point coordinates p.Set Map1.CenterX, Map1.CenterY ' Create a text feature and add it to layer 1 Set f = Map1.Layers(1).AddFeature(Map1.FeatureFactory.CreateText(p, "Some Text")) The Online Help and Reference Guide provide extensive instructions on how to use the various FeatureFactory methods. 108 MapX Developer’s Guide Chapter 7: Features and Selections How to Modify Existing Features When you have a pointer to a Feature object, it represents a real feature in a layer; a feature that comes from a layer is not a stand-alone feature, and all properties and methods work on it. Any properties and methods you read reflect the value of the feature in the layer. Once you start modifying a feature by setting its style or points or location, your changes do not take effect until you 'update' the feature. This arrangement allows you to make many changes to a feature without waiting for the database to update and the screen to redraw after each change. As a side effect, the MBR, area, length, etc. are not changed until you update the feature. To update a feature, do one of the following: • If you have modified a feature and want to commit the changes, use the Feature.Update method. • If you want to replace a feature with another feature, use the Layer.UpdateFeature method. • When a feature is updated, both the old MBR and the new MBR are invalidated so that the screen redraws correctly. Example of Feature.Update in Visual Basic ' Shift all selected objects by 1 degree Dim obj as MapXLib.Feature for each obj in map1.layers(1).selection obj.Offset(1.0, 0.0) obj.Update() next OR for each obj in map1.layers(1).selection obj.Offset(1.0, 0.0) map1.layers(1).UpdateFeature(obj, obj) next Example of Feature.Update in C++ // Shifts all selected objects by 1 degree void CSampleProjectView::ShiftObjects() { long i,ObjCount; CMapXFeature obj; MapX Developer’s Guide 109 Chapter 7: Features and Selections try { ObjCount = m_Map.GetLayers().Item(1).GetSelection().GetCount(); for(i=1;i<=ObjCount;i++) { obj = m_Map.GetLayers().Item(1).GetSelection().Item(i); obj.Offset(1.0,0.0); obj.Update(); } } catch (COleDispatchException *e) { e->ReportError(); e->Delete(); } catch (COleException *e) { e->ReportError(); e->Delete(); } } //Or... void CSampleProjectView::ShiftObjects2() { long i,ObjCount; CMapXFeature obj; try { ObjCount = m_Map.GetLayers().Item(1).GetSelection().GetCount(); for(i=1;i<=ObjCount;i++) { obj = m_Map.GetLayers().Item(1).GetSelection().Item(i); obj.Offset(1.0,0.0); m_Map.GetLayers().Item(1).UpdateFeature(obj,obj); } } catch (COleDispatchException *e) { e->ReportError(); e->Delete(); } catch (COleException *e) { e->ReportError(); e->Delete(); } } If you choose not to call Update and release the object, the next time the feature is retrieved from the layer it will still have its original values. 110 MapX Developer’s Guide Chapter 7: Features and Selections How to Delete Existing Features To delete a feature, use the Layer.DeleteFeature method. The feature and the row it represents will be deleted from the MapInfo table immediately. Example of Layer.DeleteFeature in Visual Basic ' delete all selected features from the USA layer Dim obj As MapXLib.Feature Dim selectedFtrs As MapXLib.Features Dim lyr As MapXLib.Layer Set lyr = Map1.Layers("USA") Set selectedFtrs = lyr.Selection For Each obj In selectedFtrs lyr.DeleteFeature (obj) Next Example of Layer.DeleteFeature in C++ void CSampleProjectView::DeleteAllSelectedObjectsFromLayer() { CMapXFeature obj; CMapXLayer lyr; long i,ObjCount; try { lyr = m_Map.GetLayers().Item("usa"); ObjCount = lyr.GetSelection().GetCount(); for(i=1;i<=ObjCount;i++) { obj = lyr.GetSelection().Item(i); lyr.DeleteFeature(obj); } } catch (COleDispatchException *e) { e->ReportError(); e->Delete(); } catch (COleException *e) { e->ReportError(); e->Delete(); } } MapX Developer’s Guide 111 Chapter 7: Features and Selections How to Obtain a Feature to Edit You can allow the user to click on a feature to select it. Then, to access the selection, your program can use the Layer's Selection collection. The Selection collection also provides various methods, such as SelectByPoint, that allow you to add features to the collection. The Layer object has various methods (described above), such as SearchAtPoint, that allow you to obtain a Features collection. You can use the Find.Search method to perform a query that returns a FindFeature object (a super class of the Feature object). Examining the Parts of a Region or Line A line feature or region feature in MapX is made up of many collections of Point objects. These collections of Points collections are accessed through the Feature.Parts collection of the feature. Creating a Polyline Feature This Visual Basic example demonstrates how to use the Point object, Points collection, and Parts object to create a polyline feature, one node at a time. ' create a polyline feature with 3 points Dim newobj as new MapXLib.Feature object Dim obj as MapXLib.Feature to layer Dim pts as new Points Dim pt as new Point 'stand-alone 'to hold object added newobj.Type = miFeatureTypeLine 'Use the map's default symbol style newobj.Style = map1.DefaultStyle 'set the lines 3 points pt.Set -101.023, 45.0452 pts.Add pt pt.Set -102.023, 49.0452 pts.Add pt pt.Set -100.0, 34.2564 pts.Add pt newobj.Parts.Add pts 112 MapX Developer’s Guide Chapter 7: Features and Selections 'now add the object to a layer ' obj will be the newly added object set obj = map1.Layers(1).AddFeature(newobj) Examining the Nodes that Make Up a Feature This Visual Basic example demonstrates how the Parts collection and Points collection allow you to loop through all the points in a selected feature. Dim Dim Dim set obj as MapXLib.Feature pts as new Points pt as new Point obj = map1.layers(1).selection(1) for each pts in obj.parts for each pt in pts debug.print pt.x, pt.y next next MapX Developer’s Guide 113 Chapter 7: Features and Selections 114 MapX Developer’s Guide Chapter 8: Finding Features on a Map Finding Features on a Map The Find method of the Layer object allows you to search a layer in a map object and locate a specific feature within the layer. 8 Chapter ➤ Finding Features on a Map ➤ Find Object ➤ FindFeature Object Chapter 8: Finding Features on a Map Find Object A Find Object allows you to locate features on a map. You may find a line, symbol or region feature. The layer you are searching must have an indexed field in order to utilize the Find method. See Appendix: "Using the Geodictionary Manager" for information about indexing fields in your table. For instance, if you wish to locate the city of Albany within NY state, you can use the Find Object Search method to search a city layer and a state layer for the specified feature. Method Description Code Sample Search Executes the search. Set Found = Map1.Layers(“US _ Cities”).Find.Search(“Albany”, “NY”) SearchEx Extends the search function by returning "close matches" to the search. The Find Object properties allow you to specify the parameters of your find. 116 Property Description FindDataset Dataset of field to match against. If not specified, the layer’s primary key used. FindField Field from Dataset to match against. Used in conjunction with FindDataset property. RefineDataset Override by specifying a Dataset and Field to use instead. RefineField The field to refine with. Takes a Field object. RefineLayer The layer used to refine search. Takes a Layer object. Abbreviations Whether to use abbreviation dictionary (Boolean). ClosestAddr Use a match found at the closest address (Boolean). OtherBoundary Use a match found in a boundary other than the one specified (Boolean). MapX Developer’s Guide Chapter 8: Finding Features on a Map Refining Boundary A refining boundary in your Find.Search is used to distinguish between mulitple features with the same name. For example, if you travel to Albany, you might end up in New York, California, or Georgia. The State would be the refining boundary when you say “Albany, New York” The following sample code sets the USA Layer as the refining boundary once the form is loaded: Private Sub Form_Load() '*********************************************************** 'Set the USA to be the refining layer when doing the find '*********************************************************** Dim fdObject As MapXLib.FindFeature 'Set the Refining Layer Set frmSelects.Map1.Layers("US Top 20 Cities”) _ .Find.RefineLayer = frmSelects.Map1.Layers("USA") MapX Developer’s Guide 117 Chapter 8: Finding Features on a Map FindFeature Object The Find.Search method returns the feature it finds in the form of a FindFeature object. A FindFeature object stores the properties of the Feature object found as its own properties. In addition, the FindFeature has a FindRC property which stores the result code of the Find operation. The FindFeature object is a super class of the Feature with the addition of a closest match string to be returned. Property Description Code Sample FindRC MsgBox FoundObj.FindRC The result code of a find operation. The FindRC property is a numeric value that indicates why the feature was or was not found. Result Codes Returns information on the Find Object such as why it was or was not found. This is a numeric result code. The chart below describes the numeric result codes. Digit Values Meaning **Ones Place** xx1 Exact match. xx2 A substitution from the abbreviations file used. xx3 ( - ) Exact match not found. xx4 ( - ) No object name specified; match not found. **Tens Place** 118 x1x Side of street undetermined. x2x ( + / - ) Address number was within min/max range. x3x ( + / - ) Address number was not within min/max range. x4x ( + / - ) Address number was not specified. x5x ( - ) Streets do not intersect. MapX Developer’s Guide Chapter 8: Finding Features on a Map Digit Values Meaning x6x ( - ) The row matched does not have a map object. ** Hundreds Place ** 1xx ( + / - ) Name found in only one region other than specified region. 2xx ( - ) Name found in more than one region other than the specified region. 3xx ( + / - ) No refining region was specified, and one match was found. 4xx ( - ) No region was specified, and multiple matches were found. 5xx ( + ) Name found more than once in the specified region. Once the result code is determined, you can use the results for selected cases as shown in the example below. The user input from a text box indicates a city and state to locate. The input is brought into the Find.Search method. Once the city is located from the major or minor city table, an annotation is added to the map and the map is re-centered at the location in which the feature was found. 'The code for a find command button Private Sub cmdFind_Click() 'Create a MapXLib for the feature found Dim FindCityObject As MapXLib.FindFeature 'Sets the find feature object to the city the user types in Set FindCityObject = Map1.Layers("US Top 20 _ Cities").Find.Search(txtCityName.Text, txtStateName.Text) 'Use result codes to determine if a city is found If (FindCityObject.FindRC Mod 10 = 1) Then 'Recenter the map to the city location Map1.ZoomTo 200, FindCityObject.CenterX, _ FindCityObject.CenterY Else 'Print out message box indicating city was not found MsgBox ("City not found") End If End Sub MapX Developer’s Guide 119 Chapter 8: Finding Features on a Map 120 MapX Developer’s Guide 9 Chapter 9: Tools Chapter Tools Most mapping applications provide an assortment of tools to aid with common drawing tasks (such as drawing a line on the map) and navigation tasks (such as zooming in). MapX provides several common mapping tools, plus you can also create your own custom tools. ➤ Tools ➤ Creating a Custom Tool ➤ Creating Polygon Drawing Tools (Polytools) Chapter 9: Tools Standard Tools With MapX, you can easily incorporate common toolbar buttons into your application. MapX provides built-in support for several common mapping tools, including: • Navigation tools (Zoom-In, Zoom-Out, Pan, Center) that let the user change the scale and/or position of the map. • A Labeling tool that lets the user click a map feature to label it. • A set of Selection tools that give the user various ways to select map features. • Object Creation tools, which allow for the creation of new map features. The selection tools provide built-in support for modifier keys (SHIFT key, CTRL key): Hold down the SHIFT key while using a selection tool, and the tool de-selects features; hold down CTRL while using a selection tool, and the tool adds features to the selection. MapX automatically displays a different cursor whenever a modifier key is being pressed (a plus or minus sign appears next to the cursor), so that the user will understand the effect of the key. Custom Tools If you need a type of tool button that MapX does not provide, you can simply create a custom tool by using the Map.CreateCustomTool method. When you create a custom tool, you control which 'type' of tool you create -- in other words, you choose whether this tool allows the user to click, or click and drag to draw a line, click and drag to draw a rectangle, etc. You also choose which cursor appears when a custom tool is in use. Controlling Which Tool Is the Current Tool To set which tool is being used, set the Map object’s CurrentTool property. To activate one of the standard tools, set the property to one of the ToolConstants. For example, to change the tool to the Zoom In tool: Map1.CurrentTool = miZoomInTool To activate a custom tool, use the ToolNumber value that you specified when you used the CreateCustomTool method. Map1.CurrentTool = 99 122 MapX Developer’s Guide Chapter 9: Tools Object Editing Tools Object editing tools allow the user to create and modify features in a Map layer. There are four standard object creation tools: Add Point, Add Line, Add Polyline, and Add Region. These tools add the new feature to whichever layer is specified in the Map.InsertionLayer property. There can only be one insertion layer, and the default is none. Setting the current tool to an object creation tool when there is no insertion layer results in an error. MapX also supports modification of existing map features.To edit features, the Layer.Editable property must be set to true for any layers that you wish to change. Then, the built-in Arrow tool can be used to move or resize features in the current selection. To move the selected feature(s), simply click and drag in the selection. To resize the selected feature(s), click and drag in the edit handles. To delete the selected feature(s), press the Delete key Available Standard Tools Different tools will enable the mouse to perform a variety of tasks. For example, if the current tool is set to miLabelTool, when you click the mouse, it will place a label on that particular map object. The mouse cursor will change based on the tool you are using. These are the standard tools available with MapX: Tool Constant Description Add Line miAddLineTool Adds a line feature to the insertion layer. Add Point miAddPointTool Click to add a point feature to the insertion layer. Add Polyline miAddPolyLineTool Adds a poly-line feature to the insertion layer. Add Region miAddRegionTool Adds a region feature to the insertion layer. Arrow miArrowTool Click on title or annotations. Also, moves or resizes selected features in editable layers. Center miCenterTool Click to re-center the map. Label miLabelTool Click on a feature to label the feature. MapX Developer’s Guide 123 Chapter 9: Tools Tool Constant Description Pan miPanTool Drag to re-center the map. Polygon Select miPolygonSelectTool Click to draw a polygon; objects within the polygon are selected. Radius Select miRadiusSelectTool Drag to select features within radius. Rect Select miRectSelectTool Drag to select features within rectangle. Select Tool miSelectTool Click to select features. Symbol miSymbolTool Place a symbol annotation. Text miTextTool Place a text annotation. Zoom In miZoomInTool Zoom In. Zoom Out miZoomOutTool Zoom Out. Creating a Custom Tool When you create a custom tool for any application there are three generic steps: 1. Create the tool. 2. Write the tool handler (the code for what the tool actually does). 3. Use the tool (put the tool in the user’s hand). Create the Tool To create a custom tool, call the CreateCustomTool method. This example creates a custom Ruler tool. The purpose of the Ruler tool is to determine the distance between two points on the map. First, we declare a constant RULERTOOLID equal to 500 to represent our custom tool. Then, when we load the main form of the application we create the tool. 124 MapX Developer’s Guide Chapter 9: Tools Const RULERTOOLID = 500 ‘This goes in the General declarations. Private Sub Form_Load() Map1.CreateCustomTool RULERTOOLID, miToolTypeLine, miSizeCursor End Sub In the above call of CreateCustomTool, we specified three required parameters: ToolNumber, Type, and Cursor. The ToolNumber is the RULERTOOLID constant we created to represent the tool. The Type is a ToolTypeConstants value which determines the behavior of the tool. In this case, it is miToolTypeLine which enables the user to click and drag to draw a line using the tool. The Cursor is miSizeCursor, which means that when the tool is selected it will appear as the size cursor. CreateCustomTool has two optional parameters that also take a CursorConstants value. The CursorConstants specify the cursors that you can use with a custom tool. They define the cursor shape when your custom tool is the CurrentTool. Note: See the MapX Reference or Online Help for a complete list of the CursorConstants. ShiftCursor specifies the the cursor shape of the tool when the <SHIFT> key is held down. CtrlCursor specifies the Cursor shape when the <CTRL> key is held down. These are useful if you want to give your tool behavior associated with those keys. To make your custom tool the active tool, set the CurrentTool property. For example, you could place a button on a Visual Basic form, and when the user clicks the button, you would set the CurrentTool property. MapX Developer’s Guide 125 Chapter 9: Tools Available Custom Tool Types The ToolTypeConstants describe the tool types that you can use when creating a custom tool. They describe the tool’s behavior (e.g., miToolTypeLine lets the user draw a line; miToolTypeCircle lets the user draw a circle; etc.). Constant Behavior miToolTypePoint Indicates a specific point. miToolTypeLine Draws a line. miToolTypeCircle Draws a circle. miToolTypeMarquee Draws a marquee box which selects map objects within the box. miToolTypePoly Draws a polyline. miToolTypePolygon Draws a polygon. Now that the Ruler custom tool is created, we have to write the code for what the tool actually does. Write the Tool Handler There are two different times at which the tool’s code may be executed: during the tool’s use, or after the tool is used. For our custom Ruler tool we want to execute code during the tool’s use because that’s when the work needs to be done. The way the custom Ruler tool will operate is: when the user clicks with it on a map location, the start point for the tool’s distance measurement will be marked. The user holds the mouse button down and moves the mouse across the map, then stops the mouse at another location. This will mark the end point of the tool’s distance measurement. The Ruler tool calculates the distance between the two points. To do this, we need to execute code for the Ruler tool when the user holds the mouse button down, and when the user moves the mouse across the map and stops at another spot. To capture the start point when the user clicks down, we write code in the MouseDown event: Dim XDown As Double Dim YDown As Double Private Sub Map1_MouseDown(Button As Integer, _ Shift As Integer, X As Single, Y As Single) 126 MapX Developer’s Guide Chapter 9: Tools If Map1.CurrentTool = RULERTOOLID And Button = vbLeftButton _ Then Map1.ConvertCoord X, Y, XDown, YDown, miScreenToMap End If End Sub When the user clicks down on the mouse, the MouseDown event is fired. The code in the MouseDown event takes the X,Y point where the user clicked, then converts it from screen coordinates to map coordinates, and stores it in the global variable Xdown and Ydown. Xdown and Ydown represent the start point of our distance measurement. To capture the end point when the user moves the mouse across the map and stops at another spot, we write code in the MouseMove event: Private Sub Map1_MouseMove(Button As Integer, _ Shift As Integer, X As Single, Y As Single) If Map1.CurrentTool = RULERTOOLID And Button = vbLeftButton _ Then Dim MapCoordX As Double, MapCoordY As Double Map1.MapUnit = miUnitMile Map1.ConvertCoord X, Y, MapCoordX, _ MapCoordY, miScreenToMap fMainForm.sbStatusBar.SimpleText = Map1.Distance(XDown, _ YDown, MapCoordX, MapCoordY) & " miles" End If End Sub This code will continually execute until the user stops moving the mouse and releases the mouse button. The last time this code executes is for the last point on the map before the mouse stops moving, which is the end point of our distance measurement. We convert the point from screen to map coordinates and then use the Distance method of the Map object to calculate the distance between the two points. The result is displayed in the status bar of the form. MapX Developer’s Guide 127 Chapter 9: Tools ToolUsed Event There are many times when you may want to execute a tool’s code after the tool is used. An example of this is to allow the user to draw a circle and when the mouse button is released, compute the number of customers inside that radius. If this is the functionality the tool needs, use the ToolUsed event of the Map object to place your code. This example demonstrates: • Using the Map.CreateCustomTool method to create a custom "line" tool (a tool that lets the user click and drag to draw a line). • Using the ToolUsed event to carry out an action when the user uses the custom tool. ' The following code in the Form_Load event of a form with ' a Map Object (Map1) creates a Custom Tool that is a ' "line-type" tool (it lets the user click and drag). Private Sub Form_Load() Map1.CreateCustomTool 1, miToolTypeLine, miIconCursor End Sub ' The following code (ToolUsed event)is called whenever any ' tool is used on the map. ' If the Current Tool is #1 (created above) then the code ' within the If-Then statement will be true, and we will set the caption of a label "lblDistance" equal to the Distance passed in with the "line-type" tool. Private Sub Map1_ToolUsed(ByVal ToolNum As Integer, ByVal _ X1 As Double, ByVal Y1 As Double, ByVal _ X2 As Double, ByVal Y2 As Double, ByVal _ Distance As Double, ByVal Shift As _ Boolean, ByVal Ctrl As Boolean, _ EnableDefault As Boolean) If ToolNum = 1 then lblDistance.Caption = Str$(Distance) End If End Sub 128 MapX Developer’s Guide Chapter 9: Tools Put the Tool in the User’s Hand To "put the tool in the user’s hand", set the CurrentTool property of the Map object to the tool: Map1.CurrentTool = miZoomInTool -orMap1.CurrentTool = 99 Creating Polygon Drawing Tools (Polytools) A polytool is a tool that lets the user click repeatedly -- for example, to draw a polygon or polyline. Standard Polytools MapX provides a standard polygon selection tool. This tool allows the user to draw a polygon, then selects all features whose centroids fall within the polygon. Only selectable layers are searched. Seamless, Raster, and Userdraw layers are ignored. To activate this tool, set the CurrentTool property to miPolygonSelectTool (value: 1010). When this tool is used, the PolyToolUsed event is fired. If the user ends the polygon (miPolyToolEnd) with a double-click, space, or return, the search is performed, and miPolyToolEnd (1) is passed to the PolyToolUsed event. If the user ends the polygon with the ESC key, the search is cancelled; miPolyToolEndEscaped (2) is passed to the PolyToolUsed event. The user can delete all nodes of a line (backspace Delete). When the last node is deleted, it will send a (2) flag. Custom Polytools To create a custom polytool, call the CreateCustomTool method, and specify a ToolTypeConstants value of miToolTypePoly. To make your custom polytool the active tool, set the CurrentTool property. Whenever the user selects your custom polytool and uses it on the map, MapX calls the PolyToolUsed event. Therefore, you need to add code to the PolyToolUsed event procedure to make your tool have an effect. MapX Developer’s Guide 129 Chapter 9: Tools Using Custom Polytools Example Once you have used the CreateCustomTool method to create a polytool, the following example shows you how to handle the PolyToolUsed event. This example lets the user draw a region or line feature to Layer 1. This example uses feature objects. It also uses a Parts object, which is explained in the Online Help and Reference Guide. Private Sub map1_PolyToolUsed(ByVal ToolNum As Integer, _ ByVal Flags As Long, ByVal pts As Object, _ ByVal Shift As Boolean, ByVal Ctrl As _ Boolean, EnableDef As Boolean) If Flags = miPolyToolBegin Then 'Someone's beginning the use of a PolyTool... ElseIf Flags = miPolyToolEnd Then ' The user finished using a PolyTool by double clicking If ToolNum = MY_SUPER_POLYGON_TOOL Then ' They used MY_POLYGON_TOOL! Make a new ' region feature and add it to the first layer dim f As New Feature set f = map1.FeatureFactory.CreateRegion (pts, _ map1.defaultstyle) map1.Layers(1).AddFeature f ElseIf ToolNum = MY_SUPER_POLYLINE_TOOL Then dim f As New Feature map1.Layers(1).AddFeature f End If ElseIf Flags = miPolyToolEndEscaped Then ' The user hit 'Esc' or backspaced all the nodes ' away... don't add anything in. End If End Sub 130 MapX Developer’s Guide Chapter 10: Putting Your Data on the Map 10 Chapter Putting Your Data on the Map Datasets enable you to bind user data to your maps. For example, if you have a Microsoft access database of sales by county and you had a Lotus Notes database of the location of your sales force, you could bind that data to a map and spot trends or notice correlations between the two sets of data. ➤ Putting Your Data on the Map ➤ What is Data Binding? ➤ The Power of Adding Your Data to a Map ➤ How to Add Your Data to a Map ➤ DataSet Object ➤ DataSets Collection ➤ DataSets.Add Method ➤ Fields.Add Method ➤ Displaying Your Data as a Layer of Points (BindLayer) ➤ Making Your New Layer of Points a Permanent Layer ➤ How Data Binding Uses the GeoDictionary ➤ The Different Types of Data Sources Chapter 10: Putting Your Data on the Map What is Data Binding? Data binding is the process of bringing data from a data source into MapX. There are many different types of databases in businesses today; therefore, MapX lets you bind to several different types of DataSources. In MapX, the data is represented as a DataSet object. The first argument to the Datasets.Add method lets you specify a DatasetTypeConstants value, which dictates the type of data binding you wish to perform. Types of data sources you can bind to include: ADO This type of databinding uses the MS Active data objects ADO recordset. DAO A daoRecordset object. You can get one from a Visual Basic data control, an Access form, or by creating one in Visual Basic, Access, or C++. Delphi This type uses the Borland BDE datasources. Global Handle This type of data binding lets you pass in a block of tab-delimited data. Layer This type of data binding lets you create a dataset that uses fields from a MapInfo table. Notes View/ NotesQuery ODBC These types of data binding deal specifically with Lotus Notes. OLE Data This is for containers such as PowerBuilder. Oracle Express Objects This allows access to the datacube as a dataset. RDO This uses MS Remote Data Objects and RDO Resultset object. SafeArray A COM dataset that allows static binding of data from a safearray. Unbound If you cannot support one of the other formats, MapX provides a ‘back door’. With this type of data binding, you can set up an event loop whereby MapX asks the container for data values, one cell at a time. MapX can use ODBC to retrieve data from any ODBC data source. These custom, user-created types of data binding are discussed in detail, later in the chapter. 132 MapX Developer’s Guide Chapter 10: Putting Your Data on the Map The Power of Adding Your Data to a Map There are two major advantages to binding your own data to a map: • You can view the data as features on a map. Let’s say you have a Microsoft Access table of your sales office locations for the United States. Through data binding you can add your table as a Dataset with the Datasets.Add method using a BindLayer object as one of the parameters. This will create a new layer in your map and display each sales location as a point on the United States map. Once you add the data to the map, you can use MapX to easily create an application that finds the nearest sales location to an address entered by a customer. Finding features on a map is discussed in chapter "Finding Features on a Map". • You can bind your attribute data to a map and then use it to create a thematically shaded map based on your data. Let’s say your Microsoft Access table of sales locations also contains a column of total sales volume for each location. Using the Datasets.Add method you can add the column containing total sales volume to your United States map. Once you add the data to the map, you can create a theme shading sales volume by state. Theme mapping is discussed in "Theme Mapping and Analysis". How to Add Your Data to a Map Data binding can be done two ways: • If you have Visual Basic for bound data controls, at design time you can use the DataSet property of the Map object. -or- • Bind data programmatically by using the DataSets.Add method. With this method, you can tell MapX which data source to use, some information about it, and which map layer to bind it to. Alternately, the Add method allows you to bind data without explicitly specifying the nature of the data; in this case, MapX analyzes your data and automatically determines the best way of binding your data to the map. The binding process results in the creation of a DataSet object. This DataSet, which is added to the DataSets collection, contains computed values for features in the map layer that the data is bound to. For example, if data is bound to US States map, each state would have a new data value that could then be used to control how the states are drawn. If the data source had multiple records for a state, the values could be summed, averaged, or counted. The DataSet MapX Developer’s Guide 133 Chapter 10: Putting Your Data on the Map has a Value property you can use to access the computed value for each row (that is, feature) of the map. With most types of data binding, the DataSource (the second parameter for DataSets.Add) is actually an OLE interface. MapX uses the interface to access the data directly from the data source. The data isn’t actually passed to DataSets.Add. DataSet Object The DataSet Object is the result of binding data from a data source into MapX. A DataSet contains computed values for features in the map layer to which the data is bound. The data sources may be a DAO Recordset, ODBC data source, Global Handle (this is a way to pass in a block of tab delimited data), OLE Data (this is for containers such as PowerBuilder), and Unbound Data (where MapX asks the container for data values, a cell at a time). DataSets Collection The DataSets collection is an object representing all of the DataSets for a map. The DataSets collection has methods and properties used to add, remove, or work with existing DataSet objects in the collection. Adding a DataSet Object or removing a DataSet object from a specified collection is accomplished using the methods listed below: 134 Method Description Code Sample Add Creates a specified dataset and adds it to the collection. Set ds = Map1.Datasets.Add _ (miDataSetDAO, rs) Remove Removes a specified DataSet object from the Datasets collection. Map1.Datasets.Remove 2 MapX Developer’s Guide Chapter 10: Putting Your Data on the Map DataSets.Add Method With the DataSets.Add method, you can bind data from a data source into MapX. This will tie data from an external data source to a map. The DataSets.Add method allows you to designate a specific DataSet and add it to a collection of DataSets. Let’s look at the syntax of the Datasets.Add method. Note: Optional parameters are in [square brackets]. DataSets.Add Type, SourceData, [Name], [Geofield], [SecondaryGeofield], [BindLayer], [Fields], [Dynamic] Type Parameter This parameter is the type of dataset being added. This parameter takes a DataSetTypeConstants value. Listed below are DataSet Type Constants: MapX Developer’s Guide 135 Chapter 10: Putting Your Data on the Map DatasetType Constants Type Description miDataSetADO ADO‘ miDataSetDAO Data Access Object miDataSetDelphi Delphi Native miDataSetDelphi4 Delphi4 miDataSetGlobalHandle Tab delimited data miDataSetLayer MapInfo Table miDataSetNotesQuery Lotus Notes Query miDataSetNotesView Lotus Notes View miDataSetODBC ODBC Database miDataSetOEO Oracle express Objects miDataSetOLEData OLE datasource miDataSetRDO RDO miDataSetSafeArray Safe Array miDataSetUnbound MapX requests data from container. The different types of data sources are presented in more detail, below. SourceData Parameter This parameter is a reference to the data, and is different depending on the Dataset Type. With most types of data binding, the DataSource (the second parameter for DataSets.Add) is actually an OLE interface. MapX uses the interface to access the data directly from the data source. The data isn’t actually passed to DataSets.Add. Here are valid data sources for each of dataset type: 136 Dataset Type Valid Source Data miDataSetADO ADO table miDataSetDAO A DAORecordset object. MapX Developer’s Guide Chapter 10: Putting Your Data on the Map Dataset Type Valid Source Data miDataSetDelphi Delphi Native miDataSetDelphi4 Delphi4 recordset miDataSetGlobalHandle A variant with type of VT_I4 and the lVal equal to the global memory handle. miDataSetLayer A MapInfo table. miDataSetNotesQuery Lotus Notes Query miDataSetNotesView Lotus Notes View miDataSetODBC An ODBCQueryInfo object. miDataSetOEO Oracle express Objects miDataSetOLEData Ignored by Datasets.Add. miDataSetRDO RDO table miDataSetSafeArray Safe Array miDataSetUnbound Nothing (instead, use the RequestData event to access data whose format is known only to the programmer). Name Parameter This parameter is a string that uniquely identifies the dataset. This is an optional parameter, and if not specified, a name in the form of DataSetN is used where N is a number in the Datasets collection. Geofield Parameter This parameter is the name or index of the column in the data source that contains the geographic information. If this parameter is not specified, MapX searches all the fields to determine which column in the data source contains the geographic information as specified in the GeoDictionary. This will not necessarily be a geographic data field, as it could be a unique key column such as zip codes. However, if you know which column in the data source contains the geographic information, you should specify it. If you plan to view the data as features on a map, the GeoField column in your data source must be unique. The GeoField column will be used to name the features in the new point MapX Developer’s Guide 137 Chapter 10: Putting Your Data on the Map layer. Non-unique values will result in a single point being added to the new point layer for the first occurrence of the duplicate key value, and data values in the duplicate rows will be aggregated. If a Fields collection is specified, the Geofield parameter refers to columns in the Fields collection rather than in the source data. See Fields Parameter, below. Secondary Geofield Parameter This parameter is only required when the layer that a dataset is being bound to has a key column that is not unique. For example, using the MapInfo table “United States Counties” to bind data against requires a secondary geofield parameter because county names are not unique to one state. Multiple states in the table have counties named “Warren” or “Washington”, among others. Thus, more information is needed to resolve the potential ambiguity during the data binding process. When do we want to bind our data to Warren, New York and when to Warren, New Jersey? By specifying the “County” column as the Geofield and the “State” column as Secondary Geofield, MapX can figure out which data gets bound to Warren, New York and which data gets bound to Warren, New Jersey by refining the data binding process to counties within each state. (This concept is identical to the Refining Boundary when creating a Find object; see Finding Features on a Map.) If a Fields collection is specified, the SecondaryGeofield parameter refers to columns in the Fields collection rather than in the source data. See Fields Parameter, below. BindLayer Parameter This parameter specifies the map layer to attach your data to if you are binding attribute data, or, a BindLayerObject if incoming data is to be georeferenced to a point reference file (such as Zip Codes) or contains Long/Lat values. This is an optional parameter, and if not specified, MapX searches layers in the GeoDictionary to attach to. If you know which map layer should be bound to, you should specify it for performance reasons. When doing BindLayer matching, the Geofields must be unique. Only the first item of a non-unique set of data will be matched. The rest are ignored. The BindLayer is discussed in more detail later in this chapter. 138 MapX Developer’s Guide Chapter 10: Putting Your Data on the Map Fields Parameter This parameter is a Fields object that is a collection of Field objects. The Field objects are used to describe which fields from the data source to bring in, and which aggregation function to use if more than one record for the data source matches a particular map feature. This will set up a collection of fields (columns) you wish to bind to the map. This is an optional parameter, and if not specified, all columns are brought in, and the data values are summed if more than one record is encountered per feature. The Fields collection is discussed in more detail later in this chapter. If a Fields collection is specified, the Geofield and SecondaryGeofield parameters refer to columns in the Fields collection rather than in the source data. Dynamic Parameter This parameter is a boolean value that controls whether the data binding is dynamic. It is optional; if omitted, it will default to False, meaning that the binding is static (i.e., MapX will copy needed data when the database is opened). If you specify True, MapX accesses data in a live manner, only as data is needed (e.g., when labeling). If you specify True but the dataset does not support dynamic columns, an exception will be thrown. Simple Example of DataSets.Add The following code opens the US_Cust table from the MapStats MSAccess database, which is included in the DATA folder of your MapInfo MapX 4.0 directory. Map1 is assumed to be the United States map. Dim ds As Dataset Dim db As Database Dim rs As Recordset 'Open the MapStats.MDB Databasse Set db = DBEngine.Workspaces(0).OpenDatabase( _ "C:\Program Files\MapInfo MapX 4.0\Data\Mapstats.mdb") 'rs is the SourceData recordset which is an MS Access table Set rs = db.OpenRecordset("US_Cust") 'Add the dataset to the map Set ds = Map1.Datasets.Add miDataSetDAO, rs MapX Developer’s Guide 139 Chapter 10: Putting Your Data on the Map Using the Fields Collectio A data source may have many columns of data. MapX has overhead for each column of data that is bound, so you should only bind data that is needed in the map (such as data you want to thematically map or label with). Use the last parameter of DataSets.Add (Fields) to set up a Fields collection of the fields (columns) you want to bind to the map. Note: When declaring a fields variable, declare it as "MapXLib.Fields". This is to prevent conflicts with the DAO "Fields" object. Dim flds As New MapXLib.Fields You can access a dataset’s Fields collection through the Dataset.Fields property. Method Description Code Sample Add Adds a field to a Fields collection. flds.Add “Sales”, “Sum_of_Sales” _ , miAggregationSum Remove Removes a field from a Fields collection. flds.Remove 3 RemoveAll Removes all Field objects from the collection. flds.RemoveAll Fields.Add Method The Fields.Add method enables you to add a column of data from your data source as a field to the Fields collection. The Fields collection is built to use with the DataSets.Add method (or with the Themes.Add method; see Thematic Mapping and Analysis). The Fields parameter of Datasets.Add takes a Fields collection, and is built using this Add method. The Add method cannot be used on a dataset’s Fields collection once the dataset has been created. The syntax of Fields.Add is shown below. (Note: optional parameters are in [square brackets]). Fields.Add DataSourceCol, Name, [AggregateFunction], [Type] 140 Parts Description DataSourceCol Name or index of the data source column. Name Name of field to add. MapX Developer’s Guide Chapter 10: Putting Your Data on the Map Parts Description AggregateFunction The aggregate function to use. This takes an AggregationFunctionConstants value Type The type of data in column. This takes a FieldTypeConstants value. The type parameter is used only with Unbound DataSets. It is ignored for all other DataSet types. Data Aggregation The Aggregate Function parameter of the Fields.Add method determines how MapX computes the Field value when multiple matches are found. For example, if the data looked like the following: STATE SALES CA 120 NY 100 CA 50 CA 110 Here there are three sales in California, and since only one data value will be attached to California, we need to tell MapX to either sum the sales, average the sales, or count the sales. The Aggregate Function parameter of the Fields.Add method defaults to miAggregationIndividual for string columns, and miAggregationSum for numeric columns. The following are the aggregates used to handle multiple matches: MapX Developer’s Guide 141 Chapter 10: Putting Your Data on the Map Aggregation Function Constants Constant Description MiAggregationSum Sums up data. MiAggregationAverage Takes an average of data. MiAggregationIndividual Pulls in each individual record. MiAggregationCount Counts the records. Example The following example shows how to create a fields collection from a DAO recordset data source and then add a dataset using the Fields collection. Private Sub cmdOK_Click() Dim ds As MapXLib.Dataset Dim rs As Recordset Dim i as integer Dim flds As New MapXLib.Fields 'Open the recordset selected from a list box Set rs = db.OpenRecordset(DatasetsList.Text) 'Use the AggregationFunction constant selected from a combo box Dim AggregateTypeNum As Integer Select Case AggregateType.ListIndex Case 0 AggregateTypeNum = miAggregationSum Case 1 AggregateTypeNum = miAggregationAverage Case 2 AggregateTypeNum = miAggregationCount Case 3 AggregateTypeNum = miAggregationIndividual Case 4 AggregateTypeNum = miAggregationAuto End Select 'Loop through the DAO fields of the Recordset ' and add them to a MapX Fields collection. 142 MapX Developer’s Guide Chapter 10: Putting Your Data on the Map For i = 0 To rs.Fields.Count - 1 flds.Add rs.Fields(i).Name, rs.Fields(i).Name, _ AggregateTypeNum Next 'Add the dataset, using the fields collection Set ds = Map1.Datasets.Add( _ miDataSetDAO, rs, "US State Data", , , , flds) MsgBox "Dataset " & DatasetsList.Text & " Added" Unload Me End Sub Displaying Your Data as a Layer of Points (BindLayer) BindLayer data binding is a type of data binding where source data is used to create a new layer of points at the locations specified by your data. This happens in two cases: • When your data contains x and y coordinates (such as longitude and latitude). Points are created at the specified location. See “DisplayingYour X/Y Data as a Layer of Points on a Map,” below. • When your data contains reference information, such as Zip Codes. Points are created at the Zip Code location (approximate location). See “Displaying Your Zip Code Data as a Layer of Points on a Map,” below. The Bindlayer object is required when binding data that has X/Y coordinates or point information such as Zip Codes, and you want to see points created in a new or existing layer at the locations specified by your data. When you add the dataset using a BindLayerObject, the points automatically show up on the map. This is not the case when adding a dataset without the BindLayerObject. Only BindLayerObjects have this behavior. The points will be brought in as gray stars. If you wish to change the style, you must set the Layer.StyleOverride property equal to True and change the style properties. The style changes will not show up unless StyleOverride is set to True. MapX Developer’s Guide 143 Chapter 10: Putting Your Data on the Map BindLayer Object Properties 144 Property Description Values LayerType Specifies the layer type that the data is being bound to. A BindLayerTypeConstant: MiBindLayerTypeNormal MiBindLayerTypeXY MiBindLayerTypePointRef CoordSys Specifies the coordinate system in which the layer will be created. A CoordSys Object FileSpec Allows you to specify the name and location of a file, so that the Datasets.Add method can create a permanent layer instead of a temporary layer. A text string that identifies a file path and file name. KeyLength A positive number, representing the desired size of the character column in the resulting layer. A numeric value (1-254). LayerName Specifies the name of the layer which to bind the data to if LayerType is miBindLayerTypeNormal. It is the name of the newly created layer if LayerType is miBindLayerTypeXY or miBindLayerTypePointRef. A string value. RefColumn1 The field containing the longitude when LayerType is miBindLayerTypeXY, or the field containing the reference value (such as ZIP Code) if LayerType is miBindLayerTypePointRef. A string or integer referencing a column (onebased index). RefColumn2 Specifies the field containing the latitude when LayerType is miBindLayerTypeXY. A string or integer referencing a column (onebased index). ReferenceLayer Specifies the name of the reference file to use if BindLayer.LayerType is miBindLayerTypePointRef. A string. MapX Developer’s Guide Chapter 10: Putting Your Data on the Map The order of operations for using a BindLayer object is as follows: 1. Create a BindLayer object. 2. Use this object when adding the dataset by passing it as the BindLayer parameter in the datasets.Add method. How to create a BindLayer object and display your X / Y or point reference data are shown below. Displaying Your X / Y Data as a Layer of Points on a Map If your data contains X / Y coordinates, you can create and display a layer of point features through data binding. Use a BindLayer object, and set : • Its LayerType property to be miBindLayerTypeXY. • Its RefColumn1 property to be the name or index (one-based) of the column containing the X coordinate values. • Its RefColumn2 property to be the name or index (one-based) of the column containing the Y coordinate values. Example This example does the following: • Opens the US_Cust Microsoft Access table in our sample Mapstats database. • Creates the BindLayer object from the US_Cust table specifying the type of BindLayer data binding (miBindLayerTypeXY) and the index of the columns in US_Cust containing the X and Y coordinates. • Adds US_Cust as a dataset, creates a temporary layer of points, and displays each customer in US_Cust as a point on the map. It is assumed in this example that Map1 is the United States map. Dim BindLayerObject As New MapXLib.BindLayer Dim flds As New MapXLib.Fields ' Get the recordset to map ' MapStats Access database ' Has Longitude, Latitude columns Set db = DBEngine.Workspaces(0).OpenDatabase( _ "C:\Program Files\MapInfo MapX 4.0\Data\Mapstats.mdb") Set rs = db.OpenRecordset("US_Cust") rs.Movelast MapX Developer’s Guide 145 Chapter 10: Putting Your Data on the Map Debug.Print "Record Set has " & rs.RecordCount & " records." ' Fill in the Bindlayer object BindLayerObject.LayerName = "US Customers" 'Name of new layer BindLayerObject.RefColumn1 = 8 ' "Longitude" ' Use Column number (one'based!) or Column name ' BindLayerObject.RefColumn2 = 9 ' "Latitude" BindLayerObject.LayerType = miBindLayerTypeXY 'Type for X/Y binding Debug.Print "Finished setting up Bind Layer" Set ds = Map1.Datasets.Add(miDataSetDAO, rs, "U.S. Customers" _ , "City", "State", BindLayerObject) Debug.Print "Finished adding dataset" Displaying Your ZIP Code Data as a Layer of Points on a Map If you have a table of data that has no X / Y coordinates but it has point reference information such as ZIP Codes, you can still display your data as points on a map. A process known as point reference binding allows you to data bind against a separate reference layer containing X / Y coordinates for your ZIP Code-based table of data. You do this by specifying the reference layer in the BindLayer object when setting up the BindLayer object, as shown below. MapX supplies a table called Zipcodes.cpf in the \MapInfo MapX 4.0\Maps directory which you can use as your reference layer for US ZIP Codes. Zipcodes.cpf also has a “friendly name” (the description that is assigned to the layer through the geodictionary) which is “US 5 Digit Zipcode Centers.” To create and display a layer of point features through ZIP Code data binding, use a BindLayer object, and set : 146 • Its LayerType property to be miBindLayerTypePointRef. • Its RefColumn1 property to be the name or index(zero-based) of the column in your table containing the zip code (or other point reference) data. • Its ReferenceLayer as the name of the reference file to use. A reference file contains the x and y coordinates that the data binding process will use to determine the geographical location for your ZIP Code data on the map. The ReferenceLayer property can be set to a layer's filename (a full file specification) or set to the layer's "friendly name" (the description that is assigned to the layer through the geodictionary). MapX Developer’s Guide Chapter 10: Putting Your Data on the Map Note: The reference layer does not need to be displayed in the map, but it must be installed in your geodictionary. The RefColumn2 property is not used in ZIP Code data binding because US ZIP Codes are unique. Example This example shows how to do a ZIP Code bind. It assumes there is already a user table with ZIP Codes opened as Data2.Recordset, and the fourth column in the user table contains the ZIP Codes. This example does the following: • Sets up the BindLayer object, using "US 5 Digit Zipcode Centers" as the reference layer. • Adds the dataset. When the dataset is added, MapX will create a temporary layer of points for the user table of customers at the X / Y coordinate of each customer’s ZIP Code. In addition, MapX will add the Geofield column to the newly created layer and then bind any attribute data specified in the Recordset against it. The new layer’s name is obtained from the BindLayerObject.LayerName and will be "Customers By Zipcode centers." Dim MyDataset as Dataset ' Set up the bind layer object Dim BindLayerObject As New MapXLib.BindLayer BindLayerObject.LayerName = "Customer's By Zipcode centers" BindLayerObject.RefColumn1 = 3 ' The third column in my source data contains zip code info BindLayerObject.LayerType = miBindLayerTypePointRef BindLayerObject.ReferenceLayer = "US 5 Digit Zipcode Centers" ' The values in the source data column named "GEOABBR" will ' be used as the geofield for the new point table Set MyDataset = Map.Datasets.Add(miDataSetDAO, Data2.Recordset, "Zipcode Dataset", "GEOABBR", , BindLayerObject) MyDataset.Themes.Add MapX Developer’s Guide 147 Chapter 10: Putting Your Data on the Map Making Your New Layer of Points a Permanent Layer It’s easy to make your new layer of points, created with a BindLayer object, a permanent MapInfo table. Use the BindLayer.Filespec property or specify the name and location of a file, so that the Datasets.Add method can create a permanent layer instead of a temporary layer. If you do not assign this property, the layer is temporary.This property applies to both X / Y data binding and point reference (zip code) data binding. This example creates a permanent table through data binding using X / Y coordinates. Dim BindLayerObject As New MapXLib.BindLayer Dim ds as Dataset 'Where to save the newly created permanent table BindLayerObject.FileSpec = “C:\MapInfo\Data\Dealers.TAB” BindLayerObject.LayerType = miBindLayerTypeXY ‘Binding to Long/Lat BindLayerObject.LayerName = "US Dealers" 'Layer Name to use BindLayerObject.RefColumn1 = ("LONG") 'Name of Longitude column BindLayerObject.RefColumn2 = ("LAT") 'Name of Latitude column 'Add the dataset and create the permanent layer Set ds = Map1.Datasets.Add(miDataSetDAO, rs, "My Dealers", _ Dealer, BindLayer) How Data Binding Uses the GeoDictionary MapX uses a GeoDictionary file (named GEODICT.DCT by default) to keeps track of information related to data binding. MapX comes with two utilities— GeoDictionaryManager40.EXE and GeosetManager40.exe—that help you manager the GeoDictionary. When you use the DataSets.Add method, MapX can analyze your data to determine how the data might be bound to the map. Specifically, the method has these automated behaviors: 148 • Determines which column in the data source contains geographic information. • Determines which map layer to bind to. MapX Developer’s Guide Chapter 10: Putting Your Data on the Map Both of these behaviors are optional. There are parameters so that you can explicitly specify which column in the data source contains the geographic information, as well as which map layer should be bound to. If you know either of these values, you should specify them explicitly to improve performance. For MapX to be able to bind data to a map layer, the following things need to be true: 1. The map’s geographic key column needs to be indexed. Most maps come with indexed key columns when they are installed, but it is up to the map preparer to decide which columns are key columns. For example, the United States could have at least 3 key columns: state name (“New York”), state abbreviation (“NY”), and FIPS code (36). The United States map that MapInfo ships has the first two as key columns, thus requiring data from the data source to also have either state name or abbreviation. 2. The map and its key columns must be specified in the GeoDictionar . Some key columns from the map layer might not contain unique values. An example of this is United States county names: multiple states have counties named “Warren” or “Washington”. Thus, when a row of data has the county name "Washington," MapX needs more information to resolve the ambiguity. For the United States Counties example, State is used to resolve ambiguity. The parameter SecondaryGeoColumn is used to specify the column in the data source that contains the information needed to resolve the ambiguity. The GeoDictionary contains information about which maps have non-unique keys and what their refining map is. MapX Events Used by Data Binding Once a column is defined as the geographic column from the data source, and a map layer to bind to is determined, binding begins. Each row of the data source is ‘matched’ to a feature and the data is brought in. If a row contains a geographic column that doesn’t match a feature (perhaps a typo [“NA” instead of “MA”] or simply a data value that’s not on the map [“Puerto Rico”]), a DataMismatch event is fired to notify the container. You can ignore the DataMismatch event, in which case MapX simply ignores the row. During automatic data binding, MapX calls the ResolveDataBind event if the data is ambiguous. During "unbound" data binding, you use the RequestData event to set up a loop, so that the container provides data to MapX one cell at a time. MapX Developer’s Guide 149 Chapter 10: Putting Your Data on the Map Refreshing Datasets Since the data from the data source is aggregated and stored in MapX, when the data changes in the data source, MapX does not reflect the change. The DataSet.Refresh method can be used to have MapX reread the source data and re-aggregate and store it. This, however, can be time consuming. DataSet.Refresh does not work for DataSets that create new point layers. A workaround is to simply remove the layer and re-add the dataset, or to perform the following steps: 1. Create a new point layer using Datasets.Add with a BindLayer of type miBindLayerTypeX . Create the new layer with only the X and Y columns by passing a Fields object, with only those two columns specified, in the Datasets.Add method. 2. Bind the rest of the data to this newly created layer. Use Datasets.Add with normal binding, using the X field for the Geofield parameter and the Y field as the SecondaryGeofield parameter. This second dataset can be refreshed. Note: This method will not add new features to the layer when new rows are added to the data source. The Different Types of Data Sources MapX lets you bind to several different types of DataSources. The first argument to the Datasets.Add method lets you specify a DatasetTypeConstants value, which dictates the type of data binding you wish to perform. Each of the data source types is described below. miDataSetDAO (Data Access Object Recordset) The SourceData parameter to DataSets.Add must be a daoRecordset object. You can get one from a Visual Basic data control, an Access form, or by creating one in Visual Basic, Access, or C++. Example 'This sample demonstrates the simplest use of the Datasets.Add 'method. With this usage, you specify only the data source and 'type. MapX automatically determines which column represents 'the geographic information, as well as which layer to bind that 'information to. 150 MapX Developer’s Guide Chapter 10: Putting Your Data on the Map 'Also demonstrated here is the simplest use of the Themes.Add 'method. In this usage, where all arguments are omitted, MapX 'automatically determines a name for the theme, which column to 'use to create the theme, and what type of theme to create. In 'this case, MapX will create a ranged theme on the first numeric 'column in the USA table (TOTPOPHIS). Private Sub Command1_Click() Dim db As Database Dim rs As Recordset Dim ds As Dataset 'First, get the table that will contain our source data Set db = DBEngine.Workspaces(0).OpenDatabase( _ "C:\Program Files\MapInfo MapX 4.0\Data\Mapstats.mdb") Set rs = db.OpenRecordset("USA") 'This line will create a dataset named "Dataset1" Set ds = Map1.Datasets.Add(miDataSetDAO, rs) 'Create the default theme on the dataset ds.Themes.Add End Sub miDataSetODBC (Open DataBase Connectivity data source) MapX can use ODBC to retrieve data from any ODBC data source. You need to specify the connection string, the data source name, and the SQL string to execute by using the ODBCQueryInfo object. The ODBCQueryInfo.ConnectString property sets the connect string to connect with an ODBC data source. For example, specify “ODBC;”. You can also include “uid=” , “pwd=”, or DLG=. If necessaryr information is missing, the ODBC driver for the DataSource will prompt the user. “DLG=” controls the display of the connection dialog box: DLG=0 means never put up a dialog, DLG=1 means always put one up, DLG=2 displays the connection dialog, but only if needed (i.e., if not all required information was provided). For more information on the ODBCQuery Info object, see the Online Help or Reference Guide. MapX Developer’s Guide 151 Chapter 10: Putting Your Data on the Map Example Private Sub Command2_Click() Dim ds As Dataset Dim parm As New ODBCQueryInfo Dim fd a field parm.SqlQuery = "select * from usa" parm.DataSource = "usa"' name of odbc datasource parm.ConnectString = "ODBC;"' can be left blank, or can include uid= or pwd= or DLG= Set ds = Map.Datasets.Add(miDatasetODBC, parm, "odbc Dataset") For Each fd In ds.Fields MsgBox fd.Name Next If Not (ds Is Nothing) Then ds.Themes.Add End Sub miDataSetLayer (MapInfo table) This type of data binding lets you create a dataset that uses fields from a MapInfo table. Example Dim Dim Dim Dim FoundObj As FindFeature Layer As Layer ds As Dataset Findds As Dataset ' Add a MapInfo table as a layer Map1.Layers.Add "c:\program files\mapinfo _ professional\data\usa\states.tab" Set Set Set Set Set Layer = Map1.Layers("states") Findds = Map1.Datasets.Add(miDataSetLayer, Layer) Map1.Layers("states").Find.FindDataset = Findds Map1.Layers("states").Find.FindField = Findds.Fields(2) FoundObj=Map1.Layers("states").Find.Search("New York") If (FoundObj.FindRC Mod 10 = 1) Then Map1.Zoom = 500 Map1.CenterX = FoundObj.CenterX Map1.CenterY = FoundObj.CenterY 152 MapX Developer’s Guide Chapter 10: Putting Your Data on the Map Else MsgBox "No exact match found. " + Str$(FoundObj.FindRC) End If miDataSetGlobalHandle (tab-delimited data) This type of data binding lets you pass in a block of tab-delimited data. The SourceData parameter to DataSets.Add must be a variant with type of VT_I4 and the lVal equal to the global memory handle. The format of each row of data in the block of global memory is: Field Field TAB TAB Field Field TAB TAB Field Field CRLF CRLF . . . where Field is a string value in quotes, or a numeric value without quotes; TAB is character 0x09; and CRLF is a carriage-return line-feed sequence: 0x0D 0x0A. Example: Data binding using C++ Below is one of the menu command handlers for adding data from a file using the miDataSetGlobalHandle type. The format of the data needs to be: quotes around strings, tabs between fields, and carriage return/line feed at the end of the record. For example: "\"NY\"\t105.34\t100\t1\r\n" "\"MA\"\t245.19\t200\t2\r\n" "\"NY\"\t195.0\t300\t3\r\n" "\"AK\"\t195.0\t125\t4\r\n" "\"CA\"\t56.453\t200\t5\r\n"; The function CMapxSampleView::OnMapAdddata() handles a menu item on the Map menu. It prompts for a filename containing data in the form specified above, reads the file, and adds this to the map's collection of datasets. void CMapxSampleView::OnMapAdddata() { : : CFileDialog dlgFile(TRUE, "*.txt", NULL, 0, szDataFilter, this); if (dlgFile.DoModal() == IDCANCEL) return; // User cancelled the dialog // Read file into a string, and copy it to a global memory // buffer : : MapX Developer’s Guide 153 Chapter 10: Putting Your Data on the Map // Allocate the memory buffer, copy the string into it : : // Declare the variables that will be parameters to // DataSets.Add() short Type; VARIANT SourceData, Name, GeoField, SecondaryGeoField; VARIANT BindLayerName, Fields; CString strName= "TestData"; // set up optional parameters; most will not be used // Note: you could also use the line //COptionalVariant SecondaryGeoField; // instead SecondaryGeoField.vt = VT_ERROR; SecondaryGeoField.scode = DISP_E_PARAMNOTFOUND; // let mapx auto detect geofield GeoField.vt = VT_ERROR; GeoField.scode = DISP_E_PARAMNOTFOUND; // let mapx find which layer to bind to BindLayerName.vt = VT_ERROR; BindLayerName.scode = DISP_E_PARAMNOTFOUND; // use all fields with defaults Fields.vt = VT_ERROR; Fields.scode = DISP_E_PARAMNOTFOUND; // set the name of our dataset Name.vt = VT_BSTR; // Remember to SysAlloc() the string; it's going into a BSTR Name.bstrVal = strName.AllocSysString(); // set up source data - no error checking on alloc Type = miDataSetGlobalHandle; SourceData.vt = VT_I4; SourceData.lVal = (long)hGlobalData; try { 154 MapX Developer’s Guide Chapter 10: Putting Your Data on the Map // now add the dataset to the datasets collection CMapXDataset ds = m_ctrlMapX.GetDatasets().Add(Type, SourceData, Name, GeoField, SecondaryGeoField, BindLayerName, Fields); } catch (COleDispatchException *e) { e->ReportError(); e->Delete(); } } miDataSetOLEData (PowerBuilder) This is for containers such as PowerBuilder, that pass data to MapX in the format described in miDataGlobalHandle when initializing the MapX control. Then a call to DataSets.Add with miDataSetOLEData as the type tells MapX to build a dataset using the previously passed in data. miDataSetUnbound (alternate method) If you cannot support one of the other formats, MapX provides a an alternative approach. to data binding that allows you to set up an event loop whereby MapX asks the container for data values, one cell at a time. MapX will send the RequestData event, with the row and column number of the data value wanted. You can then use any method of getting the data and feeding it through this event back to MapX. Example: Using RequestData to build an unbound dataset 'This sample demonstrates the use of Datasets.Add and the ' RequestData event supported by MapX to build an unbound ' dataset, which allows MapX to access data whose format ' is known only to the programmer. In this example, the ' data is in the form of a two-dimensional array in VB. Private Const kNumberOfRows = 3 Dim theData(1 To 3, 1 To 2) As Variant Private Sub Form_Load() theData(1, 1) = "ME" theData(2, 1) = "NH" theData(3, 1) = "VT" theData(1, 2) = 100 MapX Developer’s Guide 'Fill in the data to 'be used by RequestData 155 Chapter 10: Putting Your Data on the Map theData(2, 2) = 200 theData(3, 2) = 300 'Zoom in on New England Map1.ZoomTo 800, -70.26, 44.05 End Sub Private Sub Command1_Click() Dim flds As New MapXLib.Fields Dim ds As Dataset 'Describe the structure of the unbound dataset: flds.Add "State", "State", miAggregationIndividual, _ miTypeString flds.Add "Sales", "Sales", miAggregationSum, miTypeNumeric 'Create the unbound dataset. The "RequestData" event 'will be triggered to get the data to be used. Set ds = Map1.Datasets.Add(miDataSetUnbound, Nothing, _ "My Dataset", "State", , , flds) 'Create a theme based on the "Sales" column in the 'unbound dataset ds.Themes.Add miThemeGradSymbol, "Sales", "My Theme" End Sub Private Sub Map1_RequestData(ByVal DataSetName As String, _ ByVal Row As Long, ByVal Field _ As Integer, Value As Variant, _ Done As Boolean) Done = false If DataSetName <> "My Dataset" Or Row > kNumberOfRows Then Done = True Else Value = theData(Row, Field) End If End Sub 156 MapX Developer’s Guide Chapter 10: Putting Your Data on the Map miDataSetNotesView, miDataSetNotesQuery (Lotus Notes) These types of data binding deal specifically with Lotus Notes. For details, see "Getting Started With MapX". MapX Developer’s Guide 157 Chapter 10: Putting Your Data on the Map 158 MapX Developer’s Guide Chapter 11: Accessing Data from a DBMS 11 Chapter Accessing Data from a DBMS ➤ Accessing Remote Spatial Data MapX provides Spatial Server Access. This is a powerful ➤ Using Layers.Add Method With a LayerInfo Object feature that allows developers to connect to live data stored in spatial servers, such as MapInfo's SpatialWare running on Oracle, Informix, DB2 databases, or the Oracle 8i Spatial databases. Spatial servers allow ➤ Accessing Remote Tables through a .tab File ➤ Connection Syntax companies to host their map data in their enterprise ➤ Accessing Attribute Data database for central management and security. Spatial ➤ Performance Issues servers like SpatialWare offer advanced query processing ➤ Caching and increased performance on the server for an organization's spatial data. ➤ The MapInfo Map Catalog ➤ Using MapInfo Professional to Manage a Map Catalog ➤ Creating a MapInfo Map Catalog ➤ Making a Remote Table Mappable ➤ Symbol, Pen, Brush Clause Syntax ➤ Specifying Point Styles ➤ Specifying Line Styles ➤ Specifying Fill Styles ➤ Troubleshooting Chapter 11: Accessing Data from a DBMS Accessing Remote Spatial Data You can access data as a map layer data using MapX with different DBMS servers. The servers include: • MS Access/SQL Server/other ODBC datasources . • Spatial servers like SpatialWare for Oracle, SpatialWare Informix DataBlade, and SpatialWare DB2 Extender. • The MapInfo Geocoding DataBlades for Informix. • Oracle8i Spatial. You can add a layer from data in a DBMS using the Layers.Add method. There are two techniques: • Use the Layers.Add method with the LayerInfo object when the query needs to be calculated dynamically at run time. This would be appropriate for a case with newly entered data. For example, you have an application that determines locations of stores that have generated a user-entered amount of revenue. The revenue value entered via the application could not be known at design time and, therefore, can only be added to the query at run time. This replaces the previous AddServerLayer method. • Use the Layers.Add with a .tab file when the query is known at design time. For example, if an application requires a display of all of the fire hydrants that are in service, the query can be set to select all hydrants where the in-service condition is true. This can be set at design time. A .tab file can be placed directly into a geoset, ensuring that the file is loaded when any application using that geoset is initialized. The details of each technique for adding spatial data are included in the following sections. Once you have decided how to handle your data, follow the instructions in the appropriate section. Note: MapX 4.0 does not support opening SpatialWare 3.0 or lower tables. 160 MapX Developer’s Guide Chapter 11: Accessing Data from a DBMS Using the Layers.Add Method with a LayerInfo Object If your Layers.Add succeeds but your DBMS layer data does not display on the map, check the layer order. The layer may have been drawn and hidden by another layer. You can specify the layer order using the LayerInfo property. If the DBMS layer is the first or only layer in the Map window, the default zoom level is set too far out to see the data. You can adjust the server layers default zoom level in the MapInfo_MapCatalog by running a MapBasic tool (misetmbr.mbx). Dim lInfo As Object Dim lStr As String Set lInfo = CreateObject("mapx.layerinfo.4") lInfo.Type = 4 ' layer type is RDB lInfo.AddParameter "NAME", "city_125"' layer name lInfo.AddParameter "TOOLKIT", "ODBC" ' use "ORAINET" for oracle direct access lInfo.AddParameter "CONNECTSTRING", "DRIVER={SpatialWare 32 Bit Driver4.00};HOST=Champagne;UUID=oracle;UPWD=secret;UID=GEORGETOWN; PWD=secret;OSID=DB1;DLG=0" lInfo.AddParameter "QUERY", "SELECT * FROM CITY_125" lInfo.AddParameter "CACHE", "ON" lInfo.AddParameter "MBRSEARCH", "ON" g_map.Layers.Add lInfo Set lInfo = Nothing Accessing Remote Tables through a .tab File MapX can access DBMS data "live", or can open a MapInfo Professional linked table. However, the linked table will be read only and cannot be refreshed by MapX. The data is actually from the remote database and does not reflect the data in the local linked version. You can create a .tab file to provide access to remote maps. To generate a .tab file using MapInfo Professional, choose File > Open a DBMS table. The .tab file is a text file; you can create a .tab file using any text editor. Once you have created the .tab file, you can access it the way you access any other MapInfo .tab file programmatically through the Layers.Add method or through the Geoset Manager. MapX Developer’s Guide 161 Chapter 11: Accessing Data from a DBMS Example (ODBC) This is a sample .tab file for a SpatialWare Layer Using ODBC. !table !version 500 !charset WindowsLatin1 Definition Table Type ODBC begin_metadata "\IsReadOnly" = "FALSE" "\DATALINK" = "" "\DATALINK\Query" = "SELECT * FROM CITY_125" "\DATALINK\ConnectionString" = DRIVER={SpatialWare 32 Bit Driver4.00};HOST=Champagne;UUID=oracle;UPWD=secret;UID=GEORGETOWN; PWD=secret;OSID=DB1;DLG=0 "\DATALINK\ToolKit" = "ODBC" "\CACHE" = "OFF" "\MBRSEARCH" = "ON" end_metadata Example (Oracle Direct) This is a sample of a .tab file for Oracle Spatial Access Direct. Note: The Oracle eaxmple of a .tab file explicitly includes the password. If the password is missing an error is generated. MapX does not popup a dialog to ask for the password like ODBC will. !table !version 550 !charset WindowsLatin1 Definition Table Type ODBC begin_metadata "\IsReadOnly" = "FALSE" "\DATALINK" = "" "\DATALINK\Query" = "select ""NAME"", ""SW_MEMBER"", ""MI_SQL_RECNUM"", ""OBJECT"" from ""MAPX"".""RDBSDATA""" "\DATALINK\ConnectionString" = "SRVR=superior;UID=mapx;PWD=mapx" "\DATALINK\ToolKit" = "ORAINET" "\CACHE" = "OFF" "\MBRSEARCH" = "ON" end_metadata 162 MapX Developer’s Guide Chapter 11: Accessing Data from a DBMS Mapping DBMS Data with X/Y Columns You can add a layer from a DBMS table that has X/Y coordinates. You need to create a Map Catalog and register the tables as SpatialType 4.0 and specify two column containers as the coordinates. The columns should be indexed on the table. Connect to the DBMS via ODBC and specify the new columns as "Object" in your query. Example Private Sub AddMSAccessPointLayer() On Error GoTo TRAP Dim lInfo As Object Set lInfo = CreateObject("mapx.layerinfo.4") lInfo.Type = 4 ' layer type is RDB Dim ConnectStr As String ConnectStr = ""DRIVER={Microsoft Access Driver (*.mdb)};DBQ=C:\Programs\MapInfo\Data\USA\ACCESS\US_CUST.MDB;Drive rId=25;FIL=MS Access;MaxBufferSize=512;PageTimeout=5" lInfo.AddParameter "connectstring", ConnectStr lInfo.AddParameter "name", "TempConnect" lInfo.AddParameter "toolkit", "ORAINET" lInfo.AddParameter "query", "select `MI_SQL_RECNUM`, `OBJECT`, `Capital`, `Province_Name`, `Pop_1991`, from `Can_caps`" lInfo.AddParameter "cache", "OFF" lInfo.AddParameter "mbrsearch", "ON" g_map.Layers.Add lInfo Set lInfo = Nothing Exit Sub TRAP: MsgBox Err.Number & ", " & Err.Description End Sub You may upload a MapInfo point table like CITY_125 to MSAccess or SQL Server using MapInfo Professional in the MI Upload MBX (located in the Tools directory of MapInfo Professional). MapX Developer’s Guide 163 Chapter 11: Accessing Data from a DBMS Oracle8i Support Oracle8i support is new for MapX 4.0.You can install it in addition to the MapX ODBC Connectivity component. Oracle8i Spatial is a new implementation of a spatial database from Oracle Corporation. Although it has some similiarties to the previous Oracle SDO implementation, it is significantly different. Oracle8i Spatial maintains the Oracle SDO implementation via a relational schema. However, MapInfo does not support the Oracle SDO relational schema via the Oracle Call Interface (OCI). MapX does support simultaneous connections to Oracle8i through the OCI and to other databases through ODBC. MapX does not support downloading Oracle8i spatial geometry tables via ODBC using the current ODBC drivers from Intersolv. Oracle8i Requirements To connect to Oracle8i within MapInfo, you must have the Oracle8i v. 8.1.5 client installed. See your Oracle documentation for detailed information. Connection Dialog Workaround For Oracle8i, there is no connection dialog that will display if you do not specify the complete connection string. The DLG= option has no affect. If you do not provide the userID and password, the connection will fail. Since DBMS table .tab files created by MapInfo Professional do not contain passwords, (for security reasons), this causes the open on the ta files to fail. A way around this is to write a simple connect dialog that gets the password from the user and does a Layers.Add for a DBMS layer using layerinfo with a connection string using the userID/password for the database you wish to access. An Oracle connection string should be specified as follows: "SRVR=superior;UID=user1;PWD=secret;" Add a temporary layer. This will also add the connection desired to the connection pool. That connection will be used by all tab files opened on the same database with the same userid since the password has already been authenticated. Thus the .tab files will be opened successfully. For these tab files to work in a geoset, you may have to put this login in the application startup. You can connect to/login to multiple servers in this way and tables opened rfom them will succeed. 164 MapX Developer’s Guide Chapter 11: Accessing Data from a DBMS Tesselation Error Workaround for 8.1.5 Oracle8i spatial queries can fail with aTesselation error when you view the data at wide zoom vantages. The following code example works around the problem: 1. Step 1 is only done once. As the MDSYS Oracle user run: CREATE VIEW all_sdo_index_metadata as select SDO_INDEX_OWNER, SDO_INDEX_TYPE, SDO_INDEX_NAME, SDO_INDEX_TABLE, SDO_INDEX_PRIMARY, SDO_TSNAME, SDO_COLUMN_NAME, SDO_RTREE_HEIGHT, SDO_RTREE_NUM_NODES, SDO_RTREE_DIMENSIONALITY, SDO_RTREE_FANOUT, SDO_RTREE_ROOT, SDO_RTREE_SEQ_NAME, SDO_LEVEL, SDO_NUMTILES, SDO_MAXLEVEL, _ SDO_COMMIT_INTERVAL, SDO_FIXED_META, SDO_TABLESPACE, SDO_INITIAL_EXTENT, SDO_NEXT_EXTENT, SDO_PCTINCREASE, SDO_MIN_EXTENTS, SDO_MAX_EXTENTS from SDO_INDEX_METADATA_TABLE where (exists (select table_name from all_tables where table_name=sdo_index_table and owner=sdo_index_owner) or exists (select view_name from all_views where view_name=sdo_index_table and owner=sdo_index_owner) or exists (select table_name from all_object_tables where table_name=sdo_index_table and owner=sdo_index_owner) ); grant select on all_sdo_index_metadata to public; create public synonym all_sdo_index_metadata for all_sdo_index_metadata; 2. In the schema of the user that want to grant select to their table: grant select on sdo_geom_metadata to <user>; grant select on <table> to <user>; grant select on <sdo_index_table> to <user>; MapX Developer’s Guide 165 Chapter 11: Accessing Data from a DBMS DBMS LayerInfo Parameters Both the .tab file and the LayerInfo object accept the same parameters. However, the naming conventions for the parameter names are slightly different. 166 Parameter Description Query This is the backend DBMS query that determines the contents of the table. For the table to be mappable, you must select the spatial object column (or the pseudo column OBJECT). SpatialWare users can specify a GISSQL/Server specific SQL string/statement that will return a spatial object. Also, SpatialWare users should include the SW_GEOMETRY and SW_MEMBER columns, which are used by SpatialWare to store geographic objects and IDs. Note: If your table name is case sensitive and your database requires you to quote it, and if the identifier quote character is a double quotation mark ("), then you must repeat the double quotation marks. For example: "select * from ""tableowner"".""tablename""" ConnectionString This is the information that is necessary to connect to the DBMS. For ODBC, the Connection clause specifies an ODBC connection string. If you specify a complete connection string, the connection is established without a dialog box. If no connection string is provided, a default string of "DLG=0" is used, and an ODBC Data Source dialog box appears. For Oracle Spatial, you must specify a complete connection string with userid and password. The DLG keyword does not apply and a connect dialog will not appear. The Oracle direct connection string looks like this: "SRVR=superior;UID=mapx;PWD=secret" Note: Full connection strings are recommended for actual applications so that connections may be shared. Cache Values "ON"/"OFF", Default is on. This controls whether the data fethec when the layer is drawn is cached. Caching helps improve the performance for subsequent redraws, pans/zoom (within the cached region), labeling and themeatics. Caching on too many large layers can use all available memory and lose the value of the cache. MapX Developer’s Guide Chapter 11: Accessing Data from a DBMS Parameter Description MBRSearch Values "ON"/"OFF", default is ON When MapX dows a map draw, it fetches from the layer for the data Inside the map boundaries. To do this for dbms layers, a spatial predicate is appended to the table definition query. For some types of queries, or onm layers that have a proiblem with their Spatioal index, this predicate can slow down or cause the query to fail. This option allows you to turn off that spatial predicate. This is a required string to provide a name/alias for this layer. Name ToolKit Values "ODBC"/" "ORAINET", Default is "ODBC" This specifies the DBMS access components required to connect to The server database. For Oracle direct, specify ORAINET and use an ORAINET connection string. For others, specify ODBC. DBMS Connection String Format The format of the ODBC connection string is the same as in MapInfo Professional ODBC/ Linked tables. The string is defined by several clauses separated by semicolons (;). Each clause has the form Key=Value. Important keys are listed below. Part Description DSN= Specifies the ODBC datasource name. Caution: If you use the DSN= syntax key, the name that you specify must match the datasource name in use on the user’s system. Note that different users might use different names to refer to the same datasource. If you cannot know in advance what datasource name to use, use the DRIVER= syntax key instead of the DSN= syntax key. DRIVER= Specifies the exact driver name of the installed SpatialWare or IUS driver. Used instead of the DSN= syntax key. Examples: DRIVER={SpatialWare 32 Bit Driver} Note: Informix 2.80.0861 does NOT support DRIVER=. UID= Specifies the desired UserId for the datasource, if required. PWD= Specifies the user’s password for the datasource, if required. DLG= A number that controls the display of the connection dialog box: 0 – Suppresses the connection dialog (required for MapX Theme). 1 – Displays the connection dialog. 2 – Displays the connection dialog, but only if needed (i.e., if not all required information was provided) [default]. MapX Developer’s Guide 167 Chapter 11: Accessing Data from a DBMS Part Description SRVR= Reflects a value set in the Oracle8i EasyConfig utility. This is required for Oracle8i connectivity. You can re-use connections, thus avoiding redundant connection dialogs. If you pass a complete connection string in the exact order (see Sample Connection Strings for order) that matches an existing string in the current connection pool, that connection will be shared by the two tables. Passwords do not need to be in the connection string for the two strings to match. Sample Connection Strings Here are sample connection strings for the IDS/UDO and SpatialWare ODBC drivers. IDS/UDO connection string: DRIVER={INFORMIX 2.80 32 BIT};UID=informix;PWD=secret;DATABASE=sw;HOST=adak;SERVER=adak_tli ;SERVICE=sqlexec;PROTOCOL=onsoctcp; SpatialWare connection string: DRIVER={SpatialWare 32 Bit Driver3.50};HOST=fire;UUID=oracle;UPWD=secret;UID=GEORGETOWN;PWD=G EORGETOWN;OSID=QASW1 Accessing Attribute Data To use all available data columns, specify a query such as "Select * From tablename".You are not required to specify * (asterisk); instead, you can designate specifically which columns you want to use. For the best performance, limit your query so that it retrieves only the needed columns. To access the attribute data selected in the query with the spatial object in a DBMS layer, use the datasets.add method with dataset type midatasetlayer (to get the attributes from the existing layer). When you add a DBMS layer, for performance sake, you should only specify the columns in the query that you intend to use in your application. These are the spatial column, the key column(s), which are added automatically if you do not specify them, and columns you want to label with, or create a theme from. You may use the pseudo columns "OBJECT" for any 168 MapX Developer’s Guide Chapter 11: Accessing Data from a DBMS mappable table to refer to the column(s) containing the spatial data. This is required for a table using the MapMarker MDIGEOADDRESS column on a table with an X/Y column. Note: You can use any server side expression/function to specify a column. Also, avoid select * from tab in a real application. The following code example will open a MapInfo *.tab file, then access the remote data and tie it to the layer.You now can label or place themes based on the columns. Dim Lay As Layer Dim dsname As String Set Lay = Map1.Layers.Add(filename) dsname = Lay.Name Map1.Datasets.Add miDataSetLayer, Lay, dsname Performance Issues Establishing a connection with the database server may take several seconds. This is a onetime cost, incurred when the table is first opened. An ’open’ operation may take several seconds as well. This one-time cost is incurred every time a new table is opened. The map-display speed depends on how much data is retrieved from the server. In some cases, displaying a map from a server is noticeably slower than displaying a map from a local file. Speed also depends on whether MapX has already cached the map features that are being displayed. MapX Developer’s Guide 169 Chapter 11: Accessing Data from a DBMS Caching A DBMS layer can be cached to improve performance if your application specifies redraws, themes, and labeling (CACHE ON is the deafault). It requires significant amounts of memory to cache all of the layer data in the map, so be selective about which layers you create. ODBC layer data is cached internally as it is read and drawn to the MapX Map window. All subsequent redraws will read from this cache instead of going to the server database for the same data. The cache is able to offer significant redraw performance improvement. If you pan or zoom out of the region loaded in the cache as defined by the MBR of the Map window, the cache will automatically be flushed and reloaded with the data from the server database within the new MBR. If you want to reload the cache from the database without panning or zooming out to obtain a fresh view of potentially modified data within that geographic area, use the Layer.Refresh method. A good strategy for harnessing the full power of the cache is to try to load as much data as possible in your initial view and have all subsequent options zoom in and pan around within the cache. Note: If you try to cache too much data or too many layers, virtual memory usage may be forced, and performance gain would in turn be lost. The MapInfo Map Catalog If a MapX application needs to access remote spatial data, a special table must exist in the DBMS, known as the MapInfo Map Catalog. One catalog must be created per database befor any tables in that database can be viewed as a map layer in MapX. The Map Catalog must contain information about the spatial columns in each of the mappable tables you want to access from the database. Your MapX application can use a Map Catalog that already exists on the server. (This same catalog is shared by various MapInfo client applications, including MapInfo Professional.) If there is no Map Catalog on the server, you will need to create it. 170 MapX Developer’s Guide Chapter 11: Accessing Data from a DBMS Using MapInfo Professional to Manage a Map Catalog If you are a MapInfo Professional user, you can create and manage the Map Catalog using MapInfo Professional. MapInfo Professional includes MapBasic utilities, such as MIODBCAT.MBX, to assist you in creating and managing the Map Catalog. A Map Catalog that was created by MapInfo Professional can be used by MapX applications. For example, in a corporate setting, one user—a database administrator, perhaps—can use MapInfo Professional to create the Map Catalog, and then numerous end users can run MapX applications that read from that Map Catalog. Loading Spatial Data to DBMS If you already have spatial data in the form of a MapInfo table, and you want to import that MapInfo table into SpatialWare, you can do so using one of the following: • MISWUP32.MBX utility that is provided with MapInfo Professional, in the SpatialWare client install directory. • EasyLoader for IUS. • DB2. • Oracle Spatial Manually Creating a MapInfo Map Catalog If you are not a MapInfo Professional user, you will need to create the Map Catalog (or have your database administrator create the Map Catalog) manually, as described below. You only have to create the Map Catalog once per server/database. 1. Create the user MAPINFO in the specific database where the mappable tables are located. 2. Create the table MAPINFO_MAPCATALOG in the database. The Create Table statement needs to be equivalent to the following SQL Create Table statement: MapX Developer’s Guide 171 Chapter 11: Accessing Data from a DBMS Create Table MAPINFO_MAPCATALOG ( SPATIALTYPE Float, TABLENAME Char(32), OWNERNAME Char(32), SPATIALCOLUMN Char(32), DB_X_LL Float, DB_Y_LL Float, DB_X_UR Float, DB_Y_UR Float, COORDINATESYSTEM Char(254), SYMBOL Char(254), XCOLUMNNAME Char(32), YCOLUMNNAME Char(32) ) Note: It is important that the structure of the table is exactly like this statement. The only substitution that can be made is for databases that support varchar or text data types; these data types can be substituted for the Char data type. 3. Create a unique index on the TABLENAME and the OWNERNAME, so only one table for each owner can be made mappable. create index mapcat_i1 on mapinfo.mapinfo_catalog (OwnerName,TableName) 4. Grant Select, Update, and Insert privileges on the MAPINFO_MAPCATALOG. This allows users to make tables mappable. The delete privilege should be reserved for database administrators. 172 MapX Developer’s Guide Chapter 11: Accessing Data from a DBMS Making a DBMS Table Mappable For each spatial table that you want to access from MapX, you need to add a row to the MAPINFO_MAPCATALOG table. If you do not use MapInfo Professional to manage the Map Catalog, you will have to add rows to the MAPINFO_MAPCATALOG table manually. The following table describes the syntax and meaning of each column: Column Name Values to Assign Examples SPATIALTYPE NOTE: This columns describes the Spatial Object Format of how the data is stored and indexed and the Spatial Object type(s) supported and not supported in the column. The digits to the left of the decimal point are the Spatial Object Format. The digits to the right represent the type of Spatial Object Type that can be stored in the column. 5.3 MapInfo Spatial Object Format • 1.x: Point layer in X/Y columns indexed with micode (a serialized quadtree key) • 2.x: Oracle MD/SDO version 1 HHCODE_ - Not Supported • 3.x: Oracle MD/SDO version 1 HHCODE_PARTIONED - Not Supported • 4.x: Point layer in X/Y columns • 5.x: SpatialWare for Oracle • 6.x: Ingres SOL - Not Supported • 7.x: Sybase SQS - Not Supported • 8.x: Oracle SDO version 2 - Not Supported • 9.x: MapInfo Geocoding DataBlade SpatialWare Point Module • 10.x: MapInfo Geocoding DataBlade XY Module • 11.x: SpatialWare IUS datablade • 12.x: SpatialWare Extender for DB2 • 13.x: Oracle Spatial column Spatial Object Type • x.0: Points only • x.1: Lines only • x.2: Regions only • x.3: All types supported MapX Developer’s Guide 173 Chapter 11: Accessing Data from a DBMS 174 Column Name Values to Assign Examples TABLENAME The name of the table. DRAINAGE OWNERNAME The owner name of the table. GEORGETOWN SPATIALCOLUMN The name of the column, if any, containing spatial features: • SW_GEOMETRY (mappable using SpatialWare Type/IUS) • NULL_COLUMN (mappable using X–Y) • MI_SQL_MICODE (mappable using MI Code) • Or the name of the IUS, DB2, or Oracle column that is ST_SPATIAL datatype. • Name of the Oracle 8i SDO_GEOMETRY column. SW_GEOMETRY DB_X_LL The X coordinate of the lower left corner of the layer’s bounding rectangle, in units that are indicated by the COORDINATESYSTEM (see below). –360 DB_Y_LL The lower left bounding Y value. –90 DB_X_UR The upper right bounding X value. 360 DB_Y_UR The upper right bounding Y value. 90 COORDINATESYS TEM A string representing a MapInfo CoordSys clause (but without the keyword "CoordSys" at the very start), which specifies a map projection, coordinate units, etc. For simple Lon/Lat maps, specify "Earth Projection 1, 0". Earth Projection 1, 0 SYMBOL A MapInfo Symbol clause (if the layer contains only points); or a Symbol clause followed by a Pen clause (indicating styles for linear features) followed by another Pen clause (indicating styles for the borders of regions) followed by a Brush clause. See Also: Symbol Clause. Symbol(35,0,12) Pen(1,2,0) Pen(1,2,0) Brush(2,255,255) MapX Developer’s Guide Chapter 11: Accessing Data from a DBMS Column Name Values to Assign Examples XCOLUMNNAME NO_COLUMN For the X/Y mappable tables, specify the name of the column containing X– coordinates. If there is no such column (i.e., if this table uses a single spatial column instead of a pair of X–Y columns) then specify NO_COLUMN or leave empty. YCOLUMNNAME For the X/Y mappable tables, specify the name of the column containing Y– coordinates, or specify NO_COLUMN. NO_COLUMN Symbol, Pen, Brush Clause Syntax If you are manually creating a MAPINFO_MAPCATALOG table to provide support for a remote spatial database, you will need to specify a symbol style, and possibly line and fill styles as well. Specifying Point Styles Use a Symbol clause to specify point styles. There are three types of Symbol clauses: one for specifying MapInfo 3.0-style symbols; one for specifying TrueType font symbols; and one for specifying bitmap symbols. Symbol Syntax Example Symbol(shape, color, size) or Symbol(shape,color,size,font,fontstyle,rotation) or Symbol(bitmapname,color,size,customstyle) Symbol(35,0,12) Symbol(64,255,12,"MapInfo Weather" ,17,0) Symbol("sign.bmp", 255, 18, 0) MapX Developer’s Guide 175 Chapter 11: Accessing Data from a DBMS Specifying Line Styles Use a Pen clause to specify line styles. In a Map Catalog, you may need to specify two pen clauses: one to specify the appearance of linear features, and another to specify the appearance of region borders. Pen Syntax Example Pen(thickness, pattern, color) Pen(1, 2, 0) Specifying Fill Styles Use a Brush clause to specify the style for closed features (regions). Brush Syntax Example Brush(pattern,color,backgroundcolor) Brush(2, 255, 65535) Troubleshooting If you encounter problems with your MapX SpatialWare applications, use the following table to help analyze and solve the problem. 176 Problem Description Possible Cause Solution The MapX "Layer is not matchable." Data binding was attempted against a SpatialWare layer. Data binding is not currently supported for SpatialWare layers. MapX Developer’s Guide Chapter 11: Accessing Data from a DBMS Problem Description No object was found using the index that you specified. Possible Cause • A query was made against a table that does not exist. • No spatial object is contained in the result of the spatial query. • A query was made against a non-SpatialWare table. Solution • Check that the table name is correct and in the proper case. Also, the table may need to be mappable. • Use the SpatialWare Upload utility to make the table a SpatialWare table. • Check the query for possible syntax errors. Also make sure that the result of the query includes the field specified in the spatial column in the MapInfo_MapCatalog. MapX datasets.rowcount has the value of zero. The dataset was created from a MapX datasets.rowcount DBMS server. will always have a value of zero for datasets created from a DBMS server. When iterating through a dataset, a trappable error is generated when you exceed dataset bounds. Use this trappable error as a flag for iteration. Map appears to have incorrect zoom level. For example, the map may be zoomed out too far to identify any geography. The MBR for a SpatialWare layer is determined by the MapInfo_MapCatalog table. The table extents in the MapCatalog result in a different zoom level than the one you desire for your output. MapX Developer’s Guide Edit the extents (DB_X_LL, DB_X_UR, DB_Y_LL, DB_Y_UR) in the MapInfo_MapCatalog using the MapInfo Professional MDX tool, MISETMBR.MDX. 177 Chapter 11: Accessing Data from a DBMS 178 MapX Developer’s Guide Chapter 12: Thematic Mapping and Analysis 12 Chapter Theme Mapping and Analysis Thematic mapping is a powerful way to analyze and visualize your data. You give graphic form to your data so that you can see it on a map. Patterns and trends that are almost impossible to detect in lists of data reveal themselves clearly when you use thematic shading to ➤ Theme Mapping and Analysis ➤ What Is Thematic Mapping? ➤ Planning Your Thematic Map display data on a map. ➤ Types of Thematic Mapping With MapX, you can create applications with thematic maps using the ➤ Manipulating a Theme Map following thematic types: ranges of values, graduated symbols, dot ➤ Customizing a Thematic Legend density, individual values, and bar and pie charts. Chapter 12: Thematic Mapping and Analysis What Is Thematic Mapping? Thematic mapping is the process of shading your map according to a particular theme. The theme is usually some piece or pieces of your data, which is obtained from a dataset. Themes present your data visually with shades of color, fill patterns, symbols, or bar and pie charts. You create different thematic maps by assigning these colors, patterns, or symbols to map objects according to specific values in your data. Bar and pie charts allow you to make data comparisons for each record in your dataset. There are many ways that thematic maps can illustrate your data. The most commonly known example of a thematic map is a weather map. Where you see red, you know it is hot (high number of degrees); where you see blue, it is cold (low number of degrees). Thematic mapping also allows you to discover trends in data that would be difficult to see through tabular data. 180 MapX Developer’s Guide Chapter 12: Thematic Mapping and Analysis Using the properties and methods in the Themes collection, Theme object, and the ThemeProperties object, you can create and define your own thematic shading. A Legend object holds the theme’s key, describing what the theme’s colors, shapes, and sizes represent. MapX Developer’s Guide 181 Chapter 12: Thematic Mapping and Analysis Planning Your Thematic Map Before you create a thematic map, it is important know about the elements that make up a thematic map and how they are put together. This section will discuss thematic variables, where you can obtain your data, particularly using data from another table, and the arrangement and display of thematic layers. Thematic Variables The data that you display on your thematic map is called the thematic variable. Depending on the type of thematic analysis you are performing, your map can show one or more thematic variables. Ranges of values, grid shading, graduated symbols, dot density, and individual values maps all examine one variable. With bar or pie charts, you can display more than one thematic variable at a time. You can also create bivariate thematic maps, where one map object, such as a symbol, represents two different pieces of data. The symbol color, for example, can represent one thematic variable, and the symbol size can represent another. Where to Obtain the Data Before you begin your thematic map, you need to decide what information you want to display and locate where that information resides. The data you use to create a theme comes from a Field object or Field collection from your dataset. These field(s) are passed as the Fields parameter of the Themes.Add method of the Themes collection. 182 MapX Developer’s Guide Chapter 12: Thematic Mapping and Analysis Themes Collectio Each dataset has a collection of themes. A Themes collection creates, counts, adds, or removes a Theme object from a collection of themes. Methods Description Code Sample Add Creates a theme and adds it to the Themes collection for a particular dataset Map1.Datasets(1).Themes.Add _ miThemeRanges “TotPop”, “My _ Ranges Theme” Remove Removes a specified theme from the collection. Map1.Datasets(1).Themes.Remove “My _ Ranges Theme” RemoveAll Removes all themes from the collection Map1.Datasets(1).Themes.RemoveAll Creating a Theme If you want to thematically shade a map using data from a dataset, you create a Theme object for the dataset with the Themes.Add method. Once a dataset is added to your map, creating the theme can be done with one line of code: Map1.Datasets(1).Themes.Add miThemeRanges “TotPop”, _ “My Ranges Theme” This creates a ranged theme for the first dataset in the Datasets collection using the field “TotPop” . The Themes.Add method is described below. Optional parameters are in [brackets]. Syntax Themes.Add [Type], [Field], [Name] Part Description Type Specifies the type of thematic map to create. This takes a ThemeTypeConstants. This is an optional parameter, and if not specified (or specified as miThemeAuto), MapX will attempt to choose a good default based on the number of fields passed in as well as what other theme types are already being displayed. If MapX cannot choose a default theme type, an error is generated. MapX Developer’s Guide 183 Chapter 12: Thematic Mapping and Analysis Part Description Field(s) Specifies the field or fields to use in the thematic map. A field can be specified by name, index, or by a Field object. If you are creating a theme using multiple variables, pass in an array of field names, indexes or Field objects. This is an optional parameter, and if not specified, MapX uses the first numeric field of the DataSet. Name Specifies the name of the thematic map. This is a String parameter. This is an optional parameter, and if not specified, MapX generates a name such as StatesBySales. How MapX Selects a Default Theme If the Type parameter of the Themes.Add method is not specified (or specified as miThemeAuto), MapX will attempt to choose a good default theme based on the number of fields passed in as well as what other theme types are already being displayed, as described below. 184 No. Fields Layer Type Algorithm greater than 1 Points, Lines, Regions Default theme type is pie charts. If a multivariable theme already exists, try to create a single-variable theme using the first field in the collection of fields provided (see algorithms below). 1 Points If the bound field is aggregated by individual value, try to create an individual value theme. If a ranged or individual value theme already exist, cannot create a default theme. If the bound field is not aggregated by individual value, try to create a graduated symbol theme. If an object thematic already exists, try create a ranged theme. If a ranged or individual value theme already exist, cannot create a default theme. MapX Developer’s Guide Chapter 12: Thematic Mapping and Analysis No. Fields Layer Type Algorithm 1 Lines If the bound field is aggregated by individual value, try to create an individual value theme. If a ranged or individual value theme already exist, cannot create a default theme. If the bound field is not aggregated by individual value, try to create a ranged theme. If a ranged or individual value theme already exist, try to create a graduated symbol theme. If an object thematic already exists, cannot create a default theme. 1 Regions If the bound field is aggregated by individual value, try to create an individual value theme. If a ranged or individual value theme already exist, cannot create a default theme. If the bound field is not aggregated by individual value, try to create a ranged theme. If a ranged or individual value theme already exist, try to create a dot density theme. If a dot density theme already exists, try to create a graduated symbol theme. If an object thematic already exists, cannot create a default theme. Note: Pies, Bars, and Graduated Symbols are all object thematics. Determination of a default theme type is layer specific. In other words, themes on Layer A are not considered when attempting to determine a default theme type for a new theme on Layer B. Theme Type Constants These are the types of themes you can create: Type Description miThemeRanged Ranges Theme miThemeBarChart Bar Chart Theme miThemePieChart Pie Chart Theme miThemeGradSymbol Graduated Symbol Theme miThemeDotDensity Dot Density Theme MapX Developer’s Guide 185 Chapter 12: Thematic Mapping and Analysis Type Description miThemeIndividualValue Individual Values Theme miThemeAuto MapX “best guess” Theme Each has its own purpose and unique attributes. For example, using miThemeRanged, you could thematically shade a map of the world according to population density. You could shade the countries with graduated shades of red, the darkest red representing the most densely populated countries, and the palest red representing the least densely populated countries. At a glance you can see the distribution of the world’s population. You are not limited to representing numeric values with thematic mapping. Nominal values also may be shaded thematically. For example, you have a dataset of underground cables. Those cables that haven’t been serviced in the past six months are labeled priority status. Using miThemeIndividualValue, you can shade the cables according to their repair status. All records with the same value will be shaded the same color. See the individual sections later in this chapter for more information on each type of thematic map. Once the Theme is added to a specified collection, the Theme object is created and you may manipulate the properties of the object. Theme Object The Theme object sets the properties of the theme within the Themes collection. Modifying the Theme object methods and properties determines how a theme is viewed, the type of theme, etc. 186 Properties Description AutoRecompute Controls when theme ranges are recomputed when theme properties are changed (i.e., number of ranges). Defaults to True. ComputeTheme Controls whether themes are computed. Defaults to True. A True value will calculate the theme from the raw data. If the value is set to False, an invisible Theme object will be created with 20 ranges for Individual Value themes and 5 ranges for Ranged themes. You can then set the minimum and maximum values to define the theme. DataMax Determines the maximum value to set the theme ranges or calculates equal size ranges for ranged themes when ComputeTheme is set to False. MapX Developer’s Guide Chapter 12: Thematic Mapping and Analysis Properties Description DataMin Determines the minimum value to set the theme ranges or calculates equal size ranges for ranged themes when ComputeTheme is set to False. Fields Returns a read-only Fields collection representing the set of fields used by the dataset that this theme is based on. Layers Read-only property that returns a Layer object, representing the layer that the theme is based on. Legend Each Theme object has a Legend object (Theme.Legend). The legend object contains properties to control the display of a theme’s legend. Each ThemeCategory object (RangeCategory, IndividualCategory or MultiVarCategory) has an entry in the legend contained in a LegendText object. Name The name of a theme. Must be unique within a Themes collection. This is a read/write property, and is either specified as a parameter to the Themes.Add method or generated by MapX when the theme is created. This is the default property for the Theme object. ThemeProperties The ThemeProperties object contains the information defining a theme (range definitions, display style settings, etc.). Type The type of theme for a Theme object. This is a ThemeTypeConstants value, and is a read-only property. Visible Specifies whether a theme is visible. Defaults to true. MapX Developer’s Guide 187 Chapter 12: Thematic Mapping and Analysis Types of Thematic Mapping The following sections offer general information on the types available for creating thematic maps. Individual Values Maps Individual Value maps show points, lines, or boundaries that are shaded by individual values contained in a particular field of a dataset. You can use both numerical and nominal values in individual values maps. MapX gives each unique value its own color or symbol. When an individual values map uses symbol types, the symbols are taken from the default style of the map. 188 MapX Developer’s Guide Chapter 12: Thematic Mapping and Analysis For example, a soft drink distributor maintains a table of the supermarkets that buy soft drinks from him by Zip Code in Washington D.C. Each supermarket sells the distributor’s brand of soft drink for a different price. If the distributor shades the Zip Code boundaries by price, using individual values, all stores that sell the soft drink for 49 cents are shaded one color, all stores that sell the soft drink for 51 cents are shaded another color, and so on. Each unique value is assigned its own color. The distributor is able to see the price distribution among the supermarkets and can determine where he should increase his sales volume, based on the price. If you are shading your points, lines, or boundaries using nominal data, you can shade only by individual values. Nominal data is either non–numerical data (e.g., name, type of cuisine served, or brand of automobile sold) or numeric data where the numbers represent non– numeric data. Dates are considered numeric data and can be used in both ranged and individual values maps. For example, you have the results from a consumer survey. One question on the survey reads “What is your favorite Sunday afternoon activity?” The possible responses are: 1. Sleeping 2. Watching TV 3. Taking a drive 4. Reading 5. Playing or watching sports 6. Visiting museums or art galleries 7. Going to the movies You want to shade each consumer point with the response for the favorite Sunday activity. The SUNDAY field of your dataset contains the number that corresponds to the consumer’s favorite activity. However, the numbers in this column do not represent quantitative values. Going to the movies is not greater than playing or watching sports even though 7 > 5. When numbers are used as names instead of values, you must shade your objects by individual values. The numbers are only used to reference the pastimes so a color can be assigned to it. An individual values thematic map's settings are exposed through the IndividualValueCategories collection, which is a collection of IndividualValueCategory objects—one object for each unique value in the theme. To obtain an IndividualValueCategories collection, reference the MapX Developer’s Guide 189 Chapter 12: Thematic Mapping and Analysis ThemeProperties.IndividualValueCategories property. For more information on the InvividualValueCategories collection, see the Online Help or the Reference Guide. Ranged Maps When you create a ranged thematic map, MapX groups all dataset rows into ranges and assigns each row’s object the color, symbol, or line for its corresponding range. For example, you have a dataset of weather stations for your television viewing area, and you want to shade the locations according to their reported snowfall amounts. With the Ranged map feature, MapX groups the snowfall amounts into ranges. For instance all weather stations that received between zero and five inches of snowfall in the past month are grouped into one range. Stations receiving between five and 10 inches are in a separate range. Sites that received between 10 and 15 inches are in a third range, while those stations reporting greater than 15 inch snowfall amounts are in a fourth range. 190 MapX Developer’s Guide Chapter 12: Thematic Mapping and Analysis All records in the dataset are assigned to a range and then assigned a color based on that range. For instance the weather stations reporting the 15 plus inches of snow are shaded red. The other ranges are shaded in lighter shades of red with the last range in gray (default colors). When you display the map, the colors make it readily apparent which locations received the most and least snow accumulation. Ranges are also useful when the size of the region is not directly related to the magnitude of the data values. Types of Ranged Values MapX can create ranges automatically using five distribution methods: Equal Count, Equal Ranges, Natural Break, Standard Deviation, and Quantile. Ranges are set by the DistMeth property of the ThemeProperties object. The DistMeth property can be set to any of the following DistribMethodConstants. DistribMethodConstants Equal Count (miEqualCountPerRange) has the same number of records in each range. If you want MapX to group 100 records into 4 ranges using Equal Count, MapX computes the ranges so that approximately 25 records fall into each range, depending on the rounding factor you set. When using Equal Count (or any other range method), it’s important to watch out for any extreme data values that might affect your thematic map (in statistics, these values are referred to as outliers). For example, if you shade according to Equal Count with this database: John 5000 Andrea 7000 Penny 6000 Kyle 5500 Miguel 4500 Angela 7500 Linda 5000 Elroy 6000 Ben 100 Mark 7000 Ben and Miguel are grouped in the same range (since they have the two lowest values). This may not produce the results you want since the value for Ben is so much lower than any of the other values. MapX Developer’s Guide 191 Chapter 12: Thematic Mapping and Analysis Equal Ranges (miEqualRangeSize) divides records across ranges of equal size. For example, you have a field in your table with data values ranging from 1 to 100. You want to create a thematic map with four equal size ranges. MapX produces ranges 1–25, 26–50, 51–75, and 76– 100. Keep in mind that MapX may create ranges with no data records, depending on the distribution of your data. For example, if you shade the following database according to Equal Ranges: John 100 Andrea 90 Penny 6 Kyle 1 Miguel 4 Angela 92 Linda 95 Elroy 89 Ben 10 Mark 10 MapX creates four ranges (1–25, 26–50, 51–75, and 76–100). Notice, however, that only two of those ranges (1–25 and 76–100) actually contain records. Natural Break and Quantile are two ways to show data that is not evenly distributed. Natural Break (miNaturalBreak) creates ranges according to an algorithm that uses the average of each range to distribute the data more evenly across the ranges. It distributes the values so that the average of each range is as close as possible to each of the range values in that range. This ensures that the ranges are well–represented by their averages, and that data values within each of the ranges are fairly close together. When you create ranges using Standard Deviation (miStandardDeviation), the middle range breaks at the mean of your values, and the ranges above and below the middle range are one standard deviation above or below the mean. You can also define your own ranges using Custom (miCustomRanges). You specify your own ranges in the RangeCategories collection (and MapX won’t compute ranges). 192 MapX Developer’s Guide Chapter 12: Thematic Mapping and Analysis Custom Ranges Example A Ranged thematic map's settings are exposed through the RangeCategories collection, which is a collection of RangeCategory objects—one object for each range, sorted in ascending order. Each object in the collection describes one range (its display style, its minimum and maximum values, etc.). ' This example sets up custom ranges for a theme ' based on values in a dataset and controls on the form. ' A ranged theme was already created and this customizes ' the ThemeProperties for the theme. Public Sub GetThemeInfo() Dim rc As MapXLib.RangeCategory Dim thm As MapXLib.Theme Dim iNumRanges As Integer, iCount As Integer Dim dIncrement As Double, dCurRange As Double Set thm = Form1.Map1.Datasets(1).Themes(1) ' Prevent the theme from recomputing for each change of a ' property value because we will be setting numerous properties. thm.AutoRecompute = False thm.ThemeProperties.DistMethod = miCustomRanges ' This next line gets a value from a slider control iNumRanges = Form1.sldNumRanges.Value thm.ThemeProperties.NumRanges = iNumRanges ' This sets the object rc to be the first RangeCategory in ' the RangeCategories collection for this ranged theme. Set rc = thm.ThemeProperties.RangeCategories(1) ' This sets the color for this RangeCategory object to be ' the color of a PictureBox control rc.Style.RegionColor = Form1.picMinColor.BackColor ' This sets the object rc to be the last Range Category in ' the RangeCategories collection for this ranged theme. Set rc = thm.ThemeProperties.RangeCategories(iNumRanges) ' This sets the color for this RangeCategory object to be ' the color of a PictureBox control. rc.Style.RegionColor = Form1.picMaxColor.BackColor ' This block of code creates the custom ranges for the ' theme by stepping through each RangeCategory object ' and setting its Min and Max property values. dIncrement = Int(Val(Form1.txtmaxvalue.Text) / iNumRanges) + 1 MapX Developer’s Guide 193 Chapter 12: Thematic Mapping and Analysis dCurRange = 0 For iCount = 1 To iNumRanges thm.ThemeProperties.RangeCategories(iCount).Min = dCurRange dCurRange = dCurRange + dIncrement - 1 thm.ThemeProperties.RangeCategories(iCount).Max = dCurRange dCurRange = dCurRange + 1 Next ' This block will turn on the automatic recalculation properties ' for the legend and theme objects, and then redraw the map. thm.Legend.LegendTexts.AutoGenerate = True thm.AutoRecompute = True Form1.map1.Refresh End Sub 194 MapX Developer’s Guide Chapter 12: Thematic Mapping and Analysis Graduated Symbol Maps Graduated symbol maps use symbols to represent different values. You can use graduated symbols regardless of the type of data with which you are working. For instance, use graduated symbols to show sales orders across states. With the graduated symbols theme, MapX varies the size of each symbol according to the value in the sales order field. Or you can represent how much interest each customer has expressed in a given product by assigning a symbol whose size is proportional to the customer’s interest. Graduated symbols maps work best when you use numeric data. If you are working with a table of restaurants, it makes no sense to create graduated symbols based on the type of cuisine each restaurant serves. However, graduated symbols is appropriate when you want to show the number of hamburgers sold at 20 different fast food restaurants. MapX Developer’s Guide 195 Chapter 12: Thematic Mapping and Analysis There are two theme properties you can customize on a graduated symbols map: the DataValue and SymbolStyle. The SymbolStyle property controls the symbol that is used, as well as the size of the symbol drawn at the value specified by the DataValue property. All values between the high value and zero have interpolated point sizes. The SymbolStyle property is a Style object which controls all the stylistic aspects of the symbol such as color, font, rotation, etc. You can also supply your own bitmap to be used as the symbol. The Style object has a symbol picker (Style.PickSymbol) which displays the Symbol Style dialog. The dialog enables a user to choose symbol style properties. The Style object is updated with the new properties when the user clicks OK in the dialog. 196 MapX Developer’s Guide Chapter 12: Thematic Mapping and Analysis Dot Density Maps Dot density maps use dots to represent the data value associated with a boundary or region. The total number of dots in a region represents that region’s data value. If you have 10,000 senior citizens in a county, and each dot represents 100 senior citizens, there would be 100 dots in the county boundary. Dot density is particularly useful for showing raw data where one dot represents a large number of something: population, number of fast food restaurants, number of distributors who carry a brand of soda, etc. For example, if you have a table of population broken down into county boundaries, you could use the dot density option to show the concentration of people in each county boundary. There are two theme properties you control for dot density maps. You can specify the value of MapX Developer’s Guide 197 Chapter 12: Thematic Mapping and Analysis one dot. For example, you have a table of population statistics, broken down by county. There are 20,000 high school students in Rensselaer County, New York. If you shade Rensselaer County according to the number of high school students using the dot density method, each dot could represent 200 students. In that case, there would be 100 dots in Rensselaer County. When you increase the value each dot represents, you decrease the number of dots that display on the map. You could modify your dot density map so that one dot represents 400 students. In that case, there would only be 50 dots in Rensselaer County. Map1.Datasets(1).Themes(“My DotDensity _ Theme”).ThemeProperties.ValuePerDot = 400 A second option is to change the size of the dots according to your needs. If you are working with large populations, or large counts of something, make the dot size smaller so that the distribution of dots is easier to see. Conversely, if your working with a small data set, making the dot size larger might illustrate your analysis more clearly. Map1.Datasets(1).Themes(“My DotDensity _ Theme”).ThemeProperties.DotSize = miDotSizeLarge Note: Distribution of dots is random within the region. For example, if you shade states according to population, the dots for NewYork are spread throughout the state; they are not concentrated in New York City, where the majority of the state’s population lives. 198 MapX Developer’s Guide Chapter 12: Thematic Mapping and Analysis Bar Chart Maps Unlike one variable thematic maps such as ranges of values or graduated symbols, a thematic bar chart map allows you to examine more than one variable per row at a time. A bar chart is built for every map object (feature) at the centroid of the object, enabling you to analyze the thematic variables in a particular chart by comparing the height of the bars. You can also examine the same variable across all the charts in your map. For example, you have a table of U.S. state boundaries containing female and male population. Using bar charts, you can create a thematic map that displays a two–bar chart for each state: one bar representing female, and the other representing male population. You can compare the population differences of each state, or you can examine several states and compare one state’s population or population differences to another’s. For best results, use no more than four to six bars per bar chart in your analysis. MapX Developer’s Guide 199 Chapter 12: Thematic Mapping and Analysis There are five theme properties you control for bar charts: DataValue, Size, Independent, MultiVarCategories, and Width. The DataValue property works in conjunction with the Size property to control how big the thematic graphics are at particular values. The default value for this property is set to the largest data value of the mapped features. The Size property works in conjunction with the DataValue property to control how big the thematic graphics are at particular values. It specifies the height of the thematic graphic in Paper units (PaperUnit). This is a Double value, and defaults to .25 inches. The Width property specifies the width of each bar of a Bar theme in Paper units (Map.PaperUnit). This is a Double value, and defaults to .25 inches. The Independent property controls whether the data values for the bars should be treated independently (not comparable values such as Population and Avg Income). This is a Boolean value, and the default is False. The developer should set this to True for multi-value Bar themes where the data for each bar of a single feature is unrelated to a bar for a different field of the theme, or the maximum values for a field of data differ greatly. An example of this would be a population bar theme where one bar may represent the population of a state and another may be a ranking in exports. The population data would be in the millions and the ranking would only be between 1 and 50. If the Independent property is set to True, then the highest populated state’s population bar would be equal in height to the highest ranking state in exports export bar. Were the Independent property left False, it would be difficult to obtain any meaning from the export ranking bar because the state ranked first would have an export bar the size of a state’s population bar if that state had 1 person in it. A bar chart thematic map is exposed to OLE through the MultivarCategories collection, which is a collection of MultivarCategory objects. The collection contains one object for each bar in the bar chart. For more information on the MultivarCategories collection, see the Online Help or Reference Guide. 200 MapX Developer’s Guide Chapter 12: Thematic Mapping and Analysis Pie Chart Maps Thematic mapping using pie charts also enables you to examine more than one variable per row at a time. Like comparing the height of the bars in bar charts, in pie charts you compare the wedges in a single pie, or examine a particular pie wedge across all of the pies. Pie charts also enable you to compare parts of a whole. Both pie and bar charts are particularly useful for analyzing demographic data. For example, you have a dataset of demographic information for the United States. Your dataset shows the populations of several major demographic groups. Using pie charts, you can show the population of each demographic group, and see what fraction of the pie it makes up in each pie. This enables you to see the distribution of demographic groups on a per state basis, or across the entire United States.You can also look at one demographic group and see how the MapX Developer’s Guide 201 Chapter 12: Thematic Mapping and Analysis population of the group varies in different states. For best results, use no more than four to six pie wedges per pie chart in your analysis. There are four theme properties you control for bar charts: DataValue, Size, Graduated and MultiVarCategories. The DataValue property works in conjunction with the Size property to control how big the thematic graphics are at particular values. The default value for this property is set to the largest data value of the mapped features. The Size property works in conjunction with the DataValue property to control how big the thematic graphics are at particular values. It specifies the height of the thematic graphic in Paper units (PaperUnit).This is a Double value, and defaults to .25 inches. The Graduated property controls whether the size of the Pie charts are graduated based on the total value of the Pie. This is a Boolean value, and defaults to True. A pie chart map is exposed to OLE through the MultivarCategories collection, which is a collection of MultivarCategory objects. The collection contains one object for each wedge in the pie chart. For more information on the MultivarCategories collection, see the Online Help or the Reference Guide. Bivariate Thematic Mapping Bivariate thematic mapping uses point or line objects to represent two thematic variables. For example, a star can represent one variable, such as the number of teenagers, while a blue fill for the star represents their annual purchase amounts. To create a bivariate map in MapX, you create two thematic maps, and layer one over the other so that the objects display two variables. Types of Maps and Variables The only types of thematic maps suitable for bivariate mapping are ranged and individual values maps. You can choose between two combinations for a bivariate map, depending on your data: • two ranged maps • one ranged map and one individual values map If you have a non-numeric variable, one of your maps must be an individual values map. You cannot create a bivariate map with two non-numeric variables. 202 MapX Developer’s Guide Chapter 12: Thematic Mapping and Analysis Displaying Attributes To display two variables within one symbol, it is important to choose a different symbol attribute for each variable. For example, you cannot choose color for both variables because one color will overwrite the other. Choose from the following combinations: • color and symbol type • color and size • size and symbol type Symbol type should only be used for nominal or non-numeric data, as there is no inherent association between a symbol type and a quantity. Manipulating a Theme Map All of the theme’s properties can be adjusted at run-time. There are two ways to do this: • Theme.ThemeDlg method. • ThemeProperties object of a theme. ThemeDlg Method The theme object has a method, ThemeDlg, which displays a dialog allowing a user to modify the theme. The following line of code shows how simple it is. Map1.Datasets(1).Themes(1).ThemeDlg You will get a dialog box with the ability to change parameters appropriate for the type of theme from which it was called. There are two possible drawbacks to using this method. First, you’re stuck with the design. If these dialogs don’t fit in with your color schemes, or you don’t like how they are laid out, you can’t change them. Another problem to using these methods is that sometimes they are too powerful. Perhaps you only want the user to change the color of the top range of a ranges theme or you want to keep the colors, but not let the user choose the number of ranges. Using the ThemeDlg method, the user can change any (and all) parts of the theme. MapX Developer’s Guide 203 Chapter 12: Thematic Mapping and Analysis ThemeProperties Object You also have the ability to change just the property of the theme necessary, by manipulating the ThemeProperties object. This is easy to implement and gives you more control of what the user can and cannot change. The ThemeProperties object is stored in the Themes collection. The ThemeProperties object properties are used to define the thematic map’s appearance (colors, symbols, etc). The ThemeProperties object actually contains the information about how the theme should look. Some of the ThemeProperties object’s properties are represented by other objects. 204 Property Description AllowEmptyRanges Controls whether empty ranges are allowed in a ranged theme. DataValue Applies to g raduated symbol, pie, and bar themes. This is the value at which the thematic graphic is drawn at the size specified by the Size property. DistMethod Controls how ranges are created when a Theme object is recomputed. This is a DistribMethodConstants value and defaults to MiEqualCountPerRange. Other method constants are miEqualRangeSize, MiCustomRanges, miNaturalBreakRange, miStandardDeviation. DotSize Controls the dot size used by dot density thematic maps. Graduated Controls whether the size of the pie charts is graduated based on the total value of the pie. IndividualValueCategory IndividualValueCategory collection. Independent Controls whether the data values for the bars charts should be treated independently. MultivarCategories There is one MultiVarcategory object per variable or field mapped in a pie or bar theme. NumRanges Controls the number of ranges for a ranged thematic map. RangeCategories A ranged thematic map has a collection of RangeCategory objects. Size Works in conjunction with the DataValue property to control how big the thematic graphics are at particular values in pie and bar themes. MapX Developer’s Guide Chapter 12: Thematic Mapping and Analysis Property Description SpreadBy Controls how autospreading is done for ranged thematic maps. SymbolStyle Style object controlling the symbol used for graduated symbol themes. ValuePerDot This property applies to dot density themes. This specifies that value a dot represents. Width Specifies the width of all the bars in a bar themes. Several of the properties above are actually other objects. Those objects include the RangeCategory object, IndividualValue object, MultiVar object and the Style object. Look at the next chart to see the properties of the RangeCategory object. The other theme-related objects behave similarly. Property Description Code Sample Max Sets the maximum value for a range in a ranged theme. Map1.Datasets(1).Themes(1). Properties.RangeCategories(3).Max = 625 Min Sets the minimum value for a range in a ranged theme. Map1.DataSets(1).Themes(1). Properties.RangeCategories(3).Min = 595 NumItems Shows the number of items in a range. Print Map1.DataSets(1).Themes(1). Properties.RangeCategories(1).NumItems Style A style object representing the style of that range. Map1.Datasets(1).Themes.Item(1).Properties.Rang eCategories.Item(1).Style.PickRegion A ranged thematic map has a collection of RangeCategory objects, one for each range sorted in ascending order. The ThemeProperties.RangeCategories property stores the collection. If ThemeProperties.DistMethod is MiCustomRanges, MapX will assume that you have set this value yourself, and will use the ranges that you have defined when grouping data values. An error is generated if there are ranges that overlap when the theme is recomputed. MapX Developer’s Guide 205 Chapter 12: Thematic Mapping and Analysis Customizing a Thematic Legend When you create a thematic map, MapX automatically creates a legend that explains what the colors, symbols, or sizes represent. Legend Object Each theme has a Legend object (Theme.Legend). The Legend object contains properties to control the display of the legend. It is easily modified using the LegendDlg method from the Legend object. See the following sample and the dialog that it will bring up. Map1.Datasets(1).Themes(1).Legend.LegendDlg 206 MapX Developer’s Guide Chapter 13: Using Coordinate Systems Using Coordinate Systems In this chapter, you'll learn how to use Coordinate Systems (sometimes called "map projections") to change the appearance of a map, or to change the units in which map coordinates are processed by MapX. 13 Chapter ➤ Using Coordinate Systems ➤ Basic Concepts of Coordinate Systems ➤ Obtaining a Coordinate System Object ➤ Querying the Properties of a CoordSys Object ➤ Displaying a Map in a Different CoordSys ➤ Specifying X-Y Coordinates in a Different CoordSys ➤ Displaying the Choose Projection Dialog ➤ Using Settings From MAPINFOW.PRJ ➤ Applying an Affine Transformation ➤ Defining Custom Datums ➤ Datum Conversion ➤ For More Information... Chapter 13: Using Coordinate Systems Basic Concepts of Coordinate Systems Every map has a coordinate system, which affects mapping software in various ways: The coordinate system affects how X-Y coordinates are processed. For example, a location can be expressed in terms of degrees longitude/latitude, or it can be expressed in terms of other units, such as meters. The coordinate system affects the appearance of the map. Changing a map's coordinate system can make the map appear stretched or distorted. Coordinate systems represent a complex, advanced area of computer mapping. This discussion assumes that you are already familiar with concepts of mapping, such as false eastings and map projections. Obtaining a Coordinate System Object The MapX object model exposes coordinate system information through the CoordSys object. This object's properties tell you everything you need to know about a coordinate system. There are several ways to obtain a CoordSys object. Which technique you use depends on what you are trying to accomplish. The Map.DisplayCoordSys property returns a read-write CoordSys object. You can use this object to control the coordinate system and map projection used to display the map. For details, see the section Displaying the Map in a Different CoordSys later in this chapter. The Map.NumericCoordSys property also returns a read-write CoordSys object. Use this object to set the coordinate system that MapX uses to process X-Y coordinates. For details, see the Specifying X-Y Coordinates in a Different CoordSys section. The Layer.CoordSys property returns a read-only CoordSys object, which tells you the coordinate system used to store features in a specific map layer. If you set the Map.DisplayCoordSys to match a Layer.CoordSys, you maximize the display speed of that layer. (When the DisplayCoordSys is different than the CoordSys in which a layer was saved, MapX converts features on the fly, which slows down the display.) 208 MapX Developer’s Guide Chapter 13: Using Coordinate Systems Querying the Properties of a CoordSys Object For each type of coordinate system, only some of the properties are applicable. For example, if the CoordSys.Type property is miRobinson (12), only the Datum, Units, and OriginLongitude properties are applicable. The Robinson map projection simply does not use any of the other properties. To see whether a property is used by a particular projection, see the section Summary of Parameters Used by Coordinate Systems. You can query all of the properties for any CoordSys object—even properties that are not applicable for that type of coordinate system. If a property is not applicable given the CoordSys Type, MapX returns a default value. If you need to persist a CoordSys object, you can do so by querying and saving all of its properties, without worrying about whether each property is applicable. MapX Developer’s Guide 209 Chapter 13: Using Coordinate Systems Displaying a Map in a Different CoordSys There are two ways an application can specify the coordinate system (or "projection") in which a map is displayed: • Use the Map.DisplayCoordSys.Set method to set a new display CoordSys. -or- • Assign a new CoordSys object to the Map.DisplayCoordSys property. Note: If a map includes a raster image layer, MapX automatically displays the map in the projection specified by the raster image table. In this case, you cannot change the map's display coordinate system. Example: Displaying a Robinson Map The following Visual Basic example changes the map's DisplayCoordSys so that the map is displayed with the Robinson map projection, which looks like this: Dim Dim Dim Dim iProjectionType As Integer iDatumNumber As Integer iUnits As Integer dOriginLongitude As Double Initialize the variables to be used by coordsys.set. ' Values were obtained from the "Robinson" entry ' in the file MAPINFOW.PRJ, which looks like this: ' "Robinson", 12, 62, 7, 0 iProjectionType = miRobinson '(value: 12) iDatumNumber = 62 'North American 1927 (NAD 27) iUnits = miUnitMeter '(value: 7) dOriginLongitude = 0 Map1.DisplayCoordSys.Set iProjectionType, iDatumNumber, _ iUnits, dOriginLongitude 210 MapX Developer’s Guide Chapter 13: Using Coordinate Systems Specifying X-Y Coordinates in a Different CoordSys The Map object has a NumericCoordSys property, which represents the coordinate system used to process numeric coordinates. This property affects both the input and the output of XY coordinates, as follows: • When you specify map coordinates (as object properties or method parameters), MapX assumes the coordinates are in this coordinate system. • When MapX returns map coordinates (as object properties or events), the coordinates are in this coordinate system. By default, the coordinate system is Longitude/Latitude WGS-84. In other words, if you do not modify the NumericCoordSys, MapX assumes that map coordinates are in degrees Longitude/Latitude. There are two ways an application can specify the coordinate system used to process numeric coordinates: • Use the Map.NumericCoordSys.Set method to set a new numeric CoordSys. -or- • Assign a new CoordSys object to the Map.NumericCoordSys property. Example: Retrieving Coordinates in a Different CoordSys The following Visual Basic example changes the map's NumericCoordSys so that the coordinates are returned in a different coordinate system. Dim Dim Dim Dim iProjectionType As Integer iDatumNumber As Integer iUnits As Integer dOriginLongitude As Double ' Display map's center X-Y in original coordsys Debug.Print "Original Center: " & Map1.CenterX & ", " & _ Map1.CenterY ' ' ' ' Initialize the variables to be used by coordsys.set. Values were obtained from the "Robinson" entry in the file MAPINFOW.PRJ, which looks like this: "Robinson", 12, 62, 7, 0 MapX Developer’s Guide 211 Chapter 13: Using Coordinate Systems iProjectionType = miRobinson iDatumNumber = 62 iUnits = miUnitMeter dOriginLongitude = 0 '(value: 12) 'North American 1927 (NAD 27) '(value: 7) Map1.NumericCoordSys.Set iProjectionType, iDatumNumber, _ iUnits, dOriginLongitude ' Display map's center X-Y in the new coordsys Debug.Print "New Center: " & Map1.CenterX & ", " & Map1.CenterY Displaying the Choose Projection Dialog To display a dialog that lets the user choose a coordinate system, use the CoordSys.PickCoordSys method. 212 MapX Developer’s Guide Chapter 13: Using Coordinate Systems The dialog is automatically initialized, so that the highlighted description describes the CoordSys object. If the user clicks OK in the dialog, the method returns True, and the CoordSys object is updated to match the coordinate system chosen by the user. To display the dialog box at design time: 1. Right-click the Map control. 2. Choose Properties from the shortcut menu. 3. On the General tab, click the Projection button. MapX displays the same Choose Projection dialog, which is invoked by the PickCoordSys method. Example The following statement displays the Choose Projection dialog at run time, allowing the user to change the coordinate system in which the map is displayed. Map1.DisplayCoordSys.PickCoordSys Using Settings From MAPINFOW.PRJ If you use MapInfo Professional, you will find a file called MAPINFOW.PRJ in the same directory as the MapInfo executable. MAPINFOW.PRJ is a text file containing the parameters that define MapInfo's coordinate systems. A copy of MAPINFOW.PRJ is included with MapX. Suppose you have used a specific projection in MapInfo—the Robinson projection, for example—and you want to specify that projection in a MapX application. The MAPINFOW.PRJ file gives you the information you need to fill in the various parameters to MapX methods, such as CoordSys.Set. Entries in MAPINFOW.PRJ have the following parameters. Parameters are separated by commas. Part Description Description A string that describes the coordinate system. This description appears in dialog boxes. MapX Developer’s Guide 213 Chapter 13: Using Coordinate Systems Part Description Type A number that usually matches one of the CoordSysTypeConstants exactly. Users may have customized this number in two ways: To specify an Affine Transformation, the user adds 1000 to this number; to specify bounds, the user adds 2000 to this number. See below for details. Datum A number representing one of the Datums supported by MapX, or a special number (999 or 9999) indicating a custom datum. Units [Set of 4 Custom Datum Arguments] Optional; applies only if the Datum number is 999. [Set of 9 Custom Datum Arguments] Optional; applies only if the Datum number is 9999. Set of Projection Parameters From zero to 8 parameters, depending on which Type is specified. Refer to the Summary of Parameters Used by Coordinate Systems, in the Online Help to see which parameters are used by this Type. [Set of 7 Affine Transformation Parameters] Optional; applies only if the Type number is exactly 1000 or 3000 greater than a CoordSysTypeConstant. [Set of 4 Bounds Parameters] Optional; applies only if the Type number is exactly 2000 or 3000 greater than a CoordSysTypeConstant. Example Open MAPINFOW.PRJ in a text editor, or in a word processing package. Note: MapX uses this file when interpreting and setting the map coordinate system. Make a back up of this file prior to making any changes. Within MAPINFOW.PRJ, search for the name of a MapInfo projection, such as "Robinson". The line that you find contains the definition for the Robinson projection: "Robinson", 12, 62, 7, 0 This line tells us several things about the Robinson coordinate system: • 214 The string at the start of the line is a description. The first number after the description, 12 in this example, tells you what type of coordinate system applies. Check the number 12 against the table of MapX CoordSysType constants, and you'll see that type 12 matches the MapX constant, miRobinson. (In this case, the description made it obvious that the coordinate system uses a Robinson projection; but in other cases, the projection might not be obvious.) MapX Developer’s Guide Chapter 13: Using Coordinate Systems • Refer to the Summary of Parameters Used by Coordinate Systems to see which parameters are used by Robinson maps. Robinson maps use only three parameters: datum, units, and origin longitude. Now you know how to interpret the rest of the numbers on the line: 62 is the datum number, 7 is the unit number, and 0 is the Origin Longitude. From the list of datums supported by MapX, you can determine that datum 62 represents NAD 27 for the continental US. • From the table of MapUnit constants, you can determine that unit type number 7 matches the value of the MapX constant, miUnitMeter. You can use this set of values (12, 62, 7, 0) as the parameters when calling the CoordSys.Set method. For example: objCoordSys.Set 12, 62, 7, 0 How to Interpret Special Datum Numbers MapInfo users can customize the MAPINFOW.PRJ file by creating custom datum definitions. There are two types of custom datum definitions: • A full custom datum definition consists of datum number 9999, immediately followed by nine other custom datum parameters, separated by commas. • A simplified custom datum definition consists of datum number 999, immediately followed by four other custom datum parameters, separated by commas. If a line in MAPINFOW.PRJ specifies datum number 999 or 9999, then the custom datum parameters appear before the rest of the coordinate system parameters (units, origin longitude, etc.). For more information on custom datum syntax, see the section Defining Custom Datums later in this chapter. How to Interpret Special CoordSys Type Numbers The coordinate system type number that appears in MAPINFOW.PRJ (such as 12, in the example above) might not match any of the MapX CoordSysType constant values. You may need to subtract 1000, 2000, or 3000 from the number to obtain a number that represents a valid MapX CoordSysType. If a line from MAPINFOW.PRJ contains an affine transformation, then the coordinate system type number will have 1000 added to it, and the seven affine transformation parameters will be added to the end of the line. If the line includes a bounds definition, then the projection type number will have 2000 added to it, and the four bounds parameters will be added to the end of the line. For example, the following line from a hypothetical MAPINFOW.PRJ file represents a coordinate system with both an affine transformation and a bounds definition. This MapX Developer’s Guide 215 Chapter 13: Using Coordinate Systems coordinate system uses UTM Zone 10 (coordinate system type: miTransverseMercator, which has a value of 8). However, because this coordinate system includes both an affine transformation and a bounds description, the number following the description is 3008 (8 + 1000 + 2000). "DCS", 3008, 74, 7, -123, 0, 0.9996, 500000, 0, 3, 1.57, -0.21, _ 84120.5, 0.19, 2.81, -20318.0, 70000, 0, 80000, 50000 Although the number 3008 is valid within MAPINFOW.PRJ, you must use the unaltered number, 8, in MapX. The "DCS" example above can be interpreted as follows: name, CoordSysType + 3000, the projection parameters (Transverse Mercator uses 7 _ parameters), the 7 affine transformation parameters, The 4 bounds parameters (in the order: xmin, ymin, xmax, ymax) Applying an Affine Transformation If you need to define rotated or skewed coordinate systems, you need to specify an affine transformation. In MapX, you can define such a transformation by creating an AffineTransform object, then passing the object to the CoordSys.Set method. Note: If you simply want to rotate the map, you do not need to specify an affine transformation. Instead, set the Map object's Rotation property. An affine transformation has the following form: x' = Ax + By + C y' = Dx + Ey + F In these equations, the base coordinates (x, y) are transformed to produce the derived coordinates (x', y'). The six constants A through F determine the effect of the transformation, as follows: 216 A Performs scaling or stretching along the X axis. B Performs rotation or skewing along the X axis. C Performs shifting along the X axis. MapX Developer’s Guide Chapter 13: Using Coordinate Systems D Performs rotation or skewing along the Y axis. E Performs scaling or stretching along the Y axis. F Performs shifting along the Y axis. Example Suppose you want to define a coordinate system (we'll call it DCS) that is derived from the UTM Zone 10 coordinate system (UTM-10 for short) by using the following affine transformation: x' = 1.57x - 0.21y + 84120.5 y' = 0.19x + 2.81y - 20318.0 In this transformation, (x', y') represents the DCS derived coordinates, and (x, y) represents the UTM-10 base coordinates. The following Visual Basic code example shows how to set up the affine transformation in MapX: Dim objAffine As New MapXLib.AffineTransform ' Declare variables to hold coordinate system information Dim iProjectionType As Integer Dim iDatumNumber As Integer Dim iUnits As Integer Dim dOriginLongitude As Double Dim dOriginLatitude As Double Dim dScaleFactor As Double Dim lFalseEasting As Long Dim lFalseNorthing As Long ' initialize the AffineTransform object, using ' the numbers from the equation above objAffine.Set 7, 1.57, -0.21, 84120.5, _ 0.19, 2.81, -20318.0 ' ' ' ' Initialize the variables to be used by coordsys.set. Values were obtained from the "UTM Zone 10 (NAD 83)" entry in the file MAPINFOW.PRJ, which looks like this: "UTM Zone 10 (NAD 83)\p26910", 8, 74, 7, -123, 0, 0.9996, 500000, 0 iProjectionType = miTransverseMercator MapX Developer’s Guide '(value: 8) 217 Chapter 13: Using Coordinate Systems iDatumNumber = 74 iUnits = miUnitMeter dOriginLongitude = -123 dOriginLatitude = 0 dScaleFactor = 0.9996 lFalseEasting = 500000 lFalseNorthing = 0 'North American 1983 (NAD 83) '(value: 7) Map1.DisplayCoordSys.Set iProjectionType, iDatumNumber, iUnits, _ dOriginLongitude, dOriginLatitude, , , , _ dScaleFactor, lFalseEasting, lFalseNorthing, _ , , objAffine 218 MapX Developer’s Guide Chapter 13: Using Coordinate Systems Defining Custom Datums Most coordinate systems use one of the standard datums supported by MapX. If you need to use a datum that is not in the list, and you know the datum’s mathematical parameters, then you can define the coordinate system using a custom datum. This discussion provides examples for both MapX and MapInfo Professional, for the sake of those users who use both products. If you have already gone through the process of creating a custom datum in MapInfo, you should find it easy to adapt your datum to MapX. If you do not use MapInfo Professional, you can simply ignore the MapInfo-specific examples. What is a Datum? A datum is a mathematical description of the earth’s shape and orientation. Because the earth’s shape is not uniform, there are many different local datums used in different parts of the world. These local datums provide a close approximation to the earth’s surface in a particular area. Each Earth coordinate system uses a specific datum to approximate the earth’s surface. If two coordinate systems use different datums, then mapping software must perform a datum transformation when it converts coordinates from one coordinate system to the other. MapX and MapInfo use the Bursa-Wolfe datum transformation method, which is generally accurate to within 10 meters. (When MapInfo converts between two coordinate systems that use the same datum, no datum transformation is performed, and the results are generally accurate to within 0.1 meter.) The Parameters that Define a Datum MapX and MapInfo Professional use the following information to define a datum: • An ellipsoid, also called a spheroid. This is an ellipse rotated around its minor axis to form a three-dimensional surface. The ellipsoid is described by two mathematical parameters: the length, in meters, of its semi-major axis (denoted by the letter a) and its degree of flattening (denoted by the letter f). Over 40 predefined ellipsoids are supported; see Ellipsoids Supported by MapX. • Three shift parameters specifying the distance, in meters, to shift the ellipsoid along each of its axes. These parameters are usually denoted by dX, dY, and dZ. You may also see them denoted by u, v, and w.The MapX Datum.Set method identifies these parameters as ShiftX, ShiftY, and ShiftZ. MapX Developer’s Guide 219 Chapter 13: Using Coordinate Systems • Three rotation parameters specifying the angle, in arc-seconds, to rotate the ellipsoid around each of its axes. These parameters are usually denoted by EX, EY, and EZ. The Datum.Set method identifies these parameters as RotateX, RotateY, and RotateZ. • A scale correction factor specifying the amount, in parts per million, to adjust the size of the ellipsoid. This parameter is denoted by the letter m. • The longitude of the prime meridian, in degrees east of Greenwich. The prime meridian specifies which location on earth is assigned longitude 0°. Most datums use Greenwich as the prime meridian, so this parameter is usually zero. However, some datums use a different location as the prime meridian. For example, the NTF datum uses Paris as its prime meridian, which is 2.33722917 degrees east of Greenwich. If you use the NTF datum in a coordinate system, all longitudes in that coordinate system are relative to Paris instead of Greenwich. Defining a Datum in MapInfo Professional In MapInfo, you define a custom datum in a coordinate system by using datum number 9999 followed by the datum parameters, in this order: 9999, EllipsoidNumber, dX, dY, dZ, EX, EY, EZ, m, PrimeMeridian Some datums specify only an ellipsoid and shift parameters (dX,dY, dZ), with no rotation parameters, scale correction, or prime meridian. In those cases, you can use datum number 999 instead of 9999, to simplify the definition: 999, EllipsoidNumber, dX, dY, dZ These sets of parameters are then copied into the file MAPINFOW.PRJ; see examples below. Defining a Datum in MapX In MapX, you define a custom datum by creating a Datum object, and using its Set method to set the parameters.You then use this Datum object as one of the parameters to the CoorsSys.Set method. Common Mistakes, and How to Avoid Them The shift and rotation parameters describe the ellipsoid’s orientation in space, as compared to the WGS 84 datum. It’s important to make sure that these parameters have the correct signs (positive or negative). Usually, a document describing a local datum will list the parameters required to convert coordinates from the local datum to WGS 84. (This is the same as saying that the parameters were derived by subtracting the local datum from WGS 84.) In that case, you can use the parameters exactly as they appear in the document. However, if you have a document that lists parameters for converting coordinates in the opposite direction — from 220 MapX Developer’s Guide Chapter 13: Using Coordinate Systems WGS 84 to the local datum — then you must reverse the signs of the shift, rotation, and scale correction parameters. It’s also very important to list the parameters in the correct order. Some documents list the rotation parameters with EZ first, like this: EZ, EY, EX. In those cases, you must reverse the order of the rotation parameters when defining the custom datum. This is especially easy to overlook when your document uses Greek letters to denote the parameters. Datum Conversion When converting coordinates from one datum to another, MapX has used the Molodensky (3parameter) and Bursa-Wolfe (7-parameter) methods. These are general-purpose methods that can convert coordinates from any datum to any other datum. After the NAD 83 datum was introduced, NOAA developed a program called NADCON, which stands for North American Datum CONversion. This is a very specialized program that converts coordinates only from NAD 27 to NAD 83 and vice versa. For this specialized task, it’s much more accurate than the Molodensky general-purpose method; NADCON is accurate to about 0.1 meter, and Molodensky is accurate to only 10-30 meters. Most U.S. government agencies, including the Census Bureau, have standardized on NADCON for converting between NAD 27 and NAD 83. Beginning with MapX 3.5, the NADCON algorithm is used to convert coordinates between NAD 27 and NAD 83 if those coordinates lie within the areas covered by NADCON (United States, Puerto Rico, and the Virgin Islands). If the coordinates lie outside those areas, or if they use datums other than NAD 27 or NAD 83, MapX uses the Molodensky or Bursa-Wolfe conversion methods. Due to the file access required, the NADCON method can be slightly slower than the Molodensky method. If you want to turn off the NADCON method, add a “NADCON” entry to the registry. The registry entry should have this path: • HKEY_LOCAL_MACHINE\Software\\MapInfo\\MapX\\3.0\NadCon If this entry is set to zero, then the Molodensky conversion method will be used instead of NADCON. To enable NADCON, set the entry to 1 (default). MapX reads this entry when it is loaded, and all maps use the same setting.You can't turn NADCON on or off for a particular map. MapX Developer’s Guide 221 Chapter 13: Using Coordinate Systems For More Information... For more information about coordinate systems and map projections, see the following. Related Pamphlets • American Cartographic Association. Choosing a World Map—Attributes, Distortions, Classes, Aspects. Falls Church, VA: American Congress on Surveying and Mapping. Special Publication No. 2. 1988. • American Cartographic Association. Matching the Map Projection to the Need. Falls Church, VA: American Congress on Surveying and Mapping. Special Publication No. 3. 1991. • American Cartographic Association. Which Map is Best? Projections for World Maps. Falls Church,VA: American Congress on Surveying and Mapping. Special Publication No. 1. 1986. To obtain these pamphlets, please contact: American Congress on Surveying and Mapping 5410 Grosvenor Lane, Suite 100 Bethesda, MD 20814–2212 301–493–0200 Related Books • John P. Snyder. Map Projections—A Working Manual. Washington: U.S. Geological Survey Professional Paper 1395. 1987. • John P. Snyder and Philip M.Voxland. An Album of Map Projections. Washington: U.S. Geological Survey Professional Paper 1453. 1989. To obtain these books, please contact: Earth Science Information Center U.S. Geological Survey 507 National Center Reston, VA 22092 703–860–6045 or 1–800–USA–MAPS 222 MapX Developer’s Guide Chapter 14: Using Drilldown Layers Using Drilldown Layers In this chapter, you'll learn about a special type of map layer, known as a Drilldown layer, that lets the user perform "drill-down" analysis and exploration. If your map includes a Drilldown layer, your user can point and 14 Chapter ➤ What Is a Drilldown Layer? ➤ Terms and Concepts You Should Know ➤ How To Develop a Drilldown Application ➤ Preparing a Drilldown Layer click on part of the map to see more detail about that ➤ Creating a Drilldown Tool region. Drilldown layers provide an intuitive, easy to use ➤ Resetting the Drilldown Layer interface that allows users to explore data by pointing and clicking. ➤ Drilldown Layer Limitations and Requirements ➤ For More Information... Chapter 14: Using Drilldown Layers What Is a Drilldown Layer? A Drilldown layer is a map layer with special behavior built-in. Drilldown layers allow the user to explore the map in a hierarchical manner, by pointing and clicking on the part of the map where mor detail is needed. When a map first appears on the screen, the Drilldown layer looks like an ordinary map layer. For example, this Drilldown layer shows sales territories. If the user selects a Drilldown tool and clicks on a feature in the map, that feature is replaced by numerous smaller regions. For example, if you click on a sales territory, the territory feature is replaced by the state boundaries that make up the territory. Clicking is basically a way of requesting, "Show me more detail about this part of the map." 224 MapX Developer’s Guide Chapter 14: Using Drilldown Layers Depending on how the application and the Drilldown layer were set up, the user might be able to drill down repeatedly. With each successive click, the map can display more detail about the area where the user clicked. Clicking on a state boundary might reveal the county boundaries that make up the state. To reduce the amount of detail displayed, the user can select a different tool (a "roll up" tool), and click on the detailed area. The smaller, detailed regions are replaced with a larger region—essentially, undoing the drill-down action. A Drilldown layer is built from a set of tables. You need to provide one table for each "level" in the drill-down hierarchy, plus one special table that defines how the various levels are related hierarchically. However, the complexity of a Drilldown layer is hidden from the user. The Drilldown layer appears in a MapX map as a single layer. If the user displays the Layer Control dialog box, a Drilldown Layer appears as a single item in the list of layers. Terms and Concepts You Should Know To understand the rest of this chapter, you'll need to understand some of the terminology and basic concepts of Drilldown mapping. • To support drill-down mapping, the map must include a Drilldown laye . This is a special layer, composed of two or more separate tables. A Drilldown layer displays objects from different tables as one layer in the map. • For a Drilldown layer to be useful, it must contain at least two levels, which form a hierarchy. For example, suppose a Drilldown layer presents state boundaries, and the user can click on a state to show all the county boundaries for that state. In the preceding example, the state boundaries represent one level, and the county boundaries represent another level. The levels form a hierarchy. Each state contains a number of counties. In this example, we say that the state boundary is a parent feature, and each county boundary is a child feature. MapX Developer’s Guide 225 Chapter 14: Using Drilldown Layers 226 • Typically, the user drills down on a part of the map by selecting a Drilldown tool, then clicking on a part of the map where more detail is needed. To implement a drilldown tool, use the CreateCustomTool method to create a custom tool. • Using the Drilldown tool triggers theToolUsed event. Within this event, you handle the user's drill-down action by expanding the feature that the user clicked on. Expanding a feature is a two-step process: First, you obtain a list of child features that will replace the feature the user clicked on, and add the child features to the layer (by calling the Layer.DrilldownAddFeatures method). Then, you remove the original feature that the user clicked on. In other words, a feature is replaced by its child features. • Any Drilldown application requires a hierarchy manager, which is a software component that understands the hierarchical relationship between the various levels in the Drilldown layer. When the user clicks a feature to expand that feature, the hierarchy manager is the part of the program that decides which child features need to be added. • The ToolUsed event procedure is a simple example of a hierarchy manager. When the user uses your custom Drilldown tool to click on the map, the click event is handled by the ToolUsed event procedure; the code executed within this procedure determines which features are added to expand the map feature. • You can set up the Drilldown layer so that there are two or more alternate tables that can be used at a given level in the hierarchy. For example, suppose that for each state boundary, you have two alternate sets of child features: A state can be expanded to show a set of county boundaries, or the state can be expanded to show a set of telephone exchange numbers. Such a Drilldown layer would still be considered to have two levels—one parent level, and one child level. However, at the child level, there is a choice between two alternate sets of features (counties vs. telephone exchanges). With this arrangement, your application must determine which child level to display, perhaps by prompting the user. MapX Developer’s Guide Chapter 14: Using Drilldown Layers How to Develop a Drilldown Application Drill-down applications require a considerable amount of setup and preparation. The major steps can be summarized as follows (with more detail on each step provided later in this chapter). 1. Obtain the various tables that you will use to build your multi-level Drilldown layer. Tables can be created using MapInfo Professional, or purchased from MapInfo Corporation or from third-party vendors. 2. Create a new, empty drilldown table (a .tab file) with special columns and special metadata. The metadata assigns a level name to each component table, and also identifies important columns in the component tables — the ID column and the caption column. 3. Include your Drilldown table in your map (e.g., include the Drilldown table in the Geoset(s) you are using, or add the Drilldown table to your map through a method such as Layers.Add). 4. Add a user interface element (such as a toolbar button) to your application, so that the user can select a Drilldown tool and click on the map to drill down. 5. Add code to your application that responds to the user's use of the drill-down tool (in other words, write a hierarchy manager). This code needs to detect which feature the user selected; determine which child features should replace the feature; and invoke various methods (DrilldownRemoveFeatures, DrilldownAddFeatures) to expand or contract the map features. MapX Developer’s Guide 227 Chapter 14: Using Drilldown Layers Preparing a Drilldown Layer To build a Drilldown layer, you need to provide a set of two or more MapInfo tables. Specifically, you need: • One MapInfo table for each level of detail in your Drilldown layer. These are known as component tables. • An additional, empty table which contains special metadata that describes the component tables. This is known as the Drilldown table. For example, suppose you want to display state boundaries, but allow the user to click a state to display that state's county boundaries—a two-level Drilldown layer. You would need three tables: A (component) table of state boundaries, a (component) table of county boundaries, and a Drilldown table. Note: The Drilldown table is "empty" in that it contains no permanent data of its own (except for metadata). When you display a Drilldown layer in a map, MapX creates a temporary table, and then copies features from the component table(s) into the temporary table. The features that appear in a Drilldown layer are actually copies of features in the component table(s). When the MapX application terminates, the temporary table is discarded, and all that remains of the Drilldown table is the .tab file. Requirements for the Component Tables Each feature in a Drilldown layer must have an identifying key (possibly a string such as "New York"). All keys within a single level must be unique; for example, a state boundaries level can only contain one state known as "Washington". However, a feature's identifying key does not need to be unique across all other levels in the Drilldown layer. For example, if you Drilldown layer includes state boundaries and county boundaries, you could have a "Washington" state and a "Washington" county. Requirements for the Drilldown Table A typical MapInfo table consists of a set of files; for example, the World table consists of the files World.tab, World.map, World.id, World.ind, and World.dat. The Drilldown table is different from other tables, in that it consists of a single file: filename.tab. The .tab file is a text file, which you can view or edit in any text editor. The Drilldown table's .tab file must define specific columns and metadata keys, as described below. As you read the following requirements, please refer to the “Sample Drilldown Table” for an example. 228 MapX Developer’s Guide Chapter 14: Using Drilldown Layers The Drilldown table must define three standard columns: Key, Level, and Label. All three columns are character (string) columns, 32 characters wide. The Drilldown table must contain a set of metadata keys. Metadata key syntax is as follows: • The keyword begin_metadata marks the beginning of the metadata portion of the .tab file. • Each line of metadata has two elements: a key, and a value. For example, the key "\IsDrilldown" has the value "True". All keys and values are enclosed within double quotation marks. • The Drilldown table must include the \IsDrilldown key, and this key's value must be True. • Every key begins with the character "\" (backslash). • Metadata keys can be nested hierarchically. Each level in the hierarchy is marked by a backslash (\) character. Key values are limited to 239 characters. • The Drilldown table includes a \DDMap\ComponentMaps\ key hierarchy. Within this hierarchy, you specify four metadata keys for each component table: Component Table Metadata Keys Key Description File A required key that identifies the path and filename of a component table. LevelID A required key that defines an identifier for this component table. Example: You might use "States" as the key value if this table contains state boundaries. When calling a method such as DrilldownReset, pass "States" as the level argument. FeatureIDCol Identifies the number of the column in the component table that contains unique drill-down keys. Optional key; if omitted, column number 1 is used. FeatureCaptionCol Identifies the number of the column in the component table which should be used for labeling. Optional key; if omitted, column number 1 is used. MapX Developer’s Guide 229 Chapter 14: Using Drilldown Layers For example, the “Sample Drilldown Table” includes key hierarchies such as "\DDMap\ComponentMaps\One\LevelID" and "\DDMap\ComponentMaps\Twox\LevelID". Note that DDMap, ComponentMaps, and LevelID are standard, required portions of the key hierarchy, while One and Twox are customizable. You can use any key names you like instead of One, Twox, Twoxx, etc.; those key names serve no purpose other than to differentiate each component table's set of keys. Within the \DDMap\HierarchyManager\ key hierarchy, there are three additional keys: Key Description IsDLL Not used in version 4; reserved for future use. Boolean indicator; "TRUE" means that this Drilldown layer uses a DLL as the hierarchy manager. ID Not used in version 4; reserved for future use. The name of the DLL, or the GUID to CoCreate. InitialLevel The initial component table to display when first loading/ displaying the Drilldown layer. Optional key; it is acceptable to have an empty Drilldown layer. Sample Drilldown Table The contents of a sample Drilldown table are listed below. If you want to create your own Drilldown table, you can copy this example into a text file, and modify it to refer to your component tables. !table !version 300 !charset WindowsLatin1 Definition Table Type Native Charset "WindowsLatin1" Fields 3 Key Char (32); Level Char (32); Label Char (32); begin_metadata "\IsDrilldown" = "TRUE" "\DDMap\ComponentMaps\One\File" = "C:\Program Files\MapInfo\Data\USA\usaXXX.TAB" "\DDMap\ComponentMaps\One\LevelID" = "USA" 230 MapX Developer’s Guide Chapter 14: Using Drilldown Layers "\DDMap\ComponentMaps\One\FeatureIDCol" = "3" "\DDMap\ComponentMaps\One\FeatureCaptionCol" = "1" "\DDMap\ComponentMaps\Twox\File" = "C:\Program Files\MapInfo\Data\USA\2Region.TAB" "\DDMap\ComponentMaps\Twox\LevelID" = "2Region" "\DDMap\ComponentMaps\Twox\FeatureIDCol" = "1" "\DDMap\ComponentMaps\Twox\FeatureCaptionCol" = "3" "\DDMap\ComponentMaps\Twoxx\File" = "C:\Program Files\MapInfo\Data\USA\MultiRegionSales.TAB" "\DDMap\ComponentMaps\Twoxx\LevelID" = "MultiRegion" "\DDMap\ComponentMaps\Twoxx\FeatureIDCol" = "1" "\DDMap\ComponentMaps\Twoxx\FeatureCaptionCol" = "3" "\DDMap\ComponentMaps\Two\File" = "C:\Program Files\MapInfo\Data\USA\states.TAB" "\DDMap\ComponentMaps\Two\LevelID" = "States" "\DDMap\ComponentMaps\Two\FeatureIDCol" = "3" "\DDMap\ComponentMaps\Two\FeatureCaptionCol" = "1" "\DDMap\HierarchyManager\IsDLL" = "TRUE" "\DDMap\HierarchyManager\ID" = "SomeDLL.dll" "\DDMap\HierarchyManager\InitialLevel" = "USA" end_metadata MapX Developer’s Guide 231 Chapter 14: Using Drilldown Layers Creating a Drilldown Tool Your application's user interface should give the user a way to drill down on part of the map. Typically, the user drills down by selecting a Drilldown tool (e.g., a toolbar button), then clicking on the map. You can implement a Drilldown tool by using the CreateCustomTool method. The set of CursorConstants includes two cursors provided specifically for Drilldown applications: miDrilldownExpandCursor and miDrilldownContractCursor. For example: ' Drilldown Expand Tool Map1.CreateCustomTool 1, miToolTypePoint, miDrilldownExpandCursor, miDrilldownContractCursor, miDrilldownContractCursor This example creates a single tool that can be used for both Drilldown and RollUp actions. By default, the tool acts as a Drilldown tool, which displays an "expand" cursor (a cursor with a + sign). If the user holds down the SHIFT or CTRL key while clicking, the cursor changes to a "contract" cursor (a cursor with a - sign). This arrangement lets the user switch tools without having to move the cursor all the way to the toolbar; the built-in ZoomIn and ZoomOut tools have the same behavior. Once you have created the custom tool, you can make the tool active by setting the CurrentTool property. Map1.CurrentTool = 1 Each use of the custom Drilldown tool will trigger the ToolUsed event. Within the ToolUsed event procedure, you will need to execute code that causes the drill-down behavior. This is basically a four-step process: 1. Determine which map feature the user clicked on, using methods such as SelectByPoint or SearchAtPoint. 2. Determine which set of child features should replace the feature the user clicked on. For example, you might use one or more nested Case statements to determine which child features replace the chosen parent feature. 3. Call the DrilldownAddFeatures method to add the child features to the map. 4. Call the DrilldownRemoveFeatures method to remove the parent feature (the feature that the user clicked on) from the map. 232 MapX Developer’s Guide Chapter 14: Using Drilldown Layers Note: These add/remove actions do not modify the component tables in any way; you are not "editing" the tables. When you use the DrilldownAddFeatures method to add features, the only effect is that the features are copied into the set of features that are currently visible. Creating a RollUp Tool Once you have implemented a Drilldown tool, you will probably want to give the user a Rollup tool—a tool that has the opposite effect of the Drilldown tool. You can create a Roll-Up tool in much the same way that you create a Drilldown tool.You will need to use the same methods (DrilldownAddFeatures and DrilldownRemoveFeatures). The difference is that instead of adding child features and removing parent features, you'll do the opposite — you'll add parent features and remove child features. Example: Drilldown/Rollup Tool Example The following sample ToolUsed event procedure demonstrates how to handle a Drilldown tool and a Rollup tool. This procedure was written to handle a Drilldown layer with the following layer hierarchy: USA A layer containing a single region, representing the entire United States. 2Region A layer containing two large regions (East and West). Each region covers roughly one half the United States. MultiRegion A layer containing eight smaller regions. Each region covers roughly one eighth of the United States. States A layer containing the fifty United States state regions. Private Sub Map1_ToolUsed(ByVal ToolNum As Integer, ByVal X1 As Double, ByVal Y1 As Double, ByVal X2 As Double, ByVal Y2 As Double, ByVal Distance As Double, ByVal Shift As Boolean, ByVal Ctrl As Boolean, EnableDefault As Boolean) Dim AddKeys() As String Dim NewLevel As String Dim fs As Features Dim strLevel As String Dim DelKeys() As String Dim pnt As New Point ' --------------------------------------------- MapX Developer’s Guide 233 Chapter 14: Using Drilldown Layers ' Expand ' ---------------------------------------------If ToolNum = 1 Then ' Expand the feature the user clicked on. ' First, figure out what object we have pnt.Set X1, Y1 Set fs = Map1.Layers(strTbl).SearchAtPoint(pnt) If fs.Count = 1 Then ReDim DelKeys(0) Map1.Layers(strTbl).KeyField = "Level" strLevel = fs(1).KeyValue Map1.Layers(strTbl).KeyField = "Key" DelKeys(0) = fs(1).KeyValue If strLevel = "USA" Then NewLevel = "2Region" ReDim AddKeys(1) AddKeys(0) = "West" AddKeys(1) = "East" ElseIf strLevel = "2Region" Then NewLevel = "MultiRegion" ReDim AddKeys(3) Select Case DelKeys(0) Case "West" AddKeys(0) = "mrRgn1" AddKeys(1) = "mrRgn2" AddKeys(2) = "mrRgn3" AddKeys(3) = "mrRgn4" Case "East" AddKeys(0) = "mrRgn5" AddKeys(1) = "mrRgn6" AddKeys(2) = "mrRgn7" AddKeys(3) = "mrRgn8" End Select ElseIf strLevel = "MultiRegion" Then NewLevel = "States" Select Case DelKeys(0) 234 MapX Developer’s Guide Chapter 14: Using Drilldown Layers Case "mrRgn1" ReDim AddKeys(4) AddKeys(0) = "16" AddKeys(1) = "30" AddKeys(2) = "41" AddKeys(3) = "53" AddKeys(4) = "56" Case "mrRgn2" ReDim AddKeys(5) AddKeys(0) = "04" AddKeys(1) = "06" AddKeys(2) = "08" AddKeys(3) = "32" AddKeys(4) = "35" AddKeys(5) = "49" Case "mrRgn3" ReDim AddKeys(4) AddKeys(0) = "19" AddKeys(1) = "27" AddKeys(2) = "31" AddKeys(3) = "38" AddKeys(4) = "46" Case "mrRgn4" ReDim AddKeys(5) AddKeys(0) = "48" AddKeys(1) = "22" AddKeys(2) = "05" AddKeys(3) = "40" AddKeys(4) = "20" AddKeys(5) = "29" Case "mrRgn5" ReDim AddKeys(4) AddKeys(0) = "17" AddKeys(1) = "55" AddKeys(2) = "18" AddKeys(3) = "26" AddKeys(4) = "39" Case "mrRgn6" ReDim AddKeys(8) AddKeys(0) = "33" MapX Developer’s Guide 235 Chapter 14: Using Drilldown Layers AddKeys(1) = "09" AddKeys(2) = "23" AddKeys(3) = "25" AddKeys(4) = "34" AddKeys(5) = "36" AddKeys(6) = "42" AddKeys(7) = "44" AddKeys(8) = "50" Case "mrRgn7" ReDim AddKeys(7) AddKeys(0) = "21" AddKeys(1) = "37" AddKeys(2) = "47" AddKeys(3) = "51" AddKeys(4) = "54" AddKeys(5) = "10" AddKeys(6) = "11" AddKeys(7) = "24" Case "mrRgn8" ReDim AddKeys(4) AddKeys(0) = "28" AddKeys(1) = "01" AddKeys(2) = "12" AddKeys(3) = "13" AddKeys(4) = "45" End Select Else MsgBox "Can't drill down any further; Level: "_ + strLevel + " Key: " + DelKeys(0) Exit Sub End If ElseIf fs.Count = 0 Then MsgBox "No features selected" Exit Sub Else MsgBox "More than one feature selected; can only _ drilldown on exactly one item" Exit Sub End If Map1.Layers(strTbl).DrillDownRemoveFeatures strLevel, _ DelKeys 236 MapX Developer’s Guide Chapter 14: Using Drilldown Layers Map1.Layers(strTbl).DrillDownAddFeatures NewLevel, AddKeys ' --------------------------------------------' Contract ' ---------------------------------------------ElseIf ToolNum = 2 Then ' do the drilldown contract thang pnt.Set X1, Y1 Set fs = Map1.Layers(strTbl).SearchAtPoint(pnt) If fs.Count = 1 Then ReDim DelKeys(0) Map1.Layers(strTbl).KeyField = "Level" strLevel = fs(1).KeyValue Map1.Layers(strTbl).KeyField = "Key" DelKeys(0) = fs(1).KeyValue If strLevel = "States" Then NewLevel = "MultiRegion" Select Case DelKeys(0) Case "16", "30", "41", "53", "56" ReDim DelKeys(4) ReDim AddKeys(0) AddKeys(0) = "mrRgn1" DelKeys(0) = "16" DelKeys(1) = "30" DelKeys(2) = "41" DelKeys(3) = "53" DelKeys(4) = "56" Case "04", "06", "08", "32", "35", "49" ReDim DelKeys(5) ReDim AddKeys(0) AddKeys(0) = "mrRgn2" DelKeys(0) DelKeys(1) DelKeys(2) DelKeys(3) DelKeys(4) DelKeys(5) MapX Developer’s Guide = = = = = = "04" "06" "08" "32" "35" "49" 237 Chapter 14: Using Drilldown Layers Case "19", "27", "31", "38", "46" ReDim DelKeys(4) ReDim AddKeys(0) AddKeys(0) = "mrRgn3" DelKeys(0) DelKeys(1) DelKeys(2) DelKeys(3) DelKeys(4) = = = = = "19" "27" "31" "38" "46" Case "48", "22", "05", "40", "20", "29" ReDim DelKeys(5) ReDim AddKeys(0) AddKeys(0) = "mrRgn4" DelKeys(0) DelKeys(1) DelKeys(2) DelKeys(3) DelKeys(4) DelKeys(5) = = = = = = "48" "22" "05" "40" "20" "29" Case "17", "55", "18", "26", "39" ReDim DelKeys(4) ReDim AddKeys(0) AddKeys(0) = "mrRgn5" DelKeys(0) DelKeys(1) DelKeys(2) DelKeys(3) DelKeys(4) = = = = = "17" "55" "18" "26" "39" Case "33", "09", "23", "25", "25", "34", _ "36", "42", "44", "50" ReDim DelKeys(8) ReDim AddKeys(0) AddKeys(0) = "mrRgn6" 238 MapX Developer’s Guide Chapter 14: Using Drilldown Layers DelKeys(0) DelKeys(1) DelKeys(2) DelKeys(3) DelKeys(4) DelKeys(5) DelKeys(6) DelKeys(7) DelKeys(8) = = = = = = = = = "33" "09" "23" "25" "34" "36" "42" "44" "50" Case "21", "37", "47", "51", "54", "10", _ "11", "24" ReDim DelKeys(7) ReDim AddKeys(0) AddKeys(0) = "mrRgn7" DelKeys(0) DelKeys(1) DelKeys(2) DelKeys(3) DelKeys(4) DelKeys(5) DelKeys(6) DelKeys(7) = = = = = = = = "21" "37" "47" "51" "54" "10" "11" "24" Case "28", "01", "12", "13", "45" ReDim DelKeys(4) ReDim AddKeys(0) AddKeys(0) = "mrRgn8" DelKeys(0) DelKeys(1) DelKeys(2) DelKeys(3) DelKeys(4) = = = = = "28" "01" "12" "13" "45" End Select ElseIf strLevel = "MultiRegion" Then NewLevel = "2region" Select Case DelKeys(0) MapX Developer’s Guide 239 Chapter 14: Using Drilldown Layers Case "mrRgn1", "mrRgn2", "mrRgn3", "mrRgn4" ReDim DelKeys(3) ReDim AddKeys(0) AddKeys(0) = "West" DelKeys(0) = "mrRgn1" DelKeys(1) = "mrRgn2" DelKeys(2) = "mrRgn3" DelKeys(3) = "mrRgn4" Case "mrRgn5", "mrRgn6", "mrRgn7", "mrRgn8" ReDim DelKeys(3) ReDim AddKeys(0) AddKeys(0) = "East" DelKeys(0) = "mrRgn5" DelKeys(1) = "mrRgn6" DelKeys(2) = "mrRgn7" DelKeys(3) = "mrRgn8" End Select ElseIf strLevel = "2Region" Then NewLevel = "USA" ReDim DelKeys(1) ReDim AddKeys(0) AddKeys(0) = "1" DelKeys(0) = "West" DelKeys(1) = "East" + " Else MsgBox "Can't contract any more; Level: " + strLevel Key: " + DelKeys(0) Exit Sub End If Else MsgBox "No items or Multiple items under cursor; Can only Drilldown on one item" Exit Sub End If Map1.Layers(strTbl).DrillDownRemoveFeatures strLevel, DelKeys Map1.Layers(strTbl).DrillDownAddFeatures NewLevel, AddKeys ElseIf ToolNum = 3 Then 240 MapX Developer’s Guide Chapter 14: Using Drilldown Layers Dim Dim Dim Dim f As Feature fss As Features s As Style key() As String ' Get the feature pnt.Set X1, Y1 Set fss = Map1.Layers(strTbl).SearchAtPoint(pnt) Map1.Layers(strTbl).KeyField = "Level" strLevel = fss(1).KeyValue Map1.Layers(strTbl).KeyField = "Key" ReDim key(0) key(0) = fss(1).KeyValue If fss.Count = 1 Then Set fss = _ Map1.Layers(strTbl).GetDrilldownFeaturesByID(strLevel, key) Set f = fss(1) Set s = f.Style s.RegionColor = (RGB(0, 0, 255)) f.Style = s f.Update Else MsgBox "Can only change one feature at a time" Exit Sub End If End If End Sub MapX Developer’s Guide 241 Chapter 14: Using Drilldown Layers Resetting the Drilldown Layer You can "reset" a Drilldown layer by calling the DrilldownReset method. Resetting the Drilldown layer clears the entire layer, then re-initializes the layer using features from one of the component tables. For example, you might include a "Reset button" in your user interface. When the user clicks the button, you could call the DrilldownReset method to restore the original state of the Drilldown layer. Including a reset button is a good idea, because it gives your users a quick, easy way of restoring the drilldown layer to a homogeneous state. Example Private Sub Command2_Click() Map1.Layers("DDTestUSA2").DrilldownReset "States" End Sub Drilldown Layer Limitations and Requirements Some restrictions apply to Drilldown layers, as summarized in the following list. 242 • Each feature in a Drilldown layer must contain an ID that is unique within that component table (although the ID does not need to be unique among all of the component tables that make up the Drilldown layer). • You cannot use a raster image underlay table in a Drilldown layer. • When creating a theme with Themes.Add, computing ranges for layers with large numbers of rows, such as drilldown or server layers, can take some time. The ComputeTheme parameter of the Add method lets you create a non-compute theme for any theme type. A non-compute theme gives you the ability to create a theme without having the ranges automatically calculated for you. You can then create the ranges yourself. This is a faster way for drilldown and server layers. • A Drilldown layer does not "remember" the status of the various drill-down levels (which features have been expanded, etc.). If you want your application to restore the precise status of the map's last use, you will need to write code to store the map's drilldown settings when exiting, and restore the drill-down settings when starting. MapX Developer’s Guide Chapter 14: Using Drilldown Layers • Although you can edit the features in a Drilldown layer, the edits are not saved, and the component tables are not affected by your edits. When you edit a feature in a Drilldown layer, you are not modifying the component table, you are modifying a temporary copy of a feature from a component table. For More Information... For more information about Drilldown layers, see the following. Related Methods and Properties The Layer.DrilldownAddFeatures method adds features to a Drilldown layer. The Layer.DrilldownRemoveFeatures method removes features from a Drilldown layer. The Layer.DrilldownReset method clears an entire Drilldown layer, then shows only one level of detail from the layer. The Layer.GetDrilldownFeaturesByID method retrieves Features given their IDs. To determine whether a layer is a Drilldown layer, test whether the Layer.Type property returns the value miLayerTypeDrilldown (value: 7). Related Constants The set of CursorConstants includes two constants (miDrilldownExpandCursor and miDrilldownContractCursor) specifically designed for Drilldown/RollUp tools. Use these constants with the Map.CreateCustomTool method. MapX Developer’s Guide 243 Chapter 14: Using Drilldown Layers 244 MapX Developer’s Guide Chapter 15: Exporting Map 15 Chapter Exporting Maps Often, the user may need to print out a map or incorporate the visual image of the map in another application. MapX has methods which allow you to send the contents of a map to the clipboard, to the printer, or to a graphics file. ➤ Exporting Maps ➤ ExportSelection Property ➤ Printing Maps Chapter 15: Exporting Maps Exporting Maps To export a map to a graphics file or copy a map’s contents to the clipboard, you would use the ExportMap method. Method Description Code Sample ExportMap Exports a map to a graphics file. Map1.ExportMap _ “C:\Map.TIF”,_ miFormatTIF ExportMap Exports a map to the clipboard. Map1.ExportMap “clipboard” Note: Optional parameters are in [square brackets] Map.ExportMap (Location, Format, [W], [H]) 246 Part Description Location File specification of the place to put the output. If the keyword ‘CLIPBOARD’ is used, the image is put on the clipboard. Format Output format. This takes an ExportFormatConstants value. W Width of output. This is a double value, and specifies width in terms of Paper Units (Map.PaperUnit). This is an optional parameter, and if not specified, Map.MapPaperWidth is used. H Height of output. This is a double value, and specifies height in terms of Paper Units (Map.PaperUnit). This is an optional parameter, and if not specified, Map.MapPaperHeight is used. MapX Developer’s Guide Chapter 15: Exporting Maps Format Constants Format Description miFormatWMF Metafile miFormatBMP Bitmap miFormatJPEG JPEG image miFormatTIF TIF miFormatGIF GIF Image miFormatPNG Portable Network Graphics miFormatPSD PhotoShop 'This sample demonstrates the Map.ExportMap method. It uses 'the method to place a map in the clipboard as a BMP. Map1.PaperUnit = miUnitCentimeter 'Export a 12 cm by 9 cm map to the clipboard in BMP Format Map1.ExportMap "clipboard", miFormatBMP, 12, 9 ExportSelection Property Utilizing the ExportSelection property of the map will allow you to control whether the selection pattern will export with the map. Look at the code sample to how this property property is used: 'Export a jpg image for display and include the selection highlighting in the image Map1.ExportSelection=True Map1.ExportMap "c:\temp\map.jpg", miFormatJPEG MapX Developer’s Guide 247 Chapter 15: Exporting Maps Printing Maps To print a map, use the PrintMap method. Note: The current map is drawn to fit the rectangle given. Best results are obtained when the aspect ratio of width to height is maintained. This method only prints out the contents of the MapX map; it doesn’t show any icons, toolbars, or menu items. You may want to print the form that contains the MapX control if you need to see additional controls on your output. Method Description Code Sample PrintMap Prints the map. Map1.PrintMap Printer.hDC, 0, 0, Map1.Width * 100, Map1.Height * 100 Map.PrintMap (hDC, x, y, w, h) 248 Parts Description hDC Printer device context. Can be any device context. x Upper left corner X in HIMETRIC units. y Upper left corner Y in HIMETRIC units. w Width in HIMETRIC units. h Height in HIMETRIC units. MapX Developer’s Guide Chapter 16: Working With Visual C++ 16 Chapter Working With Visual C++ ➤ Working With Visual C++ One way to learn MapX is to study sample applications. ➤ Upgrading C++ Applications from an Earlier Version of MapX Look for sample applications in the folder: MapInfo MapX > Samples40. ➤ Understanding the Sample Application ➤ Accessing MapX Properties and Methods in C++ ➤ Including MapX.cpp in Your Project ➤ Creating a MapX Control Using C++ ➤ Creating Menu Items Using C++ ➤ Handling MapX Events Using C++ ➤ Using Custom Tools (C++ example) ➤ Data Binding Using C++ ➤ Adding a Shortcut Menu Using C++ ➤ Using the Built-In Helper Dialogs from C++ ➤ Handling MapX Exceptions Using C++ ➤ Creating a Map in a C++ Dialog Chapter 16: Working With Visual C++ Understanding the Sample Application As you study the sample C++ application mapxsamp.cpp, the following topics will help you understand MapX. • Upgrading C++ applications from an earlier version of MapX • Accessing MapX Methods and Properties in C++ • Including Mapx.cpp in your project • Creating a MapX control • Creating menu items • Handling MapX events • Using custom tools • Data binding • Adding a shortcut menu • Using the built-in helper dialogs • Handling MapX Exceptions in C++ • Creating a map in a C++ dialog Note: These topics assume that you are using Microsoft’s Document/View model (standard MFC AppWizard app.) The sample application can be built in Developer Studio with mapxsamp.mdp. Tips for C++ Developers If you are using Visual C++ 5 or a later version, add the sample mapxsamp.cpp project to your workspace. That gives you quick access to the sample files and Class Wizard, right next to your own project files. You can delete the sample project from your workspace at any time. If you created a MapX application using an earlier version of MapX, see “Upgrading C++ applications from an earlier version of MapX.” 250 MapX Developer’s Guide Chapter 16: Working With Visual C++ Upgrading C++ Applications from an Earlier Version of MapX If you wrote a C++ application using an earlier version of MapX, you will need to use the new MapX wrapper classes (mapx.h and mapx.cpp) to upgrade your application to the current version of MapX. You may need to modify the strings that you pass to CreateDispatch. With an earlier version of MapX , you may have used a string to specify an object name; for example: Flds.CreateDispatch("MapX.Fields") With the current version of MapX, you need to specify a different string: Flds.CreateDispatch("MapX.Fields.4") To make your code more compatible with future versions of MapX, you may want to use GetClsid instead of a string. The result returned by GetClsid will work in current and futur versions of MapX. For example: Flds.CreateDispatch(Flds.GetClsid()) This change applies to all objects that you create. In the MapX object model, you can create stand-alone objects with these object classes:. AffineTransform BindLayer BitmapSymols CoordSys Datum Feature Fields LayerInfo Map ODBCQueryInfo Parts Point Points Rectangle RowValue RowValues Style MapX Developer’s Guide 251 Chapter 16: Working With Visual C++ Accessing MapX Properties and Methods in C++ Objects Each MapX object is implemented by a C++ class in the files MapX.h and MapX.cpp. The name of the C++ class is the same as the MapX object, prepended by 'CMapX'. For example, the DataSet object has a class called CMapXDataset. Properties The Properties of a MapX object are implemented by member functions in the C++ classes. A Read/write property like the 'Name' property of the Dataset object will have 2 member functions in CMapXDataSet—one to set the property value, and one to get the value of the property. The member function names will have 'Get' or 'Set' prepended to the property name. CString GetName(); void SetName(LPCTSTR); A read-only property will only have a 'Get' member function, and not a 'Set' member function. Methods The methods of a MapX object are implemented by a member function with the same name as the MapX object's method. You will notice that the types of many of the parameters will be 'const VARIANT &'. This means the member function is expecting a variable of type VARIANT to be passed to it. Optional Parameters Many methods have parameters that are considered 'optional' in Visual Basic or other scripting languages. In C++ all parameters must be specified when calling these methods (see below for overloaded methods). All optional parameters are implemented asVARIANTs. To call a MapX method with an optional parameter, you must set up the variant as follows: VARIANT vtOptional; vtOptional.vt = VT_ERROR; vtOptional.scode = DISP_E_PARAMNOTFOUND; The MapX.h file includes a helper class COptionalVariant that does this in its constructor. You can use this whenever you want to call a method with an optional parameter. 252 MapX Developer’s Guide Chapter 16: Working With Visual C++ Overload Member Functions In order to make it easier to call methods using normal C++ types instead ofVARIANTS, most of the MapX methods are overloaded with simpler parameters with default values that construct VARIANTs and call the 'real' member functions. Since not all possible combinations are handled, feel free to derive your own classes from the CMapX classes and add your own overloaded member functions. OLE Dispatch Driver The C++ classes in MapX.h are derived from the MFC class COleDisplatchDriver. All properties and methods ultimately end up calling IDispatch->Invoke() to tell the MapX ocx what to do. COleDisplatchDriver usually handles calling Release() correctly on the IDispatch pointers returned from properties or methods, but there are a few places where you should be careful. When a MapX object is passed to an event via its IDispatch interface, you must be sure not to release the pointer, because objects passed to events have not been AddRef()'d by MapX. Example: void CMapxSampleView::OnThemeModifyRequested(LPDISPATCH Theme) { try { CMapXTheme theme; COptionVariant vHelpFile, vHelpID;// mark as optional since we // don't have a helpfile theme.AttachDispatch(Theme, FALSE); // don't auto release theme.ThemeDlg(vHelpFile, vHelpID); } catch (COleDispatchException *e) { e->ReportError(); e->Delete(); } catch (COleException *e) { e->ReportError(); e->Delete(); } } MapX Developer’s Guide 253 Chapter 16: Working With Visual C++ Properties and Methods that Return Other Objects You can assign the return value of methods or properties that return objects directly to a variable of the same type. Example CMapXThemes objThemes = m_ctrlMapX.GetDatasets()[1L].GetThemes(); Example class CMapXDataset : public COleDispatchDriver { public: CMapXDataset() {}// Calls COleDispatchDriver default constructor CMapXDataset(LPDISPATCH pDispatch) : COleDispatchDriver(pDispatch) {} CMapXDataset(const CMapXDataset& dispatchSrc) : COleDispatchDriver(dispatchSrc) {} // Attributes public: CString GetName(); void SetName(LPCTSTR); long GetRowCount(); CMapXFields GetFields(); CMapXThemes GetThemes(); long GetGeoField(); long GetSecondaryGeoField(); CMapXLayer GetLayer(); short GetType(); // Operations public: void Refresh(); VARIANT GetValue(const VARIANT& Row, const VARIANT& Column); VARIANT GetValue(long Row, long Column) { return GetValue(COleVariant(Row), COleVariant(Column)); } VARIANT GetValue(long Row, LPCTSTR Column) { return GetValue(COleVariant(Row), COleVariant(Column)); } CMapXSourceRows GetSourceRows(const VARIANT& Row); CMapXSourceRows GetSourceRows(long Row) { return GetSourceRows(COleVariant(Row)); }}; 254 MapX Developer’s Guide Chapter 16: Working With Visual C++ Including MapX.cpp in Your Project Include the MapX.cpp and .h files in your project. They contain the class definitions and method implementations for access to the MapX control. The MapX.h and MapX.cpp files can be found in the Samples40\CPP subdirectory where MapX is installed. Using Visual C++ Version 4 From the Insert menu, choose Files Into Project. Choose MapX.cpp as the file to insert. Note: Do not choose the Insert > Component command. Doing so would create a .cpp file, but it would be incomplete. Using Visual C++ Version 5 or Later From the Project menu, choose Add To Project > Files. Choose MapX.cpp as the file to add. Caution! Do not choose Project > Components And Controls command. Doing so would create a .cpp file, but it would be incomplete. MapX Developer’s Guide 255 Chapter 16: Working With Visual C++ Creating a MapX Control Using C++ Include the control in the view that will contain it: class CMapxSampleView : public CView { : : : protected: CMapX m_ctrlMapX; : : } To declare a constant to represent the control ID for MapX: 1. Go to View > Resource Symbols. 2. Click NEW. 3. Type "IDC_MAP" for the name. To create handlers for the WM_SIZE and WM_CREATE messages in the class Wizard: 1. Go to View > ClassWizar 2. Select your View class from the class Name combo-box. 3. In the message box, click on "WM_CREATE", and click Add Function. 4. Still, in the message box, choose "WM_SIZE" and click Add Function. 5. Then, click Edit Code. Create the control when the view is created. In CMapXSampView::OnCreate: // create map with default size // resize message will cause it to be // size to the client area of the view m_ctrlMapX.Create(NULL, WS_VISIBLE, CRect(0,0,100,100), this, IDC_MAP); Keep the control's size in sync with the containing window: // resize the map to be the same size as our client area void CMapxSampleView::OnSize(UINT nType, int cx, int cy) { CView::OnSize(nType, cx, cy); if (cx != 0 && cy != 0) m_ctrlMapX.MoveWindow(0,0,cx,cy,TRUE); } 256 MapX Developer’s Guide Chapter 16: Working With Visual C++ Create a new message header for the WM_SETFOCUS message as you did for the WM_CREATE message. In our example, we want to make sure that MapX gets the focus whenever the window is active: void CMapxSampleView::OnSetFocus(CWnd* pOldWnd) { CView::OnSetFocus(pOldWnd); m_ctrlMapX.SetFocus(); } Creating Menu Items Using C++ You can expose MapX capabilities by creating a menu for the Doc/View that contains the MapX control. Reference the menu where the doc template is created (mapxsamp.cpp): CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate( IDR_MAPXSATYPE, //Menu items to control MapX RUNTIME_CLASS(CMapxSampleDoc), RUNTIME_CLASS(CChildFrame), //custom MDI child frame RUNTIME_CLASS(CMapxSampleView)); AddDocTemplate(pDocTemplate); Add handlers for the MapX menu items. In the sample, these menu items are defined in the menu section in mapxsamp.rc. Note that in this example, we use menu commands as a quick demonstration of the map interaction tools (Zoom In tool, Radius Select tool, etc.). In a more polished application, you would probably use toolbar buttons as the user interface, rather than menu commands. "Previous &View", "View &Entire Map", SEPARATOR "&Properties...", ID_CONTEXT_PREVIOUSVIEW ID_VIEW_VIEWENTIREMAP "&Layer Control...", SEPARATOR "&Toolbar", "&Status Bar", ID_VIEW_LAYERCONTROL MapX Developer’s Guide ID_VIEW_PROPERTIES ID_VIEW_TOOLBAR ID_VIEW_STATUS_BAR 257 Chapter 16: Working With Visual C++ "&Arrow", SEPARATOR "Zoom &In", "Zoom &Out", "&Pan", "&Center", SEPARATOR "&Select", "&Radius Select", "R&ectangle Select", ID_MAP_TOOL_ARROW ID_MAP_TOOL_ZOOMIN ID_MAP_TOOL_ZOOMOUT ID_MAP_TOOL_PAN ID_MAP_TOOL_CENTER ID_MAP_TOOL_SELECT ID_MAP_TOOL_RADIUSSELECT ID_MAP_TOOL_RECTANGLESELECT Once these menu item IDs are defined, handlers can be added via Class Wizard. In your class containing the MapX control, create handlers for ID_MAP_TOOL_ARROW, ID_MAP_TOOL_ZOOMIN, etc. // tell MapX what the current tool is void CMapxSampleView::OnMapToolArrow() { m_ctrlMapX.SetCurrentTool(miArrowTool); } void CMapxSampleView::OnMapToolZoomin() { m_ctrlMapX.SetCurrentTool(miZoomInTool); } // switch to the previous view void CMapxSampleView::OnContextPreviousview() { m_ctrlMapX.ZoomTo(m_dPrevZoom, m_dPrevX, m_dPrevY); } Once the tool is selected, built-in MapX functionality handles the zooming, selecting, etc. 258 MapX Developer’s Guide Chapter 16: Working With Visual C++ Handling MapX Events Using C++ To handle MapX events, you first need to build an eventsink map for the events you are interested in. Constants for the event DISPATCH id’s are defined in MapX.h for MapX custom events, and in <olectl.h> for OLE stock events. // From #define #define #define #define #define #define #define #define #define #define #define // From #define #define #define #define #define #define #define #define #define MapX.h MAPX_DISPID_SELECTION_CHANGED 0x1 MAPX_DISPID_RESOLVEDATABIND 0x2 MAPX_DISPID_TOOLUSED 0x3 MAPX_DISPID_REQUESTDATA 0x4 MAPX_DISPID_DATAMISMATCH 0x5 MAPX_DISPID_MAPVIEWCHANGED 0x6 MAPX_DISPID_ANNOTATIONADDED 0x7 MAPX_DISPID_ANNOTATIONCHANGED 0x8 MAPX_DISPID_THEMEMODIFYREQUESTED 0x9 MAPX_DISPID_DRAWUSERLAYER 0x0a MAPX_DISPID_POLYTOOLUSED 0x0b <olectl.h> DISPID_CLICK (-600) DISPID_DBLCLICK (-601) DISPID_KEYDOWN (-602) DISPID_KEYPRESS (-603) DISPID_KEYUP (-604) DISPID_MOUSEDOWN (-605) DISPID_MOUSEMOVE (-606) DISPID_MOUSEUP (-607) DISPID_ERROREVENT (-608) The ON_EVENT macro in the EVENT_SINK also specifies an ID for the MapX control (IDC_MAP in the example), the parameters to the event, and the name of the event handler method. In the View header file (her, MapXSampView.h), put the line "DECLARE_EVENTSINK_MAP ()" below the "DECLARE_MESSAGE_MAP" line. From mapxsampview.cpp: BEGIN_EVENTSINK_MAP(CMapxSampleView, CView) ON_EVENT(CMapxSampleView, IDC_MAP, DISPID_MOUSEMOVE, OnMouseMoveInMap,VTS_I2 VTS_I2 VTS_XPOS_PIXELS VTS_YPOS_PIXELS) ON_EVENT(CMapxSampleView, IDC_MAP, MAPX_DISPID_MAPVIEWCHANGED, OnMapViewChanged, VTS_NONE) MapX Developer’s Guide 259 Chapter 16: Working With Visual C++ ON_EVENT(CMapxSampleView, IDC_MAP, DISPID_MOUSEUP, OnMouseUpInMap, VTS_I2 VTS_I2 VTS_XPOS_PIXELS VTS_YPOS_PIXELS) ON_EVENT(CMapxSampleView, IDC_MAP, MAPX_DISPID_TOOLUSED, OnToolUsed, VTS_I2 VTS_R8 VTS_R8 VTS_R8 VTS_R8 VTS_R8 VTS_BOOL VTS_BOOL VTS_PBOOL) ON_EVENT(CMapxSampleView, IDC_MAP, MAPX_DISPID_THEMEMODIFYREQUESTED, OnThemeModifyRequested, VTS_DISPATCH) END_EVENTSINK_MAP() The event handler code for the OnToolUsed event follows. The declaration, from mapxsampview.h: void OnToolUsed(short ToolNum, double X1, double Y1, double X2, double Y2, double Distance, BOOL Shift, BOOL Ctrl, BOOL* EnableDefault); …and the implementation from mapxsampview.cpp (we just output the parameters to the debug window using the TRACE macro): void CMapxSampleView::OnToolUsed(short ToolNum, double X1, double Y1, double X2, double Y2, double Distance, BOOL Shift, BOOL Ctrl, BOOL* EnableDefault) { CString str; str.Format("Tool=%d, [%f,%f] [%f, %f], dist=%f, %s %s\n", ToolNum, X1,Y1,X2,Y2,Distance, (Shift)?"Shift":"",(Ctrl)?"Ctrl":""); TRACE(str); } You would normally handle custom tools in this function, or override MapX's default behavior for built-in tools. For an example, see “Using Custom Tools”. Note: For events in which objects are passed as parameters, the event handler should not change the reference count of the object. For an example, see “Handling MapX Exceptions”. 260 MapX Developer’s Guide Chapter 16: Working With Visual C++ Using Custom Tools (C++ example) Once you have used the CreateCustomTool method to create custom tools, use the ToolUsed event to carry out an action when the user uses the custom tool. This example tests to see which tool is being used. Then, depending on which tool is in use, this example either: • Changes the style of the map feature underneath the cursor, or • Places a new symbol where the user clicked. void CMapxSampleView::OnToolUsed(short ToolNum, double X1, double Y1, double X2, double Y2, double Distance, BOOL Shift, BOOL Ctrl, BOOL* EnableDefault) { CString str; CMapXPoint pnt; str.Format("Tool=%d, [%f,%f] [%f, %f], dist=%f, %s %s\n", ToolNum, X1,Y1,X2,Y2,Distance, (Shift)?"Shift":"",(Ctrl)?"Ctrl":""); TRACE(str); // change the style of the feature under the cursor if (ToolNum == MAP_TOOL_CHANGESTYLE) { try { // Need the dispatch to use the point if (pnt.CreateDispatch(pnt.GetClsid())) { pnt.Set(X1, Y1); } else { // something went wrong, can't use the point... AfxThrowOleException(CO_E_CLASS_CREATE_FAILED); } CMapXLayers layers = m_ctrlMapX.GetLayers(); // Get the USA feature under the cursor CMapXFeatures ftrs = layers.Item("USA").SearchAtPoint(LPDISPATCH(pnt)); // work on only the first feature CMapXFeatureftr = ftrs.Item(1); // get the style object from the feature CMapXStylestyle = ftr.GetStyle(); MapX Developer’s Guide 261 Chapter 16: Working With Visual C++ style.SetRegionBackColor(255); // update the feature in the layer ftr.Update(); } catch (COleDispatchException *e) { e->ReportError(); e->Delete(); } catch (COleException *e) { e->ReportError(); e->Delete(); } } // place a new symbol at the point clicked on else if (ToolNum == MAP_TOOL_NEWPOINT) { try { CMapXLayers layers = m_ctrlMapX.GetLayers(); CMapXFeatureftr; // Need the dispatch id to use the feature if (ftr.CreateDispatch(ftr.GetClsid())) { // Symbol feature ftr.SetType(miFeatureTypeSymbol); // Get the point object from the feature // and call the Set method ftr.GetPoint().Set(X1, Y1); // Add it to the layer layers.Item("USA").AddFeature(ftr); } else { AfxThrowOleException(CO_E_CLASS_CREATE_FAILED); } } catch (COleDispatchException *e) { e->ReportError(); e->Delete(); } catch (COleException *e) { e->ReportError(); e->Delete(); } } } 262 MapX Developer’s Guide Chapter 16: Working With Visual C++ Data Binding Using C++ The CMapXSample app has databinding examples for the following dataset types: miDataSetDAO, miDataSetODBC, miDataSetUnbound, miDataSetGlobalHandle. The examples also show how to use dynamic databinding, add a layer of XY points, ZIP Code matching, and auto matching. See the mapxsampview.cpp file to examine the examples. Below is one of the menu command handlers for adding data from a file using the miDataSetGlobalHandle type. The format of the data needs to be: quotes around strings, tabs between fields, and carriage return/line feed at the end of the record. For example: "\"NY\"\t105.34\t100\t1\r\n" "\"MA\"\t245.19\t200\t2\r\n" "\"NY\"\t195.0\t300\t3\r\n" "\"AK\"\t195.0\t125\t4\r\n" "\"CA\"\t56.453\t200\t5\r\n"; Note that this type of data binding (miDataSetGlobalHandle) is only one of several dataset types that are supported. The function CMapxSampleView::OnMapAdddata() handles a menu item on the Map menu. It prompts for a filename containing data in the form specified above, reads the file, and adds this to the map's collection of datasets. void CMapxSampleView::OnMapAdddata() { : : CFileDialog dlgFile(TRUE, "*.txt", NULL, 0, szDataFilter, this); if (dlgFile.DoModal() == IDCANCEL) return; // User cancelled the dialog // Read file into a string, and copy it to a global memory buffer : : // Allocate the memory buffer, copy the string into it : : // Declare the variables that will be parameters to // DataSets.Add() short Type; MapX Developer’s Guide 263 Chapter 16: Working With Visual C++ VARIANT SourceData, Name, GeoField, SecondaryGeoField, BindLayerName, Fields; CString strName= "TestData"; // set up optional parameters; most will not be used // Note: you could also use the line //COptionalVariant SecondaryGeoField; // instead SecondaryGeoField.vt = VT_ERROR; SecondaryGeoField.scode = DISP_E_PARAMNOTFOUND; // let mapx auto detect geofield GeoField.vt = VT_ERROR; GeoField.scode = DISP_E_PARAMNOTFOUND; // let mapx find which layer to bind to BindLayerName.vt = VT_ERROR; BindLayerName.scode = DISP_E_PARAMNOTFOUND; // use all fields with defaults Fields.vt = VT_ERROR; Fields.scode = DISP_E_PARAMNOTFOUND; // set the name of our dataset Name.vt = VT_BSTR; // Remember to SysAlloc() the string; it's going into a BSTR Name.bstrVal = strName.AllocSysString(); // set up source data - no error checking on alloc Type = miDataSetGlobalHandle; SourceData.vt = VT_I4; SourceData.lVal = (long)hGlobalData; try { // now add the dataset to the datasets collection CMapXDataset ds = m_ctrlMapX.GetDatasets().Add(Type, SourceData, Name, GeoField, SecondaryGeoField, BindLayerName, Fields); } catch (COleDispatchException *e) { e->ReportError(); e->Delete(); } SysFreeString(Name.bstrVal) } 264 MapX Developer’s Guide Chapter 16: Working With Visual C++ Adding a Shortcut Menu Using C++ The DISPID_MOUSEUP event allows us to add a shortcut (right mouse button) menu. Create a menu resource for your shortcut menu (IDR_CONTEXTMENU in the sample app.) The OnMouseUpInMap handler looks like this: // if right mouse button, display the context menu BOOL CMapxSampleView::OnMouseUpInMap( short Button,short Shift,OLE_XPOS_PIXELS x,OLE_YPOS_PIXELS y) { if (Button == 2) { // right button CMenu menu; // top-level menu CMenu *pMenu=NULL; // pop-up menu // Load the menu resource. menu.LoadMenu(IDR_CONTEXTMENU); // TrackPopupMenu cannot display the top-level menu, so get // the handle of the first pop-up menu. pMenu = menu.GetSubMenu(0); if (!pMenu) { return TRUE; } SetMenuDefaultItem(pMenu->m_hMenu, ID_VIEW_PROPERTIES, FALSE); // Display the floating pop-up menu. Track the right mouse // button on the assumption that this function is called // during WM_CONTEXTMENU processing. POINT pt; GetCursorPos(&pt); pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, this, NULL); // Destroy the menu. menu.DestroyMenu(); } return TRUE; } MapX Developer’s Guide 265 Chapter 16: Working With Visual C++ Using the Built-In Helper Dialogs from C++ Using built-in helper dialogs is easy. There is a menu item to call the MapX Properties dialog. It can be hooked up to the handler with ClassWizard; here's what ClassWizard puts into mapxsamp.cpp: ON_COMMAND(ID_VIEW_PROPERTIES, OnViewProperties) And the handler: void CMapxSampleView::OnViewProperties() { // easiest way to bring up property page try { m_ctrlMapX.PropertyPage(); } catch (COleDispatchException *e) { e->ReportError(); e->Delete(); } catch (COleException *e) { e->ReportError(); e->Delete(); } } Note: It is not recommended that you include the property page in your finished application. It is a great help when writing and debugging applications, but it is not intended to be used by the end-user because it provides direct access to too many properties and is not configurable. Use the stock dialogs (such as LayersDlg) instead. 266 MapX Developer’s Guide Chapter 16: Working With Visual C++ Similarly, the Layer Control Dialog: void CMapxSampleView::OnViewLayercontrol() { try { // mark as optional since we don't have a helpfile COptionalVariant vHelpFile, vHelpID; CMapXLayers layers = m_ctrlMapX.GetLayers(); layers.LayersDlg(vHelpFile, vHelpID); } catch (COleDispatchException *e) { e->ReportError(); e->Delete(); } catch (COleException *e) { e->ReportError(); e->Delete(); } } Handling MapX Exceptions Using C++ MapX reports most errors by reporting (throwing) a COleDispatchException. It is important that you catch the exceptions when calling MapX, because the default exception handler for MFC does not catch them and your application will exit. It is also very useful to display the description of the errors in a MessageBox. The text of the error message will help you to determine if you are using a MapX feature improperly, or if some other problem has occurred. The COleDispatchException class also includes the error code in the public member m_wCode, so that your program can identify and handle different types of errors. For a list of error codes and their descriptions, see the MapX Error Codes appendix of the Reference Guide. If there is a general OLE error when trying to call MapX (as could happen if you are using an out-of-date version of MapX.h or MapX.cpp) MFC throws a COleException. It is recommended that you catch both exception types when calling MapX. MapX Developer’s Guide 267 Chapter 16: Working With Visual C++ MapX can also (although rarely) pass errors in the Error event. This only happens if there is some kind of error during asynchronous processing (like a redraw) that wasn’t directly called from a MapX property or method. In this example, in the Event handler of the ThemeModifyRequested event, we are displaying the stock Theme property dialog to let the user change the theme colors, etc. Note the exception handling. // Note: in objects passed to events, the event handler // does not change the reference count // ie: do not call release on the object void CMapxSampleView::OnThemeModifyRequested(LPDISPATCH Theme) { try { CMapXTheme theme; COptionalVariant vHelpFile, vHelpID; // mark as optional since we don't have a helpfile theme.AttachDispatch(Theme, FALSE); // don't auto release theme.ThemeDlg(vHelpFile, vHelpID); // could decide to bring up legend dlg here instead //CMapXLegend leg(theme.GetLegend()); //leg.LegendDlg(vHelpFile, vHelpID); } catch (COleDispatchException *e) { e->ReportError(); e->Delete(); } catch (COleException *e) { e->ReportError(); e->Delete(); } } 268 MapX Developer’s Guide Chapter 16: Working With Visual C++ Creating a Map in a C++ Dialog 1. Insert MapX into the dialog. • In the resource editor for the dialog template where you want to insert MapX, right-click and choose ‘Insert OLE Control’ from the menu. Then choose MapInfo MapX V4. 2. Create a CDialog derived class for the dialog. • Highlight MapX and press Ctrl+W to bring up ClassWizard. Choose Create A New Class if prompted, and enter a name for the dialog (the sample uses ‘CSampleDlg’). Press OK to create the SampleDlg.h and SampleDlg.cpp files. 3. Add CMapX as a member of the dialog class. • First, #include "MapX.h" in the dialog’s header file, and then add a member variable for MapX. Note: Do not use Class Wizard-generated wrapper classes for MapX. They are incomplete. Use the MapX.h and MapX.cpp files included with MapX in the Sample40\CPP directory. Example #include "MapX.h" ///////////////////////////////////////////////////////////// // CSampleDlg dialog class CSampleDlg : public CDialog { // Construction public: CSampleDlg(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CSampleDlg) enum { IDD = IDD_MAPXDLG }; //}}AFX_DATA . : CMapX m_ctrlMapX; . : }; MapX Developer’s Guide 269 Chapter 16: Working With Visual C++ Use DDX_Control to Link the Wrapper Class to the MapX Control Insert a line in the DoDataExchange method of the dialog class using DDX_Control as follows: void CSampleDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CSampleDlg) DDX_Text(pDX, IDC_STATICX, m_strX); DDX_Text(pDX, IDC_STATICY, m_strY); //}}AFX_DATA_MAP // IDC_MAP1 is the ID given to the mapx control when it // was inserted into the dialog template. DDX_Control(pDX, IDC_MAP1, m_ctrlMapX); } Use MapX Properties, Methods and Objects to Manipulate the Map // example use of mapx to create a temporary layer and create // some custom mapx tools to be used later. BOOL CSampleDlg::OnInitDialog() { CDialog::OnInitDialog(); try { m_ctrlMapX.SetZoom(1000); // zoom in to 1000 miles // create temporary layer on top for drawing on. CMapXLayer layer = m_ctrlMapX.GetLayers().CreateLayer("scratch layer",NULL,1); // make it the animation layer m_ctrlMapX.GetLayers().SetAnimationLayer(layer); // create some custom tools for object drawing m_ctrlMapX.CreateCustomTool(MYTOOL_SYMBOL, miToolTypePoint, miCrossCursor); m_ctrlMapX.CreateCustomTool(MYTOOL_LINE, miToolTypePoly, miCrossCursor); m_ctrlMapX.CreateCustomTool(MYTOOL_REGION, miToolTypePoly, 270 MapX Developer’s Guide Chapter 16: Working With Visual C++ miCrossCursor); m_ctrlMapX.CreateCustomTool(MYTOOL_TEXT, miToolTypePoint, miIBeamCursor); m_ctrlMapX.SetCurrentTool(MYTOOL_REGION); } catch (COleDispatchException *e) { e->ReportError(); e->Delete(); } catch (COleException *e) { e->ReportError(); e->Delete(); } return TRUE; // return TRUE unless you set the focus to a //control. EXCEPTION: OCX Property Pages should // return FALSE } Use Class Wizard to Handle Events Handling MapX events in a dialog is very easy. Just use the Class Wizard ‘Message Maps’ tab, highlight the ID for MapX (IDC_MAP1), and the Events are listed. Highlight an event and press the ‘Add Function’ button, and Class Wizard adds the event handler and EVENT_SINK entries to your dialog class automatically. MapX Developer’s Guide 271 Chapter 16: Working With Visual C++ 272 MapX Developer’s Guide Chapter 17: Distributing Your MapX Application Distributing Your MapX Application 17 Chapter ➤ Distributing Your MapX Application ➤ MapX Customer Installation ➤ Installing the MapX OCX The MapX product you have purchased from MapInfo is a developer's kit. It contains the MapX OCX, sample programs, an on-line help file, some sample maps and geosets, and various utilities and other support files. This chapter deals with distributing your MapX application(s) to your users. ➤ Installing Raster Format Handlers ➤ Installing Maps and Geosets ➤ Adding Keys to the Windows Registry ➤ Passing in the MapX License String Chapter 17: Distributing Your MapX Application MapX Customer Installation When you deliver your application to customers, you need to install several things. They are: • The software you created. • MapX control, and its related support files. • Maps and geosets that are used by your application. Ideally you will incorporate the installation of MapX into your installation procedure, so that your end user won’t need to perform a separate installation to install MapX. There are four main steps to installing and distributing MapX applications: 1. Install the necessary files onto your user's computer. 2. Run utilities (such as regsvr32.exe) to register specific files on the user's system. 3. Add specific keys to the Windows registry 4. Pass in the MapX license string at application runtime. The files that are installed with MapX can be divided into the following categories: Required files: • MapX OCX and its dependent dlls • Windows system files: including fonts, MFC, and OLE dlls Optional files: • Dataset drivers (used for databinding) • Import/Export raster handlers • Maps and Geosets The Installshield sample provided on the MapX Installation CD only illustrates how to install the required files. This chapter will cover installation requirements for both the required and optional files. 274 MapX Developer’s Guide Chapter 17: Distributing Your MapX Application Installing the MapX OCX If you have installed MapX on your own computer, it’s easy to get a rough idea of how many files are used by MapX. In previous versions of MapX, all of the files were installed under the old MapX program directory (which defaults to: \Program Files\MapInfo MapX\Program). MapX v4.0 and later installs the program files under the following path: \Program Files\Common Files\MapInfo Shared\MapX Common. This directory is the recommended location for the MapX required files, whereas all of the files necessary for your application should go under a directory meaningful to the end user and your specific application. Some of the MapX required files are Windows common dlls and should be located in the System directory. For example, MapX uses MFC42 and OLEAUT32 dlls that reside in the Windows System directory. MapX Required Files Windows Common DLLs Installed to the Windows\System directory. Do a version check before replacing these files. If you have an older version, files may be in use during the replace operation. You will need to reboot if that is the case. Mfc42.dll msvcp60.dll Olepro32.dll oleaut32.dll MapX Developer’s Guide msvcrt.dll 275 Chapter 17: Distributing Your MapX Application MapX Program Files Installed to the \Program Files\Common Files\MapInfo Shared\MapX Common folder. These files do not need to be registered. ALLTYPE.DLL AllTypeRes.dll ColLookupSystem.dll CommandProcessor.dll CommandProcessorRes.dll COMPILER.DLL COORDSYS.DLL CoordSysRes.dll CustomProperties.dll DAENGINE.DLL DAEngineRes.dll DBINFO.DLL DBInfoRes.dll DBLAYER.DLL DBLayerRes.dll ExprPacket.dll ExprPacketCreator.dll ExprPacketCreatorRes.dll ExprPacketRes.dll FcnInfoServer.dll FcnInfoServerres.dll FIND.DLL FINDRES.DLL GEO.DLL Tools.dll UTILITY.DLL UtilityRes.dll Installed to the \Program Files\Common Files\MapInfo Shared\MapX Common folder. Registered using Regsvr32.exe • Mapx40.ocx Installed to the Windows\Fonts (for Windows 95 and Windows NT 4.0) folder Fonts must also be registered with Windows. If you are using a third-party software package to create your installer, that package might handle font registration for you. Otherwise, you can register fonts manually, by calling the Win32 AddFontResource routine. 276 ARIAL.TTF MAPIS___.TTF MAPSYM.TTF TTMIAR__.TTF TTMICG__.TTF TTMIMI__.TTF TTMIOG__.TTF TTMIOS__.TTF TTMIRE__.TTF TTMITC__.TTF TTMIWE__.TTF MapX Developer’s Guide Chapter 17: Distributing Your MapX Application Optional Files NADCON Support Files Installed to the \Program Files\Common Files\MapInfo Shared\MapX Common folder. Required if you intend to support NADCON conversions from the NAD 27 to, and from, the NAD 83 coordinate systems. ALASKA.LAS ALASKA.LOS CONUS.LAS CONUS.LOS HAWAII.LAS HAWAII.LOS PRVI.LAS PRVI.LOS TGEORGE.LAS STGEORGE.LOS STLRNC.LAS STLRNC.LOS STPAUL.LAS STPAUL.LOS Bitmap Symbols Installed to the \Program Files\Common Files\MapInfo Shared\MapX Common\CustSymb folder. TOWE1-32.BMP POLI1-32.BMP MBOX2-32.BMP GOLF1-32.BMP TOWE2-32.BMP GLOB1-32.BMP PIN6-32.BMP MBOX1-32.BMP Raster Image Support Installed to the \Program Files\Common Files\MapInfo Shared\MapX Common folder. ODBC Support Installed to the \Program Files\Common Files\MapInfo Shared\MapX Common folder. Registered with Regsvr32.exe. • MODBCDataset.dll • MMapXColumnInfo.dll Registered with RegTypLib.exe • mdatasetint.tlb MapX Developer’s Guide 277 Chapter 17: Distributing Your MapX Application Notes Document Support Installed to the \Program Files\Common Files\MapInfo Shared\MapX Common folder. Registered with Regsvr32.exe. • MNotesDataset.dll • MMapXColumnInfo.dll Registered with RegTypeLib.exe • mdatasetint.tlb The sample Installshield program installs the above files. The sample can be found on the MapX SDK CD or can be downloaded from the MapX website (www.mapx.com). Registering Files and Installing Dataset Drivers As mentioned in the preceding table, some files need to be ‘registered’, and this is done by running the utility regsvr32.exe: • regsvr32 /s <filespec of mapx.ocx> • regsvr32 /s <filespec of olepro32.dll> • regsvr32 /s <filespec of oleaut32.dll> If your application uses either the ODBC or the Notes data driver, you must register the typelibrary as follows: • regtyplib <filespec of mdatasetint.tlb> The dataset drivers allow MapX to bind data to a map layer. For more information regarding databinding, please see Chapter: "Putting Your Data on a Map". This table illustrates the various options for data binding and any additional installation requirements: 278 Dataset source type Dataset drivers Installation requirements Lotus Notes Mnotesdataset.dll Notes dataset driver requires nnotes.dll to be locatable through the system path. ODBC Modbcdataset.dll Odbc32.dll must exist in system path Delphi v3 MgenDSetDrvr.dll, DSLIBP.DLL Delphimm.dll and Borlndmm.dll must exist in system path MapX Developer’s Guide Chapter 17: Distributing Your MapX Application Dataset source type Dataset drivers Installation requirements Delphi v4 MgenDSetDrvr.dll, Dslibp4.dll Borlndmm.dll must exist in system path Safe Array MsafeArrayDataset.dll ADO v2.0 MapXADODS.dll RDO v2.0 MapXRDODS.dll MapInfo ODBC Miodbc.dll Oracle 8i Spatial Mioci.dll Odbc32.dll must exist in system path Oracle Express Objects Installing Raster Format Handlers MapX also allows the developer to incorporate raster images into their application. A MapX application may open or write to various raster image types. The appropriate drivers must be included when distributing your application. MapX can use 1 of many different libraries to load a raster image. When a raster image is loaded by MapX, it will search for these DLLs and ask if the given file can be read by that DLL. If so, MapX knows which DLL is format handling for the file. The format handlers will be named "xxxxxxxx.RHx". The base part of the name is based on the format. The extension always begins with RH, but can end in any letter (A-Z). When searching for a format handler, MapX starts with RHA, then RHB, and so forth until RHZ. This allows MapX to prioritize which handlers are in use. For example, SPOT files need to be checked before any other formats because they are raw data that can be confused with other formats. The SPOT handler's extension is RHD. The Halo format handlers (those standard/built in) are named RHV. The Lead Tools are named RHX. The LEADTOOLS Win32 Pro provided by ©LEAD Technologies, Inc and HALO Imaging libraries provided by Media Cybernetics are included with MapX.You may use either of these to display the most raster files in MapX. LeadTools will load the entire raster image into memory at the time the image is referenced in MapX. This means that the image will take longer to load, but panning and zooming will be faster. HALO will only load what it needs to MapX Developer’s Guide 279 Chapter 17: Distributing Your MapX Application display into memory, so it will load the image faster, but panning and zooming will be slower. By default, HALO will be attempted first. You may change this order by either not including the HALO libraries when distributing your application, or by renaming the LeadTools handler extension from .rhx to .rhu or anything else not used before the letter “x”. There may also be some formats that are not supported by either library and therefore will have their own separate library. Note: All of these raster handlers should be installed in the same directory as the MapX OCX, which is usually found in the MapX common directory: \Program Files\Common Files\MapInfo Shared\MapX Common. Here is a list of handlers included with MapX: Format Handler Required files All raster types Lead Tools Migeoreg.dll, MIRASTER.DLL LTFIL70N.DLL, LTKRN70N.DLL, leadtool.rhx Halo Libraries Halo.rhv, mihiffl.dll TIF TIFF.RHL All raster types Migeoreg.dll, MIRASTER.DLL LTFIL70N.DLL, LTKRN70N.DLL, leadtool.rhx Lead Tools 280 Supported raster types JPG-LFCMP70N.DLL, GIF-LFGIF70N.DLL, TIF-LFTIF70N.DLL, LFFAX70N.DLL PNG- LFPNG70N.DLL, PSD- LFPSD70N.DLL, WMF-LFWMF70N.DLL, BMP-LFBMP70N.DLL BMP-miffbmp.dll, GIF-miffgif.dll, JPG-miffjpeg.dll, PCX-miffpcx.dll, TARGA-mifftga.dll, TIF-mifftiff.dll Or you may use the TIF library provided by Lead Tools or Halo. JPG-LFCMP70N.DLL, GIF-LFGIF70N.DLL, TIF-LFTIF70N.DLL, LFFAX70N.DLL PNG- LFPNG70N.DLL, PSD- LFPSD70N.DLL, WMF-LFWMF70N.DLL, BMP-LFBMP70N.DLL MapX Developer’s Guide Chapter 17: Distributing Your MapX Application Format Handler Required files Supported raster types Halo Libraries Halo.rhv, mihiffl.dll TIF TIFF.RHL BMP-miffbmp.dll, GIF-miffgif.dll, JPG-miffjpeg.dll, PCX-miffpcx.dll, TARGA-mifftga.dll, TIF-mifftiff.dll Or you may use the TIF library provided by Lead Tools or Halo. SPOT MRSID All Grid types Spot.rhd Mrsid.rhe MIGRID.DLL, MIRASTER.DLL MIG.GHL MapInfo GRID and Hillshading SID-MRSID32.DLL MIG-GRIDDLL.DLL Installing Maps and Geosets Registering a geoset is a convenient way of registering each MapInfo table associated with that geoset into the GeoDictionary. By registering a MapInfo table in the GeoDictionary, that table can be used for autobinding. For more information on autobinding, please see Chapter: "Putting your Data on a Map". If determined that you need to use the GeoDictionary, when you register a geoset, GeoDictionaryManager40.exe adds appropriate entries into the Geodictionary (geodict.dct). If the Geodictionary does not exist, GeoDictionaryManager40.exe creates it. • GeoDictionaryManager40.exe <full filespec (with drive) of geoset> This step must be done after all of the geosets and associated tables are installed on the user’s machine. Double-check your geoset to see what the expected paths are for each table. For example, if you created a geoset using MapInfo tables on different areas of your hard drive, the geoset will specify the full path to anything not in the same directory as the geoset. If redistributing this geoset, the tables will have to be found in the same paths as the original geoset. To avoid this problem, copy all MapInfo tables into the same directory prior to creating the geoset. Then create the geoset in the same directory. MapX Developer’s Guide 281 Chapter 17: Distributing Your MapX Application Adding Keys to the Windows Registry MapX also uses the following three registry keys that your installer must create on the end user's system, if they do not exist already. MapX creates these three keys when you install MapX on your system. Therefore, if you want to see what these registry keys should look like, view your system's registry using a utility such as regedit.exe. Key Description HKEY_LOCAL_MACHINE\Software\ MapInfo\MapX\4.0 GeoDictionary String – The GeoDictionary key has the file specification for the geodictionary file. Example: C:\Program Files\myappdir\Maps\GeoDict.DCT HKEY_LOCAL_MACHINE\Software\ MapInfo\MapX\4.0 SearchPaths String – The SearchPaths key has semicolondelimited file specifications of where map files and geosets may exist; it defaults to an empty string ("") other than in the directory specified in the GeoDictionary key. HKEY_LOCAL_MACHINE\Software\ MapInfo\MapX\4.0 CommonDLLDir String – Has the location of the folder where the OCX and support files are Located. Example: \Program Files\Common Files\MapInfo Shared\MapX Common Note: The GeoDictionary path is used when adding a geoset to the MapX object without specifying the full path of the Geoset and when using autobinding. In addition, the SearchPaths key is not necessary if not using the GeoDictionary. Please see the section in this chapter entitled “Installing Maps and Geosets” to determine whether these keys are necessary for your application. 282 MapX Developer’s Guide Chapter 17: Distributing Your MapX Application Passing in the MapX License String In order to instantiate a runtime version of MapX on your user’s computer, the license string must be passed in at the time of object creation during the executing of your application. Note: If you are using MapX in a dialog with Visual C++, VisualBasic, or Delphi, MapX is created with the correct license string. In these cases you can skip this section. However, if you are creating the MapX control using the CMapX::Create() method in Visual C++, or using PowerBuilder, you must take this extra step. Visual C++ Again, if using MapX in a dialog in Visual C++, you do NOT need to perform this step. In order to successfully create the MapX object, you must pass the license string as the bstrLicKey parameter to CMapx::Create(). The example below shows how to do this. You must copy the first line from the MapX40.lic file that you received with the MapX development kit to use in place of the license string below. Note: For more information on creating MapX applications with C++ in the Visual Studio environment, see Chapter: "Working with Visual C++". Example in C++ BOOL CMapxSampleView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) { if (CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext) == FALSE) { return FALSE; } try { // create map with default size - resize message will cause it to be // sized to the client area of the view // pass a license key so the .lic file is not needed //NOTE: Please use the first line from your MapX30.lic file in place of the string below. // The string below will not work CString strLic = _T("uQnZi2sFw22L0-MRa8pYX-1E4P94135N7M4407-3C122214-77777-9999"); BSTR bstrLic = strLic.AllocSysString(); MapX Developer’s Guide 283 Chapter 17: Distributing Your MapX Application BOOL b = m_ctrlMapX.Create(NULL, WS_VISIBLE, CRect(0,0,100,100), this, 100, NULL, FALSE, bstrLic); ::SysFreeString(bstrLic); if (!b) { return FALSE; } // now you can do some work with MapX m_ctrlMapX.GetTitle().SetVisible(FALSE); m_ctrlMapX.SetCurrentTool(miZoomInTool); } catch (COleDispatchException *e) { e->ReportError(); e->Delete(); } catch (COleException *e) { e->ReportError(); e->Delete(); } return TRUE; } 284 MapX Developer’s Guide Appendix A: Managing MapX Data Appendix A: Managing MapX Data In addition to the MapX software, the MapX installer installs data products (maps and demographic data) on your computer, so you can get started exploring the capabilities of MapX. Note: Use of data products is subject to the MapInfo Standard License Agreement Software & Data. By default, maps and geosets are installed in the directory: • C:\Program Files\MapInfo MapX 4.0\Maps Demographic data, in the form of a Microsoft Access table (MAPSTATS.MDB), is installed in the directory: • C:\Program Files\MapInfo MapX 4.0\Data The exact list of files installed on your computer depends partly on the options that you chose during installation. (By default, all data products are installed; but the installer allows you to un-check any or all geosets to avoid installing them.) The list of files installed also depends upon which version of the software you installed; the MapX installation CD provides more data products than the download-for-evaluation version of the software. Use the MapX GeoDictionary Manager to register information about the MapInfo tables that can be matched by MapX during automatic databinding. By default, this utility is located at the following path: • C:\Program Files\Common Files\MapInfo Shared\MapX Common\GeoDictionaryManager40.EXE Use the MapX Geoset Manager to create and manage geosets. By default, this utility is located at the following path: • C:\Program Files\Common Files\MapInfo Shared\MapX Common\GeosetManager40.EXE For more information about the Geodictionary Manager, see Appendix C: Using the GeoDictionary Manage . For more information about the Geoset Manager, see Appendix C: Using the Geoset Manager. Appendix A: Managing MapX Data Data Sources The following sources provided the data released with MapInfo MapX. For more information on MapInfo products, see the “MapInfo Data Products Catalog” or contact MapInfo Corporation. Map Name Copyright Japan Geoset Japan Cased Roads GisNET data licensed to MapInfo by GISdata Limited. © GDC Ltd 1993 Japan Cities MapInfo from Digital Chart of the World Japan Country background GisNET data licensed to MapInfo by GISdata Limited. © GDC Ltd 1993 Japan Highways GisNET data licensed to MapInfo by GISdata Limited. © GDC Ltd 1993 Japan Major Cities MapInfo from Digital Chart of the World Japan Rivers and Lakes GisNET data licensed to MapInfo by GISdata Limited. © GDC Ltd 1993 World Ocean (Lat / Long) MapInfo Australia Geoset Australia Cities MapInfo from Digital Chart of the World Australia Highways MapInfo from Digital Chart of the World Australia Major Cities MapInfo from Digital Chart of the World Australia State Boundaries MapInfo Australia State Capital Cities MapInfo from Digital Chart of the World World Ocean (Lat / Long) MapInfo Europe Geoset 286 Asia MapInfo from Digital Chart of the World European Capitals MapInfo from Digital Chart of the World European Cities MapInfo from Digital Chart of the World MapX Developer’s Guide Appendix A: Managing MapX Data Map Name Copyright European Country Boundaries Data copyright and produced by URPI 1998 and GisNET data licensed to MapInfo by GISdata Limited. © GDC Ltd 1993 European Highways GisNET data licensed to MapInfo by GISdata Limited. © GDC Ltd 1993 European Major Cities MapInfo from Digital Chart of the World European NUTS 1 Level Boundaries Copyright URPI 1998 European NUTS 2 Level Boundaries Copyright URPI 1998 World Ocean (Lat / Long) MapInfo France Geoset European Country Boundaries Data copyright and produced by URPI 1998 and GisNET data licensed to MapInfo by GISdata Limited. © GDC Ltd 1993 France Cities MapInfo from Digital Chart of the World France Highway Map GisNET data licensed to MapInfo by GISdata Limited. © GDC Ltd 1993 France Major Cities MapInfo from Digital Chart of the World France NUTS 2 Level Administrative Boundaries Copyright URPI 1998 World Ocean (Lat / Long) MapInfo UK Geoset European Country Boundaries Data copyright and produced by URPI 1998 and GisNET data licensed to MapInfo by GISdata Limited. © GDC Ltd 1993 United Kingdom Cities MapInfo from Digital Chart of the World United Kingdom Class A Roads GisNET data licensed to MapInfo by GISdata Limited. © GDC Ltd 1993 United Kingdom Motorways GisNET data licensed to MapInfo by GISdata Limited. © GDC Ltd 1993 United Kingdom Standard Regions Copyright URPI 1998 MapX Developer’s Guide 287 Appendix A: Managing MapX Data Map Name Copyright World Ocean (Lat / Long) MapInfo Canada Geoset Canada Cities MapInfo from Digital Chart of the World Canada Highways MapInfo from Digital Chart of the World Canada Major Cities MapInfo from Digital Chart of the World Canadian Province Boundaries MapInfo from Digital Chart of the World Canadian Province Capital Cities MapInfo from Digital Chart of the World US State Boundaries MapInfo from Digital Chart of the World World Ocean (Lat / Long) MapInfo US Geoset Canadian Province Boundaries MapInfo from Digital Chart of the World Mexico State Boundaries MapInfo from the Bureau of Transportation Statistics US Cities MapInfo from Digital Chart of the World US County Boundaries MapInfo from Census Bureau US Highways MapInfo from the Bureau of Transportation Statistics US Major Cities MapInfo from Digital Chart of the World US State Boundaries MapInfo from Digital Chart of the World US State Capitals MapInfo from Digital Chart of the World US top 20 Cities MapInfo from Digital Chart of the World World Ocean (Lat / Long) MapInfo World Geoset 288 World Capitals MapInfo from Digital Chart of the World World Countries MapInfo from Digital Chart of the World World Graticule MapInfo MapX Developer’s Guide Appendix A: Managing MapX Data Map Name Copyright World Ocean (Robinson) MapInfo World Top 25 Cities MapInfo from Digital Chart of the World DC Geoset Dc Area Landmarks MapInfo Dc City Boundaries MapInfo DC Highways MapInfo from the Bureau of Transportation Statistics DC Interstate Roads MapInfo from the Bureau of Transportation Statistics DC Landmarks MapInfo DC Roads MapInfo from the Bureau of Transportation Statistics DC State Roads MapInfo from the Bureau of Transportation Statistics Dc Water Layer MapInfo DC Zips © 1995 Geographic Data Technology, Inc. Asia Geoset Asia MapInfo from Digital Chart of the World Asia Capitals MapInfo from Digital Chart of the World Asia Major Cities MapInfo from Digital Chart of the World European Country Boundaries Data copyright and produced by URPI 1998 and GisNET data licensed to MapInfo by GISdata Limited. © GDC Ltd 1993 World Ocean (for Asia) MapInfo Mid-Atlantic Geoset Mid-Atlantic Capitals MapInfo from Digital Chart of the World Mid-Atlantic Cities MapInfo from Digital Chart of the World Mid-Atlantic Counties MapInfo MapX Developer’s Guide 289 Appendix A: Managing MapX Data Map Name Copyright Mid-Atlantic Highway MapInfo from the Bureau of Transportation Statistics Mid-Atlantic Major Cities MapInfo from Digital Chart of the World Mid-Atlantic States MapInfo from Digital Chart of the World World Ocean (Lat / Long) MapInfo US State Boundaries MapInfo from Digital Chart of the World China Geoset Asia MapInfo from Digital Chart of the World Asia Major Cities MapInfo from Digital Chart of the World China Cities MapInfo from Digital Chart of the World China Country Bdy MapInfo from Digital Chart of the World China Highways MapInfo from Digital Chart of the World China Major Cities MapInfo from Digital Chart of the World World Ocean (for Asia) MapInfo Mexico Geoset Mexico Cities MapInfo from Digital Chart of the World Mexico Highways MapInfo from Digital Chart of the World Mexico Major Cities MapInfo from Digital Chart of the World Mexico State Boundaries MapInfo from the Bureau of Transportation Statistics Mexico State Capital Cities MapInfo from Digital Chart of the World US State Boundaries MapInfo from Digital Chart of the World World Ocean (Lat / Long) MapInfo North American Geoset 290 Canada Cities MapInfo from Digital Chart of the World Canada Highways MapInfo from Digital Chart of the World MapX Developer’s Guide Appendix A: Managing MapX Data Map Name Copyright Canada Major Cities MapInfo from Digital Chart of the World Canadian Province Boundaries MapInfo from Digital Chart of the World Canadian Province Capital Cities MapInfo from Digital Chart of the World Mexico Cities MapInfo from Digital Chart of the World Mexico Highways MapInfo from Digital Chart of the World Mexico Major Cities MapInfo from Digital Chart of the World Mexico State Boundaries MapInfo from the Bureau of Transportation Statistics Mexico State Capital Cities MapInfo from Digital Chart of the World US Cities MapInfo from Digital Chart of the World US Highways MapInfo from the Bureau of Transportation Statistics US Major Cities MapInfo from Digital Chart of the World US State Boundaries MapInfo from Digital Chart of the World US State Capitals MapInfo from Digital Chart of the World World Ocean (Lat / Long) MapInfo Germany Geoset European Country Boundaries Data copyright and produced by URPI 1998 and GisNET data licensed to MapInfo by GISdata Limited. © GDC Ltd 1993 Germany Cities MapInfo from Digital Chart of the World Germany Highways GisNET data licensed to MapInfo by GISdata Limited. © GDC Ltd 1993 Germany Major Cities MapInfo from Digital Chart of the World Germany NUTS 2 Level Bdys MapInfo from Digital Chart of the World World Ocean (Lat / Long) MapInfo Italy Geoset MapX Developer’s Guide 291 Appendix A: Managing MapX Data Map Name Copyright European Country Boundaries Data copyright and produced by URPI 1998 and GisNET data licensed to MapInfo by GISdata Limited. © GDC Ltd 1993 Italy Cities MapInfo from Digital Chart of the World Italy Highways GisNET data licensed to MapInfo by GISdata Limited. © GDC Ltd 1993 Italy Major Cities MapInfo from Digital Chart of the World Italy NUTS 2 Level Bdys Copyright URPI 1998 World Ocean (Lat / Long) MapInfo Portugal Geoset European Country Boundaries Data copyright and produced by URPI 1998 and GisNET data licensed to MapInfo by GISdata Limited. © GDC Ltd 1993 Portugal Highways GisNET data licensed to MapInfo by GISdata Limited. © GDC Ltd 1993 Portugal Major Cities MapInfo from Digital Chart of the World Portugal NUTS 2 Level Boundary Copyright URPI 1998 World Ocean (Lat / Long) MapInfo Argentina Geoset Argentina Cities MapInfo from Digital Chart of the World Argentina Country Boundary MapInfo from Digital Chart of the World Argentina Major Cities MapInfo from Digital Chart of the World South America Country Boundaries MapInfo from Digital Chart of the World World Ocean (Lat / Long) MapInfo Brazil Geoset 292 Brazil Major Cities MapInfo from Digital Chart of the World Brazil Cities MapInfo from Digital Chart of the World Brazil Country Boundary MapInfo from Digital Chart of the World MapX Developer’s Guide Appendix A: Managing MapX Data Map Name Copyright South America Country Boundaries MapInfo from Digital Chart of the World World Ocean (Lat / Long) MapInfo Israel Geoset Africa Country Boundary MapInfo from Digital Chart of the World Asia MapInfo from Digital Chart of the World Israel Cities MapInfo from Digital Chart of the World Israel Country Boundary MapInfo from Digital Chart of the World Israel Major Cities MapInfo from Digital Chart of the World World Ocean (Lat / Long) MapInfo South Korea Geoset Asia MapInfo from Digital Chart of the World South Korea Cities MapInfo from Digital Chart of the World South Korea Country Boundary MapInfo from Digital Chart of the World South Korea Major Cities MapInfo from Digital Chart of the World World Ocean (for Asia) MapInfo Spain Geoset European Country Boundaries Data copyright and produced by URPI 1998 and GisNET data licensed to MapInfo by GISdata Limited. © GDC Ltd 1993 Spain Cities MapInfo from Digital Chart of the World Spain Highways GisNET data licensed to MapInfo by GISdata Limited. © GDC Ltd 1993 Spain Major Cities MapInfo from Digital Chart of the World Spain NUTS 2 Boundaries Copyright URPI 1998 World Ocean (Lat / Long) MapInfo India Geoset Asia MapX Developer’s Guide MapInfo from Digital Chart of the World 293 Appendix A: Managing MapX Data Map Name Copyright India Capital Cities MapInfo from Digital Chart of the World India District Bdys Risk Management Solutions, Inc India Major Cities MapInfo from Digital Chart of the World India Minor Cities MapInfo from Digital Chart of the World India State Bdys Risk Management Solutions, Inc World Ocean (for Asia) MapInfo US Detail Geoset Canadian Province Boundaries MapInfo from Digital Chart of the World Landmark Map MapInfo from USGS Mexico State Boundaries MapInfo from the Bureau of Transportation Statistics US Cities MapInfo from Digital Chart of the World US County Boundaries MapInfo from Census Bureau US Highways MapInfo from the Bureau of Transportation Statistics US Major Cities MapInfo from Digital Chart of the World US State Boundaries MapInfo from Digital Chart of the World US State Capitals MapInfo from Digital Chart of the World US top 20 Cities MapInfo from Digital Chart of the World US Zipcode Boundaries © 1997 Geographic Data Technology, Inc. World Ocean (Lat / Long) MapInfo World Detail Geoset 294 World Capitals MapInfo from Digital Chart of the World World Countries MapInfo from Digital Chart of the World World Graticule MapInfo World Major Cities MapInfo from Digital Chart of the World MapX Developer’s Guide Appendix A: Managing MapX Data Map Name Copyright World Minor Cities MapInfo from Digital Chart of the World World Ocean (Robinson) MapInfo World Top 25 Cities MapInfo from Digital Chart of the World Dallas, TX Geoset Crime County Map MapInfo Crime Demo Map MapInfo Dallas City Boundary A MapInfo from USGS Dallas City Boundary B MapInfo from USGS Dallas Locations MapInfo Dallas Major Highways A MapInfo from USGS Dallas Major Highways B MapInfo from USGS Dallas Streets A MapInfo from USGS Dallas Streets B MapInfo from USGS Dallas Streets C MapInfo from USGS Dallas Water Bodies MapInfo from USGS Dallas Water Rivers MapInfo from USGS Dallas, TX Raster Copyright © 1997, Horizons Technology, Inc Other Files Dallas City Boundary from MapXsite Streets 1.0 MapInfo from USGS Dallas Major Highways from MapXsite Streets 1.0 MapInfo from USGS Dallas Streets from MapXsite Streets 1.0 MapInfo from USGS Dallas Water Bodies from MapXsite Streets 1.0 MapInfo from USGS MapX Developer’s Guide 295 Appendix A: Managing MapX Data Map Name Copyright Dallas Water Rivers from MapXsite Streets 1.0 MapInfo from USGS US 5-Digit Zipcode Points (c) 1999 Geographic Data Technology, Inc. US 5-Digit Zipcode Points (compressed point file) (c) 1995 Geographic Data Technology, Inc. MapStats.mdb 296 Demographics for Asia Copyright United Nation Demographic Yearbook, 1994 Demographics for Australia MapInfo Australia Demographics for DC copyright 1998, The Polk Company, All Rights Reserved Demographics for Mid-Atlantic States copyright 1998, The Polk Company, All Rights Reserved Demographics for the World Copyright United Nation Demographic Yearbook, 1994 Demographics for US copyright 1998, The Polk Company, All Rights Reserved US County Age Demographics copyright 1998, The Polk Company, All Rights Reserved US County Age Demographics by Gender copyright 1998, The Polk Company, All Rights Reserved US County Household demographics copyright 1998, The Polk Company, All Rights Reserved US County Household demographics by Age, Income copyright 1998, The Polk Company, All Rights Reserved US County Household Income copyright 1998, The Polk Company, All Rights Reserved US County Housing Values copyright 1998, The Polk Company, All Rights Reserved US County Population Demographics copyright 1998, The Polk Company, All Rights Reserved MapX Developer’s Guide Appendix A: Managing MapX Data Map Name Copyright US Customer Database MapInfo MapX Developer’s Guide 297 Appendix A: Managing MapX Data 298 MapX Developer’s Guide Appendix B: Geoset Manager Appendix B: The Geoset Manager Use the Geoset Manager to keep a collection of map layers and their settings easily available to you. Geosets help you to avoid the time consuming task of opening and displaying layers individually each time you want to work with them. Computer maps are organized into layers. Think of layers as transparencies that are stacked on top of one another. Begin building a geoset by opening a map. Each map layer contains different map objects, such as regions, points, lines, and text. For example, one layer may contain state boundaries, a second layer may have symbols that represent capitals, and a third layer might consist of text labels. By stacking these layers on top of the other, you begin to build a complete map. Once you have created your geoset, you can customize the way in which the layers display, and add, delete, or reorder them. From the Geoset Manager, work with sample geosets, or create your own. To start the Geoset Manager, select Geoset Manager from the MapX Program Group on your Start menu. Note: In the Trial version of MapX, the Geoset Manager will only function on the developer’s machine. Appendix B: Geoset Manager Opening an Existing Geoset MapX includes some sample geosets. Use these as a starting point for your own geoset or use them as they are. To display an existing geoset: 1. Choose File > Open Geoset. The Open dialog displays. 2. Select the geoset you want and click Open. That geoset displays. From here you can alter a variety of layer settings using items in the Map Menu or View Menu. You can also insert other geosets to display with the current geoset. Then, save these new settings to the existing geoset or SaveAs to create a new geoset. We will discuss these items in detail in the following sections. 300 MapX Developer’s Guide Appendix B: Geoset Manager Creating a Geoset 1. Choose File > New Geoset. The Layer Control dialog displays. 2. Click Add to display the Open dialog. 3. Select the layers you want to use as a part of your geoset. Hold down the Ctrl key while selecting to mark several layers. The selected layers display in the Layer Control dialog. From here you can set display and label properties, reorder the way in which layers display, remove or add additional layers and set whether layers are visible, contain automatic labels, or are selectable. See the description of Layer Control in a following section, below. You can edit these properties later after displaying the initial geoset. MapX Developer’s Guide 301 Appendix B: Geoset Manager 4. Click OK to display the geoset. Your newly created geoset displays. Use the information in the sections that follow to manipulate and customize the layers in your geoset. When you have finished creating your geoset you'll need to save it. 302 MapX Developer’s Guide Appendix B: Geoset Manager To save your geoset: 1. Choose File > Save. The Save As dialog displays. 2. Enter a name and click Save to save the layers with the attributes you specified. Manipulating Your Layers with the Map Menu Use the options avaiable from the Map Menu to control the way in which your map displays. Zoom In Use the Zoom In tool to get a closer area view of a map or a layer. 1. Choose Map > Zoom In, or click the Zoom In button on the menu bar, or right click the mouse in the Geoset Manager window and choose Zoom In. The Zoom In mouse icon appears. 2. Click the Zoom In cursor on the center of the area you want to zoom in on, magnifying the area by a linear factor of two. This point will be at the center of the map in the zoomed in view. Repeat this procedure until you have the appropriate level of enlargement. To zoom in on a rectangular area: 1. Choose Map > Zoom In, or click the Zoom In button on the menu bar, or right click the mouse in the Geoset manager window and choose Zoom In. The Zoom In mouse icon appears. 2. Draw a marquee in the map or layout by diagonally dragging the Zoom In mouse icon. The area within the marquee is enlarged. Zoom Out Use the Zoom Out tool to get a wider area view of a map or a layer. 1. Choose Map > Zoom Out, or click the Zoom Out button, or right click the mouse in the Geoset Manager window and choose Zoom Out. The Zoom Out mouse icon appears. 2. Click the Zoom Out mouse icon on the center of the area you want to zoom out on, enlarging the area by a linear factor of two. This point will be at the center of the map in the zoomed-out view. Repeat this procedure until you have the appropriate level of magnification. MapX Developer’s Guide 303 Appendix B: Geoset Manager To zoom out from a rectangular area: 1. Choose Map > Zoom Out, click the Zoom Out button, or right click the mouse in the Geoset Manager window and choose Zoom Out. The Zoom Out mouse icon appears. 2. Draw a marquee in the map or layout by diagonally dragging the Zoom Out mouse icon. The area within the marquee is reduced, allowing more of the map to display. Pan Use Pan to reposition a map within its window. To move or adjust the map display: 1. Choose Map > Pan, or click the Pan button, or right click the mouse in the Geoset Manager window and choose Pan. The Pan mouse icon appears. 2. Click an area of the map. 3. While holding down the left mouse button, drag the map in the appropriate direction. When you release the mouse button, Geoset Manager redraws the map in its new location. Zoom To Zoom to a particular X and Y coordinate on the map and set a zoom level. Choose Map > Zoom To. The Zoom To dialog displays. Enter the coordinates to which you want to zoom. 304 MapX Developer’s Guide Appendix B: Geoset Manager View Entire Layer Use View Entire Layer to zoom and display an entire layer or all layers in a map. Use this option if the map contains layers that cover different amounts of territory. For example, you have a map containing New York counties, highways, ZIP Codes and streets for Utica. If you choose All Layers, the view will be zoomed out to display the entire map. But if you are only interested in viewing Utica streets, choose the Utica streets layer. The zoom will be zoomed in to display those streets. To display an entire map or map layer: 1. Choose Map > View Entire Layer, or right click with the mouse over the Map window and choose View Entire Layer. The View Entire Layer dialog displays. 2. Choose a specific layer or All layers to display. Click OK to view the layer(s). Layer Control Use the Layer Control dialog to: • Change the display of map layers in the active window • Determine which layers are displayed, removed, added, selectable, zoom layered, labeled and set • Change the order of map layers. To access Layer Control: • Choose Map > Layer Control, click the Layer Control button, right click the mouse over the map and choose Layer Control or create a new geoset. MapX Developer’s Guide 305 Appendix B: Geoset Manager The Layer Control dialog controls how maps display. Some important information includes: 306 • The Layer Control dialog displays the list of layers in the current map window and indicates whether each is displayed, selectable, or labeled automatically. • Layers include data tables, raster images, or thematic maps stacked in a map window. • The order of layers in the Layer Control dialog is the order of the layers in the map window. For example, when boundary layers are placed below point layers, the points remain visible. • To work with a layer, choose it by clicking on it. Control its settings by checking or clearing the appropriate box to make the layer display, selectable, or label automatically. Up Moves one or more layers up. Down Moves one or more layers down. Add Adds one or more layers to the map. Choose from the displayed listbox of tables. Remove Removes one or more layers from the map. Visible Indicates if the layer is visible. Check this box for the layer or layers, that you want to make visible in the map. Sometimes you may want to include layers in your geoset for computational purposes and not want them actually displayed in the geoset. Selectable Indicates if the layer is selectable. Check this box for the layer, or layers, that you want to make selectable. Layers must be selectable if you want to choose or label objects. A layer must be displayed to be made selectable. More than one layer may be selectable at the same time. You may, however, only select from one layer at a time. Automatic Lables Check to label the map automatically.The labels are taken from the table column designated in the Label with section of the Label Options dialog. Display Displays the Display Options dialog. Use this dialog to specify display attributes for map layers. Labels Displays the Label Properties dialog. Use this dialog to specify label attributes for map layers. MapX Developer’s Guide Appendix B: Geoset Manager To specify display attributes for a map layer, click the Display button from the Layer Control dialog. Display Mode Override Style Check to override the default style of a layer. Style Button Enabled when Style Override option is checked. Displays the button appropriate to the object type contained in the selected layer: Region, Line, Symbol, or Text. Click to display the corresponding dialog. Zoom Layering Display within zoom range Check to activate zoom layering. Zoom layering allows you to set the minimum and maximum distances at which the selected layer will be visible. For example, if you only want to see particular streets on a map when you are closer than 3 miles, set the minimum zoom to 0 and the maximum to 3. Min Zoom Specify the minimum distance at which the selected layer is visible. Max Zoom Specify the maximum distance at which the selected layer is visible. Automatic Labeling To automatically label a layer in a map using information from that layer: 1. From the Layer Control dialog, choose the layer you want to label; check the Automatic Labels check box. 2. Click OK. The map redisplays with labels from the table column designated in the Label with section of the Label Options dialog if a dataset is loaded and a field from that dataset is specified. Only one column per table displays at one time. Access the Label Properties dialog to change the visibility, content, font, text color, line style, and position of labels. MapX Developer’s Guide 307 Appendix B: Geoset Manager The Label Properties Dialog Label Properties dialog determines the visibility, content, font, text color, line style, and anchor point of labels. These settings are used for both automatic and interactive labeling using the Label tool. When using the Label tool, the label is positioned at the place you designate by clicking the mouse button. To access the Label Properties dialog: 1. Choose Map > Layer Control. 2. Click the Label button. The Label Properties dialog displays. 308 MapX Developer’s Guide Appendix B: Geoset Manager Label with Choose the Dataset and Field name that you want to be reflected in the label. Visibility On Check to allow display of labels. Off Check to prevent display of labels. Display within range Check to activate zoom labeling. Zoom labeling allows you to set the minimum and maximum distances at which the labels will be visible. For example, if you only want to see particular labels on a map when you are closer than 3 miles, set the minimum zoom to 0 and the maximum to 3. Label size does not change with zoom or scale changes. Min Zoom Specify the minimum distance at which labels are visible. Max Zoom Specify the maximum distance at which labels are visible. Allow duplicate text Check to place the same label on a map more than once. Allow overlapping text Allow more than one object with the same text to be displayed. Maximum labels Enter the maximum number of labels that will display; labels are selected from the designated table in the order in which they are entered in the table. For example, if the designated table is the States table, and you enter 10, the first ten states listed in the table, which are in view, will be labeled. Styles Text Style button Click the Text Style button to display the Text Style dialog. See Text Style Dialog. Label Lines Select a line type, or no line type, to attach the label to the anchor point. None Do not display a line with the label. Simple Create a callout by using a simple line that connects the label to the object's centroid. Label lines display after you move the label from where it was originally created. MapX Developer’s Guide 309 Appendix B: Geoset Manager Arrow Create a callout by using an arrow line that connects the label to the object's centroid. Label lines display after you move the label from where it was originally created. Position Anchor Point Click an icon to select the label position relative to the label anchor. The diamond character represents the label anchor; the rectangle represents the label. The border of the selected box is bold. Rotate label with line Check to rotate text to run parallel with line segments. This setting is ignored for points regions. Label Offset Designate number of points (a measurement of text size) label should be placed from the anchor point. Projection How do you flatten the curved surface of the earth so that you can draw maps on flat pieces of paper and (nearly) flat computer screens?You use a projection. A projection is a system that defines how to flatten objects. You can display your maps in many different projections. When you transfer objects from the spherical world to the relatively flat computer screen, there is bound to be some distortion. A projection is a method of reducing the distortion that occurs when objects from a spherical surface are displayed on a flat surface. There are many different types of projections, each designed to reduce the amount of distortion for a given area. To choose a projection: 310 MapX Developer’s Guide Appendix B: Geoset Manager Choose Map > Projection, or right-click the mouse over the map and choose projection. Using the View Menu Use the Options in the View Menu to designate if Status bars or Toolbars display and to change map distance units or coordinates. Toolbar Displays To show or hide the Map Toolbar, Geoset Name Toolbar, or the Status Bar, check or clear the menu options as appropriate. MapX Developer’s Guide 311 Appendix B: Geoset Manager Options Use the Options dialog to set the distance units and the numeric coordinates used by the map. To set options choose View > Options. The Options dialog displays. Distance Units Choose the measure of distnace used for the map. Numeric Coordinates Choose the numeric coordinates the Geoset Manager will use to find the X and Y coordinates. A coordinate system is a set of parameters that tells you how to interpret the locations coordinates for objects. Each point in a geometric object is represented by a pair of numbers. Those numbers are the coordinate for those points. Tools and the GeoDictionary Manager Use the options in the Tools menu to access the GeoDictionary manager. The GeoDictionary manager allows you to register layers in the geodictionary. Layers registered in the geodictionary can be used for databinding in other MapX sessions. For more information on the Geodictionary Manager, see Appendix: Using the GeoDictionary Manager. 312 MapX Developer’s Guide Appendix C: Using the Geodictionary Manager Appendix C: Using the Geodictionary Manager This topic describes the features of the MapX Geodictionary Manager. The Geodictionary is a file containing registration information about the MapInfo tables that can be matched by MapX during automatic databinding. Only MapInfo tables that can or will be matched against should be registered in the Geodictionary. Note: There is no need to register every .tab file that an application uses in the Geodictionary, and in fact there is some overhead in having unnecessary files registered. The Geodictionary Manager Applications allows manipulation of the Geodictionary. The Geodictionary Manager executable (GeoDictionaryManager40.exe) can be run with a graphical user interface or with command line parameters. The command line options are useful for calling GeoDictionaryManager40.exe from install programs to register the tables that a MapX application may need to match against into the Geodictionary. History Previous versions of MapX used the MapInfo Data Installer developed for Microsoft Map to manage the Geodictionary. The Data Installer also managed geosets (groups of MapInfo tables that can be displayed together), which was overkill for the Geodictionary Manager and caused confusion. There is now a Geoset Manager application which should be used to create and manage geosets. The new Geodictionary Manager will not modify geosets in any way, nor will it delete files from a user’s disk. In MapX 4.0, a permanent GeoDictionary file is no longer required for MapX to run. See the section below on the GeoDictionary file for details. There has been a change to the command line options that requires that file or path names with spaces in them require that they be enclosed in double quotes. This may make some command lines that worked previously fail now The Geodictionary File The Geodictionary is contained in a binary format file usually called geodict.dct. The geodictionary file can be located or disabled by using the registry key HKEY_LOCAL_MACHINE\SOFTWARE\MapInfo\MapX 4.0\GeoDictionary. There are three valid possibilites for this key: Appendix C: Using the Geodictionary Manager • Could contain a full file spec for the Geodictionary file (e.g. "C:\Program Files\MapInfo MapX\Maps\geodict.dct"). The effect is that the data directory is set to be the path leading to the Geodictionary file named by this key. The in-memory geodictionary is initialized from the Geodictionary file and layers contained in the Geodictionary can be automatically matched against it too. Layers added to the map are added to the in-memory geodictionary so they can be auto matched against. • Could contain just a path specification (e.g. "C:\Program Files\MapInfo MapX\Maps\"). The data directory is set to be the path named by this key. The inmemory geodictionary is initialized empty. Layers added to the map are still added to the in-memory geodictionary so they can be auto matched against. • Could not exist at all. The in-memory geodictionary is initialized empty. Layers added to the map are still added to the in-memory geodictionary so they may be auto matched. Note: An Uninstall of MapX will leave geodict.dct behind. This is the expected behavior because the Geodictionary file may have existed before the install (from an earlier version of MapX), or may be shared by other app MapX applications can share the same Geodictionary file, or use their own. In order for a MapX application to use its own Geodictionary file (or to not use one at all), the Map.GeoDictionary property can be changed at design time to point to a different registry entry. Then, when the map control is initialized at runtime, MapX will query the following registry entry: HKEY_LOCAL_MACHINE\SOFTWARE\MapInfo\MapX\4.0\<value of Map.GeoDictionary> The value of this registry entry will be interpreted as detailed above. The default value of Map.GeoDictionary is "GeoDictionary" so that MapX will use the default registry entry. The Geodictionary Manager always reads and updates the default Geodictionary file, referred to by the registry key HKEY_LOCAL_MACHINE\SOFTWARE\MapInfo\MapX\4.0\GeoDictionary. If you change the location of the Geodictionary file in the user interface, then the registry key is updated to point to that new location. The Geodictionary contains an entry for each registered table (mapinfo .tab file). The data stored with each entry is: 314 • A user-friendly name to refer to the table and to display in the layer control dialogs. This defaults to the ‘Description’ tag in the .tab file, or the file name if none exists. It can be edited through the user interface. • A list of indexed fields. The user interface allows you to check which of the indexed fields you want MapX to consider as possible columns to match against during MapX Developer’s Guide Appendix C: Using the Geodictionary Manager automatic databinding. Fields that are not checked are ignored. When a table is first registered, all indexed fields are initially checked by default. • A refining table name. Some tables, e.g., US Counties, contain indexed columns that are not unique. In that situation, a refining table is necessary to determine an exact match for data. If the table has non-unique indexed columns, the refining column combo box will be enabled and the user will be able to pick a refining table. • A list of Geoset file names. When a table is selected during automatic databinding, the list of geosets for that table is passed to the ResolveDataBind event for the MapX program to choose one. MapX will pick the first one by default if the event is not handled. Note: The table that was matched is always loaded, even if it is not in the geoset that gets loaded. Also, it is not an error to have no geosets listed for a table in the Geodictionary. In that case, only the table is loaded. Finally, only geoset files that are located in the same directory as the Geodictionary file can be added to the list. MapX Developer’s Guide 315 Appendix C: Using the Geodictionary Manager User Interface Run GeoDictionary Manager Run the GeoDictionary Manager when you want to manually register layers. Choose Tools. > Run GeoDictionary Manager. The Geodictionary dialog displays. 316 MapX Developer’s Guide Appendix C: Using the Geodictionary Manager Geodictionary The Geodictionary edit box is a read-only edit box containing the full path to the Geodictionary that's being managed. This information is found by looking at the MapX key in the registry. The button (to the right of the Geodictionary edit box) allows the user to browse for another Geodictionary to manage. Browsing to another Geodictionary changes MapX's registry key so that all subsequent MapX sessions will use the new dictionary. The button also lets you change the default MapX search path which is stored in the registry key "HKEY_LOCAL_MACHINEOFTWAREapInfoap X.0earchPaths". Registered tables The Registered Tables list box contains a list of the friendly names for all tables registered in the Geodictionary. Register Displays the common file open dialog, with the Files of Type combo box set to "MapInfo Tables (*.tab)". Copy the table to the data directory (the directory containing the Geodictionary), or add the directory containing the table to the data search path. After the table has been assimilated (either by copying or by adding the directory to the search path), the Table Properties dialog displays. Users can select multiple files to register, and also in Unregister they can select multiple tables holding ctrl /shift key to be unregistered. In cases of multiple tables being selected, the properties button is disabled. See the Table Properties Dialog. Unregister Remove the selected table from the Geodictionary. The Unregister button will not remove the files from the disk. Properties Display the Table Properties dialog for the selected table. See the Table Properties dialog below. Set the Geodictionary fields for a given table using theTable Properties Dialog. MapX Developer’s Guide 317 Appendix C: Using the Geodictionary Manager 318 MapInfo Table Read-only edit box containing the file name of the MapInfo table if it is located in the same directory of the Geodictionary, or the full pathname to the file if it is not. Description Provides a mechanism for changing the friendly name for the table. This control is defaulted to the Description tag in the .TAB file, or the filename if the Description tag is not found, but can be changed by the user. Note that changes to the description in the Geodictionary Manager will only be stored in the Geodictionary and will not be reflected in the table. This allows the Geodictionary Manager to easily work with read-only data, e.g., data on CD-ROMs. Geometry The Geometry static text control displays the type of entities stored in the table. MapX Developer’s Guide Appendix C: Using the Geodictionary Manager Field Information Contains a list of the indexed columns in the table. If the box for a given column is checked, the field will be searched during the matching process. Refining Table Some tables, e.g., US Counties, contain indexed columns that are not unique. In that situation, a refining table is necessary to determine an exact match for data. If the table has non-unique indexed columns, the refining column combo box will be enabled and the user will be able to pick a refining table. Candidate Geosets List of the geoset file names that are possible candidates to load if the MapInfo table was selected during databinding. Zero or more geoset filenames can be listed. When the table is selected during automatic databinding, the list of geosets for that table is passed to the ResolveDataBind event for the MapX program to choose one. MapX will pick the first one by default if the event is not handled. Please note: • The table matched is always loaded, even if it is not in the geoset that gets loaded. • It is not an error to have no geosets listed for a table in the Geodictionary. In that case, only the table is loaded. • Only geoset files that are located in the same directory as the Geodictionary file can be added to the list. • Multiple candidate geosets can be added or removed Add Displays a list box containing a list of the geoset file names that are in the same directory as the Geodictionary file. Selecting one adds it to the list of candidate geosets. Remove Deletes the selected geoset file name from the list of candidate geosets. MapX Developer’s Guide 319 Appendix C: Using the Geodictionary Manager Register Layers in GeoDictionary If you want the Geoset Manager to automatically register your layers, choose Tools > Register Layers. The Register Layers dialog displays. Check the layers you want to register and click OK. 320 MapX Developer’s Guide Appendix C: Using the Geodictionary Manager Command Line Options The GeoDictonary Manager command line provides a mechanism for adding and removing tables to/from the Geodictionary geosetpath The path to a geoset file containing a list of tables. Currently a path is required; just specifying the filename is considered an error • Use the geosetpath option to register all of the valid .tab files in the geoset with the Geodictionary. (Raster, Seamless, and View tables in the geoset will be ignored.) • Use the geosetpath /remove option to unregister all of the valid tab files in the geoset from the Geodictionary. tablepath The path to a MapInfo table to add to the Geodictionary (the option with no arguments). • Use the tablepath option to register a file with the Geodictionary. • Use the tablepath /remove option to unregister a file from the Geodictionary. geosetfile The file name only of a geoset file located in the same directory as the Geodictionary file. • Use the tablepath /geoset=geosetfile option to register a file with the Geodictionary and add geosetfile to its list of candidate geosets to match. • Use the tablepath /geoset=geosetfile /remove option to remove geosetfile from its list of candidate geosets to match. commandfilepath The full pathname of a text file that contains a valid migm30 command line on each line of the file. • Use the /file=commandfilepath option to process a text file of command lines, with 1 command line on each line of the file. Do not include ‘migm30.exe’ on each line of the file. • Use the /file=commandfilepath /remove option to process a text file of command lines, with 1 command line on each line of the file. The / remove option will be added to each command line before it is executed. Do not include ‘migm30.exe’ on each line of the file. Note: Paths or filenames with spaces must be enclosed in double quotes. Wherever possible, the command line usage of the Geodictionary Manager will run silently.It is not an error to attempt to register a file more than once. It is not an error to unregister a table that is not currently registered. MapX Developer’s Guide 321 Appendix C: Using the Geodictionary Manager 322 MapX Developer’s Guide Appendix D: Custom Dataset Support Appendix D: Custom Dataset Support Even if you cannot access your data sources through the standard MapX data binding techniques, you can create your own custom dataset support. MapX version 3 and later provides a run-time extensible architecture, allowing you to plug in custom dataset types through a COM-based dataset interface. Creating custom dataset support is an advanced topic. This discussion assumes that you are already familiar with creating COM objects. Static Dataset Object Overview A Static Dataset object is a COM object that MapX can use to retrieve data from an arbitrary data source. Data is fetched and aggregated when the data source is bound (via a call to MapX’s Datasets.Add(…) method), and then cached by MapX. Changes to source data are not reflected in the map until a refresh of MapX’s cached data is forced (via a call to MapX’s Dataset.Refresh(…) method). All of the behavior needed to retrieve and cache data in this manner is abstracted into three interfaces; IMMapXDataset, IMMapXStaticDataset, and IMMapXColumnInfoContainer. A Static Dataset object must implement all three of these interfaces (note that IMMapXStaticDataset is derived from IMMapXDataset). See below for a more detailed look at the contract encapsulated by each of these interfaces. Appendix D: Custom Dataset Support Special Registration When registered, a Static Dataset object server must make some special entries in the registry so that MapX knows when to use it: Add the key: HKEY_LOCAL_MACHINE\SOFTWARE\MapInfo\MapX\DatasetEngines\<DatasetID > Add the string value: HKEY_LOCAL_MACHINE\SOFTWARE\MapInfo\MapX\DatasetEngines\<DatasetID > \DE_CLSID = The CLSID of the Static Dataset object (in the form “{xxxxxxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx}”). Where <DatasetID> is a unique numeric identifier for your Static Dataset object. When the “Type” parameter to Map’s Dataset.Add(…) method is this value, your server will be asked to provided the Static Dataset object through which MapX will ultimately retrieve data. The values 0 through 1000 are reserved by MapInfo and should not be used. Note: Don’t forget to delete these registry entries when your server is unregiste ed! 324 MapX Developer’s Guide Appendix D: Custom Dataset Support Interfaces The IMMapXDataset Interface [ uuid(96e0f395-caec-11d0-9d99-00aa00a478cb), helpstring("IMMapXDataset Interface"), version(1.0) ] interface IMMapXDataset : IUnknown { HRESULT Init( [in] short sType, [in] VARIANT* pvSourceData, [in] VARIANT* pvFields ); HRESULT GetSample( [in] long lColNum, [in] long lNumSampleValuesRequested, [in] VARTYPE vtRequested, [out] VARIANT * pvarData, [out] long * pNumRecordsFetched); IMMapXDataset::Init HRESULT Init :) [in] short sType The dataset type requested (the Type parameter to the Datasets.Add method). MapX has already identified your server as the server for datasets of this type (via registry entries you made when your COM server was registered). [in] VARIANT * pvSourceData A reference to the source data. (The SourceData parameter to the Dataset.Add method). For example, this parameter contains the ODBCQueryInfo object when the bind type is miDatasetODBC, and an IDAORecordset pointer when the bind type is miDataSetDAO. MapX Developer’s Guide 325 Appendix D: Custom Dataset Support [in] VARIANT * pvFields Contains an array ofVARIANTS. Each VARIANT identifies (either by name or by index) a column from the source data that the client programmer wants bound to the matched map layer. If empty (pvFields->vt = =VT_EMPTY) all columns from the source data should be bound. Description Initializes the Static Dataset object. This method will be called immediately after the Static Dataset object is created. It gives the Static Dataset object an opportunity to establish a connection with the data source, and identifies which columns from the source data will be bound to the map. The Static Dataset object should, before returning from this call, build an internal collection of ColumnInfo objects (objects that implement IMMapXColumnInfo). The collection must contain an initialized ColumnInfo object for each bound column. This collection is exposed to MapX via the IMMapXColumnInfoContainer interface. Return Value S_OK is returned on success. E_OUTOFMEMORY is returned if an out of memory condition is encountered. E_FAIL is returned on any other failure. IMMapXDataset::GetSample HRESULT GetSample(); 326 [in] Long lColNum The source data column to get the sample data from. [in] Long lNumSamplesRequested The number of sample data values requested. [in] VARTYPE vtRequested The preferred type for returned data. MapX Developer’s Guide Appendix D: Custom Dataset Support [out] VARIANT * pvData VARIANT to receive the sample data. When GetSample returns, this VARIANT should contain an array of the type requested. MapX will try to convert data that is of a different type, but this will obviously be less efficient. [out] Long * plNumSamplesValuesFetched The number of sample data values in pvData. Description Used to collect a sample of data from a given source data column. Note that the returned variant (pvData) must contain an array, even if that array contains only a single data value. Return Value S_OK is returned on success. E_OUTOFMEMORY is returned if an out of memory condition is encountered. E_FAIL is returned on any other failure. The IMMapXStaticDataset Interface [ uuid(2e6d4cc0-d132-11d0-9da0-00aa00a478cb), helpstring("IMMapXStaticDataset Interface"), version(1.0) ] interface IMMapXStaticDataset : IMMapXDataset { HRESULT FetchData( [in] long lColNum, [in] long lIdxRow, [in] VARTYPE vtRequested, [out] VARIANT* pvarData, [out] BOOL * pbNoMoreData); HRESULT BeginFetch(); HRESULT EndFetch(); MapX Developer’s Guide 327 Appendix D: Custom Dataset Support } IMMapXStaticDataset::FetchData HRESULT FetchData(); [in] Long lColNum The source data column from which to fetch the data. [in] Long lIdxRow The source data row from which to fetch the data. [in] vtRequested vtRequested The preferred type for returned data. [out] VARIANT * pvarData VARIANT to hold the fetched data. Should be of the type identified by vtRequested. MapX will try to convert data that is of a different type, but this will obviously be less efficient. [out] BOOL * pbNoMoreData A flag to indicate that the fetch has gone past the end of the available source data. If there are 10 rows of source data, set this flag when MapX tries to fetch the 1 th. Description Fetches a cell of data from the data source. Return Value S_OK is returned on success. E_OUTOFMEMORY is returned if an out of memory condition is encountered. E_FAIL is returned on any other failure. 328 MapX Developer’s Guide Appendix D: Custom Dataset Support IMMapXStaticDataset::BeginFetc HRESULT BeginFetch(); Description Indicates that a fetch sequence is about to begin. Can be used to allocate/set up resources needed for fetching data. Return Value S_OK is returned on success. E_OUTOFMEMORY is returned if an out of memory condition is encountered. E_FAIL is returned on any other failure. IMMapXStaticDataset::EndFetch HRESULT EndFetch(); Description Indicates that a fetch sequence has ended. Can be used to free resources that are used for fetching data. Return Value S_OK is returned on success. E_OUTOFMEMORY is returned if an out of memory condition is encountered. E_FAIL is returned on any other failure. MapX Developer’s Guide 329 Appendix D: Custom Dataset Support The IMMapXColumnInfoContainer Interface [ uuid(1e584f00-d2a5-11d0-9da3-00aa00a478cb), helpstring("IMMapXColumnInfoContainer Interface"), version(1.0 ] interface IMMapXColumnInfoContainer : IUnknown { HRESULT GetColumnInfoByName( [in] BSTR bstrColumnName, [out] IMMapXColumnInfo** ppIMMapXColumnInfo); HRESULT GetColumnInfoByIndex( [in] long lIndex, [out] IMMapXColumnInfo** ppIMMapXColumnInfo); HRESULT GetColumnInfoEnumerator( [out] IMEnumMapXColumnInfo** ppIMEnumMapXColumnInfo); } IMMapXColumnInfoContainer::GetColumnInfoByName HRESULT GetColumnInfoByName(); [in] BSTR bstrColumnName The name of the source data column. [out] IMMapXColumnInfo ** ppIMMapXColumnInfo The ColumnInfo object identified by bstrColumnName Description Used to retrieve a ColumnInfo object by column name. Return Value S_OK is returned on success. E_OUTOFMEMORY is returned if an out of memory condition is encountered. E_FAIL is returned on any other failure. 330 MapX Developer’s Guide Appendix D: Custom Dataset Support IMMapXColumnInfoContainer::GetColumnInfoByIndex HRESULT GetColumnInfoByIndex (); [in] Long lIndex The index of the source data column. [out] IMMapXColumnInfo ** ppIMMapXColumnInfo The ColumnInfo object identified by lIndex. Description Used to retrieve a ColumnInfo object by column number. Return Value S_OK is returned on success. E_OUTOFMEMORY is returned if an out of memory condition is encountered. E_FAIL is returned on any other failure. IMMapXColumnInfoContainer::GetColumnInfoEnumerator HRESULT GetColumnEnumerator( ); [out] IMEnumMapXColumnInfo ** ppIMEnumMapXColumnInf o The enumerator Description Used to retrieve a ColumnInfo Enumerator object (an object that implements (IMMapXEnumColumnInfo). This object can be used to enumerate the collection of ColumnInfo objects contained in the dataset. Return Value S_OK is returned on success. E_OUTOFMEMORY is returned if an out of memory condition is encountered. E_FAIL is returned on any other failure. MapX Developer’s Guide 331 Appendix D: Custom Dataset Support ColumnInfo Enumerator object overview The ColumnInfo Enumerator object is used to enumerate the collection of ColumnInfo objects contained in a Dataset object. It implements the interface IMEnumMapXColumnInfo (described below) The IMEnumMapXColumnInfo Interface [ uuid(96e0f396-caec-11d0-9d99-00aa00a478cb), helpstring("IMEnumColumnInfo Interface"), version(1.0) ] interface IMEnumMapXColumnInfo : IUnknown { HRESULT Next([in] ULONG celt, [out] IMMapXColumnInfo ** rgelt, [out] ULONG * pceltFetched); HRESULT Skip([in] ULONG celt); HRESULT Reset(); HRESULT Clone([out] IMEnumMapXColumnInfo ** ppIMMapXColumnInfo); } IMEnumMapXColumnInfo is an example of a standard enumeration interface, modeled after IEnumUnknown, which is used to enumerate IMMapXColumnInfo pointers. For complete documentation of IEnumUnknown, see the OLE32 SDK. ColumnInfo object overview The ColumnInfo object contains information about a column of source data. It implements the interface IMMapXColumnInfo (described below) The IMMapXColumnInfo Interface [ uuid(96e0f394-caec-11d0-9d99-00aa00a478cb), helpstring("IMMapXColumnInfo Interface"), version(1.0) ] interface IMMapXColumnInfo : IUnknown { HRESULT Init( [in] BSTR bstrName, 332 MapX Developer’s Guide Appendix D: Custom Dataset Support [in] [in] HRESULT HRESULT HRESULT VARTYPE vt, long lColNum); GetName([out] BSTR *pbstrName); GetDataType([out] VARTYPE *pvt); GetColumnNumber([out] long *plColNum); } IMMapXColumnInfo::Init HRESULT Init( [in] BSTR bstrName The name of the source data column. [in] VARTYPE vt The type of the source data column. [out] long lColNum The index of the source data column. ); Description Initialize a ColumnInfo object. MapX will never call this method, it is up to the Dataset object to initialize the ColumnInfo object after it is created. Note that MapX currently supports only numeric and string data types. Return Value S_OK is returned on success. E_OUTOFMEMORY is returned if an out of memory condition is encountered. E_FAIL is returned on any other failure. IMMapXColumnInfo::GetName HRESULT GetName( [out] BSTR * The name of the source data column. ); pbstrName Description Retrieves the name of the source data column. MapX Developer’s Guide 333 Appendix D: Custom Dataset Support Return Value S_OK is returned on success. E_OUTOFMEMORY is returned if an out of memory condition is encountered. E_FAIL is returned on any other failure. IMMapXColumnInfo::GetDataType HRESULT GetDataType( [out]VARTYPE *pvtThe type of the source data column.); Description Retrieves the data type of the source data column. Note that MapX currently supports only numeric and string data types. Return Value S_OK is returned on success. E_OUTOFMEMORY is returned if an out of memory condition is encountered. E_FAIL is returned on any other failure. IMMapXColumnInfo::GetColumnNumber HRESULT GetColumnNumber( [out]long *pColNumThe column number of the source data column.); Description Retrieves the column number of the source data column. Return Value S_OK is returned on success. E_OUTOFMEMORY is returned if an out of memory condition is encountered. E_FAIL is returned on any other failure. 334 MapX Developer’s Guide Index A Accessing remote spatial data attribute data, 168–169 caching, 170 DBMS servers, 160 LayerInfo parameters, 166–167 mapping with X/Y columns, 163 ODBC connection string, 167–168 performance issues, 169 using Layers.Add method, 160–162 Accessing remote spatial tables making mappable, 173–175 MapInfo Map Catalog, 170–175 specifying styles, 175–176 Adding keys to registry, 282 layers, 81 Map control, 11–13 map to Visual Basic form, 14–15 Adding data data binding, 133–134 Affine transformations applying, 216–218 code example, 217 Animation layers, 94 Annotations, 92 Annotations collection properties and methods, 68–69 Application distribution adding registry keys, 282 customer installation, 274 installing dataset drivers, 278–279 installing maps and geosets, 281 installing MapX OCX, 275– 279 installing raster format handlers, 279–281 passing license string, 283– 284 registering files, 278–279 Attribute data accessing, 168–169 binding, 138 Automatic labeling setting for a layer, 84 B Bar chart maps thematic map type, 199– 200 Binding data, 54 BindLayer data binding BindLayer object, 144–145 BindLayer parameter, 138 displaying data as points, 143–147 Bitmap files export format, 247 Bitmap symbol files, 277 Bivariate thematic maps, 202– 203 BMP files export format, 247 Brush styles in remote spatial tables, 175 Built-in helper dialogs Visual C++, 266–267 C Caching accessing remote spatial data, 170 Choose Projection dialog displaying at run time, 212 COM objects See Static Dataset objects Component tables drilldown layers, 228 Constants aggregation functions, 142 datasets, 136 range distribution, 191–192 theme type, 185 Tool type, 126 Coordinate systems CoordSys object, 208 interpreting type numbers, 215–216 MAPINFOW.PRJ file, 213– 216 reference material, 222 specifying for a map, 210 CoordSys object obtaining, 208 querying properties, 209 Creating callouts for labels, 91 custom tools, 124–129 drilldown tools, 232–233 Features collection, 99–100 geosets, 301–302 layers, 81 map features, 106–107 map in Visual C++ dialog, 269–271 Index MapInfo Map Catalog, 171–172 MapX control in Visual C++, 256 menu items in Visual C++, 257–258 objects, 70–71 permanent point layer, 148 polygon drawing tools, 129–130 polyline feature, 112–113 RollUp tools, 233 selections at specific point, 105 symbol objects, 106–107 themes, 183–186 Custom dataset support, 323– 331 Custom tools, 122 creating, 124–129 drilldown tools, 232–233 polygon drawing tools, 129–130 type constants, 126 Visual C++ example, 261– 262 writing tool handler, 126– 127 Customer installation, 274 D Data Access Object Recordset data source type, 136, 150– 151 Data aggregation Fields.Add method, 141– 142 Data binding adding data to a map, 133– 134 BindLayer, 143–147 data source types, 132, 150–157 336 DataSet object, 134 datasets, 67 DataSets.Add method, 135, 139 Dynamic parameter, 139 Fields parameter, 139 Geodictionary, 66–67 in Visual C++, 263–264 making point layer permanent, 148 MapX events used in, 149 registering MapInfo tables, 313 SourceData parameter, 136 unbound datasets, 155–156 using Geodictionary, 148– 150 Data sources data binding, 54 Fields.Add method, 140– 143 geofield parameter, 137– 138 types, 136, 150–157 Dataset drivers installing, 278–279 Datasets data binding, 54, 67, 134 Fields collection, 140 inserting in Visual Basic sample, 19 name parameter, 137 refreshing, 150 Themes collection, 183–186 type constants, 136 DataSets collection working with DataSet objects, 134 DBMS servers accessing remote spatial data, 160 Deleting map features, 111 Delphi installing MapX, 22 Delphi Native data source type, 137 Displaying data as points, 143–147 labels, 90 raster images, 92 Dot density maps thematic map type, 197– 198 Drawing layers, 95–96 Drilldown applications component table requirements, 228 drilldown table requirements, 228–230 drilldown tool, 232–233 procedure summary, 227 RollUp tool, 233 Drilldown layers description, 224–225 limitations and requirements, 242 related constants, 243 related methods and properties, 243 resetting, 242 terms and concepts, 225– 226 Drilldown tables metadata keys, 229–230 sample, 230–231 Drilldown tools creating, 232–233 with RollUp tools, 233–241 Dynamic parameter dynamic data binding, 139 MapX Developer’s Guide Index E Editing map features, 106–113 Exporting maps, 246–247 selection pattern, 247 F Feature objects properties, 103 FeatureFactory methods, 108 Features searching in Visual Basic sample, 19–20 types, 53 Features collection creating, 99–100 description, 98 modifying, 101 Fields collection data binding, 140 Fields parameter determining data source fields, 139 Fields.Add method adding column data as a field, 140–143 Fill styles in remote spatial tables, 176 Find object locating map features, 116– 117 result codes, 118–119 FindFeature object storing feature object properties, 118–119 G Geodictionary MapX Developer’s Guide data binding, 148–150 geodictionary file, 313–315 matching data source to a layer, 65 registering layers, 320 Geodictionary Manager command line options, 313, 321 registering MapInfo tables, 313 running, 316–319 utility location, 285 Geofield parameter data sources, 137–138 Geoset Manager labels, 307–310 Layer Control options, 305–310 Map menu options, 303– 311 Pan tool, 304 setting projections, 310– 311 setting zoom level, 303–305 utility location, 285 View menu options, 311–?? Geosets creating, 301–302 list of, 48–53 opening, 300 overview, 64 saving, 303 GIF files export format, 247 Graduated symbol maps thematic map type, 195– 196 Graphics Interchange Format files export format, 247 I Individual values maps thematic map type, 188– 190 Installation procedure, 10–11 product components, 8–9 system requirements, 8 Interactive labeling, 91 J JPEG files export format, 247 K Keys adding to registry, 282 L Label tool, 91 LabelProperties object controlling label display, 90–91 Labels controlling display, 90 generating for a layer, 89– 91 in Geoset Manager, 307– 310 removing, 91 Layer Control Geoset Manager, 305–310 Layer Control dialog calling, 79 display options, 80 Layer object layer properties, 82–84 LayerInfo object parameters, 166–167 337 Index Layers adding, 81 creating, 81 description, 74 displaying raster images as, 93 draw order in collection, 84 generating labels, 89–91 number in collection, 77 positioning in collection, 82 registering in Geodictionary, 320 removing, 82 user draw layers, 95–96 zoom layering, 87–89 Layers collection checking layer feature type, 86 checking layer type, 85 methods, 78–82 obtaining, 74–76 obtaining geogrpahic extents, 78 properties, 77–78 Layers.Add method accessing remote spatial data, 160–162 Legend objects with Theme objects, 187, 206 License string, 283–284 Line styles in remote spatial tables, 176 Locating map features, 116–117 Lotus Notes accessing data via Notes function queries, 25 accessing data via Notes View, 23–25 data driver installation, 22– 23 338 data source type, 137, 157 document support files, 278 with MapX control, 22 LotusScript using a Notes View from, 24–25 M Map control adding, 11–13 Map creation creating objects, 70–71 geoset overview, 64 layers overview, 63 Map object, 58–60 map properties, 61–62 Map features creating, 106–107 deleting, 111 description, 98 editing, 106–113 examining nodes of, 113 modifying, 109–110 obtaining for editing, 112 stand-alone, 101–102 Map layer description, 74 Map menu using Geoset Manager, 303–311 Map object feature types, 53 properties, 59–60 MapInfo Map Catalog creating, 171–172 making remote tables mappable, 170–175 MapInfo Professional creating Map Catalog in, 171 MapInfo tables component files, 46 data source type, 137, 152– 153 importing into SpatialWare, 171 registering in Geodictionary, 66–67, 313 MAPINFOW.PRJ file customizing, 215 parameters, 213–214 using settings, 213–216 Maps exporting, 246–247 printing, 248 MapX documentation set description, 26–28 enhancements and additions to v. 3.0, 41– 43 enhancements and additions to v. 3.5, 37– 40 enhancements and additions to v. 3.5.1, 36–37 installation procedure, 10– 11 key features, 3–4 new for v. 4.0, 30–35 product components, 8–9 system requirements, 8 upgrading v. 2.0 applications to v. 3.0, 43–44 MapX applications upgrading from earlier versions, 251 MapX control creating in Visual C++, 256 MapX data installation notes, 285 sources, 286–297 MapX events MapX Developer’s Guide Index in Visual C++, 259–260 MapX exceptions in Visual C++, 267–268 MapX OCX installing, 275–279 MapX required files MapX program files, 276 Windows common DLLs, 275 Menu items creating in Visual C++, 257–258 Methods accessing in Visual C++, 252–254 Annotations collection, 68 DataSets collection, 134 FeatureFactory, 108 Fields collection, 140 Find object, 116 Layers collection, 78–82 Selection collection Selection collection methods, 104 Themes collection, 183–186 Modifying existing map features, 109– 110 Features collection, 101 themes, 203–205 N NADCON support files, 277 Name parameter datasets, 137 O Object editing tools, 123 Objects creating, 70–71 MapX Developer’s Guide Visual C++ implementation, 252 ODBC connection string, 167– 168 ODBC data source type, 137, 151 ODBC support files, 277 OLE Dispatch Driver , 253 Opening geosets, 300 Oracle8i support, 164–165 P Pan tool Geoset Manager, 304 Pen styles in remote spatial tables, 175 Photoshop files export format, 247 Pie chart maps thematic map type, 201– 202 PNG files export format, 247 Point reference binding, 146 Point styles in remote spatial tables, 175 Polygon drawing tools, 129– 130 Polyline features creating, 112–113 Portable Network Graphics files export format, 247 Position of labels, 90 PowerBuilder data source type, 137, 155 inserting Map control, 21 Printing a map, 248 Product features, 3–4 Projections setting in Geoset Manager, 310–311 Properties accessing in Visual C++, 252–254 Annotations collection, 69 BindLayer object, 144–145 Feature object, 103 Find object, 116 FindFeature object, 118 Layer object, 82–84 Layers collection, 77–78 Map object, 59–60 Theme objects, 186–187 Property Page modifying a map, 61–62 PSD files export format, 247 R Ranged maps custom ranges example, 193–194 range distribution types, 191–192 thematic map type, 190– 192 Raster format handlers installing, 279–281 Raster images displaying, 92 support file location, 277 Refining boundaries feature searches, 117 Refreshing datasets, 150 Registering files, 278–279 Remote spatial data accessing, 160 accessing attribute data, 168–169 339 Index caching, 170 LayerInfo parameters, 166–167 mapping with X/Y columns, 163 ODBC connection string, 167–168 performance issues, 169 Remote spatial tables making mappable, 173–175 MapInfo Map Catalog, 170–175 specifying styles, 175–176 Removing labels, 91 layers, 82 Result codes Find object, 118–119 RollUp tools creating, 233 S Sample application Visual C++, 250 Sample applications additional programs, 5 Saving geosets, 303 Search type constants selections, 105 Secondary Geofield parameter, 138 Selectable layers, 84 Selection collection description, 98 Selections creating at specific point, 105 search type constants, 105 SelectionChangedEvent, 1 05–106 using queries in Visual 340 Basic 6, 20 within a distance in Visual Basic 6, 20 Shortcut menus adding in Visual C++, 265 SourceData parameter data binding, 136 SpatialWare importing MapInfo tables into, 171 troubleshooting MapX applications, 176–177 Specifying styles labels, 91 overriding for a layer, 83 Stand-alone features, 101–102 Standard tools available types, 123 polytools, 129 Static dataset objects interfaces, 325–331 registration, 323–324 Styles in remote spatial tables, 175 Symbol objects creating, 106–107 Symbol styles in remote spatial tables, 175 System requirements for Oracle8i, 164 MapX, 8 T Tab-delimited data data source type, 137, 153– 155 Tagged Image File Format files export format, 247 Text objects, 92 Thematic legends, 187, 206 Thematic maps bivariate, 202–203 types, 188–202 using data, 182–183 Theme objects properties, 186–187 ThemeDlg method, 203 Themes creating, 183–186 inserting in Visual Basic sample, 19 modifying, 203–205 type constants, 185 Themes collection methods, 183–186 ThemeProperties object, 204–205 TIF files export format, 247 Tool handler, 126–127 Tools custom, 122 object editing, 123 polygon drawing tools, 129–130 specifying current tool, 122 standard types, 123 Visual Basic 6.0 sample, 19 ToolUsedEvent, 128 U Unbound datasets data source type, 137, 155– 156 Upgrading applications to MapX 4.0, 13–14 MapX 2.0 applications to v. 3.0, 43–44 User draw layers, 95–96 MapX Developer’s Guide Index V View menu using Geoset Manager, 311–?? Visual Basic adding a map, 14–15 adding Map control to, 12 upgrading application to MapX 4.0, 13 using a Notes Query from, 25 using a Notes View from, 24 using Notes Query from, 25 version 4 example, 16–17 version 6 example, 18–20 Visual C++ adding Map control to, 12 adding shortcut menus, 265 built-in helper dialogs, 266–267 creating a map, 269–271 creating a MapX control, 256 creating menu items, 257– 258 custom tools, 261–262 data binding, 263–264 including MapX.cpp file, 255 MapX events, 259–260 MapX exceptions, 267–268 MapX properties and methods, 252–254 sample application, 250 upgrading applications to MapX 4.0, 14 upgrading MapX applications, 251 MapX Developer’s Guide W Windows common DLLs MapX required files, 275 Windows metafile export format, 247 WMF files export format, 247 X X-Y coordinates displaying as points, 145– 146 specifying in a different CoordSys, 211–212 Z ZIP Code data displaying as points, 146– 147 Zoom layering labels, 90 map layers, 87–89 setting for a layer, 83–84 Zoom level setting in Geoset Manager, 303–305 341