We are looking to use a web mercator projection for all of our layers. A few questions on that:
Are there any example projects that specifically use that projection?
It appears that to fully use the projection, our custom shapefiles should have a coordinates system in meters, not decimal degrees. Is this correct?
What else do we need to know about shapefiles/projections/ThinkGeo map control do we need to know?
So far, our shapefile-based layers are displaying with the web mercator projection, but our data-driven layers do not show up. This is why I’m thinking that our shapefiles need to be done in meters, not decimal degrees.
The map unit and current extent make sure which part of the map should be render on screen.
We cannot know the projection information of your shape file, so you should want to get that from data provider or view the .prj file of data. If you hadn’t set the correct bounding box, you maybe won’t see the shape appear on screen.
Projections can help you convert your data or single shape into the target projection, so it can be shown in the correct bounding box.
I’ve set the map unit to meters, and I can see our shapefiles one the map. There are two issues:
I can’t zoom in past a certain point, like I can when using decimal degree. I’ve set minimum scale to 0. Is there another map setting that needs to change?
When set to meters, the map takes up to 5 seconds to redraw after changing the extent. With decimal degrees, it is instant.
Set CustomZoomLevels can make it zoom into deeper.
I think that’s maybe related with the reprojection, reprojection is an additional process so it will takes additional time, please make sure your shape file contains index file, and if possible please open cache which should be helpful.
I turned caching on, but the results there are not as promising. In some instances, especially when zoomed in, the redraw rate is good. When zoomed out, however, it is still unacceptable, taking several seconds to redraw the map. I still find it interesting that this isn’t an issue when the map unit is set to decimal degree, but is so noticeable when set to meters.
It looks you have 3 shape files here: countrieswoUS_merged states and conus_land. What’s the size of them?
If they are not so big, you can directly attach them in this topic, if not you can upload them to our FTP, you should can get a FTP account from your sales.
And please make sure all your shape file had build its index file.
Private Sub WpfMap_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
Map1.MapUnit = GeographyUnit.DecimalDegree
Me.Map1.ZoomLevelSet.CustomZoomLevels.Add(New ZoomLevel(800)) '1125
Me.Map1.ZoomLevelSet.CustomZoomLevels.Add(New ZoomLevel(500))
Me.Map1.ZoomLevelSet.CustomZoomLevels.Add(New ZoomLevel(100))
Me.Map1.ZoomLevelSet.CustomZoomLevels.Add(New ZoomLevel(50))
Me.Map1.ZoomLevelSet.CustomZoomLevels.Add(New ZoomLevel(10))
Me.Map1.ZoomLevelSet.CustomZoomLevels.Add(New ZoomLevel(1))
Me.Map1.ZoomLevelSet.CustomZoomLevels.Add(New ZoomLevel(0.1))
Dim _folder = New String("D:\8268\")
Dim LAND_COLOR = GeoColor.StandardColors.Red
Dim layerOver As New LayerOverlay
Dim proj4 = New ManagedProj4Projection
proj4.InternalProjectionParametersString = ("+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs")
proj4.ExternalProjectionParametersString = ManagedProj4Projection.GetEpsgParametersString(4326)
proj4.Open()
Dim countries As ShapeFileFeatureLayer = New ShapeFileFeatureLayer(_folder & "countrieswoUS_merged.shp")
countries.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.Country1
countries.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20
countries.FeatureSource.Projection = proj4
countries.Open()
countries.WrappingMode = WrappingMode.WrapDateline
countries.WrappingExtent = countries.GetBoundingBox
Dim statesLayer As ShapeFileFeatureLayer = New ShapeFileFeatureLayer(_folder & "states.shp")
For Each aZoom As ZoomLevel In Me.Map1.ZoomLevelSet.CustomZoomLevels
statesLayer.ZoomLevelSet.CustomZoomLevels.Add(aZoom)
statesLayer.ZoomLevelSet.CustomZoomLevels(statesLayer.ZoomLevelSet.CustomZoomLevels.Count - 1).DefaultAreaStyle = AreaStyles.CreateSimpleAreaStyle(LAND_COLOR)
Next
statesLayer.FeatureSource.Projection = proj4
statesLayer.WrappingMode = WrappingMode.WrapDateline
statesLayer.WrappingExtent = New RectangleShape(-180, 90, 180, -90)
Dim countiesLayer As ShapeFileFeatureLayer = New ShapeFileFeatureLayer(_folder & "conus_land.shp") 'conus_land counties_inland
countiesLayer.ZoomLevelSet.ZoomLevel09.DefaultAreaStyle = AreaStyles.CreateSimpleAreaStyle(LAND_COLOR)
countiesLayer.ZoomLevelSet.ZoomLevel09.DefaultAreaStyle.OutlinePen.Color = GeoColors.Transparent
countiesLayer.ZoomLevelSet.ZoomLevel09.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20
countiesLayer.Name = "counties_land"
countiesLayer.FeatureSource.Projection = proj4
countiesLayer.WrappingMode = WrappingMode.WrapDateline
countiesLayer.WrappingExtent = New RectangleShape(-180, 90, 180, -90)
layerOver.Name = "abc"
layerOver.Layers.Add(countries)
layerOver.Layers.Add(countiesLayer)
layerOver.Layers.Add(statesLayer)
layerOver.TileCache = New FileBitmapTileCache("C:\tmp", layerOver.Name)
Map1.CurrentScale = 800
Map1.MinimumScale = 0
Map1.CurrentExtent = countries.GetBoundingBox
Me.Map1.Overlays.Add(layerOver)
Me.Map1.Refresh()
End Sub
Please update your dll to our latest version, and if you still met the same problem, please build a simple sample which can reproduce your issue, so we can work for it.
With map unit set to decimal degree, I don’t have any problems either. When I set it to Meter, which I believe I need to do to use a Web Mercator projection properly, that’s when the redraw is slow.
Why I set the mapunit to decimal degree is because your code set the 4326 as ExternalProjectionParametersString, that means you convert your shape file to 4326.
If you want to set as meter, please modify the ExternalProjectionParametersString.
I’ve switched from 4326 to 3857, which looks to be the correct external projection. I’ve got routines to show country/state/county borders. They works correctly when using 4326, but do not work when using 3857. Two questions:
Is 3857 the correct EPSG value for meters/web mercator projectons?
Is there something in the shapefiles that would need to be changed when using 3857?
3857 is the projection for web mercator, you can use it like this: ManagedProj4Projection.GetGoogleMapParametersString()
I am not sure what’s projection your shape file is under, if it’s under web mercator, you don’t need reprojection it, if that’s other projection even in meter, you should have to reprojection that also. And the statesLayer.WrappingExtent need be reprojection to 3857.
I’m still not seeing any borders drawing with using GetGoogleMapParametersString, and setting the projection of that ShapeFileFeatureLayer.
I am noticing that when I set proj4.ExternalProjectionParametersString = ManagedProj4Projection.GetGoogleMapParametersString() , that the land does not redraw when zooming in close. When it is set to 4326, it redraws on all zoom levels.
and set the projection, everything shows up as expected. I’m guessing this has to do with the shapefiles? I thought setting the projection for a layer override the projection for the shapefile.
Attached is the sample code which I’ve revised, please try it out and see if the performance looks good to you.
Some notes:
If you want to use tile cache, please make sure your map’s zoomlevel scales are divided by 2 from the upper zoom level.
Your shape files are already in Mercator format so you don’t need to reproject them again, you can see the projection info by open the .prj in notepad.
For the WrappingExtent, we recommend you to use a full world extent(e.g. -180,90,180,-90) instead of the boundingbox of a shape file.
As the map is under Meter mode, so the WrappingExtent should be reprojected to that projection, see how I did that in the sample code.
Don’t forget to set the tileCache’s matrix unit if it’s not DecimalDegree.
Private Sub WpfMap_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
Map1.MapUnit = GeographyUnit.Meter
Dim scale = Map1.ZoomLevelSet.ZoomLevel01.Scale
Map1.ZoomLevelSet.CustomZoomLevels.Add(New ZoomLevel(scale))
For index = 0 To 25
Map1.ZoomLevelSet.CustomZoomLevels.Add(New ZoomLevel(scale / (2 << index)))
Next
Me.Map1.BackgroundOverlay.BackgroundBrush = New GeoSolidBrush(GeoColor.StandardColors.LightBlue)
Dim decimalProj4 = New ManagedProj4Projection
decimalProj4.InternalProjectionParametersString = ManagedProj4Projection.GetEpsgParametersString(4326)
decimalProj4.ExternalProjectionParametersString = ManagedProj4Projection.GetGoogleMapParametersString()
decimalProj4.Open()
Dim _fullMapBoundingBox = decimalProj4.ConvertToExternalProjection(New RectangleShape(-180, 90, 180, -90))
Dim _folder = "D:\8268\"
Dim countries As ShapeFileFeatureLayer = New ShapeFileFeatureLayer(_folder & "countrieswoUS_merged.shp")
countries.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.Country1
countries.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level10
'countries.FeatureSource.Projection = proj4
countries.Open()
countries.WrappingMode = WrappingMode.WrapDateline
countries.WrappingExtent = _fullMapBoundingBox
countries.Close()
Dim statesLayer As ShapeFileFeatureLayer = New ShapeFileFeatureLayer(_folder & "states.shp")
For Each aZoom As ZoomLevel In Me.Map1.ZoomLevelSet.CustomZoomLevels
statesLayer.ZoomLevelSet.CustomZoomLevels.Add(aZoom)
statesLayer.ZoomLevelSet.CustomZoomLevels(statesLayer.ZoomLevelSet.CustomZoomLevels.Count - 1).DefaultAreaStyle = AreaStyles.Country2
Next
'statesLayer.FeatureSource.Projection = proj4
statesLayer.WrappingMode = WrappingMode.WrapDateline
statesLayer.WrappingExtent = _fullMapBoundingBox
Dim countiesLayer As ShapeFileFeatureLayer = New ShapeFileFeatureLayer(_folder & "conus_land.shp") 'conus_land counties_inland
countiesLayer.ZoomLevelSet.ZoomLevel09.DefaultAreaStyle = AreaStyles.Country2
countiesLayer.ZoomLevelSet.ZoomLevel09.DefaultAreaStyle.OutlinePen.Color = GeoColors.Transparent
countiesLayer.ZoomLevelSet.ZoomLevel09.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20
countiesLayer.Name = "counties_land"
'countiesLayer.FeatureSource.Projection = proj4
countiesLayer.WrappingMode = WrappingMode.WrapDateline
countiesLayer.WrappingExtent = _fullMapBoundingBox
Dim layerOver As New LayerOverlay
layerOver.Name = "test"
layerOver.Layers.Add(countries)
layerOver.Layers.Add(countiesLayer)
layerOver.Layers.Add(statesLayer)
layerOver.TileCache = New FileBitmapTileCache("C:\tmp", layerOver.Name)
layerOver.TileCache.TileMatrix.BoundingBoxUnit = GeographyUnit.Meter
Me.Map1.Overlays.Add("test", layerOver)
'Me._bordersOverlay = New LayerOverlay
'Me.Map1.Overlays.Add(OVERLAY_BORDERS, Me._bordersOverlay)
Me.Map1.CurrentExtent = _fullMapBoundingBox
Me.Map1.MinimumScale = 0
Me.Map1.Refresh()