Sticky Zoom for geoJson - zooming

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.

Related

google maps -- incorrect pop-up information

I have converted multiple shapefiles to KML using the Shp2kml2 software from Zonums Solutions. I have made a map with the KML layers (of which I have imported to google docs to get the url). My map is found at: http://userpages.flemingc.on.ca/~catam/collab2.html
I have:
6 polygon KML layers,
1 point KML layer,
1 Google Fusion Table point layer
But when I try to click on a specific point, the pop-up information is that of the polygon which rests in the same place as the specific point.
My code is:
var map, layer2;
function initialize() {
var ontario = new google.maps.LatLng(49.2867873, -84.7493416);
var mapOptions = {
zoom: 5,
center: ontario
}
var infoWindow = new google.maps.InfoWindow();
var openInfoWindow = function (KMLevent) {
infoWindow.close();
infoWindow.setOptions(
{
content: KMLevent.featureData.infoWindowHtml,
position: KMLevent.latLng,
pixelOffset: KMLevent.pixelOffset
});
infoWindow.open(map);
};
var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var kmlOptions = {
suppressInfoWindows: true, // do not to display an info window when clicked
preserveViewport: false,
map: map
};
var urls = [
'https://docs.google.com/uc?authuser=0&id=0B79b02nBK5vkajc2OGZTZDZBV0k&export=download', // SCHOOLS, NDP, LIBERAL, PC1, PC2, PC3,
'https://docs.google.com/uc?authuser=0&id=0B79b02nBK5vkQzRSdVB1TVRseU0&export=download', 'https://docs.google.com/uc?authuser=0&id=0B79b02nBK5vkWFlscVM5N01lSDQ&export=download', 'https://docs.google.com/uc?authuser=0&id=0B79b02nBK5vkbHNSTjhCN1dLQTg&export=download', 'https://docs.google.com/uc?authuser=0&id=0B79b02nBK5vkdnRoYnN1bnpubEU&export=download', 'https://docs.google.com/uc?authuser=0&id=0B79b02nBK5vkaHg1WlNKdU1VWHc&export=download'
];
layer2 = new google.maps.FusionTablesLayer({
query: {
select: 'col9',
from: '1FzRSqRcxY37i7VtejqONHhAB-MrzFhakYSvZaIvo'
}
});
layer2.setMap(map);
urls.forEach(function(url) {
var layer = new google.maps.KmlLayer(url, kmlOptions);
layer.setMap(map);
KmlLayer.setZIndex(999);
google.maps.event.addListener(layer, "click", openInfoWindow);
});
}
//initialize();
google.maps.event.addDomListener(window, 'load', initialize);
It looks like the polygon layers are getting plotted over the points. Due to this even though you think you're clicking on the point the actual click event is generated on the polygon.
One solution would be to plot the polygons first followed by the points.
If that's not possible then you should set the z-index of the layer depending on whether it is a polygon or point.
kmlLayer.setZIndex(999);
The higher the z-index the higher the layer will be. I would suggest using a high z-index for the points while using a low z-index for the polygons. That should solve your problem.
The first option would be to move the url for points after the polygon urls. This should work without the need for z-index and will work without changing any of the code.
var urls = [
'https://docs.google.com/uc?authuser=0&id=0B79b02nBK5vkQzRSdVB1TVRseU0&export=download', 'https://docs.google.com/uc?authuser=0&id=0B79b02nBK5vkWFlscVM5N01lSDQ&export=download', 'https://docs.google.com/uc?authuser=0&id=0B79b02nBK5vkbHNSTjhCN1dLQTg&export=download', 'https://docs.google.com/uc?authuser=0&id=0B79b02nBK5vkdnRoYnN1bnpubEU&export=download', 'https://docs.google.com/uc?authuser=0&id=0B79b02nBK5vkaHg1WlNKdU1VWHc&export=download',
'https://docs.google.com/uc?authuser=0&id=0B79b02nBK5vkajc2OGZTZDZBV0k&export=download', // SCHOOLS, NDP, LIBERAL, PC1, PC2, PC3,
];
The second option is to remove the points url from the array and add that separately. First plot the polygons as shown below.
var urls = [
'https://docs.google.com/uc?authuser=0&id=0B79b02nBK5vkQzRSdVB1TVRseU0&export=download', 'https://docs.google.com/uc?authuser=0&id=0B79b02nBK5vkWFlscVM5N01lSDQ&export=download', 'https://docs.google.com/uc?authuser=0&id=0B79b02nBK5vkbHNSTjhCN1dLQTg&export=download', 'https://docs.google.com/uc?authuser=0&id=0B79b02nBK5vkdnRoYnN1bnpubEU&export=download', 'https://docs.google.com/uc?authuser=0&id=0B79b02nBK5vkaHg1WlNKdU1VWHc&export=download',
];
urls.forEach(function(url) {
var layer = new google.maps.KmlLayer(url, kmlOptions);
layer.setZIndex(10);
layer.setMap(map);
google.maps.event.addListener(layer, "click", openInfoWindow);
});
After this add the points layer
var pointsUrl = 'https://docs.google.com/uc?authuser=0&id=0B79b02nBK5vkajc2OGZTZDZBV0k&export=download'; // SCHOOLS, NDP, LIBERAL, PC1, PC2, PC3,
var layer = new google.maps.KmlLayer(url, kmlOptions);
layer.setZIndex(10);
layer.setMap(map);
google.maps.event.addListener(layer, "click", openInfoWindow);

