MapDotNet UX Help

MapDotNet UX Services can render, query, edit and transform spatial data from several different sources- SQL Server 2008/2012, SQL Azure (spatial), ArcSDE 9.x, PostGIS, KML, and shapefiles.  Regardless of the data source, there are two requirements that a data source must satisfy.

  1. All features from the data source must be of the same type.  An enumeration of WKT types is used to represent possible types.  These are Point, MultiPoint, LineString, MultiLineString, Polygon, and MultiPolygon.  There is limited support for geometry collections.  Geometry collections are parsed and a single type of shape is returned.  If the collection contains polygons, they are all returned as a MultiPolygon.  Otherwise if the collection contains lines, they are all returned as a MultiLineString.  Otherwise all points are returned as a MultiPoint.

    In practice, mixing the basic and MULTI versions of the same sort of geometry will not prevent rendering, but may cause problems during exports or prevent auto-detection of geometry type.  Mixing different geometry types may cause some features not to render.
  2. All features from the data source must use the same coordinate reference system.  Common coordinate reference systems are assigned a number called an SRID.  Customized coordinate reference systems can be described using Proj4 or WKT strings.  MapDotNet UX Services generally work with SRIDs or Proj4 strings.

    For some back end stores, mixed coordinate reference systems will cause rendering to fail.  For others, some features will not render.


When Studio is used to add a layer to a map file, it will attempt to determine the coordinate reference system and geometry type but will prompt the user for these when they cannot be determined.  These determinations are made in different ways for different data sources.

To be able to export data from one data source to another, Studio must also be able to determine the extent of the spatial data.  The extent is generally the bounding box of the features.  For some data sources, Studio may instead obtain user-defined extents which may differ from the actual data extents.  Extents are used when specifying spatial indexes, which Studio creates when exporting data..

Spatial indexing almost always improves the performance of map rendering and spatial queries.  Even if you don't use Studio to create data sources, you should make sure all your data sources are indexed.

SQLServer 2008/2012

MapDotNet UX Services support the Geometry data type.  The Geography type is unsupported.

By default, SQL Server 2008/2012 does not constrain the type or the SRID for data in a given table.  However, comparisons between shapes with different SRIDs always fail. Studio looks for check constraints to determine the type and SRID for a SQL Server 2008/2012 layer.  Check constraints should restrain the geometry column to a single type and SRID.  Without such constraints, Studio will have to prompt you for this information.

Here is an example of a check constraint that restricts both type and SRID.  The table name is "scratch_point_wgs84" and the geometry column is called "the_geom".

ALTERTABLE [dbo].[scratch_point_wgs84] WITH CHECK ADD CONSTRAINT [CK_scratch_point_wgs84] CHECK ([the_geom].[STSrid]=(4326)AND [the_geom].[STGeometryType]()='Point')

When you use Studio to export data to SQL Server 2008/2012, it creates such constraints for you.  This can cause issues when the actual data is loaded.  SQL Server 2008/2012 is very strict about valid geometries.  We call the "MakeValid()" function on every geometry added toSQL Server 2008/2012.  If a geometry is not valid, "MakeValid()" may change the type.  For instance, a MULTILINESTRING that consists of two duplicate lines will be reduced to a LINESTRING.  This will fail against the type constraint and the row will not insert.

Performance will be improved for SQL Server 2008/2012 data sources if the data has a spatial index.  Additionally, Studio uses the bounding box of the spatial index as the extent for the data source.  Here is an example of a spatial index on a table called "scratch_polygon_wgs84".

CREATESPATIALINDEX [scratch_polygon_wgs84_sidx] ON [dbo].[scratch_polygon_wgs84] ([the_geom] )
USING GEOMETRY_GRID
WITH (BOUNDING_BOX =(-85.25, 29.5, -83.25, 31.5), GRIDS =(LEVEL_1 = MEDIUM,LEVEL_2 = MEDIUM,LEVEL_3 = MEDIUM,LEVEL_4 = MEDIUM),CELLS_PER_OBJECT = 16)

When Studio exports data to Sql Server 2008 creates a spatial index.  The bounding box will be slightly larger than the extent of the data.  If you will often query over a larger region, you should drop and recreate the index with a bounding box that will contain your query region.

When executing feature queries against SQL Server 2008/2012 data sources, QueryRequest.MaxRows constraints will prevent the index from being used.  You should avoid using MaxRows and handle any needed row limits within your application.

PostGIS

PostGIS uses a table called "geometry_columns" to hold metadata about spatial tables, including the SRID and geometry type.  Studio uses this table to determine the type and SRID.  When Studio exports data to PostGIS it populates this table appropriately, as do utilities such as shp2pgsql.  If you create a table manually, you must add a reference to it to the "geometry_columns" table.  You should also add check constraints corresponding to the settings in the "geometry_columns" table.

