Disappearing custom markers - google maps v3 - google-maps

I am trying to create a map with custom markers.
When heights and widths are all the same, everything works fine. If I change one of them to be bigger (2x), that marker starts to behave funny - it's partially rendered on map, it disappears and reappears when zooming in/out, on some zoom levels it looks ok. Input images are all 128x128, I am scaling them to 32x32 but i would like some of them to be 64x32
Here's main function for adding markers (I commented out things that I tried before):
jQuery(xml).find("marker").each(function(){
var name = jQuery(this).find('name').text();
var address = jQuery(this).find('address').text();
// create a new LatLng point for the marker
var lat = jQuery(this).find('lat').text();
var lng = jQuery(this).find('lng').text();
var twidth = jQuery(this).find('width').text();
var theight = jQuery(this).find('height').text();
var point = new google.maps.LatLng(parseFloat(lat),parseFloat(lng));
var imgPath = jQuery(this).find('icon').text();
var hw = twidth/2;
var hh = theight/2;
var imageForMarker = new google.maps.MarkerImage(
imgPath,
null, //new google.maps.Size(128, 128),
// The origin for this image is 0,0.
null, //new google.maps.Point(0,0),
// The anchor for this image is at the centre
null, //new google.maps.Point(hw, hh),
// Scaled size
new google.maps.Size(twidth, theight));
// extend the bounds to include the new point
MYMAP.bounds.extend(point);
var marker = new google.maps.Marker({
position: point,
map: MYMAP.map,
icon: imageForMarker,
zIndex:0
});
citiesArray.push(marker);
var html='<strong>'+name+'</strong.><br />'+address+'<br><img src="http://chart.apis.google.com/chart?cht=qr&chs=200x200&chl=http%3A//maps.google.com/maps%3Fq=%26ll%3D'+lat+'%2C'+lng+'%26z%3D14&chld=H|0">';
google.maps.event.addListener(marker, 'click', function() {
if(infoWindow)
infoWindow.close();
infoWindow = new google.maps.InfoWindow();
infoWindow.setContent(html);
infoWindow.open(MYMAP.map, marker);
});
MYMAP.map.fitBounds(MYMAP.bounds);
});
xml is this:
<?xml version="1.0"?>
<markers>
<marker>
<name>name1</name>
<address></address>
<lat>54.721844</lat>
<lng>17.41024</lng>
<width>32</width>
<height>32</height>
<icon>park2.png</icon>
</marker>
( ...)
<marker>
<name>name2</name>
<address></address>
<lat>50.417408112618686</lat>
<lng>23.491015625</lng>
<width>32</width>
<height>32</height>
<icon>park.png</icon>
</marker>
</markers>
here's MYEDIT definition + initialization:
var infoWindow;
var MYMAP = {
map: null,
bounds: null,
iWindow: null
}
MYMAP.init = function(selector, latLng, zoom) {
var myOptions = {
zoom:zoom,
center: latLng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
this.map = new google.maps.Map(jQuery(selector)[0], myOptions);
this.bounds = new google.maps.LatLngBounds();
}
test bed is at:
http://null-zero.com/test/markers/markers.html
IMPORTANT: you have to scroll down, tick CITIES, then at the top of the map near GDANSK a castle should appear - it's broken (top part of the castle is visible), strange things happen when you zoom in/out.
There are two PlaceMarkers functions - the bottom one uses different width/height and is broken (placeMarkersCities)
Any ideas what causes it and how to fix it?

Your current code is
var twidth = jQuery(this).find('width').text();
var theight = jQuery(this).find('height').text();
...
new google.maps.Size(twidth, theight));
But Size takes two Numbers. Odd things have been known to happen when maps objects are fed the wrong parameter type. In this case, you only convert some data from Strings to Numbers. You don't convert twidth and theight.
I suggest converting the data when you read it
var lat = parseFloat(jQuery(this).find('lat').text());
var lng = parseFloat(jQuery(this).find('lng').text());
var twidth = parseInt(jQuery(this).find('width').text());
var theight = praseInt(jQuery(this).find('height').text());
rather than when you use it (as in your current code)
var point = new google.maps.LatLng(parseFloat(lat),parseFloat(lng));
because then it's done once and you don't have to remember it.

Related

Sticky Zoom for geoJson

