Show InfoWindo with ArcGis Api - javascript

Hello everyone I m actually work on geographic application with ArcGsi JavaScript API and I am looking for method that is run when user click on suggestion Menu in the Search Bar for show a Specific
feature InfoWindow

There are a few ways.
First mouse drag options;
var services = new FeatureLayer("http://blablabla/MapServer/0", {
// mode: FeatureLayer.MODE_SNAPSHOT,
// infoTemplate: popupTemplate,
outFields: ["NAME", "ID", "VALUE"]
});
services.on("mouse-over", function (evt) {
var t = "<div class='title'><b>${NAME}</b></div><p>${ID}<br>${VALUE}<br>${VALUE}<br><strong>value: </strong>${VALUE}</p>";
var content = esriLang.substitute(evt.graphic.attributes, t);
//var highlightGraphic = new Graphic(evt.graphic.geometry, highlightSymbol);
//map.graphics.add(highlightGraphic);
dialog.setContent(content);
domStyle.set(dialog.domNode, "opacity", 1);
dijitPopup.open({
popup: dialog,
x: evt.pageX,
y: evt.pageY
});
});
services.on("mouse-out", function (evt) {
closeDialog();
});
Or second away. Click to graphic;
var services = new FeatureLayer("http://blablabla/MapServer/0", {
mode: FeatureLayer.MODE_SNAPSHOT,
// infoTemplate: popupTemplate,
outFields: ["NAME", "ID", "VALUE"]
});
services.on("click", function (evt) {
var name = evt.graphic.attributes.NAME;
var value = evt.graphic.attributes.VALUE;
// your custom html
$("#SevicesContainer").collapse("show");
$("#SevicesContainer").draggable({ containment: "map", scroll: false });
$("#SevicesContainer .close").click(function () {
$("#SevicesContainer").collapse("hide");
});
});

Related

Creating popup window and displaying data

I'm moving from OpenLayers 2 to OpenLayers 6 in my project.
In the OpenLayers 2 project when I click on a feature in a
vector layer I get the description of the feature in a popup window.
Here is the code:
function createVectorLayer(layer) {
var l = new OpenLayers.Layer.Vector(
layer.Title,
{
eventListeners: {
'featureselected': function (evt) {
var f = evt.feature;
var popup = new OpenLayers.Popup.FramedCloud("popup",
//OpenLayers.LonLat.fromString(f.geometry.toShortString()),// Michael commented 25/02/2018
OpenLayers.LonLat.fromString(f.geometry.getCentroid().toShortString()),
null,
"<div style='font-size:.8em'>" + f.attributes.Description + "<br/><a href='#picturedFeatureEditor' class='ui-btn ui-mini' id='featureEditButton'>עדכון</a></div>",
null,
true
);
f.popup = popup;
map.addPopup(popup);
$("#featureEditButton").click(function () {
editableFeature = f.attributes;
editableFeatureObject = f;
initFeatureEditor();
//$.mobile.changePage("#picturedFeatureEditor");
});
},
'featureunselected': function (evt) {
var feature = evt.feature;
map.removePopup(feature.popup);
feature.popup.destroy();
feature.popup = null;
}
},
}
);
return l;
}
Here is how I create a Vector layer in OpenLayers 6:
function createVectorLayer(layer) {
var source = new ol.source.Vector({
loader: dataServices.getFeatures(layer.Id,
function (response) {
if (!response) return;
var features = [];
$(response).each(function (i, j) {
let shapeObject = getShapeObject(j);
let feature = new ol.Feature({ 'geometry': shapeObject });
features.push(feature);
});
source.addFeatures(features);
},
function (jqXhr, textStatus, errorMessag) {
console.log(errorMessag);
})
});
return new ol.layer.Vector({
source: source,
style: createStyle(source)
});
}
I know that I can create a popup using Overlay and ol.interaction.Select
which is fired when the feature is clicked, but I don't know how to access the feature description when the feature is clicked to display it in the popup.
My question is how I can implement the same behaviour using OpenLayers 6 (i.e. how to implement feature popups in 6)?
You can add properties to the feature in the constructor (assuming the data is available from your dataServices):
let feature = new ol.Feature({
geometry: shapeObject,
description: ....
});
which can then be accessed using feature.get('description') or feature.getProperties().description
If you are using a Select interaction
select.on('select', function(event) {
if (event.selected.length > 0) {
var feature = event.selected[0];
var description = feature.get('description');
}
});
You can look at the ol-ext FeaturePopup.
See example: https://viglino.github.io/ol-ext/examples/popup/map.popup.feature.html
Or https://viglino.github.io/ol-ext/examples/popup/map.popup.html

