Embedding a map inside a InfoWindow - javascript

I've attempted to embed a map inside an InfoWindow in order to create a pop up with a preview of the clustering. However once the InfoWindow is closed, the map div fails to render.
My attempt of a simplified jsfiddle, http://jsfiddle.net/behewur2/
function initialize() {
var mapOptions = {
center: {
lat: -34.9290,
lng: 138.6010
},
zoom: 8,
streetViewControl: false,
overviewMapControl: false
};
var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var mcOptions = {
gridSize: 30,
zoomOnClick: false
};
var mcOptionsZoom = {
gridSize: 30,
zoomOnClick: true
};
var mc = new MarkerClusterer(map, [], mcOptions);
google.maps.event.addListener(mc, 'clusterclick',
function (cluster) {
if (typeof infowindow !== 'undefined') prevInfoWindow = infowindow;
infowindow = new google.maps.InfoWindow({
content: $('#inner-map-canvas')[0]
});
if (typeof prevInfoWindow !== 'undefined') prevInfoWindow.close();
infowindow.setPosition(cluster.getCenter());
infowindow.open(map);
google.maps.event.trigger(innermap, 'resize');
innermap.setZoom(innermap.getZoom());
for (var i = 0; i < cluster.getMarkers().length; i++) {
innermc.addMarker(
new google.maps.Marker({
position: cluster.getMarkers()[i].position,
map: innermap,
icon: cluster.getMarkers()[i].icon,
title: cluster.getMarkers()[i].title
}),
false);
}
});
var marker = new google.maps.Marker({
position: new google.maps.LatLng(mapOptions.center.lat, mapOptions.center.lng),
map: map,
icon: 'https://chart.googleapis.com/chart?chst=d_map_pin_letter&chld=0|FF0000|000000'
});
mc.addMarker(marker, false);
var innermap = new google.maps.Map(document.getElementById("inner-map-canvas"), mapOptions);
var innermc = new MarkerClusterer(innermap, [], mcOptionsZoom);
}
google.maps.event.addDomListener(window, 'load', initialize);
html
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDKxl8sh1TEN61taio3wdbGwuSI8FVeQ5k"></script>
<script type="text/javascript" src="https://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclustererplus/src/markerclusterer_packed.js"></script>
<div id="map-canvas"></div>
<div id="inner-map-canvas">
</dev>

