ThinkGeo.com    |     Documentation    |     Premium Support

Shapefile and FeatureLayerWpfDrawingOverlay

Hi

We have a WPF application using ThinkGeo for showing a raster map and several layers contained in shapefiles. Each shapefile can be show/hide, moved to the front pushed to the back, …
When showing shapefiles I load the shape file with similar code:

    ShapeFileFeatureLayer shapeFileLayer = null;

    try
    {
        shapeFileLayer = new ShapeFileFeatureLayer(shapefile.LayerFile);
        shapeFileLayer.Open();

        shapeFileLayer.Name = shapefile.LayerName;
        shapeFileLayer.IsVisible = shapefile.Visible;

        // set the wished ZoomLevels and styles
        
        // configure the projection
    }
    catch (Exception ex)
    {
        return false;
    }
    finally
    {
	if (shapeFileLayer.IsOpen)
	{
	    shapeFileLayer.Close();
	}
    }

    m_OverlayShapeFiles.Layers.Add(shapefile.LayerName, shapeFileLayer);
    m_OverlayShapeFiles.Layers.MoveToTop(shapeFileLayer);

Where m_OverlayShapeFiles is:

private readonly LayerOverlay m_OverlayShapeFiles;

I have tried to replace LayerOverlay with FeatureLayerWpfDrawingOverlay but I got the following exception:
EXCEPTION: The FeatureSource is not open. Please call the Open method before calling this method.
at ThinkGeo.Core.ValidatorHelper.CheckFeatureSourceIsOpen(Boolean isOpen)
at ThinkGeo.Core.QueryTools.GetFeaturesInsideBoundingBox(RectangleShape boundingBox, ReturningColumnsType returningColumnNamesType)
at ThinkGeo.UI.Wpf.FeatureLayerWpfDrawingOverlay.xEM=(GeoCollection`1 layers, IMapArguments mapView)
at ThinkGeo.UI.Wpf.FeatureLayerWpfDrawingOverlay.DrawAsyncCore(RectangleShape targetExtent, OverlayRefreshType overlayRefreshType, CancellationToken cancellationToken)
at ThinkGeo.UI.Wpf.Overlay.DrawAsync(RectangleShape targetExtent, OverlayRefreshType refreshType, CancellationToken cancellationToken)
END EXCEPTION --------------------------------------------------------------------

Is it possible to use FeatureLayerWpfDrawingOverlay with shape files?
If so what is wrong in my code?

Best regards
Domenico

Hi Domenico,

The issue comes from the shapeFileLayer.Close(); in your finally block — by the time the overlay tries to draw, the layer has already been closed. With FeatureLayerWpfDrawingOverlay , you don’t need to manually call Open() or Close() . The overlay will handle that lifecycle for you.

You can check the sample How Do I → Vector Data Styling → Render Layers to see how shapefiles are rendered with either LayerOverlay or FeatureLayerWpfDrawingOverlay .

Just as a note: if your shapefile contains many features, FeatureLayerWpfDrawingOverlay may not be the best choice because it will redraw all features on each pan/zoom. In such cases, LayerOverlay is generally more efficient.

Thanks,
Ben

Hi Ben

If I do not open the layer then I got this exception:

EXCEPTION: The Layer must be opened before you can perform this method.
   at ThinkGeo.Core.ValidatorHelper.CheckLayerIsOpened(Boolean isOpen)
   at ThinkGeo.Core.ShapeFileFeatureLayer.GetShapeFileType()
   at Damm.MapCtrl.WPF.MapShapeFilesLayerUpdater.ImportShapefile(DammMapShapefile shapefile, Boolean centerShapefile, PointShape& centerAt) in D:\Repos\Releases\Ver08_12\Damm\DammMapCtrl.WPF\MapShapeFilesLayerUpdater.cs:line 410
END EXCEPTION --------------------------------------------------------------------

In order to explain this I show what I mean with the comment: // set the wished ZoomLevels and styles

This is what I am doing in the code:

    Collection<ThinkGeo.Core.ZoomLevel> layerZoomLevels = shapeFileLayer.ZoomLevelSet.GetZoomLevels();

        for (int i = 0; i < layerZoomLevels.Count; i++)
        {
        	layerZoomLevels[i].Scale = m_MVVMZoomLevels[i].Scale;
            layerZoomLevels[i].IsActive = i >= minIdxZoomLevel && i <= maxIdxZoomLevel;
        }


        PointStyle stylePoint = MapShapesStyles.GetDefaultPointStyle(shapefileMVVM.StylePoint);
        AreaStyle styleArea = MapShapesStyles.GetDefaultAreaStyle(shapefileMVVM.StyleArea);
        LineStyle styleLine = MapShapesStyles.GetDefaultLineStyle(shapefileMVVM.StyleLine);

        ThinkGeo.Core.ZoomLevel startZoomLevel = layerZoomLevels[(int)minIdxZoomLevel];

        switch (shapeFileLayer.GetShapeFileType())
        {
            case ShapeFileType.Null:
                break;

            case ShapeFileType.Point:
            case ShapeFileType.PointM:
            case ShapeFileType.PointZ:
                startZoomLevel.DefaultPointStyle = stylePoint;
                break;

            case ShapeFileType.Polygon:
            case ShapeFileType.PolygonM:
            case ShapeFileType.PolygonZ:
                startZoomLevel.DefaultAreaStyle = styleArea;
                break;

            case ShapeFileType.MultipointZ:
            case ShapeFileType.MultipointM:
            case ShapeFileType.Multipoint:
            case ShapeFileType.Polyline:
            case ShapeFileType.PolylineM:
            case ShapeFileType.PolylineZ:
                startZoomLevel.DefaultLineStyle = styleLine;
                break;

            default:
                break;
        }

        ApplyUntilZoomLevel applyLevel = ApplyUntilZoomLevel.Level20;

        switch (maxIdxZoomLevel)
        {
            case 0U: applyLevel = ApplyUntilZoomLevel.Level01; break;
            case 1U: applyLevel = ApplyUntilZoomLevel.Level02; break;
            case 2U: applyLevel = ApplyUntilZoomLevel.Level03; break;
            case 3U: applyLevel = ApplyUntilZoomLevel.Level04; break;
            case 4U: applyLevel = ApplyUntilZoomLevel.Level05; break;
            case 5U: applyLevel = ApplyUntilZoomLevel.Level06; break;
            case 6U: applyLevel = ApplyUntilZoomLevel.Level07; break;
            case 7U: applyLevel = ApplyUntilZoomLevel.Level08; break;
            case 8U: applyLevel = ApplyUntilZoomLevel.Level09; break;
            case 9U: applyLevel = ApplyUntilZoomLevel.Level10; break;
            case 10U: applyLevel = ApplyUntilZoomLevel.Level11; break;
            case 11U: applyLevel = ApplyUntilZoomLevel.Level12; break;
            case 12U: applyLevel = ApplyUntilZoomLevel.Level13; break;
            case 13U: applyLevel = ApplyUntilZoomLevel.Level14; break;
            case 14U: applyLevel = ApplyUntilZoomLevel.Level15; break;
            case 15U: applyLevel = ApplyUntilZoomLevel.Level16; break;
            case 16U: applyLevel = ApplyUntilZoomLevel.Level17; break;
            case 17U: applyLevel = ApplyUntilZoomLevel.Level18; break;
            case 18U: applyLevel = ApplyUntilZoomLevel.Level19; break;
            case 19U: applyLevel = ApplyUntilZoomLevel.Level20; break;
            default: applyLevel = ApplyUntilZoomLevel.Level20; break;
        }

    startZoomLevel.ApplyUntilZoomLevel = applyLevel;
}
  1. I apply the scale to the zoom levels based to the scales I defined in the map
  2. I activate/deactivate the zoom level in the layer (I assume the shape file is not shown when the zoom level is not active)
  3. I apply the style based on the shapeFileLayer.GetShapeFileType() and a set of predefined styles.

The call to shapeFileLayer.GetShapeFileType() is raising an exception if the layer is not open

Best regards
Domenico

Hi Ben

If I call ShapeFileFeatureLayer.Open shall I call Close when I remove the shapefile layer from the overlay?

Best regards

Domenico

Hi Domenico,

I see. In this case, you can simply keep the layer open — there’s no need to close it until it’s no longer needed, for example when the window is closed or when you remove it from the overlay.

Thanks,
Ben