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.
Related
I am working on a Google Streetview indoor application using the Google Maps JS API. I am using panorama pictures that are available on Google Streetview. I sometimes want to programatically change the position, for instance when somebody clicks on a position in a small map. However, when I call panorama.getPosition() I automatically get redirected to a different position. I can actually see the position_changed event being triggered twice.
I already sort of found the cause of this issue. It has something to do with the starting/entrance positions Google maps uses for Streetview Indoor.
The two orange circles depict the two possible starting/entrance points into the building. When dropping the pegman over these circles you will enter the building in Streetview Indoor.
It looks like when these starting points exist, the Google Maps API does not let you programatically set the position to some position other then any of the starting points. It will always redirect you to one of the starting points. This is obviously not what I want.
//The starting/entrance position is lat: 52.089988, lng: 5.178041
//The position I want to go to
var goToPosition = {lat: 52.0898852, lng: 5.1780344};
//Position changed EventListener
google.maps.event.addListener(panorama, 'position_changed', function() {
var newPosition = panorama.getPosition();
console.log('changed position to:', newPosition.lat(), newPosition.lng());
});
//Calling setPosition with goToPosition
panorama.setPosition(goToPosition);
//Will result in two console.logs directly printed after another:
changed position to: 52.0898852 5.1780344 //goToPosition
changed position to: 52.089988 5.178041 //starting position
The console.logs show that it looks like the position is being changed twice directly after each other, ending the position at the starting position.
I'm wondering if any body else has encountered this problem and if there is a known workaround for this. I am in contact with the photographer that uploaded the panorama pictures to Google. Maybe there's something in the way these pictures are uploaded to Google and configured. I wonder if this can even be fixed in my application code, or if it's an API problem or even expected behavior.
Thanks!
I found the solution for my problem, partly thanks to #LilDevil's answer.
Each panorama for a position has a panorama ID. If you know the panorama ID in advance, it can be used to move to that position using setPano().
I store panorama ID together with the lat,lng of a position. When clicking on the map I calculate the known position that is nearest to the clicked position. I can then look up the panorama ID that belongs to this position and use it to move to that panorama using setPano().
This doesn't seem to be a very clean way to solve the problem, because the panorama ID might change over time (for instance when new panorama pictures are uploaded to Google Streetview). However, I couldn't find anything in the documentation that says this method shouldn't be used. The documentation says that this method should be used when dealing with custom panorama pictures, which is not the case in my situation. Also, in this specific situation we are in control of when new panorama pictures will be uploaded (because it's for Google Indoor) so I can change the stored panorama ID's if that happens.
You can't just set the panorama to any coords. You need to use getPanorama() with your start coords and a radius, to find the coords to the nearest panorama, then set the pano to those coords. Some examples on https://developers.google.com/maps/documentation/javascript/streetview?hl=en
I am working with markers and adding them like this:
markerLatLang = new google.maps.LatLng(35.6412142,139.6988337);
marker = new google.maps.Marker({position: markerLatLang, map: map});
When I go in to street view all the markers are at ground level. Is there a way to position a marker at x meters above ground or at a set altitude?
Unfortunately, as Dr.Molle said, this option doesn't exist in Google Maps API for now.
I have done this using a PNG image having bottom empty space how much you want. I also did not find a proper way to do that but this trick may be helpful to you.
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 building a simple PHP based off-road navigation webpage for use on a smartphone that will display two icons on a Google map, one being my my current location and one my destination. As I move, the position of the icon for me will automatically update.
Sample code to do the basic stuff includes:This Stackoverflow example and This tutorial.
I would like my icon to be an arrow that points in the direction I am currently walking. The direction would be based on my previous position and my current position. Does anyone know of any method to achieve that please?
One crude method would be to have 8 (or 16) icons, representing N, S, E, W, NE... and pick the icon that approximately matches my direction, but I was hoping for something more dynamic.
The other option is to simply draw a path on the map of where I have been. I am thinking of doing that anyway, but would also like the arrow.
To clarify exactly what I want, This Stackoverflow example contains this code to display a marker of my current position on a map:
map = new google.maps.Map(document.getElementById("map_canvas"), {
zoom: 18,
center: new google.maps.LatLng(startPos.coords.latitude, startPos.coords.longitude),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var marker = new google.maps.Marker({
position: new google.maps.LatLng(startPos.coords.latitude, startPos.coords.longitude),
map: map
});
Instead of the teardrop type marker I want an arrow that is pointing in the direction I am walking. I would calculate the direction for it to point based on the lat/long of my previous location and my current location, but I need the code to insert in the above code where it says position:...
This is basic navigation stuff so I am sure it has been done before. I just haven't been able to find any examples. (I do not want to use Google directions API. It has a usage limit and is not really suited to off-road.)
I haven't tried this myself, but it seems the Google Maps Javascript API provides functionality for this. You can use the google.Maps.Symbol object.
With the rotation property you can set the rotation of the symbol in degrees. You need to get the angle between the current location and destination from the API first then.
With the path property you can set a the symbol. Google already implemented symbols for arrows, they use the constants BACKWARD_CLOSED_ARROW, BACKWARD_OPEN_ARROW, FORWARD_CLOSED_ARROW and FORWARD_OPEN_ARROW.
It also seems to support coloring, scaling, etc. for the symbol, so you can do quite some things with it. I hope this information helped.
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.