It would be better to dynamically create the div node in the infowindow, it is destroyed when the infowindow is closed.
google.maps.event.addListener(mc, 'clusterclick', function (cluster) {
if (typeof infowindow !== 'undefined') prevInfoWindow = infowindow;
var innermapNode = document.createElement("div");
innermapNode.setAttribute("id", "inner-map-canvas");
innermapNode.style.height = "300px";
innermapNode.style.width = "300px";
infowindow = new google.maps.InfoWindow({
content: innermapNode
});
if (typeof prevInfoWindow !== 'undefined') prevInfoWindow.close();
infowindow.setPosition(cluster.getCenter());
infowindow.open(map);
innermap = new google.maps.Map(innermapNode, mapOptions);
innermc = new MarkerClusterer(innermap, [], mcOptionsZoom);
google.maps.event.addListener(infowindow, 'domready', function () {
google.maps.event.trigger(innermap, 'resize');
// innermap.setZoom(innermap.getZoom());
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < cluster.getMarkers().length; i++) {
innermc.addMarker(
new google.maps.Marker({
position: cluster.getMarkers()[i].position,
map: innermap,
icon: cluster.getMarkers()[i].icon,
title: cluster.getMarkers()[i].title,
keycount: cluster.getMarkers()[i].keycount
}),
false);
bounds.extend(cluster.getMarkers()[i].position);
}
google.maps.event.trigger(innermap, 'resize');
innermap.fitBounds(bounds);
});
});
proof of concept fiddle
code snippet:
function colorForCount(count) {
if (count == 1) return '4080FE';
if (count == 2) return 'F7C207';
if (count > 2 && count < 5) return 'F50D07';
if (count >= 5) return 'FF00F0';
else return 'B600FF';
}
var innermap;
var innermc;
function initialize() {
var mapOptions = {
center: {
lat: -34.9290,
lng: 138.6010
},
zoom: 8,
streetViewControl: false,
overviewMapControl: false
};
var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var mcStyles = [{
url: "http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/images/m1.png",
height: 53,
width: 53
}, {
url: "http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/images/m2.png",
height: 53,
width: 53
}, {
url: "http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/images/m3.png",
height: 53,
width: 53
}, {
url: "http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/images/m4.png",
height: 53,
width: 53
}, {
url: "http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/images/m5.png",
height: 53,
width: 53
}];
var mcOptions = {
gridSize: 30,
zoomOnClick: false,
styles: mcStyles
};
var mcOptionsZoom = {
gridSize: 30,
zoomOnClick: true,
styles: mcStyles
};
var mc = new MarkerClusterer(map, [], mcOptions);
mc.setCalculator(function(markers, numStyles) {
var count = markers.length;
var total = 0;
var max = 0;
var index = 0;
if (max == 1) index = 0;
if (max == 2) index = 2;
if (max > 2 && max < 5) index = 3;
if (max >= 5) index = 4;
return {
text: count,
index: index
};
});
google.maps.event.addListener(mc, 'clusterclick',
function(cluster) {
if (typeof infowindow !== 'undefined') prevInfoWindow = infowindow;
var innermapNode = document.createElement("div");
innermapNode.setAttribute("id", "inner-map-canvas");
innermapNode.style.height = "300px";
innermapNode.style.width = "300px";
infowindow = new google.maps.InfoWindow({
content: innermapNode
});
if (typeof prevInfoWindow !== 'undefined') prevInfoWindow.close();
infowindow.setPosition(cluster.getCenter());
infowindow.open(map);
innermap = new google.maps.Map(innermapNode, mapOptions);
innermc = new MarkerClusterer(innermap, [], mcOptionsZoom);
google.maps.event.addListener(infowindow, 'domready', function() {
google.maps.event.trigger(innermap, 'resize');
// innermap.setZoom(innermap.getZoom());
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < cluster.getMarkers().length; i++) {
innermc.addMarker(
new google.maps.Marker({
position: cluster.getMarkers()[i].position,
map: innermap,
icon: cluster.getMarkers()[i].icon,
title: cluster.getMarkers()[i].title,
keycount: cluster.getMarkers()[i].keycount
}),
false);
bounds.extend(cluster.getMarkers()[i].position);
}
google.maps.event.trigger(innermap, 'resize');
innermap.fitBounds(bounds);
});
});
google.maps.event.addListenerOnce(map, 'bounds_changed', function() {
var mapBnds = map.getBounds();
var mapSpan = mapBnds.toSpan();
for (var i = 0; i < 25; i++) {
var latRan = (Math.random() * mapSpan.lat() / 2) + mapSpan.lat() / 4;
var lngRan = (Math.random() * mapSpan.lng() / 2) + mapSpan.lng() / 4;
var marker = new google.maps.Marker({
position: new google.maps.LatLng(mapBnds.getSouthWest().lat() + latRan, mapBnds.getSouthWest().lng() + lngRan),
map: map,
icon: 'https://chart.googleapis.com/chart?chst=d_map_pin_letter&chld=' + i + '|FF0000|000000'
});
mc.addMarker(marker, false);
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
/**
* Pull out the unique keys and counts.
* #param {Object} json The Inventory object.
* #return {Array.<{portal:{portalGuid:string,portalLocation:string,
* portalImageUrl:string,portalTitle:string,portalAddress:string},
* count:number}>}
*/
function getKeys(json) {
// parse the json string
var inventory = json.gameBasket.inventory;
// loop over the inventory items to find keys
var keys = [];
var iitckeys = {};
for (var i = 0; i < inventory.length; i++) {
// if it's a key, attempt to add to the key list
var item = inventory[i];
if (item[2].resource && item[2].resource.resourceType == "PORTAL_LINK_KEY") {
addKey(keys, iitckeys, item[2].portalCoupler);
} else if (item[2].resource && (item[2].resource.resourceType == "CAPSULE" || item[2].resource.resourceType == "INTEREST_CAPSULE")) {
parseCapsule(keys, iitckeys, item[2].container.stackableItems);
}
}
// return back the keys
return {
keys: keys,
iitckeys: iitckeys
};
}
/**
* Parse the items within a capsule.
* #param {Array.<{portal:{portalGuid:string,portalLocation:string,
* portalImageUrl:string,portalTitle:string,portalAddress:string},
* count:number}>} keys The current key array.
* #param {Array.<Object>} items The capsule's contents.
*/
function parseCapsule(keys, iitckeys, items) {
for (var i = 0; i < items.length; i++) {
if (typeof items[i].exampleGameEntity[2].resource !== 'undefined') {
if (items[i].exampleGameEntity[2].resource.resourceType == "PORTAL_LINK_KEY") {
var count = items[i].itemGuids.length;
while (count > 0) {
addKey(keys, iitckeys, items[i].exampleGameEntity[2].portalCoupler);
count--;
}
}
}
}
}
/**
* Add a key def to the keys list.
* #param {Array.<{portal:{portalGuid:string,portalLocation:string,
* portalImageUrl:string,portalTitle:string,portalAddress:string},
* count:number}>} keys The current key array.
* #param {{portalGuid:string,portalLocation:string,portalImageUrl:string,
* portalTitle:string,portalAddress:string}} keyDef The key definition.
*/
function addKey(keys, iitckeys, keyDef) {
// try to find the key and increment the count
console.log("keyDef : " + keyDef);
for (var i = 0; i < keys.length; i++) {
if (keys[i].portal.portalGuid == keyDef.portalGuid) {
keys[i].count++;
iitckeys[keyDef.portalGuid] ++;
return;
}
}
// couldn't find the key, add it
keys.push({
portal: keyDef,
count: 1
});
iitckeys[keyDef.portalGuid] = 1;
}
function getLatLng(location) {
var newLoc = parseInt(location, 16);
//if MSB is set
if ((newLoc & 0x80000000) !== 0x00000000) {
console.log("neg");
return (newLoc - 0x100000000) / 1E6;
} else {
console.log("pos");
return newLoc / 1E6;
}
}
body,
html {
height: 100%;
width: 100%;
}
#map-canvas {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
.cluster img {
width: 53px;
height: 53px;
}
#commands {
width: 100%;
}
#inner-map-canvas {
width: 300px;
height: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script src="https://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclustererplus/src/markerclusterer.js"></script>
<div id="map-canvas"></div>
<div id="keyjson"></div>

Related

Get Variables from Qlik Sense to JavaScript

I'm new with JS and I have this extension from Qlik Sense that I'm trying to change, I need to point some pins according to a variable. If value of variable $type is 'A' I use some pin, if value is 'B' another and so on. But I really don't know how this extension get values from QS. Any help please?
Follow the JS:
require.config({
paths: {
async: '/extensions/GoogleMaps-Sense/lib/async',
markerclusterer: '/extensions/GoogleMaps-Sense/lib/markerclusterer'
},
shim: {
'markerclusterer': {
exports: 'MarkerClusterer'
}
}
});
define(['qlik', './src/properties', './src/styles', 'markerclusterer', './src/abbreviateNumber', 'qvangular', 'async!https://maps.googleapis.com/maps/api/js?key=AIzaSyASz5bdD789VzsLyki1JCKhSnCd5pEPY3Q'], function(qlik, properties, styles, MarkerClusterer, abbreviateNumber, qv) {
var BASE_URL = '/extensions/GoogleMaps-Sense/';
if (typeof(Number.prototype.toRad) === "undefined") {
Number.prototype.toRad = function() {
return this * Math.PI / 180;
}
}
if (typeof(Number.prototype.toDeg) === "undefined") {
Number.prototype.toDeg = function() {
return this * 180 / Math.PI;
}
}
return {
initialProperties: {
version: 1,
qHyperCubeDef: {
qSuppressZero: true,
qSuppressMissing: true
},
gmaps: {
cluster: {
oneStyle: false,
maxZoom: 10
},
map: {
mode: 'cluster',
customIcon: null,
iconUrl: '',
maxZoom: 18,
style: 'default'
}
}
},
definition: properties,
snapshot: {
canTakeSnapshot: true
},
paint: function($element, layout) {
$element.empty();
this.backendApi.cacheCube.enabled = false;
var _this = this;
var markers = [];
var selectedMarkers = [];
var rectangles = [];
var selectedRects = [];
var columns = layout.qHyperCube.qSize.qcx;
var totalheight = layout.qHyperCube.qSize.qcy;
var pageheight = Math.floor(10000 / columns);
var numberOfPages = Math.ceil(totalheight / pageheight);
var Promise = qv.getService('$q');
var promises = Array.apply(null, Array(numberOfPages)).map(function(data, index) {
var page = {
qTop: (pageheight * index) + index,
qLeft: 0,
qWidth: columns,
qHeight: pageheight
};
return this.backendApi.getData([page]);
}, this)
Promise.all(promises).then(function(data) {
render(data);
});
function render(data) {
var useCustomStyle = layout.gmaps.map.style !== 'default';
var hasMeasure = layout.qHyperCube.qMeasureInfo.length >= 1 ? true : false;
var hasPopup = layout.qHyperCube.qMeasureInfo.length === 2 ? true : false;
//The bounds object, used to determain which part of the map to show based on data
var bounds = new google.maps.LatLngBounds();
var mapOptions = {
maxZoom: layout.gmaps.map.maxZoom,
panControl: true,
zoomControl: true,
overviewMapControl: false,
overviewMapControlOptions: {
opened: false
},
scaleControl: false,
streetViewControl: true,
mapTypeControlOptions: {
mapTypeIds: [google.maps.MapTypeId.ROADMAP, google.maps.MapTypeId.TERRAIN, google.maps.MapTypeId.HYBRID, 'map_style']
}
};
//Put the map on the page so give some visual feedback
var map = new google.maps.Map($element.get(0), mapOptions);
if (useCustomStyle) {
var selectedStyle = styles.filter(function(d) {
return d.key === layout.gmaps.map.style
});
var styledMap = new google.maps.StyledMapType(selectedStyle[0].data, {
name: layout.gmaps.map.style
});
map.mapTypes.set('map_style', styledMap);
map.setMapTypeId('map_style');
};
//Create a marker for each row of data
data.forEach(function(obj) {
obj[0].qMatrix.forEach(function(row, index) {
if (row[0].qText == '-') return;
//Parse the dimension
var latlng = JSON.parse(row[0].qText);
//Reverse the order as QS sends long lat
var point = new google.maps.LatLng(latlng[1], latlng[0]);
//Create our marker - if we have a expression then use that otherwise default to just show locations
var image = 'https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png';
var marker = new google.maps.Marker({
position: point,
title: '',
icon: image,
customData: hasMeasure ? row[1].qText : 1,
qElem: row[0].qElemNumber
});
//If we have popup values for each marker create the popup windows
if (hasPopup) {
marker.infoWindow = new google.maps.InfoWindow({
content: row[2].qText
});
google.maps.event.addListener(marker, 'mouseover', function() {
this.infoWindow.open(map, this);
});
google.maps.event.addListener(marker, 'mouseout', function() {
this.infoWindow.close();
});
};
//Add click handler
google.maps.event.addListener(marker, 'click', (function(value) {
return function() {
_this.selectValues(0, [value], true);
highlightMarkers(value)
}
})(row[0].qElemNumber));
bounds.extend(point);
markers.push(marker);
});
});
//Fit map to bounds
map.fitBounds(bounds);
//Clustering enabled
if (layout.gmaps.map.mode === 'cluster') {
if (layout.gmaps.cluster.oneStyle) {
var clusterStyles = [{
opt_textColor: 'black',
url: BASE_URL + 'images/singlecluster.png',
height: 56,
width: 55
}];
};
var mcOptions = {
imagePath: BASE_URL + 'images/m',
styles: clusterStyles,
maxZoom: layout.gmaps.cluster.maxZoom
};
//Draw clusters onto map
var markerCluster = new MarkerClusterer(map, markers, mcOptions);
markerCluster.setCalculator(function(markers, clusterStyles) {
var index = 0,
count = markers.length,
total = count;
while (total !== 0) {
//Create a new total by dividing by a set number
total = parseInt(total / 5, 10);
//Increase the index and move up to the next style
index++;
}
index = Math.min(index, clusterStyles);
var measure = 0;
for (var i = 0, k = count; i < k; i++) {
measure += parseInt(markers[i].customData)
}
var abbreviatedValue = abbreviateNumber(measure)
return {
text: abbreviatedValue,
index: index
};
});
};
if (layout.gmaps.map.mode === 'marker') {
markers.forEach(function(d) {
d.setMap(map);
})
};
if (layout.gmaps.map.mode === 'boxes') {
markers.forEach(function(d) {
var distance = d.customData > 1 ? d.customData : 10;
var lat = d.position.lat();
var lng = d.position.lng();
var boxbounds = new google.maps.LatLngBounds(box(lat, lng, 225, distance), box(lat, lng, 45, distance))
var rect = new google.maps.Rectangle({
strokeColor: layout.gmaps.boxes.strokeFill,
strokeOpacity: +layout.gmaps.boxes.strokeOpacity,
strokeWeight: +layout.gmaps.boxes.strokeWeight,
fillColor: layout.gmaps.boxes.fillColor,
fillOpacity: +layout.gmaps.boxes.fillOpacity,
qElem: d.qElem,
map: map,
bounds: boxbounds
});
//Add click handler
google.maps.event.addListener(rect, 'click', (function(value) {
return function() {
_this.selectValues(0, [value], true);
highlightRects(value)
}
})(d.qElem));
rectangles.push(rect);
})
};
};
//In selection mode - loop over markers to highlight markers scheduled for selection.
function highlightMarkers(qElem) {
var idx = selectedMarkers.indexOf(qElem);
if (idx > -1) {
selectedMarkers.splice(idx, 1)
} else {
selectedMarkers.push(qElem)
}
markers.forEach(function(marker) {
if (selectedMarkers.indexOf(marker.qElem) === -1) {
marker.setOpacity(0.5)
} else {
marker.setOpacity(1);
}
});
};
//In selection mode - loop over markers to highlight markers scheduled for selection.
function highlightRects(qElem) {
var idx = selectedRects.indexOf(qElem);
if (idx > -1) {
selectedRects.splice(idx, 1)
} else {
selectedRects.push(qElem)
}
rectangles.forEach(function(marker) {
if (selectedRects.indexOf(marker.qElem) === -1) {
marker.setOptions({
fillOpacity: +layout.gmaps.boxes.fillOpacity / 2,
strokeOpacity: +layout.gmaps.boxes.strokeOpacity / 2
})
} else {
marker.setOptions({
fillOpacity: +layout.gmaps.boxes.fillOpacity,
strokeOpacity: +layout.gmaps.boxes.strokeOpacity
})
}
});
};
function box(lat, lng, brng, dist) {
this._radius = 6371;
var dist = dist / this._radius;
var brng = brng.toRad();
var lat1 = lat.toRad();
var lon1 = lng.toRad();
var lat2 = Math.asin(Math.sin(lat1) * Math.cos(dist) +
Math.cos(lat1) * Math.sin(dist) *
Math.cos(brng));
var lon2 = lon1 + Math.atan2(Math.sin(brng) * Math.sin(dist) *
Math.cos(lat1), Math.cos(dist) -
Math.sin(lat1) * Math.sin(lat2));
lon2 = (lon2 + 3 * Math.PI) % (2 * Math.PI) - Math.PI;
return new google.maps.LatLng(lat2.toDeg(), lon2.toDeg());
}
}
};
});
I think this might help
/**
* Retrieve the values of a list of variables.
*
* Since $q.all fails on the first error, we have to resolve all first
*
* #param {string[]} `varList` - The variable names.
* #param {object} `app` - The (Qlik Sense) app.
*
* #returns {Promise}
*
* #api public
*/
this.getEngineVarListValues = function ( app, varList ) {
if ( varList && Array.isArray( varList ) ) {
var promises = [];
varList.forEach( function ( variable ) {
promises.push( self.getEngineVarValue( app, variable ) )
} );
return $q.all( promises );
}
return $q.reject( new Error( 'getEngineVarListValues variable list passed.' ) );
};
Taken from https://github.com/stefanwalther/sense-extension-utils/blob/master/src/variable-utils.js
var app = qlik.currApp();
//get the variable content
app.variable.getContent('MYVAR',function ( reply ){
alert( JSON.stringify( reply ) );
});
source: http://help.qlik.com/en-US/sense-developer/June2017/Subsystems/APIs/Content/CapabilityAPIs/qlik-variable-interface.htm

Google corechart map not showing anymore

I have a map that is drawn by coordinates.
It was working 3 days ago but now it's not showing.
code:
google.load("visualization", "1", {packages:["corechart"]});
error:
jsapi:22 A Parser-blocking, cross-origin script,
https://www.google.com/uds/?file=visualization&v=1&packages=corechart,
is invoked via document.write. This may be blocked by the browser if
the device has poor network connectivity.google.loader.f # jsapi:22
2jsapi:22 A Parser-blocking, cross-origin script,
https://www.google.com/uds/api/visualization/1.0/1195ca6324d5ce101c2f520f3c62c843/format+pt_PT,default+pt_PT,ui+pt_PT,corechart+pt_PT.I.js,
is invoked via document.write. This may be blocked by the browser if
the device has poor network connectivity.
I tryed to change to:
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
google.charts.load('current', {'packages':['corechart', 'map']});
google.charts.setOnLoadCallback(CarregaMapa("map-geral","eda",continente,7,-1,"#FFF",1000,600));
and i get the error:
loader.js:152 Uncaught TypeError: a.shift(...) is not a function(…)
Update:
I change to
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
google.charts.load('current', {'packages':['corechart', 'map']});
MapaConcelhos.map = new google.visualization.Map(document.getElementById(mapa), {
scrollwheel: false,
draggable: isDraggable,
disableDoubleClickZoom: true,
disableDefaultUI: true,
center: local,
mapTypeId: "",
backgroundColor: bk,
zoom: zoomlocal
});
but I have to add a polygon to the map:
var concelho = new google.maps.Polygon({
paths: coords,
idc: idconcelho,
strokeColor: "black",
strokeOpacity: 0.3,
strokeWeight: 1,
fillColor: item.Cor ? item.Cor : "white",
fillOpacity: 0.8,
html: contentString
});
concelho.setMap(MapaConcelhos.map);
so the error is:
setMap: not an instance of Map
Is it possible to add polygon to a visualization map?
Why can't I use the old code? Why jsapi is having warnings and the map and polygons are not drawn anymore?
Old code:
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
google.load("visualization", "1", {packages:["corechart"]})
var MapaConcelhos = CarregaMapa("map-geral","eda",continente,7,-1,"#FFF",1000,600);
var mapbounds = new google.maps.LatLngBounds();
var centromapa = new google.maps.LatLng();
var isDraggable = !('ontouchstart' in document.documentElement);
var longpress = false;
function CarregaMapa(mapa,mapatipo,local,zoomlocal,idd, bk,w,h) {
var MapaConcelhos = {
concelhos: [],
addlegenda: function(item) {
var leg = {
ordem: item.Legenda_key,
cor: item.Cor,
label: item.Label
}
Array.prototype.inArray = function(comparer) {
for(var i=0; i < this.length; i++) {
if(comparer(this[i])) return true;
}
return false;
};
Array.prototype.sortOn = function(key){
this.sort(function(a, b){
if(a[key] < b[key]){
return -1;
}else if(a[key] > b[key]){
return 1;
}
return 0;
});
}
Array.prototype.pushIfNotExist = function(element, comparer) {
if (!this.inArray(comparer)) {
Mapalegenda.push(element);
Mapalegenda.sortOn("ordem")
var legenda="<p><b>Legenda:</b></p>";
for (var i=0; i<Mapalegenda.length; i++) {
legenda = legenda +'<div id="map-legenda-linha"><div id="map-legenda-cor" style="background: ' + Mapalegenda[i].cor + ';"></div>' + Mapalegenda[i].label + '</div>';
}
document.getElementById("map-legenda").innerHTML = legenda;
}
};
Mapalegenda.pushIfNotExist(leg, function(e) {
return e.cor === leg.cor && e.label === leg.label;
});
},
addConcelho: function(item) {
//Set concelho coordenadas
var coords = [];
var coord = item.Coordenadas.split("|");
for (var i = 0; i < coord.length; i++) {
var latlng = coord[i].split(",");
coords.push(new google.maps.LatLng(latlng[1], latlng[0]));
}
var contentString="<b>"+item.Nome+"</b>"+item.Descricao;
//Create polygon
var idconcelho=item.Id;
var concelho = new google.maps.Polygon({
paths: coords,
idc: idconcelho,
strokeColor: "black",
strokeOpacity: 0.3,
strokeWeight: 1,
fillColor: item.Cor ? item.Cor : "white",
fillOpacity: 0.8,
html: contentString
});
MapaConcelhos.concelhos.push(concelho);
concelho.setMap(MapaConcelhos.map);
var bounds = new google.maps.LatLngBounds();
for (var i=0; i< coords.length; i++) {
bounds.extend(coords[i]);
mapbounds.extend(coords[i]);
}
var centroconcelho = bounds.getCenter();
var timer = null;
if (isDraggable)
{
google.maps.event.addListener(concelho,"click",function(){
showConcelho(concelho.idc);});
}
else
{
google.maps.event.addListener(concelho, 'mousedown', function(event){
start = new Date().getTime();
});
google.maps.event.addListener(concelho, 'mouseup', function(){
end = new Date().getTime();
longpress = (end - start < 300) ? false : true;
if (longpress) showConcelho(concelho.idc);
});
}//else
MapaConcelhos.addlegenda(item);
if (item.Ultimo=="1")
{
MapaConcelhos.map.fitBounds(mapbounds);
MapaConcelhos.map.setCenter(local);
}
function isInfoWindowOpen(infoWindow){
var map = infoWindow.getMap();
return (map !== null && typeof map !== "undefined");
}
var minZoom=8;
if (idd==41 || idd==-1) minZoom=7;
google.maps.event.addListenerOnce(MapaConcelhos.map, 'bounds_changed', function(event) {
if (this.getZoom() < minZoom) {
this.setZoom(minZoom);
MapaConcelhos.map.setCenter(local);
}
});
function showArrays(event) {
var vertices = this.getPath();
var contentString =this.html;
infoWindow.setContent(contentString);
infoWindow.setPosition(event.latLng);
infoWindow.open(MapaConcelhos.map);
}
function showConcelho(idc) {
$.fancybox({
href : "/ficha.php?id="+idc,
width : w,
height : h,
fitToView : true,
autoSize : false,
type: "iframe",
padding: 0,
openEffect : "elastic",
openSpeed : 150,
aspectRatio : true,
closeEffect : "elastic",
closeSpeed : 150,
closeClick : true,
scrolling : "auto",
preload : true
});
}
},
map: undefined,
mapContainer: document.getElementById(mapa),
initialize: function() {
google.maps.visualRefresh = true;
MapaConcelhos.map = new google.maps.Map(document.getElementById(mapa), {
scrollwheel: false,
draggable: isDraggable,
disableDoubleClickZoom: true,
disableDefaultUI: true,
center: local,
mapTypeId: "",
backgroundColor: bk,
zoom: zoomlocal
});
}
};
var requester = {};
requester.Request = function () {
$.ajax({
url: "/scripts/concelhos.php",
type: "GET",
data: { tipo: mapatipo, distrito:idd},
contentType: "application/x-www-form-urlencoded;charset=ISO-8859-1",
dataType: "json",
}).done(function(result) {
if (result) {
$.each(result, function(index, item) {
MapaConcelhos.addConcelho(item);
});
} else {
}
}).error(function() {
});
};
MapaConcelhos.initialize();
requester.Request();
return MapaConcelhos;
} //CarregaMapa
New code:
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
google.charts.load('current', {
'callback': function () {
var MapaConcelhos = CarregaMapa("map-geral","eda",continente,7,-1,"#FFF",1000,600);
},
'packages': ['corechart', 'map']
});
var mapbounds = new google.maps.LatLngBounds();
var centromapa = new google.maps.LatLng();
var isDraggable = !('ontouchstart' in document.documentElement);
var longpress = false;
function CarregaMapa(mapa,mapatipo,local,zoomlocal,idd, bk,w,h) {
var MapaConcelhos = {
concelhos: [],
addlegenda: function(item) {
var leg = {
ordem: item.Legenda_key,
cor: item.Cor,
label: item.Label
}
Array.prototype.inArray = function(comparer) {
for(var i=0; i < this.length; i++) {
if(comparer(this[i])) return true;
}
return false;
};
Array.prototype.sortOn = function(key){
this.sort(function(a, b){
if(a[key] < b[key]){
return -1;
}else if(a[key] > b[key]){
return 1;
}
return 0;
});
}
Array.prototype.pushIfNotExist = function(element, comparer) {
if (!this.inArray(comparer)) {
Mapalegenda.push(element);
Mapalegenda.sortOn("ordem")
var legenda="<p><b>Legenda:</b></p>";
for (var i=0; i<Mapalegenda.length; i++) {
legenda = legenda +'<div id="map-legenda-linha"><div id="map-legenda-cor" style="background: ' + Mapalegenda[i].cor + ';"></div>' + Mapalegenda[i].label + '</div>';
}
document.getElementById("map-legenda").innerHTML = legenda;
}
};
Mapalegenda.pushIfNotExist(leg, function(e) {
return e.cor === leg.cor && e.label === leg.label;
});
},
addConcelho: function(item) {
//Set concelho coordenadas
var coords = [];
var coord = item.Coordenadas.split("|");
for (var i = 0; i < coord.length; i++) {
var latlng = coord[i].split(",");
coords.push(new google.maps.LatLng(latlng[1], latlng[0]));
}
var contentString="<b>"+item.Nome+"</b>"+item.Descricao;
//Create polygon
var idconcelho=item.Id;
var concelho = new google.maps.Polygon({
paths: coords,
idc: idconcelho,
strokeColor: "black",
strokeOpacity: 0.3,
strokeWeight: 1,
fillColor: item.Cor ? item.Cor : "white",
fillOpacity: 0.8,
html: contentString
});
MapaConcelhos.concelhos.push(concelho);
concelho.setMap(MapaConcelhos.map);
var bounds = new google.maps.LatLngBounds();
for (var i=0; i< coords.length; i++) {
bounds.extend(coords[i]);
mapbounds.extend(coords[i]);
}
var centroconcelho = bounds.getCenter();
var timer = null;
if (isDraggable)
{
google.maps.event.addListener(concelho,"click",function(){
showConcelho(concelho.idc);});
}
else
{
google.maps.event.addListener(concelho, 'mousedown', function(event){
start = new Date().getTime();
});
google.maps.event.addListener(concelho, 'mouseup', function(){
end = new Date().getTime();
longpress = (end - start < 300) ? false : true;
if (longpress) showConcelho(concelho.idc);
});
}//else
MapaConcelhos.addlegenda(item);
if (item.Ultimo=="1")
{
//MapaConcelhos.map.fitBounds(mapbounds);
//MapaConcelhos.map.setCenter(local);
}
function isInfoWindowOpen(infoWindow){
var map = infoWindow.getMap();
return (map !== null && typeof map !== "undefined");
}
var minZoom=8;
if (idd==41 || idd==-1) minZoom=7;
google.maps.event.addListenerOnce(MapaConcelhos.map, 'bounds_changed', function(event) {
if (this.getZoom() < minZoom) {
this.setZoom(minZoom);
MapaConcelhos.map.setCenter(local);
}
});
function showArrays(event) {
var vertices = this.getPath();
var contentString =this.html;
infoWindow.setContent(contentString);
infoWindow.setPosition(event.latLng);
infoWindow.open(MapaConcelhos.map);
}
function showConcelho(idc) {
$.fancybox({
href : "/ficha.php?id="+idc,
width : w,
height : h,
fitToView : true,
autoSize : false,
type: "iframe",
padding: 0,
openEffect : "elastic",
openSpeed : 150,
aspectRatio : true,
closeEffect : "elastic",
closeSpeed : 150,
closeClick : true,
scrolling : "auto",
preload : true
});
}
},
map: undefined,
mapContainer: document.getElementById(mapa),
initialize: function() {
google.maps.visualRefresh = true;
MapaConcelhos.map = new google.visualization.Map(document.getElementById(mapa), {
scrollwheel: false,
draggable: isDraggable,
disableDoubleClickZoom: true,
disableDefaultUI: true,
center: local,
mapTypeId: "",
backgroundColor: bk,
zoom: zoomlocal
});
}
};
var requester = {};
requester.Request = function () {
$.ajax({
url: "/scripts/concelhos.php",
type: "GET",
data: { tipo: mapatipo, distrito:idd},
contentType: "application/x-www-form-urlencoded;charset=ISO-8859-1",
dataType: "json",
}).done(function(result) {
if (result) {
$.each(result, function(index, item) {
MapaConcelhos.addConcelho(item);
});
} else {
}
}).error(function() {
});
};
MapaConcelhos.initialize();
requester.Request();
return MapaConcelhos;
} //CarregaMapa
definitely need to use the following library, remove jsapi
<script src="https://www.gstatic.com/charts/loader.js"></script>
the load statement looks fine
google.charts.load('current', {'packages':['corechart', 'map']});
however, setOnLoadCallback expects a reference to a function, not the result of a function
regardless, the 'callback' can be added to the load statement as well
recommend using the following load statement...
google.charts.load('current', {
'callback': function () {
CarregaMapa("map-geral","eda",continente,7,-1,"#FFF",1000,600);
},
'packages': ['corechart', 'map']
});
I found the solution.
To keep the old code working I had to use a frozen version...
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?**v=3.25**&key=XXX>
I wonder if this version is retired what will hapen?
it's showing the same jsapi warnings but the map and polygons are drawn...
so the problem was with the version of the maps api...

cannot create map route with auto complete search functionality

In my form autocomplete search input and Map route is not working togetherly.
autocomplete search is working when I add async defer in script
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=true&key=*key*&libraries=places&callback=initAutocomplete"
>
</script>
and Map route is working when I remove async defer in script
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=true&key=AIzaSyBNHI4xFw5CzYJSvbotLPu93C81q69ZbZA&libraries=places&callback=initAutocomplete"
async defer>
</script>
this is my complete code
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=true&key=AIzaSyBNHI4xFw5CzYJSvbotLPu93C81q69ZbZA&libraries=places&callback=initAutocomplete"
async defer>
</script>
</head>
<body>
<form method="post">
<div id="locationField">
<input id="autocomplete" name="txtpickup" placeholder="Enter your address"
onFocus="geolocate()" type="text" style="width:20em;"></input>
<br/>
<br/>
<input id="autocomplete1" name="txtdrop" placeholder="Enter your address"
onFocus="geolocate()" type="text" style="width:20em;"></input>
<br/>
<br/>
<input id="checkprice" type="submit" value="checkprice" name="checkprice" style="width:20em;"></input>
</div>
<form>
<?php
if (isset($_POST['checkprice']))
{
$pickupaddress = $_POST['txtpickup'];
$dropaddress = $_POST['txtdrop'];
$geo = file_get_contents('http://maps.googleapis.com/maps/api/geocode/json?address='.urlencode($pickupaddress).'&sensor=false');
$geo = json_decode($geo, true);
if ($geo['status'] == 'OK') {
$latitude = $geo['results'][0]['geometry']['location']['lat'];
$longitude = $geo['results'][0]['geometry']['location']['lng'];
}
//------- drop coordnates -----------
$geo1 = file_get_contents('http://maps.googleapis.com/maps/api/geocode/json?address='.urlencode($dropaddress).'&sensor=false');
$geo1 = json_decode($geo1, true);
if ($geo1['status'] == 'OK') {
$latitude1 = $geo1['results'][0]['geometry']['location']['lat'];
$longitude1 = $geo1['results'][0]['geometry']['location']['lng'];
}
echo '<div><input id="anything" type="button" value="Show Route" onClick="updatePos(\''.str_replace("'", "\\'", $latitude).'\', \''.str_replace("'", "\\'", $longitude).'\', \''.str_replace("'", "\\'", $latitude1).'\', \''.str_replace("'", "\\'", $longitude1).'\');" ></div>';
}
// -------- distance -------------
function distance($lat1, $lon1, $lat2, $lon2, $unit) {
$theta = $lon1 - $lon2;
$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
$dist = acos($dist);
$dist = rad2deg($dist);
$miles = $dist * 60 * 1.1515;
$unit = strtoupper($unit);
if ($unit == "K") {
return ($miles * 1.609344);
} else if ($unit == "N") {
return ($miles * 0.8684);
} else {
return $miles;
}
}
?>
<div id="map_canvas" style="float:left;width:70%;height:400px;"></div>
<ul></ul>
<p id="pMsg"></p>
</body>
<script type="text/javascript">
function updatePos(latitude,longitude,latitude1,longitude1){
ginit(latitude,longitude,latitude1,longitude1);
}
function initAutocomplete() {
autocomplete = new google.maps.places.Autocomplete(
(document.getElementById('autocomplete')),
{types: ['geocode']});
autocomplete1 = new google.maps.places.Autocomplete(
(document.getElementById('autocomplete1')),
{types: ['geocode']});
}
function geolocate() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var geolocation = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
var circle = new google.maps.Circle({
center: geolocation,
radius: position.coords.accuracy
});
autocomplete.setBounds(circle.getBounds());
});
}
}
var directions = {};
var bounds = new google.maps.LatLngBounds();
function ginit(latitude,longitude,latitude1,longitude1) {
var opts = {
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: new google.maps.LatLng(52.524268, 13.406290000000013)
}
map = new google.maps.Map(document.getElementById("map_canvas"), opts);
var routes = [{
label: 'Erkner',
request: {
origin: new google.maps.LatLng(latitude, longitude),
destination: new google.maps.LatLng(latitude1, longitude1),
travelMode: google.maps.DirectionsTravelMode.DRIVING
},
rendering: {
marker: {
icon: 'http://labs.google.com/ridefinder/images/mm_20_blue.png'
},
draggable: true
}
}
];
var dists = [10000, 5000, 3000, 1000];
var selects = document.createElement('select');
list = document.getElementsByTagName('ul')[0];
for (var d = 0; d < dists.length; ++d) {
selects.options[selects.options.length] = new Option(dists[d], dists[d], d == 0, d == 0);
}
for (var r = 0; r < routes.length; ++r) {
bounds.extend(routes[r].request.destination);
bounds.extend(routes[r].request.origin);
routes[r].rendering.routeId = 'r' + r + new Date().getTime();
routes[r].rendering.dist = dists[0];
var select = selects.cloneNode(true);
select.setAttribute('name', routes[r].rendering.routeId);
select.onchange = function () {
directions[this.name].renderer.dist = this.value;
setMarkers(this.name)
};
list.appendChild(document.createElement('li'));
list.lastChild.appendChild(select);
list.lastChild.appendChild(document.createTextNode(routes[r].label));
requestRoute(routes[r], map);
}
map.fitBounds(bounds);
}
function setMarkers(ID) {
var direction = directions[ID],
renderer = direction.renderer,
dist = renderer.dist,
marker = renderer.marker,
map = renderer.getMap(),
dirs = direction.renderer.getDirections();
marker.map = map;
for (var k in direction.sets) {
var set = directions[ID].sets[k];
set.visible = !! (k === dist);
for (var m = 0; m < set.length; ++m) {
set[m].setMap((set.visible) ? map : null);
}
}
if (!direction.sets[dist]) {
if (dirs.routes.length) {
var route = dirs.routes[0];
var az = 0;
for (var i = 0; i < route.legs.length; ++i) {
if (route.legs[i].distance) {
az += route.legs[i].distance.value;
}
}
dist = Math.max(dist, Math.round(az / 100));
direction.sets[dist] = gMilestone(route, dist, marker);
}
}
}
function requestRoute(route, map) {
if (!window.gDirSVC) {
window.gDirSVC = new google.maps.DirectionsService();
}
var renderer = new google.maps.DirectionsRenderer(route.rendering);
var renderer = new google.maps.DirectionsRenderer(route.rendering);
renderer.setMap(map);
renderer.setOptions({
preserveViewport: true
})
google.maps.event.addListener(renderer, 'directions_changed', function () {
if (directions[this.routeId]) {
//remove markers
for (var k in directions[this.routeId].sets) {
for (var m = 0; m < directions[this.routeId].sets[k].length; ++m) {
directions[this.routeId].sets[k][m].setMap(null);
}
}
}
directions[this.routeId] = {
renderer: this,
sets: {}
};
setMarkers(this.routeId);
});
window.gDirSVC.route(route.request, function (response, status) {
if (status == google.maps.DirectionsStatus.OK) {
renderer.setDirections(response);
}
});
}
function gMilestone(route, dist, opts) {
var markers = [],
geo = google.maps.geometry.spherical,
path = route.overview_path,
point = path[0],
distance = 0,
leg,
overflow,
pos;
for (var p = 1; p < path.length; ++p) {
leg = Math.round(geo.computeDistanceBetween(point, path[p]));
d1 = distance + 0
distance += leg;
overflow = dist - (d1 % dist);
if (distance >= dist && leg >= overflow) {
if (overflow && leg >= overflow) {
pos = geo.computeOffset(point, overflow, geo.computeHeading(point, path[p]));
opts.position = pos;
markers.push(new google.maps.Marker(opts));
distance -= dist;
}
while (distance >= dist) {
pos = geo.computeOffset(point, dist + overflow, geo.computeHeading(point, path[p]));
opts.position = pos;
markers.push(new google.maps.Marker(opts));
distance -= dist;
}
}
point = path[p]
}
console.log(markers); //alert(markers);
for (var key in markers) {
var obj = markers[key];
console.log(obj);
if (markers[key].hasOwnProperty("position")) {
document.getElementById("pMsg").innerHTML += key+":"+markers[key].getPosition().toUrlValue(6) +"<br>";
}
}
return markers;
}
</script>
</html>
any help would be appreciated
You should use the asynchronous version of the API.