Dynamically loading geoJson for Chloropleth map. When I zoom in and pan all is well but if I choose another Cell Carrier which rerenders the Chloropleth it always jumps back out to the original default Zoom/Center.
How can I implement a 'sticky zoom' to preserve the session bounds?
I've been playing with storing it in an hidden field but if always seems to be overwritten by the change in geoJson features.
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/light-v10',
center: [-100, 38],
zoom: 3
});
if (document.getElementById('hfldBounds').value != 'null') {
map.fitBounds(document.getElementById('hfldBounds').value);
};
map.on('zoom', function (e) {
document.getElementById('hfldBounds').value = map.getBounds();
});
Ideally the user selects a carrier that renders the map. They zoom in and pan and then they want to see what another carrier owns in the same bounds so they change carrier, get the new geoJson data but maintain the previous map extents.
I finally worked this out myself so I'll post the solution here:
<script>
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/light-v10',
center: [-100, 38],
zoom: 3
});
map.on('zoom', function (e) {
sessionStorage.setItem('bounds', map.getBounds());
});
map.on('drag', function (e) {
sessionStorage.setItem('bounds', map.getBounds());
});
if (sessionStorage.getItem('bounds') != null) {
let bounds = sessionStorage.getItem('bounds');
var araBounds = bounds.toString().split(',');
var swX = parseFloat(araBounds[0].replace('LngLatBounds(LngLat(',''));
var swY = parseFloat(araBounds[1].replace(')',''));
var neX = parseFloat(araBounds[2].replace('LngLat(',''));
var neY = parseFloat(araBounds[3].replace('))', ''));
var ne = new mapboxgl.LngLat(neX, neY);
var sw = new mapboxgl.LngLat(swX, swY);
var box = new mapboxgl.LngLatBounds(sw, ne);
map.fitBounds(box);
};
</script>
load map
save bounds to session variable on move or pan
check for bounds and construct a new bounds object
use bounds object with map.fitBounds() to zoom back to your previous extents.

Custom Search box for Google map

