onclick event for marker is not working in openlayer3 on changing the size of the div - resize

i am plotting the markers on the map in openlayer3 as shown below
<!DOCTYPE html>
<html>
<head>
<title>Rotation example</title>
<link rel="stylesheet" href="http://openlayers.org/en/v3.0.0/css/ol.css" type="text/css">
<script src="http://openlayers.org/en/v3.11.2/build/ol.js"></script>
</head>
<body>
<div id="map" style="width:1000px;height:1000px"></div>
<script>
var map;
function initMap() {
map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
target: 'map',
controls: ol.control.defaults({
attributionOptions: ({
collapsible: false,
})
}),
view: new ol.View({
center: ol.proj.fromLonLat([103.986908, 1.353199]),
rotation: 68*Math.PI/180,
zoom: 18
})
});
}
function invokeAddMarker(){
var markerData = [
{
"title": 'point1',
"lat": 1.350664,
"lng": 103.985190,
"description": 'yyyy'
}, {
"title": 'point2',
"lat":1.353604,
"lng": 103.986395,
"description": 'zzz'
}, {
"title": 'point3',
"lat": 1.357227,
"lng": 103.9879999,
"description": 'uuu'
}
];
for(var i=0;i<markerData.length;i++){
addmarker(markerData[i].lat,markerData[i].lng);
}
}
function addmarker(lat,lng){
console.log("*****lat******"+lat);
console.log("*****lng******"+lng);
var iconFeature = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform([lng,lat],'EPSG:4326', 'EPSG:3857')),
name: 'camera'
});
var iconStyle = new ol.style.Style({
image: new ol.style.Icon(({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
opacity: 0.75,
src: 'camera.png'
}))
});
iconFeature.setStyle(iconStyle);
vectorSource = new ol.source.Vector({
features: [iconFeature]
});
/*t clear the markers*/
/*vectorSource.clear();*/
vectorLayer = new ol.layer.Vector({
source: vectorSource
});
map.addLayer(vectorLayer);
map.on('click', function(evt) {
var feature = map.forEachFeatureAtPixel(evt.pixel,
function(feature, layer) {
return feature;
});
if (feature) {
alert("video comes here");
}
});
}
initMap();
invokeAddMarker();
</script>
</body>
</html>
I am facing two problem in the above code
1:the click event will fired 3 times ie, the number marker on the map that should only onces by theory
2:when i resize the div say(new width and height of the div is varied to new value in which the map is displayed)the markers will adjust to div but the event is not fired
please say why is this behavior and how to overcome it

Related

In Nuxt.js, load a simple Google map

I am doing this successfully on another project and I do not understand at all, why I am getting an empty div here instead of a map. The map should render here:
<template>
<div class="row mt-5">
<div style="height: 500px; width: 500px;" ref="map"></div>
</div>
</template>
And the code:
head() {
return {
title: 'Properties',
script: [{
src: "https://maps.googleapis.com/maps/api/js?key=XXX",
hid: "map",
defer: true,
}]
}
},
mounted(){
const mapOptions = {
zoom: 18,
center: new window.google.maps.LatLng(43.758773, -79.391785),
disableDefaultUI: true,
zoomControl: true
};
const map = new window.google.maps.Map(this.$refs.map, mapOptions);
const position = new window.google.maps.LatLng(43.758773, -79.391785)
const marker = new window.google.maps.Marker({ position })
marker.setMap(map)
},
Inside your mapOptions object change center to center: { lat: 43.758773, lng: -79.391785 }
You can reference this https://developers.google.com/maps/documentation/javascript/examples/map-latlng-literal

Enable arcgis API JS popups with Vue CLI 3