How to replace old geometry with new geometry in localStorage using Google Maps API?

I have 2 data layers on my Google Map: savedLayer (used for displaying/loading saved data on the map), and drawLayer (used for drawing on the map).
I'm currently able to store a drawn polygon on the map in localStorage using the Save button, and then display it on the map from localStorage.
What I'm struggling with is updating localStorage with any changes that are made to a particular polygon afterwards. Let's say you draw 3 or 4 polygons (I assign unique IDs to them). How do I update the geometry in localStorage for the selected polygon? How do I remove it? I basically want to send new updates of that polygon to localStorage once Saved is clicked.
I know there's a setgeometry event that I can use, and I'm currently using that to detect when the a geometry in savedLayer changes, but am struggling with replacing the old geometry with the new one:
changedGeom = savedLayer.addListener('setgeometry', function(e) {
console.log('changed geometry for polygon #' + e.feature.getProperty('featureID'));
console.log(e.newGeometry);
});
JSFiddle - http://jsfiddle.net/h0f3ycf4
P.S. You can currently delete/remove polygons from map using right-click on your mouse. But once I hit Save, this change is not reflected in localStorage.
Full JS:
var map, data, drawLayer, savedLayer, changedGeom;
var currentID = 0;
var uniqueID = function() {
return ++currentID;
}
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: -33.865143,
lng: 151.209900
},
zoom: 16,
clickableIcons: false,
mapTypeId: google.maps.MapTypeId.TERRAIN,
mapTypeControl: false
});
drawLayer = new google.maps.Data({
map: map
});
savedLayer = new google.maps.Data({
map: map
});
drawLayer.setControls(['Polygon']);
drawLayer.setStyle({
editable: true,
draggable: true
});
bindDataLayerListeners(drawLayer);
savePolygons(drawLayer);
loadPolygons(savedLayer);
}
function bindDataLayerListeners(drawLayer) {
drawLayer.addListener('addfeature', function(e) {
e.feature.setProperty('featureID', uniqueID());
});
drawLayer.addListener('mouseover', function(e) {
drawLayer.revertStyle();
drawLayer.overrideStyle(e.feature, {
fillOpacity: 0.5,
editable: true,
draggable: true
});
});
}
function loadPolygons(map) {
data = JSON.parse(localStorage.getItem('geoData'));
savedLayer.forEach(function(f) {
savedLayer.remove(f);
});
savedLayer.addGeoJson(data);
savedLayer.addListener('mouseover', function(e) {
savedLayer.revertStyle();
savedLayer.overrideStyle(e.feature, {
fillOpacity: 0.5,
editable: true,
draggable: true
});
});
map.addListener('click', function() {
savedLayer.revertStyle();
});
savedLayer.addListener('rightclick', function(e) {
data = JSON.parse(localStorage.getItem('geoData'));
data.features = data.features.filter(function(feature) {
return feature.properties.featureID !== e.feature.getProperty('featureID');
});
savedLayer.remove(e.feature);
});
changedGeom = savedLayer.addListener('setgeometry', function(e) {
console.log('changed geometry for polygon #' + e.feature.getProperty('featureID'));
console.log(e.newGeometry);
});
}
function savePolygons(json) {
var btn = document.getElementById('save-edits');
btn.onclick = function() {
// if (changedGeom) {
// console.log('geometry was changed and updated');
//savedLayer.addListener('setgeometry', savePolygon);
// } else {
// if (json.features.length === 0) {
// console.log('nothing to save');
// } else {
drawLayer.toGeoJson(function(json) {
localStorage.setItem('geoData', JSON.stringify(json));
alert('Saved to localStorage');
});
// }
// }
};
}
initMap();
I didn't spend a lot of time to read your code and I didn't get the point of using two layers instead of one layer. With some console.log() statements I realized that you are always saving drawLayer to localStorage and that's why you miss saved/updated data.
I forked your jsfiddle HERE and did small modifications in savePolygons() method and seems that it is working now as expected.
In short words I make sure that I'm saving the data from drawLayer and savedLayer to localStorage so we don't miss anything.
Just for reference:
function savePolygons(json) {
var btn = document.getElementById('save-edits');
btn.onclick = function() {
var drawLayerData, savedLayerData;
drawLayer.toGeoJson(function(json) {
console.log('saving geo data drawLayer ...')
console.log(json);
drawLayerData = json;
if(typeof savedLayerData != 'undefined'){
json.features = json.features.concat(savedLayerData.features)
localStorage.setItem('geoData', JSON.stringify(json));
alert('Data was saved');
}
});
savedLayer.toGeoJson(function(json) {
console.log('saving geo data savedLayer ...')
console.log(json);
savedLayerData = json;
if(typeof drawLayerData != 'undefined'){
json.features = json.features.concat(drawLayerData.features)
localStorage.setItem('geoData', JSON.stringify(json));
alert('Data was saved');
}
});
};
}