I am developing web application using Google map JavaScript version. I need to add search box like Google Search box which is on Google map (like attached image). And I need to search custom places which are on my database.
If it is possible, how to do this?
This example adds a search box to a map, using the Google Place Autocomplete feature. People can enter geographical searches. The search box will return a pick list containing a mix of places and predicted search terms.
function initialize() {
var markers = [];
var map = new google.maps.Map(document.getElementById('map-canvas'), {
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var defaultBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(-33.8902, 151.1759),
new google.maps.LatLng(-33.8474, 151.2631));
map.fitBounds(defaultBounds);
// Create the search box and link it to the UI element.
var input = /** #type {HTMLInputElement} */(
document.getElementById('pac-input'));
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
var searchBox = new google.maps.places.SearchBox(
/** #type {HTMLInputElement} */(input));
// Listen for the event fired when the user selects an item from the
// pick list. Retrieve the matching places for that item.
google.maps.event.addListener(searchBox, 'places_changed', function() {
var places = searchBox.getPlaces();
for (var i = 0, marker; marker = markers[i]; i++) {
marker.setMap(null);
}
// For each place, get the icon, place name, and location.
markers = [];
var bounds = new google.maps.LatLngBounds();
for (var i = 0, place; place = places[i]; i++) {
var image = {
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(25, 25)
};
// Create a marker for each place.
var marker = new google.maps.Marker({
map: map,
icon: image,
title: place.name,
position: place.geometry.location
});
markers.push(marker);
bounds.extend(place.geometry.location);
}
map.fitBounds(bounds);
});
// Bias the SearchBox results towards places that are within the bounds of the
// current map's viewport.
google.maps.event.addListener(map, 'bounds_changed', function() {
var bounds = map.getBounds();
searchBox.setBounds(bounds);
});
}
google.maps.event.addDomListener(window, 'load', initialize);

Mini Map in InfowWindow for direction route

I am working in Google Map v3(actually migrating V2 to V3), and trying to customize the Infowindow of the Direction Service.
I am able to display the Direction using Origin, Destination and waypoints.
My Map displayed the route correctly with Marker (green marker with A, B, C... text).
By default, On click of teh marker infowindow will display address of that marker.
I want to customize it, so that on click of marker it should disply mini map of that location in Infowindow with more zoom.
I am able to do some progress, but the problem here is,
- Marker is changed to red pointing marker instead of Green marker (with A, B, C...text)
- whichever the marker I click, infowindow will open on the last marker
- Once marker is clicked it will display minimap, but on close and again click of that marker it will display address (default behaviour)
- my code is actually overwriting the green marker with red pointed marker
Can soboby help me how to fix all these issue
Below is my code:
function CreateDirection (arrWaypoints) {
if (!this.directions) {
this.directions = new google.maps.DirectionsService();
var origin = arrWaypoints[0];
var destination = arrWaypoints[arrWaypoints.length - 1];
var tripWaypoints = [];
for (var i = 1; i < arrWaypoints.length - 1; i++) {
tripWaypoints.push({
location: new google.maps.LatLng(arrWaypoints[i].hb, arrWaypoints[i].ib),
stopover: true
});
}
var myMap = MyMap.getMap();
var steps = [];
this.directions.route({
origin: origin,
destination: destination,
waypoints: tripWaypoints,
travelMode: google.maps.DirectionsTravelMode.DRIVING,
unitSystem: google.maps.DirectionsUnitSystem.METRIC
}, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay = new google.maps.DirectionsRenderer();
// directionDiv div element in my page
directionsDisplay.setPanel(document.getElementById("directionDiv"));
directionsDisplay.setMap(myMap);
directionsDisplay.setDirections(result);
}
});
}
}
function CreateMiniMapInfoWindow (wayPointsArray) {
for (var i = 0; i < wayPointsArray.length; i++) {
var myMap = MyMap.getMap();
var marker = new google.maps.Marker({
position: wayPointsArray[i],
map: myMap
});
google.maps.event.addListener(marker, 'click', function() {
var myOptionsMini = {
zoom: 14,
center: wayPointsArray[i],
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var infowindow = new google.maps.InfoWindow();
var minimap = new google.maps.Map(document.getElementById ("minimap"), myOptionsMini);
document.getElementById("minimap").style.display = 'block';
minimap.setCenter(marker.getPosition());
var minimapDiv = document.getElementById("minimap");
infowindow.setContent(minimapDiv);
infowindow.open(myMap, marker);
});
}
}
I need the solution for:
- How to get customized infowindow (with minimap) for all the markers
- How to put the green markers with text A, B, C...
Attached image is what I am getting from the above code
I hope my question is clear.
Please let me know if anyone have any inputs.
Thanks,
Sharath
Pass the following object as argument to the DirectionsRenderer:
{markerOptions:{clickable:false,zIndex:1000}}
It will have 2 effects:
the custom markers will be placed behind the A,B,C-markers created by the DirectionsRenderer(currently they are still present, but behind your custom markers)
the markers created by the DirectionsRenderer are not clickable, the underlying custom markers are able to receive the click.
another option(I would prefer it): set the suppressMarkers-option of the DirectionsRenderer to true and use the A,B,C-markers for your custom markers(e.g. https://maps.gstatic.com/mapfiles/markers2/marker_greenA.png , https://maps.gstatic.com/mapfiles/markers2/marker_greenB.png )
Related to the infoWindow: all you need is 1 infoWindow with 1 map for all markers. Observe the click-event of the markers and when it occurs open the infoWindow and center the map inside the infowindow at the markers position(may be retrieved inside the click-callback via this.getPosition())
Note: instead of using your predefined waypoints you better parse the route returned by the directionsService to place the custom markers at the exact positions(these may differ from your predefined waypoints)

How can I check if google map is already loaded

I am working in a project to provide a map to mobile phone. For now I am trying on a iPhone.
It works fine, and when I load my first page I can see a map with my position, and the market is refreshed each 10 sec and move to my next position.
Some time when I change of page and I come back to the first page, the map is not full displayed. If I move the map, it move but some image of the map is still not displayed.
Also I am working with jquery mobe.
I also noticed that each time I return to the first map, the map is reloaded.
Is there a way to load the map once?
So how can i check that my map is already loaded?
Here is my code
$('#home').live('pagebeforeshow', function(e){
// Resize #mapHome (#mapHome = Sreen hight - footer - header)
$('#mapHome').css('height', Resize.content()-2 +'px');
// extract les id des modules existants
navigator.geolocation.getCurrentPosition(function(position){
showMap('mapHome',position.coords.latitude, position.coords.longitude);
//console.log(position.coords.latitude, position.coords.longitude);
},
function(){
//error
},
{
enableHighAccuracy : true,
maximumAge : 30000
//maximumAge:Infinity
});
// Place and move the marker regarding to my position and deplacement
var track_id = "me";
Tracking.watch_id = navigator.geolocation.watchPosition(
// Success
function(position){
console.log('WatchPosition called');
var lat = position.coords.latitude;
var long = position.coords.longitude;
var latLng = new Array();
latLng[0] = lat;
latLng[1] = long;
//Tracking.myCoordinates.push(lat,long);
Tracking.myCoordinates.push(latLng);
addMarker(lat, long);
},
// Error
showError,
{
frequency: 1000
});
})
I just changed that line to
$('#home').live('pageshow', function(e){... code...}
And it semas to be better but I am not sure-
Here is the code of my function showMap()
function showMap(canvas,lat,long){
var latLng = new google.maps.LatLng(lat,long);
// Google Map options var myOptions = {
zoom: 19,
//zoomControl : 1,
center: latLng,
mapTypeId: google.maps.MapTypeId.ROADMAP////ROADMAP, SATELLITE, HYBRID and TERRAIN };
// Create the Google Map, set options Tracking.mapy = new google.maps.Map(document.getElementById(canvas), myOptions);
}
And here is the code addMarker()
function addMarker(lat, long){
Tracking.mapBounds = new google.maps.LatLngBounds();
// Clean previous markers
for (var i = 0; i < Tracking.markers.length; i++ ) {
Tracking.markers[i].setMap(null);
}
// Add the owner's marker
var latitudeAndLongitude = new google.maps.LatLng(lat, long);
var image = "img/iconGoogleMap/phones.png";
marker = new google.maps.Marker({
title : 'me',
//animation: google.maps.Animation.DROP, //BOUNCE
position: latitudeAndLongitude,
map : Tracking.mapy,
icon : image
});
Tracking.markers.push(marker);
//Tracking.markers.push(marker);
//console.log(localStorage.getItem('mapToDisplay'));
/* ADDING MODULES MAKERS */
// Store the ID of available module.
modulesJSON = Modules.get('bipme');
for (var i = 0; i < modulesJSON['modules'].length; i++) {
console.log('module id = ' +modulesJSON['modules'][i].id);
console.log('Module ' + modulesJSON['modules'][i].id + ' position : ' + ModulesPos.module(modulesJSON['modules'][i].id));
nlatLong = ModulesPos.module(modulesJSON['modules'][i].id).split(",");
var LatitudeAndLongitudeModules = new google.maps.LatLng(nlatLong[0],nlatLong[1]);
var image = "img/iconGoogleMap/" + modulesJSON['modules'][i].profile + "-" + modulesJSON['modules'][i].iconColor + ".png";
marker = new google.maps.Marker({
title : modulesJSON['modules'][i].pseudo,
//animation: google.maps.Animation.DROP, //BOUNCE
position: LatitudeAndLongitudeModules,
map : Tracking.mapy,
icon : image
});
Tracking.mapBounds.extend(LatitudeAndLongitudeModules);
Tracking.markers.push(marker);
};
By the way, is there a way to create a button, from which I can manually refresh the map?

Google Maps Does not Zoom "organically" when new markers are loaded

I have this code that loads XML graphic markers, and I also set it to zoom when new markers are loaded. What I don't like however, is that the zoom happens "instantly" and doesnt zoom to level slowly, and also, for some reason the map zooms out much further than it needs too. I would like the map to zoom out only as far as it needs to so that the markers are in view.
Any suggestions? Thanks!
clearOverlays();
downloadUrl("AllActivityxml.php", function(data) {
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var name = markers[i].getAttribute("id");
var address = markers[i].getAttribute("id");
var type = markers[i].getAttribute("venue_type");
var point = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
var html = "<b>" + name + "</b> <br/>" + address;
var icon = customIcons[type] || {};
markerBounds.extend(point);
var marker = new google.maps.Marker({
map: map,
position: point,
icon: icon.icon,
shadow: icon.shadow
});
markersArray.push(marker);
bindInfoWindow(marker, map, infoWindow, html);
map.fitBounds(markerBounds);
}
});
zoom happens "instantly" and doesnt zoom to level slowly -- that is how it actually happens when you do fitBounds(). Looks like you want something like the map.panTo() which makes the transition on map slowly unlike the map.setCenter(), but that is not the case in fitBounds().
map zooms out much further than it needs too -- move the map.fitBounds(markerBounds); outside the for loop