I am trying to get popups from the ArcGIS API JS to display using the framework Vue-CLI 3.
But even with a simple sample code, I cannot make it work: Here is the code in vanilla JS:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<title>Popup actions | Sample | ArcGIS API for JavaScript 4.17</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.17/esri/themes/light/main.css" />
<script src="https://js.arcgis.com/4.17/"></script>
<script>
require([
"esri/Map",
"esri/layers/FeatureLayer",
"esri/views/MapView",
"esri/geometry/geometryEngine"
], function (Map, FeatureLayer, MapView, geometryEngine) {
// Create the Map
var map = new Map({
basemap: "gray-vector"
});
// Create the MapView
var view = new MapView({
container: "viewDiv",
map: map,
center: [-117.08, 34.1],
zoom: 11
});
var template = {
// autocasts as new PopupTemplate()
title: "Trail run",
content: "{name}",
};
var featureLayer = new FeatureLayer({
url:
"https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/TrailRuns/FeatureServer/0",
outFields: ["*"],
popupTemplate: template,
});
map.add(featureLayer);
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
As you can see, when clicking a feature, a popup appears.
If I try to implement this in my vue-CLI project I can not make it work. When clicking on the a feature, it will highlight, but nothing will open. Here is my code .vue:
<template>
<div></div>
</template>
<script>
import { loadModules } from "esri-loader";
export default {
name: "web-map",
mounted() {
// lazy load the required ArcGIS API for JavaScript modules and CSS
loadModules([
"esri/Map",
"esri/views/MapView",
"esri/layers/FeatureLayer",
]).then(([ArcGISMap, MapView, FeatureLayer]) => {
const map = new ArcGISMap({
basemap: "topo-vector",
});
this.view = new MapView({
container: this.$el,
map: map,
center: [-117.08, 34.1],
zoom: 11,
});
var template = {
// autocasts as new PopupTemplate()
title: "Trail run",
content: "{name}",
};
var featureLayer = new FeatureLayer({
url:
"https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/TrailRuns/FeatureServer/0",
outFields: ["*"],
popupTemplate: template,
});
map.add(featureLayer);
});
},
beforeDestroy() {
if (this.view) {
// destroy the map view
this.view.destroy();
}
},
};
</script>
<style scoped>
div {
padding: 0;
margin: 0;
width: 100%;
height: 100%;
}
</style>
Am I missing something? (I followed arcgis api js tutorial to get it work in vue-cli -https://developers.arcgis.com/javascript/latest/guide/vue/ )
Thank you very much for your help!
Julien
Your code is fine, you are just not adding css. You are missing { css: true }, that's all.
loadModules(
["esri/Map", "esri/views/MapView", "esri/layers/FeatureLayer"],
{ css: true } // <-- HERE
).then(([ArcGISMap, MapView, FeatureLayer]) => {
//...
}
HERE code with the fix.

Performance issue Vue with Leaflet and Leaflet.markercluster thousands Markers

Leaflet this is a popular geo library.
For some reason, I have serious performance problems when using this library together with the Vue.
Problem 1:
More than 500 markers and the page is already beginning to stumble, 2,000 markers - strongly breaks, 10,000 markers - does not load.
On an HTML web page, 50,000 are loaded peacefully.
Problem 2:
The Leaflet.markercluster plugin is very weak, it does not collapse the markers.
mounted() {
this.initMap();
setTimeout(() => {
this.initLocation()
}, 100)
},
methods: {
initMap() {
this.map = L.map('map').setView([38.63, -90.23], 12);
this.tileLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap contributors',
});
this.tileLayer.addTo(this.map);
},
initLocation() {
this.map.locate({
setView: true,
maxZoom: 17
});
//Leaflet.markercluster
let markers = L.markerClusterGroup();
function r(min, max) {
return Math.random() * (max - min) + min;
}
let icon = L.divIcon({
className: 'icon'
});
for (let i = 0; i < 500; i++) {
let marker = L.marker([r(53.82477192, 53.97365592), r(27.3878027, 27.70640622)], {
icon: icon
}).addTo(this.map);
markers.addLayer(marker);
}
this.map.addLayer(markers);
},
}
Do not add your marker both to this.map and to your markers Marker Cluster Group (MCG).
Add them only to the MCG, and let it handle the adding to your map as needed.
new Vue({
el: '#app',
data: {
map: null,
tileLayer: null,
},
mounted() {
this.initMap();
setTimeout(() => {
this.initLocation()
}, 100)
},
methods: {
initMap() {
this.map = L.map(this.$refs.map).setView([53.9, 27.6], 9);
this.tileLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap contributors',
});
this.tileLayer.addTo(this.map);
},
initLocation() {
//this.map.locate({setView: true, maxZoom: 17});
//Leaflet.markercluster
let markers = L.markerClusterGroup();
function r(min, max) {
return Math.random() * (max - min) + min;
}
let icon = L.divIcon({
className: 'icon'
});
// Quick test with 5k markers:
for (let i = 0; i < 5000; i++) {
let marker = L.marker([
r(53.82477192, 53.97365592),
r(27.3878027, 27.70640622)
], {
icon: icon
}) /*.addTo(this.map)*/ ; // <= do not add individual `marker` to map!
markers.addLayer(marker); // <= but only to MCG
}
this.map.addLayer(markers);
},
},
});
<script src="https://unpkg.com/vue#2"></script>
<!-- Leaflet assets -->
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.3.1/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" />
<script src="https://unpkg.com/leaflet#1.3.1/dist/leaflet-src.js" integrity="sha512-IkGU/uDhB9u9F8k+2OsA6XXoowIhOuQL1NTgNZHY1nkURnqEGlDZq3GsfmdJdKFe1k1zOc6YU2K7qY+hF9AodA==" crossorigin=""></script>
<!-- Leaflet.markercluster assets -->
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster#1.3.0/dist/MarkerCluster.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster#1.3.0/dist/MarkerCluster.Default.css">
<script src="https://unpkg.com/leaflet.markercluster#1.3.0/dist/leaflet.markercluster-src.js"></script>
<div id="app">
<div ref="map" style="height: 180px"></div>
</div>
For greater performance
When handling a lot of markers make sure to make use of the scaling capabilities of markercluster. They have batch methods for adding and removing lots of markers: addLayers(), removeLayers(), and clearLayers(). They are much more performant. Also note that you can use the chunkedLoading option on the markerClusterGroup. Allowing you to return the main thread frequently, to make the UI more snappy.
So extending on the answer from #ghybs above. I would adapt the snippet like this:
new Vue({
el: '#app',
data: {
map: null,
tileLayer: null,
},
mounted() {
this.initMap();
setTimeout(() => {
this.initLocation()
}, 100)
},
methods: {
initMap() {
this.map = L.map(this.$refs.map).setView([53.9, 27.6], 9);
this.tileLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap contributors',
});
this.tileLayer.addTo(this.map);
},
initLocation() {
//Leaflet.markercluster
const markerClusterGroup = L.markerClusterGroup({
chunkedLoading: true
}); // <= Add chunked loading here
function r(min, max) {
return Math.random() * (max - min) + min;
}
let icon = L.divIcon({
className: 'icon'
});
const markers = []
// Quick test with 5k markers:
for (let i = 0; i < 5000; i++) {
let marker = L.marker([
r(53.82477192, 53.97365592),
r(27.3878027, 27.70640622)
], {
icon: icon
})
markers.push(marker)
// markers.addLayer(marker); // <= do not add individual marker to MCG
}
markerClusterGroup.addLayers(markers) // <= use batch method to add markers to MCG
this.map.addLayer(markerClusterGroup);
},
},
});
<script src="https://unpkg.com/vue#2"></script>
<!-- Leaflet assets -->
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.3.1/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" />
<script src="https://unpkg.com/leaflet#1.3.1/dist/leaflet-src.js" integrity="sha512-IkGU/uDhB9u9F8k+2OsA6XXoowIhOuQL1NTgNZHY1nkURnqEGlDZq3GsfmdJdKFe1k1zOc6YU2K7qY+hF9AodA==" crossorigin=""></script>
<!-- Leaflet.markercluster assets -->
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster#1.3.0/dist/MarkerCluster.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster#1.3.0/dist/MarkerCluster.Default.css">
<script src="https://unpkg.com/leaflet.markercluster#1.3.0/dist/leaflet.markercluster-src.js"></script>
<div id="app">
<div ref="map" style="height: 300px"></div>
</div>
I hope that helps others.

