I am trying to display a google static map, which when clicked, will open up a larger iframe, where the user can pan, zoom, etc.
JSFiddle here
Code below:
<div>
<a class="various fancybox.iframe" title="Whitehouse - USA" href="https://maps.google.com/maps?f=d&source=s_d&saddr=&daddr=1600+Pennsylvania+Ave+NW,+White+House,+Washington,+DC+20500&hl=en&geocode=Ca3jx5Eq6BcjFQ6IUQIdG4Ro-ynPaZnjvLe3iTGGOSyaFzTP2g&sll=38.897678,-77.036517&sspn=0.009644,0.01443&g=1600+Pennsylvania+Avenue+Northwest,+Washington,+DC&mra=ls&ie=UTF8&t=m&ll=38.89768,-77.036519&spn=0.008016,0.013733&z=16&output=embed">
<img src="http://maps.googleapis.com/maps/api/staticmap?center=1600+Pennsylvania+Ave+NW,+White+House,+Washington,+DC+20500&markers=1600+Pennsylvania+Ave+NW,+White+House,+Washington,+DC+20500&size=300x300&sensor=false">
</a>
</div>
I have tried to look for the non-javascript documentation relating to the iframe,but haven't come across anything. I would like to add the following to the iframe:
Center on the marker - The JSFiddle appears centered, but the exact same code run on the production site renders an iframe with the marker appearing in the top left.
Remove the marker label "B"
Input my own coordinates from my database - for example... do the same for New York City, Chicago, etc.. However, I have tried changing the daddr (destination address), but am unsure what the other variable stand for (i.e. sll, sspn, g, mra, ll, etc.)
Get directions - insert starting point, and get directions to pre-determined destination
At first a explanation of the parameters you need:
f
has to be d for directions
saddr
the start-address, may be a string(would be geolocated) or a latLng
daddr
the destination-address, may be a string(would be geolocated) or a latLng
ll
where to center the map(latlng) .when ommited, the map will be centered based on the markers
z
the zoom of the map. When ommitted the map will be zoomed based on the direction
output
has to be embed for iframe
A detailed list and explanation of the parameters you'll find at http://www.seomoz.org/ugc/everything-you-never-wanted-to-know-about-google-maps-parameters
However: you should note that none of the parameters is a part of any official API, it may change every day
The issues:
Center on the marker:
the marker could not be centered, because the iframe isn't visible when the map starts loading, unable to determine the size of the iframe . You could use a workaround:
First load a dummy-page into the iframe, when the fancybox is open, load the map.
This can be done by adding this to the fancybox-options:
beforeLoad: function(){
//store the original href for later use
this.oldhref=this.href;
//replace the href with some dummy-page
this.href='wait.htm';
return true;
},
afterLoad:function(){
//load the originally requested page to the iframe
$('.fancybox-iframe').attr('src',this.oldhref);
}
Remove the marker label "B"
there is no option to remove the B, all you can to is replace it with an A .
Therefore you must set the marker as the marker for the start-destination (saddr)
Input my own coordinates from my database
apply the coordinates to saddr or daddr(depending on what it should be, start or destination)
Get directions - insert starting point, and get directions to pre-determined destination
see 3.
Finally: you should consider to create a own map using the Maps-Javascript-API to get a map that you can handle yourself.
Related
I am trying to use tiles that I have generated with the google maps static API with leaflet (I need to generate some tiles in advance because they will be used offline with no internet connection).
For example, to create a 640x640 tile centred on the Isle of Man at lat/lng (54.217, -4.5373) with a zoom level 8, I am using the following request URL: https://maps.googleapis.com/maps/api/staticmap?center=54.217,-4.5373&zoom=8&size=640x640&maptype=roadmap
The resulting tile is shown below:
Next I want to use this tile with leaflet and add a marker at the center of the tile with the following code:
<html>
<header>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.0.2/dist/leaflet.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="http://localhost/leaflet.js"></script>
<style>
#map {height: 640px; width:640px;}
</style>
</header>
<body>
<div id="map"></div>
<script type="text/javascript">
$( document ).ready(function() {
// Handler for .ready() called.
console.log("document ready!");
var map = L.map('map').setView([54.217, -4.5373], 8);
L.tileLayer('http://localhost/staticmap.png', {
attribution: 'Copyright Google Maps',
tileSize: 640,
minZoom:8,
maxZoom:8,
continuousWorld: false,
nonoWrap: false,
}).addTo(map);
var marker = L.marker([54.217, -4.5373]).addTo(map);
});
</script>
</body>
</html>
It seems however that the resulting map is completely "off-centred" as illustrated below (the marker should also be on the isle of man). Not sure what I am doing wrong here:
Any help of this would be greatly appreciated! Thanks!
First, take into account that images from the "static maps API" are not tiles: you can request arbitrary sizes, and there is no trivial scheme to stitch such images back together. Tiles work nice because when one tile ends, another tile begins. Tiles need a grid, much like the one explained in the TMS specification.
Second, as they are not tiles, using a L.TileLayer is not the best way. For a north-oriented image fitting the map's projection scheme, the way to go is using a L.ImageOverlay.
To use an image overlay, you'll need to calculate the bounding box of the image. In your case, we can do that manually as so:
console.log('lat-lng of center:', map.containerPointToLatLng( map.getSize().divideBy(2) ));
console.log('lat-lng of center -320px:', map.containerPointToLatLng( map.getSize().divideBy(2).subtract([320,320]) ));
console.log('lat-lng of center +320px:', map.containerPointToLatLng( map.getSize().divideBy(2).add([320,320]) ));
Once you have the URL for the image overlay and the bounds, add it to the map and it should look like this.
Last, be aware of the terms and conditions for stuff coming from the google maps API, in particular:
10.5.d No caching or storage. You will not pre-fetch, cache, index, or store any Content to be used outside the Service, [...]
Also be aware that other web map platforms don't have those restrictions.
I am creating a map object with a long/lat position as center. When clicking the google logo in the bottom left corner you are routed to google maps with the same position as center. But in the embedded map I have also added a marker at the center position.
Is it possible to have that marker set when you route to google maps as well?
I couldn't find anything in the documentation..
The logo's link looks like this:
https://maps.google.com/maps?ll=40.758893,-73.985132&z=10&t=m&hl=en-US&gl=US&mapclient=apiv3
In your case all you have to do is change the parameters of the link.
Using the ?q=40.758893,-73.985132 parameter instead of ?ll=40.758893,-73.985132 is probably enough for you. The q=latitude,longitude puts a marker to the position. Although it is possible to use both parameters. The q is the marker's position and the ll is the center of the map. (use the & separator between them).
I think it is against the Google Maps API ToS to modify the Google branding or the link. But anyway it is possible with javascript.
You can see the original answer here: How to change Google logo's href
After the map is loaded you can manipulate the link:
...
map.addListener('tilesloaded', function(){
modifyLogoLink();
});
...
And here is how to change the link:
function modifyLogoLink(){
var anchors = document.getElementsByTagName('a'),
l = anchors.length,
i,
a;
for (i = 0; i < l; i++) {
a = anchors[i];
if (a.href.indexOf('maps.google.com/maps?') !== -1) {
// here you can manipulate the anchor
a.href = a.href.replace('ll=', 'q=')
}
}
}
Please also note that the Google's link is changed every time when the map is dragged or zoomed. So you must handle this as well.
Hope this helps.
HTML has supported image maps since time immemorial. You know, this sort of thing
<img src="url/to/your/image.jpg" alt="" usemap="#Map" />
<map name="Map" id="Map">
<area href="#" shape="poly" coords="381,90,386,64,421,32,462,19,501,32,535,62,540,83" />
<area href="#" shape="poly" coords="509,115,511,127,492,132,483,119,487,112" />
<area href="#" shape="poly" coords="425,113,433,108,449,118,444,128,429,128" />
</map>
I have some data in a database that determines the source for an image and defines named sets of area coordinates. This is stored as a string of JSON which parses into an object graph, and knockout renders it all into a web page complete with click handlers that return the correct identifier for each area.
All this works just fine, and I mention it only to provide operational context.
When the user clicks an area, I'd like to toggle its visibility. For example, imagine indicating one or more affected regions for an injury on an anatomical diagram, or the bent bits of the car in an insurance claim app, that sort of thing.
The problem is making an area visible. Areas do not render. So I need to draw over the image. I know it can be done; google maps does it.
I don't know where to start or what to search for. This is the first time I've ever needed to draw directly - normally I supply elements and let the browser render as it will.
So, how about some search terms, key words and perhaps even links to video tutorials? In particular I need to overlay the image so I need to draw in the same coordinate space. While you're all busy downvoting this question I'll be researching "canvas" and "drawing over images".
You can "highlight" mapped portions of your img like this:
Exactly overlay a canvas element of the same size using CSS
Tell canvas not to respond to mouse/touch events: pointer-events:none
When a mapped area is clicked, tell canvas to draw that area in a low-opacity fill using path commands:
context.beginPath();
context.moveTo(381,90);
context.lineTo(386,64);
context.lineTo(421,32);
context.lineTo(462,19);
context.lineTo(501,32);
context.lineTo(535,62);
context.lineTo(540,83);
context.closePath();
// fill the path area with a low-opacity red (or color of you choosing)
context.globalAlpha=0.15;
context.fillStyle='red';
context.fill(); // this fills the path
context.globalAlpha=1.00; // just resetting to default opacity
That allows you to keep your existing code that uses img.
Alternatively, if your design permits significant refactoring, you can draw the image on canvas and use context.isPointInPath to hit-test each path versus the mouse-click position. Then fill the hit path with the low-opacity fill.
[ Addition: Saving area coordinates for later use in hit-testing ]
Warning: untested code, might need tweaking
For easy re-use of each areas coordinates, you can put each set of coordinates in an object and put those objects in an array:
var areas=[];
// first area coordinates
arrays.push([ {x:381,y:90}, {x:386,y:64}, ... etc ]);
// second area coordinates
arrays.push([ {x:509,y:115}, {x:511,y:127}, ... etc ]);
...
Then use those saved area coordinates to do your hit-testing:
function isMouseInArea(mouseX,mouseY){
var index; // index of any "hit" area. leave it initially null
for(var i=0;i<areas.length;i++){
// create a path from this area's coordinates
defineAreaPath(areas[i]);
// test if the mouse is inside this area
if(ctx.isPointInPath(mouseX,mouseY)){
index=i;
}
}
// return any "hit" index of areas[] or return null if no hits
return(index);
}
// utility function to define a path from the supplied coordinates
function defineAreaPath(pts){
// create a path from this area's coordinates
ctx.beginPath();
ctx.moveTo(pts[0].x,pts[0].y);
for(var i=1;i<pts.length;i++){
ctx.lineTo(pts[i].x,pts[i].y);
}
ctx.closePath();
}
And you can use the isMouseInArea function like this:
var index=isMouseInArea(mouseX,mouseY)
if( index ){
// draw the area path that was "hit" by the mouse
defineAreaPath(areas[index]);
// fill that path with low-opacity fill
ctx.globalAlpha=0.15;
ctx.fillStyle='red';
ctx.fill();
ctx.globalAlpha=1.00;
}
From responses to other related questions it appears the HTML committee has been squabbling about image maps for canvas for five years.
Short version: you can't.
Long version: Use a canvas, set the image as its background and do your own hit testing.
how to have custom image marker on google static map, i need url format:
this is what i have tried, but its having default marker image
http://maps.google.com/maps/api/staticmap?center=25.3176452,82.97391440000001,&zoom=15&markers=25.3176452,82.97391440000001|25.3176452,82.97391440000001&path=color:0x0000FF80|weight:5|25.3176452,82.97391440000001&size=175x175&sensor=TRUE_OR_FALSE
This is what you want:
http://maps.googleapis.com/maps/api/staticmap?zoom=17&size=512x512&maptype=hybrid&markers=icon:http://cdn.sstatic.net/Sites/stackoverflow/img/favicon.ico|34.052230,-118.243680
for a custom image, put the icon:url after of markers...
Format
icon:url|lat,lng
Example
icon:http://cdn.sstatic.net/Sites/stackoverflow/img/favicon.ico|34.052230,-118.243680
a result of my example
For more information check google maps api, there are more information like size, markers position, center map, map type... etc.
https://developers.google.com/maps/documentation/static-maps/intro#MapTypes
*If the icon, img, don't appear it will be the size of image, try with another size,less than 64x64 px, format of image, "GIF, JPEG and PNG", the documentation recommend "PNG", if it doesn't appear check permision of image for public request(external request)...
According to the documentation you can specify custom icons like so:
markers=icon:...
e.g. amending your URL:
http://maps.google.com/maps/api/staticmap?center=25.3176452,82.97391440000001,&zoom=15&markers=icon:http://www.megaadresse.com/images/icons/google-maps.png|25.3176452,82.97391440000001&path=color:0x0000FF80|weight:5|25.3176452,82.97391440000001&size=175x175
Gives you:
PS: the sensor parameter is no longer required.
PPS: also you seemed to have specified the same coordinates twice in your markers parameter, so it was actually drawing two markers on the same location.
You can add an image in the marker:
var campaign_map = new google.maps.Map(document.getElementById("campaign_map_canvas"), mapOptions);
var selected_marker = new google.maps.Marker({
position: position,
map: campaign_map,
icon: 'path/to/image'
});
google.maps.event.trigger(campaign_map,'resize');
EDIT
You can use the following:
https://maps.googleapis.com/maps/api/staticmap?size=480x480&markers=icon:path/to/image.png%257C996600%7Carea/you/want/
We are now trying to build a map library like google/bing/yahoo,we will use it offline.
However I found that I have no idea about how to arange the divs in the page,since there are some many different types of divs.
1) the map tiles (small image 256X256)
2)the overlayer(marker/informationwindow/polygon...)
3)the control.
I have to try to read the html source codes of google and bing and etc. But I found it is difficult to understand them.
For exmaple,this frangment is copyed from another online map site of China.
As you can see,it is just a exmaple for how to adding a marker to the map.
But take the code,there are so many nested divs,most of them have the property of "width:0;height:0",I do not know why?
Since in my opinion,the marker is just an icon,just put it in the page.
Why use so many nested divs and even the "map" tag?
But I think they must have the advantages which I can not find.
Any one can give some suggestions?
Typically you insert a div in HTML when you want to create a block element but there is no more semantically-loaded element available with the correct meaning.
I think the answer to your question is to use just as many div elements as you need for your purposes. Do not add more just because you can. Sometimes you don't need any div elements at all - you can use other more meaningful elements such as img, ul, p, etc. You can sometimes avoid inserting a wrapping div by using CSS to change an inline element such as a into a block element.
If you need more later then add them later. Don't worry about what Google/Bing/Yahoo do. Their requirements are probably different to yours.
Have you looked at the Google Maps sample code and demo gallery?
http://code.google.com/apis/maps/documentation/javascript/demogallery.html
http://code.google.com/apis/maps/documentation/javascript/examples/index.html
I'm not sure how you would use this "offline" considering the sample you provided makes a call to the internet to get the map. Also all of these types of maps rely heavily on javascript and ajax calls to constantly update the map. Do you mean these pages would be secured and not public?
How about you just use maybe a 5x5 grid of divs, move them as they are dragged out of view, and then texture them dynamically with AJAX calls.
If I am understanding you correctly, all of the layers can be thrown on top of each other with z-index.
<div id="control" style="z-index:-1;"></div>
<div id="overlay" style="z-index:-2;"></div>
<div id="map" style="z-index:-3;"></div>
Then you can use each of these divs as containers for different parts of your map.
As you drag 1 div off to, say, the right, then it will automatically bump itself to the left side of your grid and retexture itself (background-image) through an ajax call.
That's what I would do, at least.
Use the Google Maps API you can see an example of custom tiles here: http://code.google.com/apis/maps/documentation/javascript/examples/maptype-base.html
You would need to copy all the files to your computer to be exceccible offline. Your javascript would look something like this:
function CoordMapType() {
}
CoordMapType.prototype.tileSize = new google.maps.Size(256,256);
CoordMapType.prototype.maxZoom = 19;
CoordMapType.prototype.getTile = function(coord, zoom, ownerDocument) {
var div = ownerDocument.createElement('DIV');
div.style.backgroundImage=coord+'.js';
return div;
};
CoordMapType.prototype.name = "Tile #s";
CoordMapType.prototype.alt = "Tile Coordinate Map Type";
var map;
var chicago = new google.maps.LatLng(41.850033,-87.6500523);
var coordinateMapType = new CoordMapType();
function initialize() {
var mapOptions = {
zoom: 10,
streetViewControl: false,
mapTypeId: 'coordinate',
mapTypeControlOptions: {}
};
map = new google.maps.Map(document.getElementById("map_canvas"),
mapOptions);
google.maps.event.addListener(map, 'maptypeid_changed', function() {
var showStreetViewControl = map.getMapTypeId() != 'coordinate';
map.setOptions({'streetViewControl': showStreetViewControl});
});
// Now attach the coordinate map type to the map's registry
map.mapTypes.set('coordinate', coordinateMapType);
}