Google Maps API infoWindowAnchor not working? - javascript

I am trying to get the infoWindow to display in just the right place on a Google Maps integration I'm working on (just above the top right/top left corner of an image). Whenever I try to adjust the "infoWindowAnchor" it doesn't seem to be working? However, the "iconAnchor" seems to be working as expected. I am wondering if anyone has ever run into a similar scenario before? I am making use of a custom icon, but even when I revert back to the standard icons provided by Google, the infoWindow seems to be displaying incorrectly (The tail is centered on the icon as opposed to being placed in it's top right position).
Below is the code I'm using to get this all working. The Important bits are here, but I've removed some of the other functions that may get in your way when diagnosing.
$(document).ready(function() {
var centerLatitude = 37.782112;
var centerLongitude = -122.419281;
var sanFran = new GLatLng(centerLatitude, centerLongitude);
var startZoom = 12;
var map;
var icon;
// Creates a default icon using our tuberent image
var myIcon = new GIcon();
myIcon.image = baseurl + 'my/imageFolder/markerFolder/image.png';
myIcon.shadow = baseurl + 'my/imageFolder/markerFolder/shadow.png';
myIcon.iconSize = new GSize(25,25);
myIcon.shadowSize = new GSize(38,25);
myIcon.iconAnchor = new GPoint(13,25);
myIcon.infoWindowAnchor = new GPoint(13,0);
myIcon.printImage = baseurl + 'my/imageFolder/markerFolder/printImage.gif';
myIcon.mozPrintImage = baseurl + 'my/imageFolder/markerFolder/mozPrintImage.gif';
myIcon.printShadow = baseurl + 'my/imageFolder/markerFolder/printShadow.gif';
myIcon.transparent = baseurl + 'my/imageFolder/markerFolder/transparent.png';
myIcon.imageMap = [22,0,22,1,22,2,21,3,21,4,21,5,21,6,21,7,23,8,24,9,24,10,22,11,22,12,22,13,22,14,22,15,22,16,22,17,22,18,22,19,22,20,22,21,22,22,22,23,22,24,2,24,1,23,1,22,1,21,1,20,1,19,1,18,1,17,1,16,1,15,1,14,1,13,1,12,1,11,0,10,0,9,1,8,3,7,4,6,5,5,7,4,8,3,9,2,10,1,11,0];
map = new GMap2(document.getElementById('map'));
map.addControl(new GMapTypeControl());
map.addControl(new GLargeMapControl3D());
map.setCenter(sanFran, startZoom);
/* Some Random Code and Functions here .... */
var point = new GLatLng(location.lat, location.lng);
var marker = new GMarker(point, myIcon);
map.addOverlay(marker);
/* Some Random Code and Functions here .... */
GEvent.addListener(marker, "click", function(){
var randomText = "Just some random test text";
var myHtml = "<b>#" + location.id + "</b><br/>" + location.neighborhood + "<br/>" + randomText;
map.openInfoWindowHtml(point, myHtml);
});
});
$(document.body).unload(function() {
if (GBrowserIsCompatible()) {
GUnload();
}
});

You could also try setting the pixel offset in the GInfoWindowOptions of openInfoWindowHTML().
Can you move the info window at all? By setting very large values just to test?
Otherwise, I doubt this is the answer, but I'd try it just in case.
From Google Maps API:
"Once we've created a map via the GMap2 constructor, we need to initialize it. This initialization is accomplished with use of the map's setCenter() method. The setCenter() method requires a GLatLng coordinate and a zoom level and this method must be sent before any other operations are performed on the map, including setting any other attributes of the map itself."
You're adding a couple of controls before calling setCenter().

Related

How do I create an image reference in Javascript equivalent to a document.getElementById?

I have javascript code that retrieves GPS coordinates from a geotagged image. I use document.GetElementByID which loads a variable with (as I understand it) the reference to the HTML image object. It then passes that reference to my custom code which then retrieves the GPS coordinates from the image. This all works beautifully.
I want to eliminate the HTML image div and ID, and simply send my function the SAME sort of reference using purely javascript, without using document.GetElementById.
Basically, I want to convert from this:
var myimage = document.getElementById("img1"); //img1
getLocation(myimage, function(location) {
console.log("latitude is " + location[0] + " and longitude is " + location[1]);
}); //location is the array with the gps coordinates, created by getLocation
to something like this:
var myimage = "...some image reference here, equivalent to above";
getLocation(myimage, function(location){
console.log("latitude is " + location[0] + " and longitude is " + location[1]);
}); //location is the array with the gps coordinates, created by getLocation
I don't want to use HTML divs as eventually I will be retrieving images from a db and using the code to "process" them. I tried using document.createElement but that didn't seem to work.
If I understand it correctly
var x = document.getElementByID("img1");
stores a reference to the image in the variable 'x' whereas
var x = document.createElement("img1");
x.setAttribute("src", "img1.jpg");
actually creates and stores the image DOM object itself?? In any case, the code using document.createElement didn't successfully process 'x' in the second example, so it appears that isn't the right way to do this.
How would I resolve this? Thanks.
All: based on your inputs and various attempts, I've settled on using new Image(); etc. and it works brilliantly.....BUT, only in MOZILLA! I've set up a sample array of image objects, and the code processes the images in the array in turn, pulling the GPS coordinates and logging them to the console. In Chrome, however, it only returns a single set for one image, and after lots of trial and error it seems to work ONLY for the image listed in the HTML (which I wanted to remove!).... Not sure why Mozilla would behave one way and Chrome differently unless it has something to do with cacheing.....in fact, if I refresh in Mozilla it re-loads and re-runs the code perfectly, but in Chrome I don't get the gps coordinates logged when I refresh the browser. In fact, much of my time was wasted trying to "fix" code that works fine (at least in Mozilla). Here's the current version:
<!doctype html>
<html>
<head>
<script type="text/javascript" src="exif.js"></script>
</head>
<body>
<br/><br/>
<img src="coussay.jpg" id="img1" />
<br/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script type="text/javascript">
function convertDMtoDD (coordinates, direction) {
//convert the decimal minutes coordinate array to decimal degrees
//set the sign based on direction where "S" or "E" is negative
gpsdegrees = (coordinates[0]);
gpsminutes = (coordinates[1]);
leftminutes = Math.floor(gpsminutes);
rightminutes = (gpsminutes - leftminutes) / 60;
leftminutes = leftminutes / 60;
rightminutes = leftminutes + rightminutes;
degdecimal = (gpsdegrees + rightminutes).toFixed(6);
if (direction == "S" || direction == "W") {
degdecimal = 0 - degdecimal;
}
return degdecimal;
}
function getLocation(myimage, fn) {
//EXIF.getData in the EXIF.js library gets the EXIF data from the raw image DOM object
myimage.onload=EXIF.getData(myimage, function() {
//EXIF.getTag pulls the various data for each tag such as latitude, longitude, etc.
//lati and longi are arrays containing decimalminutes values; latd and longd are single values of either "N", "S", "W", or "E")
var lati = EXIF.getTag(this, "GPSLatitude");
var latd = EXIF.getTag(this, "GPSLatitudeRef");
var longi = EXIF.getTag(this, "GPSLongitude");
var longd = EXIF.getTag(this, "GPSLongitudeRef");
var location = [];
//convert data from decimal minutes to decimal degrees and set direction as neg or pos
location[0] = convertDMtoDD(lati, latd);
location[1] = convertDMtoDD(longi, longd);
fn(location);
});
}
var imagelist = [
{name: 'Chateau Coussay', src: 'coussay.jpg'},
{name: 'Chateau Courlaine', src: 'coulaine.jpg'},
{name: 'Chateau Sainte-Chapelle', src: 'chapelle.jpg'}
];
for (var i=0; i<imagelist.length; i++) {
var myimage = new Image();
myimage.src = imagelist[i].src;
getLocation(myimage, function(location) {
console.log("latitude is " + location[0] + " longitude is " + location[1]);
});
}
</script>
</body>
</html>
You need to use the proper tag name img, not img1.
var x = document.createElement("img");
x.setAttribute("src", "img1.jpg");
You may also need to add the element into the DOM, perhaps like so:
document.getElementById("img-container").appendChild(x);

Bing Maps not displaying properly on website

I have used Bing Maps onto my website, in which I used Script
<script>
$(document).ready(function () {
var map = null;
function LoadMap() {
map = new Microsoft.Maps.Map(
document.getElementById('bing_maps_content'),
{
credentials: ".............."
});
}
$('#btnlocation').click(function () {
var url = "/Home/getlocation";
$.getJSON(url, null, function (data) {
$.each(data, function (index, LocationData) {
var pushpin = new Microsoft.Maps.Pushpin(map.getCenter(), null);
pushpin.setLocation(new Microsoft.Maps.Location(
LocationData.longitutde,
LocationData.latitude
));
map.entities.push(pushpin);
map.setView({
zoom: 4, centre: new Microsoft.Maps.Location("-37.81633","144.97097")
});
});
});
});
LoadMap();
});
$(".jump-response").each(function () {
var hue = 'rgb(' + (Math.floor((256 - 199) * Math.random()) + 200) + ',' + (Math.floor((256 - 199) * Math.random()) + 200) + ',' + (Math.floor((256 - 199) * Math.random()) + 200) + ')';
$(this).css("background-color", hue);
});
and loaded the data using controller and Model using Microsoft Bing map tutorial C# MVC . It works fine but when displayed onto my website it becomes like this.
It's displaying these diamond white shapes even if I zoom in. How do I get rid of these covering the map?
lol, wow, that is impressive. In the 9+ years I have been working with Bing Maps I have never seen that before.
Ok, now onto solving the issue. The code you provided won't cause this effect. It looks like each circle consists of a single map tile which is nothing more than an image tag. I suspect that somewhere in your application you have a CSS style for images that gives them a large border radius in order to make them look like circles. This style appears to be applied to all images in your app. Take a look at your CSS and look for any definitions on the img tag.

Nokia / HERE maps goes back to level 0 zoom after map.zoomTo

My javascript code loops through some user data and adds each one as a marker to a container. It then adds that container to a nokia map and uses the Display zoomTo to zoom to the bounding box of the container holding all the markers.
However, right after that happens, the map just zooms itself all the way back out. The zoomTo call is the very last of my code that executes so it seems like something weird is going on.
this.finishMapping = function () {
map.objects.add(multiMapContainer);
var markerHopefully = multiMapContainer.objects.get(0);
$.ajax({
dataType: "jsonp",
url: "https://route.api.here.com/routing/7.2/calculateroute.json?app_id=WgevZ2m4AF8WHx1TY6GS&app_code=G11AO2dbvCRTdCjfTf-mUw&waypoint0=geo!" + markerHopefully.coordinate.latitude + "," + markerHopefully.coordinate.longitude + "&waypoint1=geo!" + markerHopefully.coordinate.latitude + "," + markerHopefully.coordinate.longitude + "&mode=fastest;car;",
success: function (data) {
onRouteCalculated(data)
},
jsonp: "jsoncallback"
});
function onRouteCalculated(data) {
if (data.response) {
var position = data.response.route[0].waypoint[0].mappedPosition;
var coordinate = new nokia.maps.map.StandardMarker([position.latitude, position.longitude]);
var tempContainer = new nokia.maps.map.Container();
tempContainer.objects.add(coordinate);
map.zoomTo(multiMapContainer.getBoundingBox().merge(tempContainer.getBoundingBox()), false);
}
}
}
I debugged through it in Chrome and I can see that zoomTo does actually zoom to the proper bounding box, but then right after I hit the 'continue' button it jumps back to the highest zoom level.
I recently came across a similar issue. The basic issue was that the containing <DIV> for the map was itself being initialized during the map initialization. My problem was compounded because map.zoomTo() doesn't work during map initialization anyway (since 2.5.3 map loading is always asynchronous)
The crux of the issue was that I was trying to use zoomTo() on a 0x0 pixel map since the <DIV> wasn't displayed yet - hence I ended up with a zoomLevel zero map.
The solution is to add listeners to the map as shown:
map.addListener("displayready", function () {
if(bbox){map.zoomTo(bbox, false);}
});
map.addListener("resize", function () {
if(bbox){map.zoomTo(bbox, false);}
});
And set up the bbox parameter as each coordinate is received as shown:
function onCoordinateReceived(coordinate){
if(bbox){
bbox = nokia.maps.geo.BoundingBox.coverAll([
bbox.topLeft, bbox.bottomRight, coordinate]);
} else {
bbox = nokia.maps.geo.BoundingBox.coverAll([coordinate]);
}
map.zoomTo(bbox, false);
}
So that:
If the map is already intialized and displayed the zoomTo() in the onCoordinateReceived() will fire
If the map completes intialization after onCoordinateReceived(), the zoomTo() in the displayready listener will fire.
If the <DIV> update occurs last, the zoomTo() in the resize listener will fire, which will alter from a zoomed Out map to the "right" zoom level.

Google Maps API + Wax.g + IE = Tiny Tiles

I'm using wax.g to display custom tiles on a Google Map. This works fine in every browser I've tested, except IE. In other browsers, the tiles are rendered correctly, but in IE, the tiles a rendering as a smaller version of their true selves. The issue is best explained in the following screenshots:
What they should look like: http://cl.ly/image/2E0U2b0c0f0W
What they look like in IE: http://cl.ly/image/2F3B353q0G0c
This issue doesn't happen all the time, and if I pan or zoom, sometimes I get the correctly sized tiles, and sometimes I don't. Not sure if this is a Wax issue or an issue with how the Google Maps API renders custom overlayMapTypes. Has anyone else experienced this issue? Any insight is much appreciated...
(cross-posted from MapBox GitHub issue - no answers there yet)
So the problem is that my images were inheriting a style height and width of auto, and Wax.g's getTile method method creates an Image using new Image(256, 256), which writes to height and width attributes of the img itself (img attributes, not inline style). The inline styles took priority over the attributes, so the img was being sized using auto. I fixed this by ensuring the img had a height and width of 256 using inline styling.
Wax.g code:
// Get a tile element from a coordinate, zoom level, and an ownerDocument.
wax.g.connector.prototype.getTile = function(coord, zoom, ownerDocument) {
var key = zoom + '/' + coord.x + '/' + coord.y;
if (!this.cache[key]) {
var img = this.cache[key] = new Image(256, 256);
this.cache[key].src = this.getTileUrl(coord, zoom);
this.cache[key].setAttribute('gTileKey', key);
this.cache[key].onerror = function() { img.style.display = 'none'; };
}
return this.cache[key];
};
My modified code:
// Get a tile element from a coordinate, zoom level, and an ownerDocument.
wax.g.connector.prototype.getTile = function(coord, zoom, ownerDocument) {
var key = zoom + '/' + coord.x + '/' + coord.y;
if (!this.cache[key]) {
var img = this.cache[key] = new Image(256, 256);
img.style.height = '256px'; // added this line
img.style.width = '256px'; // added this line
this.cache[key].src = this.getTileUrl(coord, zoom);
this.cache[key].setAttribute('gTileKey', key);
this.cache[key].onerror = function() { img.style.display = 'none'; };
}
return this.cache[key];
};

OpenLayers on Load Markers Popup

I'm using OpenLayers to view a map and I'm having an issue with the marker's popup. When the Markers are loaded, I'm assigning them two events the moouseover and mouseout but when any of the markers are triggered with these events only the first created marker's popup is shown, even when I mouseover other markers. Its like I'm only creating these events for the first marker and not for all of them.. Any ideas? Thanks
var listMarkers = getMarkers();
for (var i = 0; i < listMarkers.length; i++) {
var size = new OpenLayers.Size(21, 25);
var offset = new OpenLayers.Pixel(-(size.w / 2), -size.h);
var icon;
if (listMarkers[i].Icon.trim() === "red") {
icon = new OpenLayers.Icon
('http://www.openlayers.org/dev/img/marker.png', size, offset);
}
else {
icon = new OpenLayers.Icon
('http://www.openlayers.org/dev/img/marker-' + listMarkers[i].Icon.trim() + '.png', size, offset);
}
var mark = new OpenLayers.Marker(new OpenLayers.LonLat(listMarkers[i].Longitude,
listMarkers[i].Latitude).transform(new OpenLayers.Projection("EPSG:4326"),
map.getProjectionObject()), icon);
//here add mouseover event
mark.events.register('mouseover', mark, function (evt) {
popup = new OpenLayers.Popup.FramedCloud("Popup",
new OpenLayers.LonLat(listMarkers[i].Longitude,
listMarkers[i].Latitude).transform(new OpenLayers.Projection("EPSG:4326"),
map.getProjectionObject()),
null,
'<div><b>' + listMarkers[i].Title + '</b><br/>' + listMarkers[i].Description + '</div>',
null,
false);
map.addPopup(popup);
});
//here add mouseout event
mark.events.register('mouseout', mark, function (evt) { popup.hide(); });
markers.addMarker(mark);
}
In the mouseover event while creating popup you're referring to listMarkers[i], which in javascript scope would remember last value of given variable i, so for every popup it would get information from listMarkers[listMarkers.length-1]. To fix this, add details (Title, Latitude, Longitude) into the mark object (mark.data.Title = listMarkers[i]), and then read them in event handler from evt or this object (as you're setting it in register call).

Categories

Resources