Show the attribute inspector without saving a new feature

The requirement is to add a new feature from template picker but without applying it, can i show the attribute inspector than save the feature.
selectedTemplate = templatePicker.getSelected();
This selectedTemplate is then selected to put the points on the map than opens the attribute inspector by selecting it.
selectedTemplate.featureLayer.applyEdits([newGraphic], null, null);
Sample Code Block :
dojo.connect(drawToolbar, "onDrawEnd", function(geometry) {
//display the editable info window for newly created features
if (map.infoWindow.isShowing) {
map.infoWindow.hide();
}
drawToolbar.deactivate();
var fieldAttributes = layerFieldToAttributes(selectedTemplate.featureLayer.fields);
var newAttributes = dojo.mixin(fieldAttributes, selectedTemplate.template.prototype.attributes);
var newGraphic = new esri.Graphic(geometry, null, newAttributes);
var layerInfos = [{
'featureLayer': selectedTemplate.featureLayer,
'isEditable': true
}];
var attInspector = new esri.dijit.AttributeInspector({
layerInfos: layerInfos
}, dojo.create("div"));
selectedTemplate.featureLayer.applyEdits([newGraphic], null, null, function() {
var screenPoint = map.toScreen(getInfoWindowPositionPoint(newGraphic));
map.infoWindow.setContent(attInspector.domNode);
map.infoWindow.resize(325, 185);
map.infoWindow.show(screenPoint, map.getInfoWindowAnchor(screenPoint));
templatePicker.clearSelection();
});
dojo.connect(attInspector, "onAttributeChange", function(feature, fieldName, newFieldValue) {
feature.attributes[fieldName] = newFieldValue;
feature.getLayer().applyEdits(null, [feature], null);
});
dojo.connect(attInspector, "onDelete", function(feature) {
feature.getLayer().applyEdits(null, null, [feature]);
map.infoWindow.hide();
});
});
}
I would like my client first add the attribute to feature and (save & apply) it.
Any help would be appreciated.
Here is the sample project : https://www.dropbox.com/s/fh71g1k9nsa70nq/index-2.html.zip?dl=0
I dont think you can do that with the AttributeInspector, try creating a custom popup that will have options to save and delete/cancel, when saving fire the applyEdits, when clicking delete, remove, ect.
Content:
var content = "<input id='text1'></input> </br>" +
"<input id='text1'></input> </br>" + "<button id='submit'>Submit</button>" + "<button id='delete'>Delete</button>"
/*
var attInspector = new AttributeInspector({
layerInfos: layerInfos
}, dojo.create("div"));
*/
map.infoWindow.setTitle(selectedTemplate.featureLayer.name);
map.infoWindow.setContent(content);
map.infoWindow.resize(350, 240);
map.infoWindow.show(evt.geometry, map.getInfoWindowAnchor(evt.geometry));
Listener:
on(map.infoWindow, "show", function () {
on(dom.byId("submit"), "click", function () {
alert("I should be saving");
});
on(dom.byId("delete"), "click", function () {
alert("I should be deleting");
});
})
Check out this fiddler: https://jsfiddle.net/kreza/jpLj5y4h/2/