ALTER TABLE scratch_polygon_wgs84
ADD CONSTRAINT enforce_geotype_the_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL);

ALTER TABLE scratch_polygon_wgs84
ADD CONSTRAINT enforce_srid_the_geom CHECK (srid(the_geom) = 4326);

PostGIS is very sensitive to the case of identifiers.  To avoid problems, table and column names should be in lower case.

PostGIS spatial indexes are very simple to create and do not require bounding boxes.

CREATE INDEX scratch_polygon_wgs84_the_geom_gist ON scratch_polygon_wgs84
USING gist(the_geom)

Studio can determine the actual extent of features in a PostGIS table even if the table is not indexed.  Indexing tables is still highly recommended.

When Studio exports data to PostGIS it creates a spatial index.

ArcSDE

MapDotNet UX accesses ArcSDE through the C API.  Studio uses API calls to determine the geometry type and user-defined extents.  ArcSDE uses WKT strings for coordinate reference systems.  Studio generally can't determine the SRID and will display the WKT and prompt the user for an SRID.  (If the extents are within the range -180, -90 to 180, 90 studio will suggest that the SRID may be 4326, which represents WGS 84.)

Studio can export from ArcSDE but cannot export to it.

ArcSDE spatial indexes are very complex and beyond the scope of this document.

The C API for ArcSDE must be installed on any machine hosting MapDotNet Web Services or MapDotNet Studio in order to connect to ArcSDE.

Oracle Spatial

Oracle Spatial is supported.  SRIDs and extents are determined from the ALL_SDO_GEOM_METADATA view.  All Oracle Spatial tables must have spatial indexes.

Studio can export from Oracle Spatial but cannot import to it.

Oracle Instant Client 11.1.0.6.0 must be installed on any machine hosting MapDotNet Web Services or MapDotNet Studio in order to connect to ArcSDE.  Hosts must be specified using TNS names.

Shapefiles

Shapefiles store spatial data in a set of flat files.  At a minimum there must be .shp, .shx, and .dbf files.  Studio can determine the type and extent from these.  Studio generally can't determine the SRID and will prompt the user for an SRID.  If there is a .prj file, the WKT from that will be displayed.

Studio can export from shapefiles but cannot export to them.  The ISC.MapDotNetServer.Core.Data.ShapefileSupport namespace contains a class, ShapefileHelper, with methods for writing shapefiles.

Shapefiles typically render slowly.  To alleviate this, we provide a command line utility called ShapefileIndexer.  ShapefileIndexer creates a file with an .mdns.index extension.  The syntax is

ShapefileIndexer shapefilepath\shapefile.shp [level]

where level is an optional value from 2 to 10.  The default is 7, and generally values around 7 or 8 will work best.  For very large data sets try 9 or 10.  A good rule of thumb is that the .mdns.index file should be roughly comparable to the size of the .shx file +/- 50%.

The index file will improve the performance, but it creates a very basic spatial index.  You will get better performance by exporting the data to a database.  You can export to Sql Server 2008 or PostGIS using Studio.  You can also export to PostGIS by using the shp2pgsql utility and piping the output to psql, and you can export to ArcSDE by using the shp2sde utility.

KML

Data can be stored as "Placemark" elements in KML files.  MapDotNet UX can extract geometries from KML placemarks in KML files (but not in KMZ files).  Style information is not extracted.  Type and extents are determined by processing all placemarks.  SRID is always reported as 4326 (WGS 84).

Studio can export from KML files but cannot export to them.

World Data Sets

Data at the global level can pose some additional challenges.  Spatial filters that extend beyond the expected value regions of a coordinate system may produce unexpected results, and shapes that cross the antimeridian (180th meridian) may not render correctly.  See Overview of the Map Model for a discussion of the MaximumExtents and TestForCrossingMaximumExtents properties of a Map object that can be used to control how world data is handled.  There are a few key points.

  • If none of your data will cross the antimeridian you can set TestForCrossingMaximumExtents to false in your map requests (MapRequest.Map.TestForCrossingMaximumExtents).
  • If you will not need to render data on tiles at the edge of the world you can set MaximumExtents to false in your map requests (MapRequest.Map.MaximumExtents).  Note that at zoom level one, all four tiles are at the edge of the world.  If you set MaximumExtents to false you will want to set MinZoomLevel appropriately on your TileLayer objects.
  • Our test for crossing the antimeridian is such that shapes wider than half the world but not as wide as the entire world will not render correctly.  Avoid such data and make sure that objects that should span the entire world, such as Antarctica, have points at the -180 and +180 longitudes.