On click Data populate in info window of a polygon using GeoXMl3

I'm using geoXMl3 to parse multiple kml files at a time.
I'm getting polygons plotted on the map. when I click on the polygon an info-window pops up. I'm not getting from where this info-window is coming up
My requirement is I want to edit the content of info-window through some java-script object
My java-script object will be like
popUpDetails = {'district-name':'content'}.
Not getting how to pass this in my parser
I have refered few links like:
https://code.google.com/p/geoxml3/wiki/Usage
and also how could I put data dynamically from database in infowindow of a certain polygon?
I'm parsing kml files this way:
var mapProp = {
center: new google.maps.LatLng(51.508742,-0.120850),
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("googleMap"), mapProp);
var parser = new geoXML3.parser({
map: map,
processStyles: true,
zoom: false,
});
var infowindow = new google.maps.InfoWindow();
for (i = 0; i < ListofPathsofkmlfiles.length; i++) {
parser.parse([ListofPathsofkmlfiles[i]]);
}
Advance thanks for your help
I have finally figured out solution for same.
You need to overwrite createPolygon attribute of your parser for same.
var districtInfoMap = {doc_url1:infowindow_content1, doc_url2:infowindow_content2 };
var parser = new geoXML3.parser({
createPolygon: mapDrawingToType(),
map: map,
processStyles: true,
zoom: false,
singleInfoWindow: true,
});
mapDrawingToType = function() {
return function(placemark, doc) {
var polygon = geoXML3.instances[geoXML3.instances.length-1].createPolygon(placemark, doc);
if(polygon.infoWindow) {
polygon.infoWindowOptions.content = districtInfoMap[doc.baseUrl];
}
return polygon;
}
}
Here I have made one object containing the map of district url and window content you have to show.
This will overwrite the default behavior of how your infowindow is displayed and the desired content you want to show will be displayed.
If you still face any issue please do let me know.

GoogleMaps - gmaps.js with clustering and multiple cluster solution

So am I am using gmaps.js and the gmaps.js along with marker clusterer. In my case I may have multiple markers with the exact same location, but in reality represent different data. To overcome this I am trying to implement the solution found here on SO - in particular the solution by Nathan Colgate.
The idea is when max zoom has reached on a cluster it will execute the multiChoice function. I have this part working. What I cannot get to work is showing an infoWindow with that function.
My goal is to show an infoWindow on this cluster click to display information about each marker (particularly each marker's infoWindow content (this will have additional details specific to it).
JS :
//create the map
var map = new GMaps({
el: '#map_canvas_main',
lat: response.results[0].lat,
lng: response.results[0].lng,
zoom: 5,
maxZoom: 15,
panControl: false,
markerClusterer: function(map) {
markerCluster = new MarkerClusterer(map, [], {
title: 'Location Cluster',
maxZoom: 15
});
// onClick OVERRIDE
markerCluster.onClick = function(clickedClusterIcon) {
return multiChoice(clickedClusterIcon.cluster_);
}
return markerCluster;
}
});
//loop through array
for(var i = 0; i < response.results.length; i++)
{
//create marker image
var markerLoc = {
url: '/custom/plugins/gmaps/images/marker-red.png',
size: new google.maps.Size(24, 30), //size
origin: new google.maps.Point(0, 0), //origin point
anchor: google.maps.Point(9, 30) // offset point
};
//add marker
map.addMarker({
lat: response.results[i].lat,
lng: response.results[i].lng,
icon: markerLoc,
title: response.results[i].ip_address,
infoWindow: {
content: '<p>'+response.results[i].ip_address+'</p>'
//add more details later
}
});
}
//cluster function to do stuff
function multiChoice(clickedCluster)
{
//clusters markers
var markers = clickedCluster.getMarkers();
//console check
console.log(clickedCluster);
console.log(markers);
if (markers.length > 1)
{
//content of info window
var infowindow = new google.maps.InfoWindow({
content: ''+
'<p>'+markers.length+' = length</p>'+
'<p>testing blah blah</p>'
});
//show the window
//infowindow.open(??????????);
return false;
}
return true;
};
Finally figured this out playing around with it some more... it makes sense now, but didn't before. Here is the new 'display' function to be replaced by the one in the OP. Of course, there are a few other change needed yet... showing all clustered marker data in the new info window for example, but this is the gist of getting the window to work.
//cluster function to do stuff
function multiChoice(clickedCluster)
{
//clusters markers
var markers = clickedCluster.getMarkers();
if (markers.length > 1)
{
//create the info window
var infoWindow = new google.maps.InfoWindow({
content: ''+
'<p>'+markers.length+' = length</p>'+
'<p>testing blah blah</p>',
position: clickedCluster.center_
});
//display the infowindow
infoWindow.open(clickedCluster.map_);
return false;
}
return true;
};

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)

Disappearing custom markers - google maps v3

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.