ThinkGeo.com    |     Documentation    |     Premium Support

Limiting zoom levels when using InMemoryMarkerLayer

I've got a map which uses an InMemoryMarkerLayer to display a range of numbered markers over a OSM layer. I've got the data displaying fine, however I'm having trouble limiting the range of zoom levels.


I'd like to limit the zoom levels to between 8 and 18, when I tried this with a ShapeFileFeatureLayer I simply modified the ZoomLevelSet, however it seems that the MarkerZoomLevel has a different interface which doesn't allow for this.


Any ideas how I go about modifying the available zoom levels?



private static RectangleShape englishExtents =
    new RectangleShape(-645000, 7530000, 210000, 6430000);

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        // Set viewport, etc on map
        SignsMap.MapBackground.BackgroundBrush =
            new GeoSolidBrush(GeoColor.FromHtml("#E5E3DF"));
        SignsMap.CurrentExtent = englishExtents;
        SignsMap.RestrictedExtent = englishExtents;
        SignsMap.MapUnit = GeographyUnit.Meter;
        SignsMap.MapTools.MouseCoordinate.Enabled = true;
        
        // Setup OSM layer on map
        OpenStreetMapOverlay osmOverlay =
            new OpenStreetMapOverlay("Open Street Map");
        SignsMap.CustomOverlays.Add(osmOverlay);

        // Define marker overlay for placing marker pins on map
        InMemoryMarkerOverlay markerOverlay =
            new InMemoryMarkerOverlay("MarkerOverlay");

        markerOverlay.FeatureSource.Open();
        markerOverlay.Columns.Add(new FeatureSourceColumn("Label"));
        markerOverlay.Columns.Add(new FeatureSourceColumn("Status"));
        markerOverlay.FeatureSource.Close();

        ValueMarkerStyle markerStyle = new ValueMarkerStyle("Status");

        // Small Map Marker, used for single digit marker numbers
        MarkerValueItem smallMarker = new MarkerValueItem("Small");
        smallMarker.DefaultMarkerStyle.WebImage =
            new WebImage("/Images/SignMarker.png", 40, 35, 0, -35);
        smallMarker.DefaultMarkerStyle.WebImage.Text = "[#Label#]";
        smallMarker.DefaultMarkerStyle.WebImage.TextOffsetX = 14;
        smallMarker.DefaultMarkerStyle.WebImage.TextOffsetY = 3;
        smallMarker.DefaultMarkerStyle.WebImage.FontColor = GeoColor.StandardColors.Yellow;
        smallMarker.DefaultMarkerStyle.WebImage.FontStyle =
            new GeoFont("ARIAL", 10, DrawingFontStyles.Bold);
        markerStyle.ValueItems.Add(smallMarker);

        markerOverlay.ZoomLevelSet.ZoomLevel01.CustomMarkerStyle = markerStyle;
        markerOverlay.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

        // Add marker layer to map
       SignsMap.CustomOverlays.Add(markerOverlay);
    }
}

protected void Button1_Click(object sender, EventArgs args)
{
    // Grab the marker overlay
    InMemoryMarkerOverlay markerOverlay =
        (InMemoryMarkerOverlay)SignsMap.CustomOverlays["MarkerOverlay"];

    Feature feature1 = new Feature(-296134, 6731273, "veh1");
    feature1.ColumnValues.Add("Label", "4");
    feature1.ColumnValues.Add("Status", "Small");
    markerOverlay.Features.Add(feature1);

    Feature feature2 = new Feature(-294510, 6730280, "veh2");
    feature2.ColumnValues.Add("Label", "44");
    feature2.ColumnValues.Add("Status", "Medium");
    markerOverlay.Features.Add(feature2);

    Feature feature3 = new Feature(-292484, 6729076, "veh3");
    feature3.ColumnValues.Add("Label", "444");
    feature3.ColumnValues.Add("Status", "Large");
    markerOverlay.Features.Add(feature3);

    // Set the zoom extents
    SignsMap.CurrentExtent = new RectangleShape(-296134, 6731273, -292484, 6729076);
}



 


Iain,
The ZoomLevels of InMemoryMarkerLyaer is determined by the base overlay that the map used now. So if we want to limit the Zoom levels of MarkerOverlay, we need to limit the zoom levels of base overlay.
The OpenStreetMap is a kind of XYZ server. In other words, they generated the tile images based on zoom levels, latitude and longitude. It’s a little special, different from other overlay. To limit the OSMOverlay, here are hints:
1.       Set the customZoomLevels on server side. Please remember to invoke the SyncClientZoomLevels of the map.
2.       On client side, overwrite the mapParser.InitBaseOverlay to reset the baselayer’s numzoomlevels and resolutions in OnMapCreating function.
3.       On client side, overwrite the method “getURL” of Openlayers.Layer.OSM to make sure the z value is based on 8 not 0. Sample code like below:
penLayers.Layer.OSM.prototype.getURL = function(bounds) {
                var res = this.map.getResolution();
                var x = Math.round((bounds.left - this.maxExtent.left) / (res * this.tileSize.w));
                var y = Math.round((this.maxExtent.top - bounds.top) / (res * this.tileSize.h));
                var z = this.map.getZoom() + 8;
 
                var url = this.url;
                var s = '' + x + y + z;
                if (url instanceof Array) {
                    url = this.selectUrl(s, url);
                }
 
                var path = OpenLayers.String.format(url, { 'x': x, 'y': y, 'z': z });
 
                return path;
            };
Please have a try, any questions please let us know.
Thanks,
Johnny

Thanks for that, I'll look into it when I get the chance.



Iain, 
  
 Ok, Any question please let us know. 
  
 Thanks, 
  
 Johnny