So you want to add custom street names or other labels on your Google Map? For example on this location. After learning current (3.6) google map js API you have these possible options:
KmlLayer (not works now)
GroundOverlay (works!)
OverlayView (should work)
KmlLayer "...adds geographic markup to the map from a KML, KMZ or GeoRSS file that is hosted on a publicly accessible web server...”. We can try this latest feature to add path with label. And it will work in Google Earth. But if path is too short – Google Earth will not show us a label. Workaround for short path is just make it long by adding start and end points few times:
<coordinates>
55.043196,82.907145 55.043473,82.909902
55.043196,82.907145 55.043473,82.909902
55.043196,82.907145 55.043473,82.909902
55.043196,82.907145 55.043473,82.909902
</coordinates>
Then we already see our nice custom label in Google Earth, but in Google Map not. Most possible reason is that google earth's latest feature is too latest. Currently it’s a fail way, but may be later, google map's KML renderer will take that feature into account.
GroundOverlay is "... a rectangular image overlay on the map ...". All is much simple.
Create image:
Open your Google Earth (make sure your latitude/longitude settings are Mercator) and go to your location
Add one pixel white image on your area and make it 33% transparent
Go to properties / place tab of your image overlay and copy latitudes/longitudes from there
Make screenshot in Google Earth and paste it to your favorite graphic editor
Crop image to the borders of your white transparent area
Add layer, where you will add your custom labels and add them
Switch off your base layer and save the result as png, for example overlay.png
Add the resulting image to your google map as:
google.maps.event.addDomListener(window, 'load', function() {
var mapDiv = document.getElementById('map'),
opts = {mapTypeId: google.maps.MapTypeId.HYBRID},
map = new google.maps.Map(mapDiv, opts),
area = new google.maps.LatLngBounds(
new google.maps.LatLng(55.042297, 82.906337),
new google.maps.LatLng(55.043862, 82.910473)
),
overlay = new google.maps.GroundOverlay(
'overlay.png', area, {map: map, clickable: false}
);
map.fitBounds(area);
});
OverlayView you can try by yourself.
ps: Is this a correct format for article? Or may be it should be a community wiki?
I created a MapLabel utility library a while ago. While it doesn't have any rotation or text-on-path capabilities (I'd love to see you add it!), it does let you put text on a map.
Related
I set up a PostGIS database that I added in GeoServer via a parameterized SQL view. I used Leaflet to display this layer via wms.
It worked fine until I add GeoWebCache using the url "/geoserver/gwc/service/wms" instead of "/geoserver/wms". I can still see my polygons when I'm at the minimal zoom. But then when I zoom I see only a red polygon and a half of a green polygon and if I zoom again I see only the red polygon. You can see these 3 states on the images below:
I guess this is a problem of tiling: I get the minimal tiles and also some tiles around the red polygon for further zooms but for some reason it seems that the other tiles are not sent.
Here is the code I use to get my wms layer with leaflet:
geoJSONlayer = L.tileLayer.wms("/geoserver/gwc/service/wms", {
layers: 'cartowiki:choix',
format: 'image/png',
transparent: true,
viewparams: 'year:'+(annee+3000)
}).addTo(map);
geoJSONlayer.addTo(map);
Do you have an idea of the problem here ?
Thanks in advance,
The bounding box was the problem indeed. In Geoserver, I had to modify the properties of the layer in 2 places :
I clicked 'Compute from SRS bounds' and then 'Compute from native bounds' in the Bounding Boxes part of the Data section
I erased and created again the available gridsets in the Tile Caching section so that the grid subset bounds would update with the new Bounding Boxes
I hope it can help someone in the future!
I am using the Google Maps API to add some overlays to the map. I'm not having any trouble actually adding the overlays where I want since I found this nifty jsfiddle to determine corners on a map: http://jsfiddle.net/4cWCW/3/
But I discovered that Google skews some of the image overlays, specifically ones that are more north or south. This makes sense since a map is a 2D projection of a globe and some skewing happens, but I don't want google impose this on my overlays. I am wondering if there is any way to correct for this?
overlay method(javascript):
var imageBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(42, 27.9),
new google.maps.LatLng(80, -168.6));
var tempOverlay = new google.maps.GroundOverlay("ru2.png", imageBounds);
tempOverlay.setMap(map);
Specifically here, I have a silhouette of Russia I want to place on the map, but it stretches the top of the image without changing the lower part of it, so I can't actually line it up with the county location.
I am using Leafletjs. Currently its pretty straight forward, I have a streets view from open maps.
var streets = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: 'Map data © OpenStreetMap contributors'
});
I also have a WMS layer that is coming from a geoserver. It has the standard getFeatureInfo and everything shows up correctly.
L.tileLayer.wms("GEOSERVERURL", {
layers: 'layers',
format: 'image/png'
,transparent: true
}).addTo(map);
The wms layer is also clickable and I use getFeatureInfo to get the info for that layer. The issue is that the user doesn't know its clickable because the cursor never changes when they hover of the wms layer. My question is how do make the cursor change when hovering over the layer?
Has anyone implemented this feature before or have an idea to implement it? The only research I have stumbled across so far has using mouseover on the map and calling getFeatureInfo to tell if its over a layer. However, that seems like it would cause a lot of chatter just to identify cursor area.
EDIT: To clarify, I want the cursor to only change when its hovered over the wms layer that is populated. Although it technically gets applied to the whole map, it only has content on a part of it. Which kind of raises the question of 'Can I limit the wms layer to only the content area and then show a cursor?' Maybe a bounding area or something along those lines?
EDIT 2: Below is an example of what it looks like. The street map parts I want to keep the normal cursor but I want a pointer when hovering over the colored wms map parts.
Set an ID on the tileLayer's container and then use CSS to change the cursor:
Javascript:
var wms = L.tileLayer.wms("GEOSERVERURL", {
layers: 'layers',
format: 'image/png',
transparent: true
}).addTo(map);
wms.getContainer().setAttribute('id', 'wmsContainer');
Stylesheet:
#wmsContainer {
cursor: grab; /* or any other cursor: https://developer.mozilla.org/en-US/docs/Web/CSS/cursor */
}
Note: you need to do this after the layer is added to the map. Before you add it to the map the getContainer method will return undefined.
Edit after question edit and comments:
Unfortunatly that's not possible. At least not as far as i know. Because L.TileLayer.WMS is a layer of images, there is absolutely no way of deducting which tiles have features on them and which are transparent.
What you could do as a workaround is work out the boundaries of your object, use that to create a transparent polygon without stroke and put that over your WMS layer. Polygons are interactive thus you get the cursorchange included, plus as an extra bonus, you can do other fancy stuff like show the outline or something like that on mouseover. I've created a little demo from the WMS example you supplied in the comments.
http://plnkr.co/edit/1HGn6IUzdrn1N5KGazXQ?p=preview
Note that i'm using a GeoJSON layer with one feature instead of a polygon, because it was easier to find the outline of the US in GeoJSON format. But in your case a four point polygon would do the trick just as wel.
Hope that helps, let me know if something isn't clear.
I'm currently using Mapnik to create choropleth tiles of regions in Brazil via node-mapnik by using the g.connector from Wax as in the code below and it works well.
var map = new google.maps.Map(document.getElementById('map-canvas'), {
center: new google.maps.LatLng(-23.1851, -51.0754),
zoom: 8,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.SMALL
},
mapTypeId: google.maps.MapTypeId.HYBRID
});
var tiles = {
tilejson: '2.0.0',
tiles: ['url/{z}/{x}/{y}.png']
};
map.overlayMapTypes.insertAt(0, new wax.g.connector(tiles));
But I've noticed, using Chrome developer tools, that Google maps is sending two separate pngs per x, y, z tile back (one a 512x512 vt png with roads and labels and the second a 256x256 kh png of the ground).
Using Wax or other JavaScript tools, is it possible to insert the PNG I'm getting back from Mapnik between the two Google map pngs? My goal is to get the labels to be on top of the images returned by Mapnik. This can certainly be accomplished by changing the opacity of the Mapnik tiles, but the colors don't stand out nearly as well when opacity is reduced. Any help is greatly appreciated.
Looks like it's not currently supported.
If you look at the actual html - the two satellite image layers are in a nested div with a z-index, and the overlay is in a separate div with a different z-index. I believe it's not possible to for a separate div to be nested inside two different z-index's of a different div, aka, this doesn't work:
<div style:"z-index: 5"></div>
<div>
<div style:"z-index: 1"></div>
<div style:"z-index: 10"></div>
</div>
For a single tile, it is possible to detach it from the overlay div, and re-attach it to the map tile div, and assign z-indexes to all three images, but it doesn't seem very practical.
At the moment, there are a number of open requests to add this as a feature to google maps, but nothing exists.
Here's and idea for an alternate approach - enable your google map without the road layer (search for google map style wizard), and render the road layer onto your tiles using mapnik from openStreetMap data.
I am currently working on google map and new to it..
I want to know is it possible to divide the map into certain tiles with definite height and width and to color them.. If yes then somebody can just explain how to do it as i am facing difficulties.
I think what you are referring to is known as overlays in the Google Maps API. Do you want to achieve something like this? (click to show overlay)
The polygons section in the Google Maps API documentation would be the place to go to learn more.
If there is a limited area (geographically) that you would like to color based on map tiles, then you could create a custom tile layer overlay for that area (with each tile colored appropriately).
You can read the documentation for Tile Layer Overlays, but the gist is that you create a GTileLayer object, then set a property on that object with a function, getTileUrl, that is called when Google maps need to insert a tile in Google Maps.
In your getTileUrl function, you can return your own version of the tile (which you can draw with a colored tint based on the origional tile):
tilelayer.getTileUrl = function(point, zoom) {
if (zoom == 17 && point.x == 38598 && point.y == 49259)
return "../pics/origional_tile_with_colored_tint.png";
};
Once you have a a GTileLayer object, you instantiate a GTileLayerOverlay (passing in your GTileLayer) and add it to the GMap2 object (with the addOverlay method).
You can find an example of this here.