Filter Markers by State combined with Places Autocomplete - Google Maps JavaScript API

I'm using the Google Maps Places Library to work on something similar to the following: http://codepen.io/maudulus/pen/oxNXod. As you can see, when you load the page there are a number of markers that can be filtered using the State select. You can also use the search box to find markers within one standard deviation of the location you search.
However, I'm trying to combine these two features (for example, someone searches for a location, and then filters the results by state). I'm not sure why this doesn't currently work...my guess is that it might be double-adding points, because it does seem to be wanting to filter locations (you can see them flicker when you change the select).
LOCATION CODE
var map;
var originalStores = [];
var markersArr = [];
var geocoder = new google.maps.Geocoder();
var typingTimer; //timer identifier
var doneTypingInterval = 1000; //time in ms, 5 second for example
var $location = $('#location');
$location.on('keyup', function(e) {
clearTimeout(typingTimer);
typingTimer = setTimeout(queryLocation, doneTypingInterval);
});
$location.on('keydown', function() {
clearTimeout(typingTimer);
});
function queryLocation(urlParamLocation) {
var queryingLocation = (urlParamLocation) ? urlParamLocation : $('#location').val();
getLatLong(queryingLocation, function(discoveredLatLng) {
replotMap(discoveredLatLng);
});
}
function getLatLong(address, cb) {
var tempCurrentPosition = {
latitude: "",
longitude: ""
};
geocoder.geocode({
'address': address
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
tempCurrentPosition.latitude = results[0].geometry.location.lat();
tempCurrentPosition.longitude = results[0].geometry.location.lng();
cb(tempCurrentPosition);
}
});
}
function replotMap(locationValue) {
if (locationValue) {
$.each(originalStores, function(index, thisLocale) {
thisLocale.distance = getDistanceFromLatLon(locationValue.latitude, locationValue.longitude, thisLocale.latitude, thisLocale.longitude);
});
var sdCompliant = withinOneSD(originalStores, standardDeviation(originalStores));
addMapMarkers(sdCompliant);
}
}
function initialize() {
var input = document.getElementById('location');
var autocomplete = new google.maps.places.Autocomplete(input);
}
initialize();
function initializeMap() {
var myLatlng = new google.maps.LatLng(39.768408, -86.157975);
var mapOptions = {
zoom: 7,
center: myLatlng,
scrollwheel: false,
navigationControl: false,
mapTypeControl: false,
scaleControl: false,
draggable: true,
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
plotAllMarkers();
}
initializeMap();
function plotAllMarkers() {
removeExtraneousMarkers();
$.each($('#locations-ul li'), function(index, store) {
var thisStoreObj = {};
thisStoreObj.Address = $(store).attr('address');
thisStoreObj.latitude = $(store).attr('data-latitude');
thisStoreObj.longitude = $(store).attr('data-longitude');
thisStoreObj.Store = $(store).attr('data-store');
thisStoreObj.distance = "";
originalStores.push(thisStoreObj);
});
originalStores = originalStores.sort(compare);
$.each(originalStores, function(index, thisStore) {
if (thisStore.Store) {
plotTableRow(thisStore);
}
});
addMapMarkers(originalStores);
}
function addMapMarkers(arr, allArr) {
removeExtraneousMarkers();
deleteMarkers();
var bounds = new google.maps.LatLngBounds();
$.each(arr, function(index, thisLocation) {
plotTableRow(thisLocation);
var currentState = findState(thisLocation.Address);
var currLatlng = new google.maps.LatLng(thisLocation.latitude, thisLocation.longitude);
var marker = new google.maps.Marker({
position: currLatlng,
map: map,
title: thisLocation.Store,
state: currentState
});
markersArr.push(marker);
});
for (var i = 0; i < markersArr.length; i++) {
bounds.extend(markersArr[i].getPosition());
}
map.fitBounds(bounds);
adjustPlottedMarkersToBounds(markersArr);
}
function filterByState(stateMarkerArr) {
$('#state-select').on('change', function() {
var stateCode = $(this).val();
$('.locations-table .locations-div').hide();
$.each($('.locations-table .locations-div.filtered-location'), function(index, thisLocation) {
var addressText = $(thisLocation).find('h4').text();
if (addressText.indexOf(stateCode) > -1) {
$(thisLocation).show();
}
});
clearMarkers();
$.each(stateMarkerArr, function(index, thisStateMarker) {
if (thisStateMarker.state == stateCode) {
thisStateMarker.setMap(map);
}
});
});
}
function adjustPlottedMarkersToBounds(allArr) {
google.maps.event.addListener(map, 'bounds_changed', function() {
removeExtraneousMarkers();
var markersArrStateFilter = [];
for (var i = 0; i < allArr.length; i++) {
if (map.getBounds().contains(allArr[i].getPosition())) {
// markers[i] in visible bounds
markersArrStateFilter.push(allArr[i]);
allArr[i].setMap(map);
$.each(originalStores, function(index, thisStore) {
if (thisStore.Store == allArr[i].title) {
plotTableRow(thisStore, "filtered-location");
}
});
} else {
// markers[i] is not in visible bounds
allArr[i].setMap(null);
}
}
filterByState(markersArrStateFilter);
});
};
function removeExtraneousMarkers() {
$('.locations-div').remove()
$('#state-select').val('').change();
}
// Sets the map on all markers in the array.
function setMapOnAll(map) {
for (var i = 0; i < markersArr.length; i++) {
markersArr[i].setMap(map);
}
}
// Removes the markers from the map, but keeps them in the array.
function clearMarkers() {
setMapOnAll(null);
}
function deleteMarkers() {
clearMarkers();
markersArr = [];
}
function findState(subStr) {
if (subStr.indexOf('OH') > -1) {
return 'OH';
} else if (subStr.indexOf('IL') > -1) {
return 'IL';
} else if (subStr.indexOf('MO') > -1) {
return 'MO';
} else if (subStr.indexOf('MI') > -1) {
return 'MI';
} else if (subStr.indexOf('IN') > -1) {
return 'IN';
}
}
function plotTableRow(thisStore, addedClass) {
$('.locations-table').append('<div class="columns small-12 medium-6 locations-div ' + addedClass + '"><div class="row"><div class="columns small-3"><img src="https://cdn1.iconfinder.com/data/icons/mirrored-twins-icon-set-hollow/512/PixelKit_point_marker_icon.png"></div><div class="columns small-9"><h3>Marker</h3><h4>' + thisStore.Address + '</h4></div></div></div>');
};
APPENDIX CODE:
function compare(a, b) {
if (a.distance < b.distance)
return -1;
if (a.distance > b.distance)
return 1;
return 0;
}
function getDistanceFromLatLon(lat1, lon1, lat2, lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2 - lat1); // deg2rad below
var dLon = deg2rad(lon2 - lon1);
var a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c; // Distance in km
return getMiles(d);
}
function deg2rad(deg) {
return deg * (Math.PI / 180)
}
//converts to miles
function getMiles(i) {
return i * 0.621371192;
}
function withinOneSD(arr, sd) {
var tempArr = [];
var arrMax = Math.max.apply(Math, numArr);
var arrMin = Math.min.apply(Math, numArr);
$.each(arr, function(index, currValue) {
if (currValue.distance <= (arrMin + sd)) {
tempArr.push(currValue);
}
});
return tempArr;
}
var numArr;
function standardDeviation(values) {
numArr = [];
$.each(values, function(index, currentValue) {
numArr.push(currentValue.distance);
})
var avg = average(numArr);
var squareDiffs = numArr.map(function(value) {
var diff = value - avg;
var sqrDiff = diff * diff;
return sqrDiff;
});
var avgSquareDiff = average(squareDiffs);
var stdDev = Math.sqrt(avgSquareDiff);
return stdDev;
}
function average(data) {
var sum = data.reduce(function(sum, value) {
return sum + value;
}, 0);
var avg = sum / data.length;
return avg;
}
See it here: http://codepen.io/maudulus/pen/oxNXod
One problem is this code, which only shows markers, doesn't hide them if they don't match the state, doesn't seem like clearMarkers is doing what you think:
function filterByState(stateMarkerArr) {
$('#state-select').on('change', function() {
var stateCode = $(this).val();
$('.locations-table .locations-div').hide();
$.each($('.locations-table .locations-div.filtered-location'), function(index, thisLocation) {
var addressText = $(thisLocation).find('h4').text();
if (addressText.indexOf(stateCode) > -1) {
$(thisLocation).show();
}
});
clearMarkers();
$.each(stateMarkerArr, function(index, thisStateMarker) {
if (thisStateMarker.state == stateCode) {
thisStateMarker.setMap(map);
}
});
});
}
Add an else to the if (thisStateMarker.state == stateCode) {
function filterByState(stateMarkerArr) {
$('#state-select').on('change', function() {
var stateCode = $(this).val();
$('.locations-table .locations-div').hide();
$.each($('.locations-table .locations-div.filtered-location'), function(index, thisLocation) {
var addressText = $(thisLocation).find('h4').text();
if (addressText.indexOf(stateCode) > -1) {
$(thisLocation).show();
}
});
clearMarkers();
$.each(stateMarkerArr, function(index, thisStateMarker) {
if (thisStateMarker.state == stateCode) {
thisStateMarker.setMap(map);
} else {
thisStateMarker.setMap(null);
}
});
});
}

Icon of marker does not change the second time on google maps

I am building a web application to search for events using the backbone. In the home page, I have 10 images (that corresponds to the events) on right column and each of them have an id of event. In the left column have the markers that corresponds to the location of the images and each of the markers have an id of event too.
I have a function that detects an event mouseover of the image, and when this event occurs the icon of the marker that corresponds to the image is changed. And when I do a mouseover of another image the icon before is changed again to the icon default.
But my problem is when I do the mouseover the same image twice, the icon of the marker is not changed. Here's a gif to better understand the issue:
the problem
My code:
ev.views.Home = Backbone.View.extend({
initialize: function(map, p, firstEntry){
var that = this;
that.template = _.template(ev.templateLoader.get('home'));
ev.router.on("route", function(route, params) {
that.deleteMarkers();
});
that.map = map;
that.firstEntry = firstEntry;
that.p = p; // valor da pagina
that.icons = [];
that.render(that.map, that.p, that.firstEntry);
},
local: function(map){
...
},
deleteMarkers: function(){
...
},
events: {
'click #search' : 'searchKey',
'click #maisFiltros' : 'maisFiltros',
'mouseover .back' : 'overImagem'
},
overImagem: function(ev){
var target = $(ev.currentTarget);
var id = $(target).data("id");
this.icons.push(id);
var last = this.icons.length-2;
if(typeof this.icons[last] !== 'undefined'){
if(this.icons[last] !== this.icons[last+1]){
for (var i = 0; i < this.marcadores.markers.length; i++) {
if(id == this.marcadores.markers[i].get('id')){
this.marcadores.markers[i].setIcon('http://maps.google.com/mapfiles/ms/icons/blue-dot.png');
}
}
if(this.icons.length !== 1){
this.marcadores.markers[last].setIcon('http://maps.google.com/mapfiles/ms/icons/red-dot.png');
}
}
}else{
for (var i = 0; i < this.marcadores.markers.length; i++) {
if(id == this.marcadores.markers[i].get('id')){
this.marcadores.markers[i].setIcon('http://maps.google.com/mapfiles/ms/icons/blue-dot.png');
}
}
}
},
searchKey: function(){
...
},
render: function(map, p, firstEntry){
var that = this;
that.map = map;
that.firstEntry = firstEntry;
that.p = p;
that.$el.html(that.template());
setTimeout(function() {
that.local(that.map);
if(that.firstEntry != 0){
that.marcadores = new ev.views.Markers(that.map,p);
$("#lista").html(new ev.views.ListaEventos(that.p).el);
}else{
that.keyword = ev.keyword.get('key');
that.secondSearch = new ev.views.Pesquisa(that.keyword, that.p, that.map);
$("#lista").html(that.secondSearch.el);
}
}, 0);
return that;
}
});
View of markers:
ev.views.Markers = Backbone.View.extend({
initialize: function(map,p){
this.map = map;
this.p = p;
this.render(this.map,this.p);
},
apagar: function(){
for (var i = 0; i < this.markers.length; i++) {
this.markers[i].setMap(null);
}
this.markers = [];
},
render: function(map,p){
var that = this;
that.markers = [];
var imagens = new ev.models.ImagemCollection();
imagens.fetch({
success: function(){
var len = imagens.models.length;
var startPos = (that.p - 1) * 10;
var endPos = Math.min(startPos + 10 , len);
var marcadores = imagens.models;
for (var i = startPos; i < endPos; i++) {
var myLatlng = new google.maps.LatLng(marcadores[i].get('latitude'),marcadores[i].get('longitude'));
var marker = new google.maps.Marker({
position: myLatlng,
map: that.map,
icon: 'http://www.google.com/intl/en_us/mapfiles/ms/micons/red-dot.png',
id: marcadores[i].get('id')
});
that.markers.push(marker);
}
return that;
}
});
}
});
what I'm doing wrong.

Categories

Resources