Mapbox handle multiple GEOJSON files with loadURL

I'm currently working on a map that's meant to load multiple layers from different sources based on a config.json file.
Each layer should also display a popup on click but for some reason I only get the popup for the last loaded layer.
I'm using the ready event on the layers to make sure all the data gets loaded and iterating through them using .eachLayer method before binding the popup but still no success and can't figure out what am I missing.
Please find below my code as well a reproduction on: plnkr.co
var myMap = function(options) {
var self = this;
this.settings = $.extend({
layersConfig: 'config.json',
layerData: 'layer',
accessToken: 'pk.eyJ1IjoibWF0dGJsaXNzIiwiYSI6ImNpb3dwczBwZjAwOTh3OWtqOWZ1aG5ob3gifQ.Ot6GdtKew9u27TROm_4A6Q'
}, options);
this.map;
this.layers;
$.ajax({
url: this.settings.layersConfig,
cache: true
}).done(function(data) {
self.init(data);
});
};
myMap.prototype = {
init: function(data) {
var self = this,
settings = this.settings;
L.mapbox.accessToken = settings.accessToken;
var map = this.map = L.mapbox.map('map', 'mapbox.streets')
.setView([54.6, -2.3], 4);
var popup = new L.Popup({
minWidth: 250
});
for (var i = 0; i < data.length; i++) {
var featureLayers = this.layers = L.mapbox.featureLayer(null, {
style: {
weight: 2,
color: data[i].color,
fillColor: data[i].color,
fillOpacity: 0.4
}
}).addTo(map);
// load layers data
featureLayers.loadURL(settings.layerData + data[i].layerId + '.json')
.on('ready', function(e) {
featureLayers.eachLayer(function(layer) {
// cache layer properties
var layerProps = layer.feature.properties;
// cache feature bounds
var bounds = layer.getBounds().toBBoxString();
// bind modal
layer.bindPopup(showPopup(layer, bounds));
});
});
}
map.on('popupopen', function() {
$('.zoom-to').on('click', function() {
var array = $(this).data('zoom').split(',');
map.fitBounds([
[array[1], array[0]],
[array[3], array[2]]
])
});
});
function showPopup(popup, bounds) {
var popupData = popup.feature.properties;
var popupLabel = popupData.NAME;
var popupStructure = '<div class="leaflet-popup-label">' + popupLabel + '</div><button class="zoom-to" data-zoom="' + bounds + '">Zoom to</button></div>'
return popupStructure;
}
}
}
var map = new myMap();
.on('ready',...)
^ Has nothing to do with an AJAX call.
You need to perform actions after the ajax call is finished, that is, inside the AJAX callback.
Here:
}).done(function(data) {
/* do stuff */
});
Found the issue.
Just replace featureLayers.eachLayer with e.target.eachLayer and the popup will show as desired.

AlloyUI Scheduler Event Click

I'm using alloyui 2.0 scheduler http://alloyui.com/versions/2.0.x/ (with Liferay EE 6.2)
this is my scheduler :
YUI().use('aui-scheduler', function(Y) {
var config = {
color: '#2bd434',
content: 'Prova!',
id: 'CUSTOM-ID',
disabled: true,
allDay: true
}
var Events = new Y.SchedulerEvent(config);
var weekView = new Y.SchedulerWeekView();
var scheduler = new Y.Scheduler(
{
boundingBox: '#myScheduler',
date: new Date(),
items: [Events],
render: true,
views: [weekView]
}
)
});
When I click on event, I want open another page with details of that specific event.
I have this listener on my scheduler :
$("#myScheduler").on('click','.scheduler-event',function(e){
console.log(e);
var instance = this;
console.log(e.currentTarget);
});
I how can I set custom attributes on currentTarget?
If is not possible, can I set a custom id for that event?(so I can get the detail of this one)
I solved doing this :
Y.Do.after(function(e) {
$('.popover').hide();
var evt = e.getData('scheduler-event');
var id = evt.get('id');
//Other attr created in events array
var MYATTRIBUTE = evt.get('MYATTRIBUTE');
}, eventRecorder, 'showPopover');

Categories

Resources