I have drop down in my page, when the drop down value changes the contents of the map i.e the data to be loaded should change.It successfully loads for the first time but when again changed it is not changing. I am new to ArcGis map and want to reload the map. tried several methods but that doesn't help. Below is my code please suggest the way to fix this.
require([
"esri/map",
"esri/TimeExtent", "esri/dijit/TimeSlider",
"esri/geometry/Point",
"esri/symbols/PictureMarkerSymbol", "esri/graphic",
"esri/layers/GraphicsLayer",
"esri/geometry/Polyline",
"dojo/_base/array", "dojo/dom", "dojo/domReady!"
], function (
Map, TimeExtent, TimeSlider,
Point, PictureMarkerSymbol, Graphic,
GraphicsLayer, Polyline,
arrayUtils, dom
) {
var globalLocationArray = //my json data with latitude and longitude
var map;
var longitude = 96.07677;
var latitude = 16.97986;
var point = new Point(longitude, latitude);
var layer = new GraphicsLayer();
var layer1 = new GraphicsLayer();
map = new Map("mapDiv", {
basemap: "osm",
center: point, // longitude, latitude
zoom: 7,
maxZoom: 15,
minZoom: 3,
});
map.on("load", function () {
map.infoWindow.resize(250, 100);
//layer.clear();
//layer1.clear();
//map.removeLayer(layer)
//map.removeLayer(layer1)
//map.refresh();
//map.setExtent(map.extent)
});
layer1.on("click", function (evt) {
console.log(evt);
map.infoWindow.setTitle("Information");
var dataDisplay ="Contents";
map.infoWindow.setContent(dataDisplay);
map.infoWindow.show(evt.screenPoint, map.getInfoWindowAnchor(evt.screenPoint));
});
function createMarker(longitude, latitude, externalCause, date) {
var point = new Point(longitude, latitude);
point = esri.geometry.geographicToWebMercator(point);
var symbol;
if (externalCause == "SUCCESS") {
symbol = new PictureMarkerSymbol(
"http://static.arcgis.com/images/Symbols/Shapes/BluePin1LargeB.png", 32, 32)
.setOffset(0, 15);
} else {
symbol = new PictureMarkerSymbol(
"http://static.arcgis.com/images/Symbols/Shapes/RedPin1LargeB.png", 32, 32)
.setOffset(0, 15);
}
//var symbol= symbol = new PictureMarkerSymbol("http://static.arcgis.com/images/Symbols/Shapes/BluePin1LargeB.png", 32, 32).setOffset(0, 15);
var graphic = new esri.Graphic(point, symbol);
layer1.add(graphic);
}
function createPolyLine(sourcePoint, destPoint) {
var point1 = new Point(sourcePoint[0], sourcePoint[1]);
var point2 = new Point(destPoint[0], destPoint[1]);
var line = new esri.geometry.Polyline();
var lineSymbol = new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([0, 0, 255, 0.5]), 3);
line.addPath([point1, point2]);
var graphic = new Graphic(line, lineSymbol);
layer.add(graphic);
}
function drawGeoMap(data) {
console.info(data);
for (var row in data) {
var rowObj = createObject(data[row]);
createMarker(rowObj.long, rowObj.lat, rowObj.externalCause, rowObj.date,rowObj.cellName,rowObj.bts);
createMarker(rowObj.sbLong, rowObj.sbLat, rowObj.sbExternalCause, rowObj.sbDate,rowObj.sbCellName,rowObj.sbBts);
createPolyLine([rowObj.long, rowObj.lat], [rowObj.sbLong, rowObj.sbLat]);
}
map.addLayer(layer);
map.addLayer(layer1);
}
function createObject(rowData) {
var count = 0;
var obj = {
sbLat: rowData[count++],
sbLong: rowData[count++],
sbExternalCause: rowData[count++],
sbDate: rowData[count++],
sbCellName: rowData[count++],
sbBts: rowData[count++],
lat: rowData[count++],
long: rowData[count++],
externalCause: rowData[count++],
date: rowData[count++],
cellName: rowData[count++],
bts: rowData[count++]
};
return obj;
}
initSlider();
function initSlider() {
var timeSlider = new TimeSlider({
style: "width: 100%;"
}, dom.byId("timeSliderDiv"));
var timeExtent = new TimeExtent();
timeExtent.startTime = new Date("2/14/2015");
timeExtent.endTime = new Date("2/15/2015");
timeSlider.setThumbCount(2);
timeSlider.createTimeStopsByTimeInterval(timeExtent, 30, "esriTimeUnitsMinutes");
timeSlider.setThumbIndexes([0, 1]);
timeSlider.setThumbMovingRate(2000);
timeSlider.startup();
//add labels for every other time stop
var labels = arrayUtils.map(timeSlider.timeStops, function (timeStop, i) {
console.log(timeStop)
if (i % 2 === 0) {
var minutes;
if (timeStop.getMinutes() < 10) {
minutes = "0" + timeStop.getMinutes();
} else {
minutes = timeStop.getMinutes();
}
return timeStop.getHours() + ":" + minutes;
} else {
return "";
}
});
timeSlider.setLabels(labels);
timeSlider.on("time-extent-change", function (evt) {
layer.clear();
layer1.clear();
map.infoWindow.hide();
var startMinutes;
var endminutes;
if (new Date(evt.startTime).getMinutes() < 10) {
startMinutes = "0" + new Date(evt.startTime).getMinutes();
} else {
startMinutes = new Date(evt.startTime).getMinutes();
}
if (new Date(evt.endTime).getMinutes() < 10) {
endminutes = "0" + new Date(evt.endTime).getMinutes();
} else {
endminutes = new Date(evt.endTime).getMinutes();
}
var startValString = new Date(evt.startTime).getHours() + ":" + startMinutes;
var endValString = new Date(evt.endTime).getHours() + ":" + endminutes;
var start=globalArrayWithLocationAndImsi.length;
var end = 0
for(var i=0;i<globalArrayWithLocationAndImsi.length;i++)
{
var srt = parseInt(globalArrayWithLocationAndImsi[i].start.split(' ')[1].split(':')[0])
if(srt>= new Date(evt.startTime).getHours() && srt<=new Date(evt.endTime).getHours())
{
console.log(srt);
console.log(globalArrayWithLocationAndImsi[i].start);
if(start>i)
{
start=i;
}
if(end<i)
{
end=i;
}
}
}
console.log(start);
console.log(end);
for (var j = start; j < end; j++) {
drawGeoMap([[globalArrayWithLocationAndImsi[j].latitude, globalArrayWithLocationAndImsi[j].longitude, globalArrayWithLocationAndImsi[j].externalCause, globalArrayWithLocationAndImsi[j].timeStamp1,globalArrayWithLocationAndImsi[j].cellName, globalArrayWithLocationAndImsi[j].bts,globalArrayWithLocationAndImsi[j + 1].latitude, globalArrayWithLocationAndImsi[j + 1].longitude, globalArrayWithLocationAndImsi[j + 1].externalCause, globalArrayWithLocationAndImsi[j + 1].timeStamp1,globalArrayWithLocationAndImsi[j+1].cellName, globalArrayWithLocationAndImsi[j+1].bts]]);
}
dom.byId("daterange").innerHTML = "<i>" + startValString + " and " + endValString + "<\/i>";
});
}
});
Also time extent needs to be refreshed. Note: when the dropdown changes I call the entire function above. Please suggest a way to refresh the contents to be loaded to the arcGIS map. Thank you in advance
Related
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Is Chrome’s JavaScript console lazy about evaluating objects?
(7 answers)
Closed 2 years ago.
Good morning,
I get data from JSON, with physical addresses that get converted to geo coordinates (If needed I can put the whole code here or a link to the site under construction).
Then I need to work with these coordinates to calculate distances or whatever.
But somehow I can't access them.
my code (extract) looks like this:
var positionsCenter = [];
for (let i = 0; i < positions.length; i++) {
lux.geocode({
num: positions[i].num,
street: positions[i].street,
zip: positions[i].zip,
locality: positions[i].locality
}, function (position) {
**positionsCenter[i] = position;**
var pFeature = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform(position, 'EPSG:2169', 'EPSG:3857')),
id: i
});
vectorSource.addFeature(pFeature);
});
}
These are coordinates on a map (vector layer) but something's wrong.
When I output this via:
console.log(positionsCenter);
It gives me this:
[]
0: (2) [75980.11870000046, 75098.00039954418]
1: (2) [87897.10419999996, 63546.633999540085]
2: (2) [88238.34310000022, 63389.17289954127]
3: (2) [73701.38559999966, 76385.07059954498]
4: (2) [71212.77219999957, 74969.26619954518]
5: (2) [80450.28039999957, 72414.96529954427]
6: (2) [83811.06230000037, 75487.27249954658]
7: (2) [86081.38100000011, 86362.58049954918]
8: (2) [77022.02340000033, 80667.17809954635]
9: (2) [66163.39429999988, 62664.86699954068]
length: 10
__proto__: Array(0)
But when I try to access one of the entries like this:
console.log(positionsCenter[1]);
or
console.log(positionsCenter[1][1]);
or even
console.log(positionsCenter.length);
it's always undefined!
What do I miss? I'm confused :-/
Thank you for any help.
Best regards,
Claude
Here's the whole part of this code:
var map;
var vectorSource;
var highlightedFeature = null;
var selectedFeature = null;
function loadMap() {
map = new lux.Map({
target: 'map',
bgLayer: 'basemap_2015_global', //default basemap_2015_global, streets_jpeg
zoom: 16, //18
position: [75977, 75099],
showLayerInfoPopup: true,
search: {
target: 'searchbox',
dataSets: ['Adresse', 'Coordinates']
}
});
//-------------------------------------------------------------- FEATURES -
vectorSource = new ol.source.Vector({
features: []
});
var vectorLayer = new ol.layer.Vector({
source: vectorSource
});
function styleFunction(feature, resolution) {
var sti = feature.get('status');
const liv = 'livraison';
const tak = 'take-away';
var newColor = [128, 128, 128];
if (sti.includes('ouvert')) {
newColor = [0, 255, 0];
}
var imgSource = '../images/pin.png';
if (sti.includes(liv) && sti.includes(tak)) {
imgSource = '../images/pin-livraison-takeaway.png';
} else {
if (sti.includes(liv)) {
imgSource = '../images/pin-livraison.png';
} else {
if (sti.includes(tak)) {
imgSource = '../images/pin-takeaway.png';
}
}
}
var isSelected = feature.get('selected') || feature.get('highlighted');
var iconStyle = new ol.style.Style({
image: new ol.style.Icon(({
anchor: [0.5, 0.5],
color: newColor,
anchorXUnits: 'fraction',
anchorYUnits: 'fraction',
src: imgSource,
scale: isSelected ? 1.5 : 1
}))
});
return [iconStyle];
}
vectorLayer.setStyle(styleFunction);
map.addLayer(vectorLayer);
for (let i = 0; i < positions.length; i++) {
lux.geocode({
num: positions[i].num,
street: positions[i].street,
zip: positions[i].zip,
locality: positions[i].locality
}, function (position) {
positionsCenter[i] = position;
var pFeature = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform(position, 'EPSG:2169', 'EPSG:3857')),
id: i
});
const sti = statuses[i];
pFeature.set('status', sti);
pFeature.setId(i);
pFeature.set('selected', false);
pFeature.set('highlighted', false);
vectorSource.addFeature(pFeature);
});
//console.log(positions[i]);
}
map.on('click', function (evt) {
var feature = map.forEachFeatureAtPixel(evt.pixel, function (feature) {
return feature;
});
if (feature !== undefined) {
if (selectedFeature !== null) {
selectedFeature.set('selected', false);
selectedFeature = null;
}
feature.set('selected', true);
selectedFeature = feature;
var outPut = feature.get('id');
infoField.innerHTML = arr[outPut].innerHTML;
infoField.style.display = 'block';
CloseinfoField.style.display = 'block';
galImage.style.display = 'none';
ClosegalImage.style.display = 'none';
getThumbs(outPut);
for (let j = 0; j < arr.length; j++) {
arr[j].classList.remove('active');
}
arr[outPut].className += ' active';
var current = document.getElementById('item' + outPut);
current.scrollIntoView({
behavior: 'smooth',
block: 'center'
});
} else {
console.log('');
}
});
map.on('pointermove', function (evt) {
if (highlightedFeature !== null) {
highlightedFeature.set('highlighted', false);
highlightedFeature = null;
}
var feature = map.forEachFeatureAtPixel(evt.pixel, function (feature) {
return feature;
});
if (feature !== undefined) {
highlightedFeature = feature;
highlightedFeature.set('highlighted', true);
}
});
//------------------------------------------------------------------ DISTANCE -
var sourceProj = map.getView().getProjection();
var wgs84Sphere = new ol.Sphere(6378137);
var coordinates1 = [75977, 75099];
var coordinates2 = [76977, 75099];
// EDIT/UPDATE ----------------------------------------
function delay(ms) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve();
}, ms);
});
}
function getFive() {
return delay(100).then(function () {
return positionsCenter[0];
})
}
getFive().then(function (five) {
console.log(five);
});
// EDIT ----------------------------------------
var c1 = ol.proj.transform(coordinates1, sourceProj, 'EPSG:4326');
var c2 = ol.proj.transform(coordinates2, sourceProj, 'EPSG:4326');
var distance = wgs84Sphere.haversineDistance(c1, c2);
console.log(distance);
//----------------------------------------------------------------- /DISTANCE -
document.getElementById('myLocation').addEventListener('click', getLocation);
document.getElementById('navList').addEventListener('click', getnavList);
}
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
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);
}
});
});
}
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.
I have the following js object:
virtualEarthBingMap = {
map : "",
propertiesDataArray : [],
locations : [],
initialLatLong : "",
initialZoom : "",
isInitialized : false,
MM : "",
overMap : false,
init : function(){
},
addLoadEvent : function(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
oldonload();
func();
}
}
},
pushpinObj : function(){
this.number;
this.lat;
this.longitude;
this.type;
this.iconstyle;
},
generatePushpinData : function(rowCount){
if(rowCount == undefined){
rowCount = "";
}
//initiate hidden field objects
var pushPinNumberObj = document.getElementsByName("pushpin-number"+rowCount);
var pushPinLatObj = document.getElementsByName("pushpin-lat"+rowCount);
var pushPinLongObj = document.getElementsByName("pushpin-long"+rowCount);
var pushPinTypeObj = document.getElementsByName("pushpin-type"+rowCount);
var pushPinIconStyleObj = document.getElementsByName("pushpin-iconstyle"+rowCount);
for(i=0; i < pushPinNumberObj.length; i++){
var propertyData = new virtualEarthBingMap.pushpinObj;
propertyData.number = Number(pushPinNumberObj[i].value);
propertyData.lat = pushPinLatObj[i].value;
propertyData.longitude = pushPinLongObj[i].value;
propertyData.type = pushPinTypeObj[i].value;
if(pushPinIconStyleObj!= null && pushPinIconStyleObj.length>0){
propertyData.iconstyle = pushPinIconStyleObj[i].value;
}
virtualEarthBingMap.propertiesDataArray.push(propertyData);
}
},
mouseEvent: function (e){
if(e.eventName == 'mouseout')
virtualEarthBingMap.overMap = false;
else if(e.eventName == 'mouseover')
virtualEarthBingMap.overMap = true;
},
//renders VEMap to myMap div
getMap: function (mapObj, rowCount) {
if(rowCount == undefined){
rowCount = "";
}
try{
virtualEarthBingMap.MM = Microsoft.Maps;
//Set the map options
var mapOptions = { credentials:document.getElementById("bingKey"+rowCount).value,
mapTypeId: virtualEarthBingMap.MM.MapTypeId.road,
enableClickableLogo: false,
enableSearchLogo: false,
tileBuffer: Number(document.getElementById("tileBuffer"+rowCount).value)};
virtualEarthBingMap.map = new virtualEarthBingMap.MM.Map(document.getElementById("map"+rowCount), mapOptions);
var dataLayer = new virtualEarthBingMap.MM.EntityCollection();
virtualEarthBingMap.map.entities.push(dataLayer);
var pushpinOptions,pushpin,propertyData;
for(var x=0; x < virtualEarthBingMap.propertiesDataArray.length; x++){
propertyData = virtualEarthBingMap.propertiesDataArray[x];
if(document.getElementsByName(("pushpin-iconstyle"+rowCount)).length > 0)//All other maps push pins
{
pushpinOptions ={icon: mapObj.getCustomIcon(propertyData.iconstyle)};
}
else//classic search map push pin
{
pushpinOptions ={icon: mapObj.getCustomIcon(propertyData.type)};
}
// creating a pushpin for every property
pushpin = new virtualEarthBingMap.MM.Pushpin(new virtualEarthBingMap.MM.Location(Number(propertyData.lat), Number(propertyData.longitude)), pushpinOptions);
pushpin.setOptions({typeName:("pushpin"+rowCount)});
// set pushpin on map
dataLayer.push(pushpin);
// adding to locations array to be used for setMapView when there are more than one property on a map
virtualEarthBingMap.locations.push(new virtualEarthBingMap.MM.Location(Number(propertyData.lat), Number(propertyData.longitude)));
};
//Handle blur event for map
if(rowCount == ""){
$("html").click(function() {
if(!virtualEarthBingMap.overMap)
virtualEarthBingMap.map.blur();
});
}
//Set the events for map, pushpin and infobox
virtualEarthBingMap.map.blur();//Removes focus from the map control
virtualEarthBingMap.MM.Events.addHandler(pushpin, 'mouseover', function (e) { virtualEarthBingMap.displayInfobox(e, rowCount)});
virtualEarthBingMap.MM.Events.addHandler(pushpin, 'click', function (e) { virtualEarthBingMap.displayInfobox(e, rowCount)});
virtualEarthBingMap.MM.Events.addHandler(virtualEarthBingMap.map, 'viewchangeend', virtualEarthBingMap.hideInfobox);
virtualEarthBingMap.MM.Events.addHandler(virtualEarthBingMap.map, 'mouseout', virtualEarthBingMap.mouseEvent);
virtualEarthBingMap.MM.Events.addHandler(virtualEarthBingMap.map, 'mouseover', virtualEarthBingMap.mouseEvent);
//Plot the pushpin
mapObj.setMapView();
}catch(e){
mapObj.displayMapError(rowCount);
}
//clean up properties data array
virtualEarthBingMap.propertiesDataArray = [];
},
//returns flyout info id
getFlyoutId : function(lat, longitude, rowCount){
if(rowCount == undefined){
rowCount = "";
}
try{
var flyoutId = "flyout"+rowCount+"[" + lat + "][" + longitude + "]";
return flyoutId
}catch(e){}
},
//Show info box
displayInfobox: function (e, rowCount) {
var disableToolTip = $('#disableToolTip').val();
if ((disableToolTip == undefined || disableToolTip == "" || disableToolTip == 'false') && e.targetType == 'pushpin') {
virtualEarthBingMap.hideInfobox();
if(rowCount == undefined){
rowCount = "";
}
var flyoutLat = $("input[name='pushpin-lat"+rowCount+"'][type='hidden']").val();
var flyoutLong = $("input[name='pushpin-long"+rowCount+"'][type='hidden']").val();
var flyoutId = virtualEarthBingMap.getFlyoutId(flyoutLat,flyoutLong, rowCount);
var infobox = document.getElementById(flyoutId);
$(infobox).css("display","inline");
$(infobox).css("z-index","10000");
$(infobox).css("position","absolute");
var pushpinPosition;
if(rowCount != "")
{
pushpinPosition = $('.pushpin'+rowCount).offset();
$(infobox).css("top",pushpinPosition.top + "px");
$(infobox).css("left",pushpinPosition.left + "px");
} else {
//original position
pushpinPosition = virtualEarthBingMap.map.tryLocationToPixel(e.target.getLocation(), virtualEarthBingMap.MM.PixelReference.page);
$(infobox).css("top",(pushpinPosition.y-40) + "px");
$(infobox).css("left",(pushpinPosition.x-5) + "px");
}
$('body').append(infobox);
setTimeout(virtualEarthBingMap.hideInfobox,12000); //hide infobox after 12 sec
}
},
//Hide infobox
hideInfobox: function () {
$('.display-off').css("display","none");
}
}//End virtualEarthBingMap
I am trying to set the bing map to zoom in on a location right now I am using this script to differentiate between single and multiple locations:
setMapView: function () {
if (virtualEarthBingMap.locations.length > 1) {
// set mapview for multiple hotels that dynamically sets the zoom so all pushpins are shown in ititial map window
virtualEarthBingMap.map.setView({bounds:virtualEarthBingMap.MM.LocationRect.fromLocations(virtualEarthBingMap.locations),padding:10});
} else {
// set mapview for single hotel
virtualEarthBingMap.map.setView({center:new Microsoft.Maps.Location(virtualEarthBingMap.propertiesDataArray[0].lat,virtualEarthBingMap.propertiesDataArray[0].longitude),zoom:15});
}
}
This is working on multiple locations but not on single locations. Anyone have any ideas?
A padding of 10 won't have an effect on the zoom level unless the map is less than 20 pixels wide. A simple solution is to set the zoom level instead. I recommend zoom level 15 or 16 for a single location.