I have the following code available for Google Maps which works with FusionTable Layer.
It changes based on the zoom level of the user.
The array draw_str and draw_str_zoom are dynamic and gets generated based on the API calls we make and the response we receive.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<title>KML Layers</title>
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 90%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
var layerState = [];
var draw_str = '27089,27013,27053,27029,27035,27067,27081,27069,27155,27153,27131,27123,27109,27051,27043,27031,27027,27007,27005,27003,27001';
var draw_str_zoom = '48131,48197,48459,48497,48163,48379,48403,48471,48499,48505,48067,48249,48289,48323,48351,48399,48467,48481,48485,48507,48031,48139,48187,48303,48315,48355,48409,48419,48429,48483,48489,48021,48027,48035,48053,48099,48143,48145,48157,48195,48225,48251,48271,48317,48319,48361,48427,48431,48463,48479,48043,48155,48215,48321,48343,48381,48425,48451,48469,48079,48135,48347,48363,48407,48477,48085,48201,48299,48325,48339,48413,48453,48503,48177,48291,48401,48423,48475,48089,48439,48095,48117,48253,48275,48329,48397,48441,48465,48259,48279,48335,48437,48487,48003,48045,48061,48121,48161,48209,48245,48281,48313,48375,48395,48445,48457,48473,48491,48501,48449,48435,48415,48405,48391,48387,48373,48371,48357,48349,48345,48337,48331,48309,48307,48293,48285,48277,48273,48265,48257,48255,48241,48231,48227,48223,48221,48219,48217,48213,48193,48189,48185,48183,48181,48175,48171,48167,48153,48151,48149,48147,48141,48133,48123,48119,48115,48113,48105,48097,48093,48091,48087,48077,48073,48071,48063,48059,48057,48055,48051,48049,48047,48041,48039,48037,48029,48025,48019,48015,48009,48005';
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 5,
center: {lat: 41.876, lng: -87.624}
});
layerState[0] = new google.maps.FusionTablesLayer({
query: {
select: '\'geometry\'',
from: '1fio1qgy5HkinUDKqYvREIlSoBaHjl2RBe3DLJa38'
},
options: {suppressInfoWindows: true},
styles: [{
polygonOptions: {
fillColor: '#000000',
fillOpacity: 0.001
}
}, {
where: "'GEO_ID2' IN (" + draw_str_zoom + ")",
polygonOptions: {
fillOpacity: 0.3
}
}]
});
layerState[0].setMap(map);
google.maps.event.addListener(map, 'zoom_changed', function () {
var zoom_level = map.getZoom();
if (zoom_level >= 6 && zoom_level < 7) {
clearRegion(zoom_level);
layerState[0] = new google.maps.FusionTablesLayer({
query: {
select: '\'geometry\'',
from: '1fio1qgy5HkinUDKqYvREIlSoBaHjl2RBe3DLJa38'
},
options: {suppressInfoWindows: true},
styles: [{
polygonOptions: {
fillColor: '#000000',
fillOpacity: 0.001
}
}, {
where: "'GEO_ID2' IN (" + draw_str + ")",
polygonOptions: {
fillOpacity: 0.3
}
}]
});
layerState[0].setMap(map);
}
});
function clearRegion(level) {
layerState.forEach(function(kml) {
kml.setMap(null);
});
}
}
// }
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBMtoh9P3UkoxbXndKu_HOP7KsVwTRvxGU&callback=initMap">
</script>
</body>
</html>
Google Fusion Table is going down - https://support.google.com/fusiontables/answer/9185417
Is there a way I could create this similar map with all the functionality without using FusionTable layer?
Since Fusion Tables will not be available after Dec. 3, 2019, I suggest:
Download your tables as KML files,
https://support.google.com/fusiontables/answer/2548807?hl=en
Host your KML files at a publicly accessible URL that does not require authentication to access. This is because Maps JavaScript API uses a Google hosted service to retrieve and parse KML files for rendering.
https://developers.google.com/maps/documentation/javascript/kmllayer
Finally, display the information of your KML files in a Google map and sidebar.
https://developers.google.com/maps/documentation/javascript/kml
Alternatively, you can host your KML files in the same domain where your webpage is, but for that you'll need a library like GeoXML3:
Examples:
http://www.dyasdesigns.com/geoxml/GeoXmlSamples.html
Repository that I used, EDIT 1 below:
https://github.com/geocodezip/geoxml3/tree/master/kmz
EDIT1: With GeoXML3, dynamically styling from draw_str would be:
<div id="map"></div>
<script src="geoxml3.js"></script>
<script>
var draw_str = [/* your array */];
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 5,
center: {lat: 41.876, lng: -87.624}
});
var myParser = new geoXML3.parser({map: map,zoom: false}); // zoom needs to be set to false to keep mapOptions intact.
myParser.parse('Counties.kml'); // our Document (myParser.docs[0]) is the only parsed kml
google.maps.event.addListener(map, 'zoom_changed', function () {
var polygonOptions = {fillColor: "#000000" , fillOpacity: 0.001};
var polygonOptionsID2 = {fillOpacity: 0.3};
var zoom_level = map.getZoom();
if (zoom_level >= 6 && zoom_level < 7) {
for (var i = 0; i < draw_str.length; i++) {
for (var j = 0; j < myParser.docs[0].placemarks.length; j++) {
if (draw_str[i] == myParser.docs[0].placemarks[j].vars.val.GEO_ID2) { // GEO_ID2 is stored as Extended Data for every placemark (myParser.docs[0].placemarks is an array with 3250 entries)
myParser.docs[0].gpolygons[j].setOptions(polygonOptionsID2); // myParser.docs[0].gpolygons is an array with 3250 polygons
} else {
myParser.docs[0].gpolygons[j].setOptions(polygonOptions);
}
}
}
}
});
}
</script>
It will be a bit slow since the KML downloaded from Fusion Tables has more than 15 MB
EDIT2: fully functional demo consuming both draw_str and draw_str_zoom, dependent on having both GeoXML3.js and the KML downloaded from the Fusion Table page, referenced in the code.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<title>KML Layers</title>
<style>
#map {
height: 100%;
}
html, body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="map"></div>
<script src="static/geoxml3.js"></script>
<script>
var draw_str = "27089,27013,27053,27029,27035,27067,27081,27069,27155,27153,27131,27123,27109,27051,27043,27031,27027,27007,27005,27003,27001";
var draw_str_zoom = "48131,48197,48459,48497,48163,48379,48403,48471,48499,48505,48067,48249,48289,48323,48351,48399,48467,48481,48485,48507,48031,48139,48187,48303,48315,48355,48409,48419,48429,48483,48489,48021,48027,48035,48053,48099,48143,48145,48157,48195,48225,48251,48271,48317,48319,48361,48427,48431,48463,48479,48043,48155,48215,48321,48343,48381,48425,48451,48469,48079,48135,48347,48363,48407,48477,48085,48201,48299,48325,48339,48413,48453,48503,48177,48291,48401,48423,48475,48089,48439,48095,48117,48253,48275,48329,48397,48441,48465,48259,48279,48335,48437,48487,48003,48045,48061,48121,48161,48209,48245,48281,48313,48375,48395,48445,48457,48473,48491,48501,48449,48435,48415,48405,48391,48387,48373,48371,48357,48349,48345,48337,48331,48309,48307,48293,48285,48277,48273,48265,48257,48255,48241,48231,48227,48223,48221,48219,48217,48213,48193,48189,48185,48183,48181,48175,48171,48167,48153,48151,48149,48147,48141,48133,48123,48119,48115,48113,48105,48097,48093,48091,48087,48077,48073,48071,48063,48059,48057,48055,48051,48049,48047,48041,48039,48037,48029,48025,48019,48015,48009,48005";
var draw_strArray = draw_str.replace(/, +/g, ",").split(",").map(Number);
var zoomArray = draw_str_zoom.replace(/, +/g, ",").split(",").map(Number);
var tempOptions = {fillColor: "#FFFF00", strokeColor: "#000000", fillOpacity: 0.9, strokeWidth: 10};
var geoXmlDoc;
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 5,
center: {lat: 41.876, lng: -87.624}
});
var myParser = new geoXML3.parser({map: map,zoom: false, afterParse: useTheData });
myParser.parse('static/Counties.kml');
google.maps.event.addListener(map, 'zoom_changed', function () {
var zoom_level = map.getZoom();
if (zoom_level >= 6 && zoom_level < 7) {
for ( i = 0; i < draw_strArray.length; i++) {
for (var j = 0; j < geoXmlDoc.placemarks.length; j++) {
if (draw_strArray[i] == geoXmlDoc.placemarks[j].vars.val.GEO_ID2) {
geoXmlDoc.gpolygons[j].setOptions(tempOptions);
}
}
}
} else {
for ( i = 0; i < draw_strArray.length; i++) {
for (var j = 0; j < geoXmlDoc.placemarks.length; j++) {
if (draw_strArray[i] == geoXmlDoc.placemarks[j].vars.val.GEO_ID2) {
geoXmlDoc.gpolygons[j].setOptions({fillOpacity: 0.0});
}
}
}
}
});
function useTheData(doc) {
geoXmlDoc= doc[0];
for ( i = 0; i < zoomArray.length; i++) {
for (var j = 0; j < geoXmlDoc.placemarks.length; j++) {
if (zoomArray[i] == geoXmlDoc.placemarks[j].vars.val.GEO_ID2) {
geoXmlDoc.gpolygons[j].setOptions(tempOptions);
}
}
}
};
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBMtoh9P3UkoxbXndKu_HOP7KsVwTRvxGU&callback=initMap">
</script>
</body>
</html>
iam pradeep i have a problem on google maps
the problem is iam creating multiple markers based on the latitude and longitude which(latitude and longitude) i get from my database.
Here comes the problem.
when i create the marker, only last marked is loaded on to the map rather than loading all the maps.
Below you can see the code.
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<%#page import="java.sql.*" %>
<%!
Connection connection = null;
boolean foundResults = false;
ResultSet set = null;
Statement statement = null;
%>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css"> html { height: 100% } body { height: 100%; margin: 0px; padding: 0px } #map_canvas { height: 100% } </style>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"> </script>
<script type="text/javascript">
var locations;
var h = new Array(10);
function initialize()
{
var latlng = new google.maps.LatLng(17.4531555176, 78.4580039978);
var myOptions = { zoom: 4, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP };
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
//google.maps.event.addListener(map, 'zoom_changed', function() { setTimeout(moveToDsnr, 500);});
google.maps.event.addListener(map, 'zoom_changed', function() { setTimeout(moveToAmpp, 500);});
var marker = new google.maps.Marker({position: latlng,map: map,title:"Hyderabad"});
google.maps.event.addListener(marker, 'click', function() { map.setZoom(12);});
}
function moveToAmpp()
{
<%
String lat=null;
String lng=null;
int i=0;
try
{
Class c = Class.forName("org.postgresql.Driver");
connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/postgres","postgres", "password");
statement = connection.createStatement();
set = statement.executeQuery("SELECT lat, lng FROM latlng");
while(set.next())
//for(i=0;set.next();i++)
{
lat=set.getString(1);
lng=set.getString(2);
%>
alert(<%= lat%>);
alert(<%= lng%>);
locations = [['Dilsukhnagar', <%= lat%>, <%= lng%>, 1]];
alert(locations);
var map = new google.maps.Map(document.getElementById("map_canvas"),{zoom: 12,center: new google.maps.LatLng(17.38,78.48),mapTypeId:google.maps.MapTypeId.ROADMAP});
var infowindow = new google.maps.InfoWindow();
var marker;
var i;
//alert(locations.length);
alert(locations[0][0]);
alert(locations[0][1]);
alert(locations[0][2]);
alert(locations[0][3]);
for (i = 0; i < locations.length; i++)
{
marker = new google.maps.Marker({position: new google.maps.LatLng(locations[i][1],locations[i][2]),map: map});
alert("done");
google.maps.event.addListener(marker, 'click', (
function(marker, i)
{
return function()
{
infowindow.setContent(locations[i][0]);
infowindow.open(map, marker);
}
})
(marker, i));
alert("created");
}
alert("hello");
<%
}
}
catch(Exception e)
{
}
%>
}
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="width:100%; height:100%"></div>
</body>
</html>
So please help me on this.
Thank you.
You have a problem when you set locations = [['Dilsukhnagar', lat, lng, 1]];
This reset all the locations table and leaves only one record.
Check this correction: (I remove the JSP because I don't have a server)
You will have to rethink the JSP loop to make it work with your DB.
You have to initiate a zoom to call on the initialize function. I think you may want to change this because it leads to strange behaviour.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css"> html { height: 100% } body { height: 100%; margin: 0px; padding: 0px } #map_canvas { height: 100% } </style>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"> </script>
<script type="text/javascript">
var locations;
var h = new Array(10);
function initialize()
{
var latlng = new google.maps.LatLng(17.4531555176, 78.4580039978);
var myOptions = { zoom: 4, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP };
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
google.maps.event.addListener(map, 'zoom_changed', function() { setTimeout(moveToAmpp, 500);});
var marker = new google.maps.Marker({position: latlng,map: map,title:"Hyderabad"});
google.maps.event.addListener(marker, 'click', function() { map.setZoom(12);});
}
function moveToAmpp()
{
var locations = new Array(2);
for(i = 0; i < locations.length; i++) {
locations[i] = new Array(4);
}
<%
String lat=null;
String lng=null;
int i=0;
try
{
Class c = Class.forName("org.postgresql.Driver");
connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/postgres","postgres", "password");
statement = connection.createStatement();
set = statement.executeQuery("SELECT lat, lng FROM latlng");
while(set.next())
{
%>
/* Can be embedded into JSP loop */
locations[<%= i %>][0]="SomeThing You get from your DB?";
locations[<%= i %>][1]=<%= lat%>;
locations[<%= i %>][2]=<%= lng%>;
locations[<%= i %>][3]="Something you get from your DB?";
<% i++;
}
%>
var map = new google.maps.Map(document.getElementById("map_canvas"),{zoom: 12,center: new google.maps.LatLng(17.38,78.48),mapTypeId:google.maps.MapTypeId.ROADMAP});
var infowindow = new google.maps.InfoWindow();
var marker;
var i;
for (i = 0; i < locations.length; i++)
{
marker = new google.maps.Marker({position: new google.maps.LatLng(locations[i][1],locations[i][2]),map: map});
//alert("done");
google.maps.event.addListener(marker, 'click', (
function(marker, i)
{
return function()
{
infowindow.setContent(locations[i][0]);
infowindow.open(map, marker);
}
})
(marker, i));
}
}
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="width:100%; height:100%"></div>
</body>
</html>
Does it work for you?