Add PercentDoneByStoryPoint to HTML DIV

In the 1.x version of the Rally SDK I was able to query and assign to an HTML DIV with a query like the following:
var querySI48 = {
type : 'portfolioitem',
query:'(Name = "Q3 2015 Release (2.8.0)")',
key : 'SI48Key',
fetch: 'PercentDoneByStoryCount'
};
And assign it to a DIV like this:
var WS215 = document.getElementById("WS215");
WS215.innerHTML = "<h2>" + pisInfo + "%</h2>";
How can I assign the PercentDoneByStoryPoint to a DIV with the 2.X SDK? I'm creating a dashboard in Confluence that contains Rally data.
Something similar to the following should do the trick:
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script type="text/javascript" src="/apps/2.0/sdk.js"></script>
<script type="text/javascript">
Rally.onReady(function() {
Ext.define('Rally.example.App', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
var me = this;
var divTemplateString = "<h2>{0}: Percent Done by Story Count = {1}</h2>";
Ext.create('Rally.data.wsapi.Store', {
model: 'PortfolioItem/Feature',
fetch: true,
autoLoad: true,
filters: [
{
property: 'FormattedID',
value: 'F15'
}
],
listeners: {
load: function(store, data, success) {
var formattedID = data[0].get('FormattedID');
var pctDoneByStoryCount = data[0].get('PercentDoneByStoryCount');
var divHTML = Ext.String.format(divTemplateString, formattedID, pctDoneByStoryCount);
var div = Ext.get('F15');
me.add({
xtype: 'container',
html: divHTML,
renderTo: div
});
}
},
});
}
});
Rally.launchApp('Rally.example.App', {
name: 'Example'
});
});
</script>
<style type="text/css">
</style>
</head>
<body>
<div id="F15"</div>
</body>
</html>

Google maps API not working on my site

<script type="text/javascript"
src="http://maps.googleapis.com/maps/api/js?key=MYKEYHERE&sensor=false">
</script>
<script type="text/javascript">
var simplerweb = new google.maps.LatLng(55.977046,-3.197118);
var marker;
var map;
function initialize() {
var myOptions = {
center: new google.maps.LatLng(55.977046,-3.197118),
disableDefaultUI: true,
zoom: 15,
scrollwheel: false,
navigationControl: false,
mapTypeControl: false,
scaleControl: false,
draggable: false,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"),
myOptions);
marker = new google.maps.Marker({
map:map,
draggable:true,
animation: google.maps.Animation.DROP,
position: andrewmorris,
icon: 'http://www.andrewsmorris.co.uk/images/point.png'
});
google.maps.event.addListener(marker, 'click', toggleBounce);
}
function toggleBounce() {
if (marker.getAnimation() != null) {
marker.setAnimation(null);
} else {
marker.setAnimation(google.maps.Animation.BOUNCE);
}
}
</script>
So I can't figure out why this isn't working on my new site, works fine on my old site.
I dumped in a div called map_canvas
It SHOULD work, right?
Google maps API set up to allow referrals from that URL.
It should work fine as long as you have the correct key.
Did you double check that you are calling initialize() within your html body like
<body onload="initialize()">
<div id="map_canvas" style="width:100%; height:100%"></div>
</body>
Also the link to your marker image is dead.