Adding Feature Layer hangs browser - javascript

When I create map object using ArcGISDynamicMapServiceLayer then things work fine but since I need lot of graphics and want to handle user interactions on map so I want to feature layer to my map but when I add feature layer the browser hangs.
Please let me know what could be the issue how can I avoid feature layer from hanging from my machine. Can I add onclick mouse over functionality for ArcGISDynamicMapServiceLayer
Below is the code
map = new esri.Map("map");
var layer = new esri.layers.ArcGISDynamicMapServiceLayer("http://10.32.9.106:6080/arcgis/rest/services/Administrative_Maps/World_Countries_v1/MapServer");
map.addLayer(layer);
var url = "http://10.32.9.106:6080/arcgis/rest/services/Administrative_Maps/World_Countries_v1/MapServer/0";
var info_content = "<table><tr><td><b>COUNTRY :</b></td><td style='text-align:right'>${COUNTRY}</td></tr></table>";
var infoTemplate1 = new esri.InfoTemplate("${COUNTRY}", info_content);
var fl = new esri.layers.FeatureLayer(url, {
id: "world-regions",
infoTemplate: infoTemplate1
});
map.addLayer(fl);
MY HTML CODE Is below
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=7, IE=9, IE=10">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
<title>Feature Layer Only Map</title>
<link rel="stylesheet" href="http://js.arcgis.com/3.6/js/esri/css/esri.css">
<style>
html, body, #map {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
</style>
<script src="http://js.arcgis.com/3.6/"></script>
<script>
dojo.require("esri.map");
dojo.require("esri.layers.FeatureLayer");
dojo.require("esri.tasks.QueryTask");
var map;
function init(){
try{
map = new esri.Map("map");
var layer = new esri.layers.ArcGISDynamicMapServiceLayer("http://10.32.9.106:6080/arcgis/rest/services/Administrative_Maps/World_Countries_v1/MapServer");
map.addLayer(layer);
var url = "http://10.32.9.106:6080/arcgis/rest/services/Administrative_Maps/World_Countries_v1/MapServer/0";
var info_content = "<table><tr><td><b>COUNTRY :</b></td><td style='text-align:right'>${COUNTRY}</td></tr></table>";
var infoTemplate1 = new esri.InfoTemplate("${COUNTRY}", info_content);
var fl = new esri.layers.FeatureLayer(url, {
id: "world-regions",
mode: esri.layers.FeatureLayer.MODE_ONDEMAND,
autoGeneralize :true,
allowGeometryUpdates:false,
infoTemplate: infoTemplate1,
outFields: ["COUNTRY"]
});
dojo.connect(fl, "onLoad", function(){
console.log(" adding feature layer");
fl.setAutoGeneralize(true)
map.addLayer(fl);
console.log("allowGeometryUpdates "+fl.allowGeometryUpdates);
console.log("editable "+fl.isEditable());
console.log("autoGeneralize"+fl.autoGeneralize);
console.log("geometryType"+fl.geometryType);
console.log("graphics"+fl.graphics);
console.log("defaultVisibility "+fl.hasAttachments);
});
var queryTask = new esri.tasks.QueryTask(url);
//build query filter
var query = new esri.tasks.Query();
query.returnGeometry = true;
query.where = "COUNTRY='India'";
infoTemplate = new esri.InfoTemplate("Alert", "Alert for Re-insurance");
dojo.connect(queryTask, "onComplete", function(featureSet) {
alert('calling queryTask'+featureSet);
//map.graphics.clear();
try{
/*var sfs = new SimpleFillSymbol(SimpleFillSymbol.STYLE_FORWARD_DIAGONAL, new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([255, 0, 0]), 2), new Color([255, 255, 0, 0.5]));
alert('somethign');*/
var symbol0 = new esri.symbol.SimpleFillSymbol().setColor(new dojo.Color([255, 0, 0, 0.9]));
//QueryTask returns a featureSet. Loop through features in the featureSet and add them to the map.
dojo.forEach(featureSet.features,function(feature){
alert('feature'+feature);
var graphic = feature;
graphic.setSymbol(symbol0);
alert("infoTemplate"+infoTemplate);
graphic.setInfoTemplate(infoTemplate);
alert("graphic"+graphic);
alert("map.graphics"+map.graphics);
map.graphics.add(graphic);
});
}catch(e){
alert("e"+e);
}
});
queryTask.execute(query);
require(["dojo/on", "esri/symbols/SimpleFillSymbol", "esri/symbols/SimpleLineSymbol", "dojo/_base/Color", "esri/graphic"], function(on, SimpleFillSymbol, SimpleLineSymbol, Color, Graphic) {
on(fl, "click", function(evt) {
console.log(" on click method");
// clears current selection
map.graphics.clear();
// create new graphic with selected graphic's geometry
alert("evt.graphic.geometry "+evt.graphic.geometry);
var graphic = new Graphic(evt.graphic.geometry);
alert("graphic "+graphic);
// create a new symbol for the graphic
var symbol0 = new esri.symbol.SimpleFillSymbol().setColor(new dojo.Color([255, 0, 0, 0.9]));
// add symbol to the graphic
graphic.setSymbol(symbol0);
// add the graphic to the map
map.graphics.add(graphic);
});
});
} catch(e){
console.log(" exception occured"+e);
}
}
dojo.addOnLoad(init);
</script>
</head>
<body>
<div id="map"></div>
</body>
</html>

The trouble is nearly to come with the amount of data retrieved by the browser and displayed. FeatureLayer is limited in number of detailed features displayed at once.
But the server is helpful at this point, you ask the server to generalize on the fly the geometries. This reduce a lot the geometry volume depending on the scale.
in your code, you can use the setAutoGeneralize(enable) to true on the FeatureLayer.
you can also set a minsccale and maxscale of the feature layer to avoid display the scales on which you have a lot of geometries.
Documentation on FeatureLayer, and setAutoGeneralize method/option
autoGeneralize option in constructor :
autoGeneralize Enable or disable the auto generalization of
features from a non-editable layer in on-demand mode. When true, the
layer uses the current map resolution as the maxAllowableOffset for
all queries issued to the server. The default value is true. As of
v2.7
by using this code to choose the generalization parameter (max allowableOffset), could reduce the amont of datas transferred to the browser, and gaining in user experience.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=7, IE=9, IE=10">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
<title>Feature Layer Only Map</title>
<link rel="stylesheet" href="http://js.arcgis.com/3.6/js/esri/css/esri.css">
<style>
html, body, #map {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
</style>
<script src="http://js.arcgis.com/3.6/"></script>
<script>
var map;
require(["dojo/on","esri/config", "esri/map", "dojo/domReady!","esri/layers/ArcGISDynamicMapServiceLayer","esri/layers/FeatureLayer","esri/InfoTemplate" ], function(on,config, Map,Ready,ArcGISDynamicMapServiceLayer,FeatureLayer,InfoTemplate) {
config.defaults.io.alwaysUseProxy = true;
config.defaults.io.proxyUrl = "/proxy.jsp";
config.defaults.io.corsEnabledServers.push("sampleserver1.arcgisonline.com");
map = new Map("map", { lods : [
{"level" : 0, "resolution" : 0.010986328125, "scale" : 4617149.97766929},
{"level" : 1, "resolution" : 0.0054931640625, "scale" : 2308574.98883465},
{"level" : 2, "resolution" : 0.00274658203125, "scale" : 1154287.49441732},
{"level" : 3, "resolution" : 0.001373291015625, "scale" : 577143.747208662},
{"level" : 4, "resolution" : 0.0006866455078125, "scale" : 288571.873604331}
]
});
var layer = new ArcGISDynamicMapServiceLayer("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer");
map.addLayer(layer);
layer.setVisibility(false);
var url = "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/3";
var info_content = "<table><tr><td><b>COUNTRY :</b></td><td style='text-align:right'>${COUNTRY}</td></tr></table>";
var infoTemplate1 = new InfoTemplate("${STATE_NAME}", info_content);
var fl = new FeatureLayer(url, {
id: "usa-regions",
mode: FeatureLayer.MODE_ONDEMAND,
autoGeneralize:false,
allowGeometryUpdates:false,
infoTemplate: infoTemplate1,
outFields: ["STATE_NAME"],
maxAllowableOffset : 0.02
});
on(map,"zoom-end", function(evt)
{
fl.setMaxAllowableOffset(evt.extent.getWidth() / 400);
});
map.addLayer(fl);
});
</script>
</head>
<body>
<div id="elements"></div>
<div id="map"></div>
</body>
</html>

Related

How to display a pop up data on mouse click event for the sphere objects which is overlayed on the 3D model(using Autodesk forge)

I have created a project to display a 3d model in the viewer(using Autodesk forge). On top of it I have added a scene to display two sphere objects as shown in the image
I want to add a mouse click event for the sphere objects – On click of the sphere objects I need to have a pop up data. As I am a beginner, I am stuck in this click event of the overlayed scene. This is the github link of my project for reference(https://github.com/vennilabalaraman/SphereClick). It will be helpful if I get solution for this. Thanks in advance.
This is my javascript and html code
let viewer = null;
function setupViewer(divId, documentId, tokenFetchingUrl, exrtensionArray, AccessToken) {
console.log('Entered setupViewer');
let options = {
env: 'AutodeskProduction',
getAccessToken: (onGetAccessToken) => {
fetch(tokenFetchingUrl)
.then(response => response.json())
.then(data => {
let accessToken = AccessToken;
let expireTimeSeconds = data["expires_in"];
onGetAccessToken(accessToken, expireTimeSeconds);
})
}
};
var config3d = {extensions: exrtensionArray};
Autodesk.Viewing.Initializer(options, () => {
viewer = new Autodesk.Viewing.GuiViewer3D(document.getElementById(divId), config3d);
viewer.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT,()=>{
//Create Custom Geometry
//alert("Under Custom Geom");
var geom = new THREE.SphereGeometry(0.05, 4, 5);
var material = new THREE.MeshBasicMaterial({ color: 0xFF0000 });
var sphereMesh = new THREE.Mesh(geom, material);
var sphereMesh1 = new THREE.Mesh(geom, material);
//sphereMesh1.position.set(11, 10, 30);
sphereMesh.position.x = -5; sphereMesh.position.y = -0.8; sphereMesh.position.z = 1.8;
sphereMesh1.position.x = -3.5; sphereMesh1.position.y = -1.5; sphereMesh1.position.z = 1.8;
//Create Overlay scene
if (!viewer.overlays.hasScene('my_scene')) {
viewer.overlays.addScene('my_scene');
}
viewer.overlays.addMesh([sphereMesh], 'my_scene');
viewer.overlays.addMesh([sphereMesh1], 'my_scene');
});
viewer.start();
Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
});
function onDocumentLoadSuccess(doc) {
var viewables = doc.getRoot().getDefaultGeometry();
viewer.loadDocumentNode(doc, viewables).then(i => {
// documented loaded, any action?
});
}
function onDocumentLoadFailure(viewerErrorCode) {
console.error('onDocumentLoadFailure() - errorCode:' + viewerErrorCode);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Example</title>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=no"/>
<meta charset="UTF-8">
<!-- Autodesk Forge Viewer files -->
<link rel="stylesheet" href="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/style.min.css" type="text/css">
<script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/viewer3D.min.js"></script>
<!-- Developer CSS -->
<link rel="stylesheet" href="./assets/css/main.css"/>
<!-- Developer JS -->
<script src="app.js"></script>
<script src="./assets/js/extensions/markupExt.js"></script>
</head>
<body>
<div id="MyViewerDiv"></div>
<script>
let divId = "MyViewerDiv";
let documentId = 'urn:dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6bmlzaGFudF90ZXN0Ml8yMDIwXzA0XzMvZ2F0ZWhvdXNlLm53ZA';
let tokenFetchingUrl = "https://9irt90dm6j.execute-api.us-east-1.amazonaws.com/prod";
let extensionArray = ['MarkUp3DExtension'];
let AccessToken = "";
setupViewer(divId, documentId, tokenFetchingUrl, extensionArray, AccessToken);
</script>
</body>
</html>
I'd suggest to try the latest SceneBuilder API of Viewer - you'd be able to append your own geometry and enjoy all the features that come out of the box with a bubble view (document model) like selecting, highlighting (rollover) and isolating etc with your own geometry...
const sphereGeometry = new THREE.BufferGeometry().fromGeometry(new THREE.SphereGeometry(5, 8, 8));
const sphereMaterial = new THREE.MeshPhongMaterial({ color: new THREE.Color(0, 1, 0) });
const sphereTransform = new THREE.Matrix4().compose(
new THREE.Vector3(0, 0, 0),
new THREE.Quaternion(0, 0, 0, 1),
new THREE.Vector3(1, 1, 1)
);
const sphereFragId = modelBuilder.addFragment(sphereGeometry, sphereMaterial, sphereTransform);
modelBuilder.changeFragmentsDbId(sphereFragId, 12345); // Use this dbId in Viewer APIs as usual
See this tutorial here to get started ...
I have no experience with Autodesk Forge but a lot with Three.js. So on the high level you will need to:
Subscribe to the click event of the MyViewerDiv.
Perform a raycast into the scene to pick objects below the mouse cursor: offial docs, another tutorial.
If there was an intersection, show a popup using a dedicated librar. Some were discussed in this question.

Stumped completely by "UncaughtReferenceError: X not defined at function"

I am trying to build a google map that takes data from a fusion table using their api and displays it on the map. I have the data displaying on the map now.
I would like to have a button that toggles the data on/off and after googling extensively I have tried to implement the solutions I found. I have the code set up almost exactly the same but am still unable to toggle the data.
I believe something is wrong with my scope because whenever I click the button it gives a "Uncaught ReferenceError: view1 is not defined" error in the Javascript Dev Console .
I have googled this as well and at first I believed that the function "toggleView1" was not defined globally so I changed it, however it still will not work... Any suggestions would be greatly appreciated, I am at a loss at this point.
<!DOCTYPE html>
<html>
<head>
<title>WorkingMapTiles</title>
<meta charset="utf-8"/>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>
<script src="https://maps.google.com/maps/api/js?key=XXXAPIKEYXX">. </script>
<script>
var view1 = new google.maps.FusionTablesLayer({
query: {
select: '\'LatitudeLongitude\'',
from: 'XXXfusionTableIdXXX'
}
});
function init() {
var mapBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(45.000, -65.000),
new google.maps.LatLng(46.000, -64.000));
var mapMinZoom = 14;
var mapMaxZoom = 17;
var map = new google.maps.Map(document.getElementById("map"));
map.fitBounds(mapBounds);
view1.setMap(map);
}
////FUNCTION NOT GETTING TRIGGERED BY BUTTONS
function toggleView1() {
if(view1.map) {
view1.setOptions({map: null});
} else {
view1.setOptions({map: map});
}
}
</script>
<style>
html, body, #map { width:100%; height:100%; margin:0; padding:0; }
#floating-panel { position: absolute; top: 10px; left: 25%;}
</style>
</head>
<body onload="init()">
<div id="map"></div>
<div id="floating-panel">
<input type="button" value="Toggle view1" onclick="toggleView1();">. </input>
</div>
</body>
</html>
Originaly:
function init() {
var mapBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(45.000, -65.000),
new google.maps.LatLng(46.000, -64.000));
var mapMinZoom = 14;
var mapMaxZoom = 17;
var map = new google.maps.Map(document.getElementById("map"));
map.fitBounds(mapBounds);
var view1 = new google.maps.FusionTablesLayer({
query: {
from: 'XXXfusionTableIdXXX'
}
});
view1.setMap(map);
}
View one is in init()'s scope because that is where is defined. Brought variable definition of view1 out of init()'s scope. Note that you may not have another definition of view1 inside of init()'s scope or there will be variable shadowing

ARCGIS Attribute Editing at RunTime Using Javascript API

Currently I am building a web Application using ArcGIS Javascript API.
Where I can add marker to the map graphics, on adding marker request I am setting few attributes to that marker using Popup Template like this
map.graphics.add(new Graphic(evt.geometry, symbol, PointAtt, popupTemplate));
Here I want to ask, how I can edit these attributes at Map Runtime because I want to do some changes in the attributes.
<script src="https://js.arcgis.com/3.17/"></script>
<script>
var map, tb;
var otherWindow;
var PointAtt = {};
require([
"esri/map",
"esri/toolbars/draw",
"esri/dijit/PopupTemplate",
"esri/symbols/SimpleMarkerSymbol", "esri/symbols/SimpleLineSymbol",
"esri/symbols/PictureFillSymbol", "esri/symbols/CartographicLineSymbol",
"esri/graphic",
"esri/Color", "dojo/dom", "dojo/on",
"dojo/domReady!"
], function (
Map, Draw, PopupTemplate,
SimpleMarkerSymbol, SimpleLineSymbol,
PictureFillSymbol, CartographicLineSymbol,
Graphic,
Color, dom, on) {
map = new Map("mapDiv", {
basemap : "streets",
center : [-25.312, 34.307],
zoom : 3
});
otherWindow = window.open("integrationPage.html", "otherWindow");
map.on("load", initToolbar);
// markerSymbol is used for point and multipoint, see http://raphaeljs.com/icons/#talkq for more examples
var markerSymbol = new SimpleMarkerSymbol();
markerSymbol.setPath("M16,4.938c-7.732,0-14,4.701-14,10.5c0,1.981,0.741,3.833,2.016,5.414L2,25.272l5.613-1.44c2.339,1.316,5.237,2.106,8.387,2.106c7.732,0,14-4.701,14-10.5S23.732,4.938,16,4.938zM16.868,21.375h-1.969v-1.889h1.969V21.375zM16.772,18.094h-1.777l-0.176-8.083h2.113L16.772,18.094z");
markerSymbol.setColor(new Color("#00FFFF"));
// lineSymbol used for freehand polyline, polyline and line.
var lineSymbol = new CartographicLineSymbol(
CartographicLineSymbol.STYLE_SOLID,
new Color([255, 0, 0]), 10,
CartographicLineSymbol.CAP_ROUND,
CartographicLineSymbol.JOIN_MITER, 5);
// fill symbol used for extent, polygon and freehand polygon, use a picture fill symbol
// the images folder contains additional fill images, other options: sand.png, swamp.png or stiple.png
var fillSymbol = new PictureFillSymbol(
"images/mangrove.png",
new SimpleLineSymbol(
SimpleLineSymbol.STYLE_SOLID,
new Color('#000'),
1),
42,
42);
function initToolbar() {
tb = new Draw(map);
tb.on("draw-end", addGraphic);
// Get Marker Click Event
map.graphics.on("click", function (evt) {
// alert("Marker Clicked");
var lat = evt.mapPoint.getLatitude();
var lon = evt.mapPoint.getLongitude();
var sendEvent = [];
sendEvent[0] = evt.graphic.attributes.ID;
sendEvent[1] = evt.mapPoint.getLatitude();
sendEvent[2] = evt.mapPoint.getLongitude();
// Sending event to other html page
otherWindow.postMessage(sendEvent, "http://localhost:9090");
});
// event delegation so a click handler is not
// needed for each individual button
on(dom.byId("info"), "click", function (evt) {
if (evt.target.id === "info") {
return;
}
var tool = evt.target.id.toLowerCase();
map.disableMapNavigation();
tb.activate(tool);
});
}
function addGraphic(evt) {
// deactivate the toolbar and clear existing graphics
tb.deactivate();
map.enableMapNavigation();
var sendEvent = []; // Array which is sent to other sources
var counter = 0;
sendEvent[0] = "added"
sendEvent[1] = evt.geometry.getLatitude();
sendEvent[2] = evt.geometry.getLongitude();
otherWindow.postMessage(sendEvent, "http://localhost:9090");
// Marker ID is being received from the Key Generator
window.addEventListener("message", function (event) {
var receivedEvent;
console.log("onMessage::" + event.data);
receivedEvent = event.data;
if (receivedEvent[0] == "added" && counter == 0) {
PointAtt = {
Name : "Islamabad", // The name of the pipeline
Type : "City", // The owner of the pipeline
ID : receivedEvent[1],// The length of the pipeline
Latitude : evt.geometry.getLatitude(),
Longitude: evt.geometry.getLongitude()
};
var popupTemplate = new PopupTemplate({
title : "{*}", // The title of the popup will be the name of the pipeline
content : "{*}" // Displays a table of all the attributes in the popup
})
// figure out which symbol to use
var symbol;
if (evt.geometry.type === "point" || evt.geometry.type === "multipoint") {
symbol = markerSymbol;
} else if (evt.geometry.type === "line" || evt.geometry.type === "polyline") {
symbol = lineSymbol;
} else {
symbol = fillSymbol;
}
map.graphics.add(new Graphic(evt.geometry, symbol, PointAtt, popupTemplate));
counter = counter + 1;
event.data = "";
}
}, false);
}
});
you can use esri AttributeInspector for this. Though it works for feature layers to but you can customize it accordingly.
Either you can create feature layer on the map and add graphics to it and pass that to layerInfos OR you can override the attribute inspector so support graphics layer too.
Use Below code for this-
//add a save button next to the delete button
var saveButton = new Button({ label: "Save", "class": "saveButton"},domConstruct.create("div"));
domConstruct.place(saveButton.domNode, attInspector.deleteBtn.domNode, "after");
saveButton.on("click", function() {
updateFeature.getLayer().applyEdits(null, [updateFeature], null);
});
attInspector.on("attribute-change", function(evt) {
//store the updates to apply when the save button is clicked
updateFeature.attributes[evt.fieldName] = evt.fieldValue;
});
attInspector.on("next", function(evt) {
updateFeature = evt.feature;
console.log("Next " + updateFeature.attributes.OBJECTID);
});
For attribute inspector please click here...
Here is the working code for feature layer-
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<title>Editable FeatureLayer with Attribute Inspector</title>
<link rel="stylesheet" href="https://js.arcgis.com/3.18/dijit/themes/claro/claro.css">
<link rel="stylesheet" href="https://js.arcgis.com/3.18/esri/css/esri.css">
<style>
html, body, #mapDiv{
height: 100%;
width: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
#detailPane{
padding: 6px;
height:20px;
color:#570026;
font-size:12pt;
font-weight:600;
overflow: hidden;
}
.dj_ie .infowindow .window .top .right .user .content { position: relative; }
.dj_ie .simpleInfoWindow .content {position: relative;}
.esriAttributeInspector .atiLayerName {display:none;}
</style>
<script src="https://js.arcgis.com/3.18/"></script>
<script>
var map, updateFeature;
require([
"esri/map",
"esri/layers/FeatureLayer",
"esri/dijit/AttributeInspector",
"esri/symbols/SimpleLineSymbol",
"esri/symbols/SimpleMarkerSymbol",
"esri/Color",
"esri/renderers/UniqueValueRenderer",
"esri/config",
"esri/tasks/query",
"dojo/dom-construct",
"dijit/form/Button",
"dojo/domReady!"
], function(
Map, FeatureLayer, AttributeInspector,
SimpleLineSymbol, SimpleMarkerSymbol, Color, UniqueValueRenderer,
esriConfig,
Query, domConstruct, Button
) {
// refer to "Using the Proxy Page" for more information: https://developers.arcgis.com/javascript/3/jshelp/ags_proxy.html
esriConfig.defaults.io.proxyUrl = "/proxy/";
map = new Map("mapDiv", {
basemap: "dark-gray",
center: [-97.395, 37.537],
zoom: 5
});
map.on("layers-add-result", initSelectToolbar);
//Feature Layer representing 2015 men's NCAA basketball tournament teams
var teamsFL = new FeatureLayer("https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/NCAA_Tourney_2015/FeatureServer/1", {
outFields: ["University", "WINPER", "Rd_64_Venue", "Rd_64_Result", "Rd_64_Margin"]
});
var selectionSymbol = new SimpleMarkerSymbol(
SimpleMarkerSymbol.STYLE_CIRCLE, 6,
new SimpleLineSymbol(
"solid",
new Color([255,0,0,0.5]),
4
),
new Color("#ED3939")
);
var defaultSymbol = new SimpleMarkerSymbol(
SimpleMarkerSymbol.STYLE_CIRCLE, 7,
null,
new Color([255,255,255])
);
teamsFL.setSelectionSymbol(selectionSymbol);
//Symbolize features by W/L record
var recordRenderer = new UniqueValueRenderer(defaultSymbol, "Rd_64_Result");
recordRenderer.addValue("W", new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE, 7, null, new Color([93,240,79])));
recordRenderer.addValue("L", new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE, 7, null, new Color([240,146,79])));
teamsFL.setRenderer(recordRenderer);
map.addLayers([teamsFL]);
function initSelectToolbar(evt) {
var teamsFL = evt.layers[0].layer;
var selectQuery = new Query();
map.on("click", function(evt) {
selectQuery.geometry = evt.mapPoint;
selectQuery.distance = 50;
selectQuery.units = "miles"
selectQuery.returnGeometry = true;
teamsFL.selectFeatures(selectQuery, FeatureLayer.SELECTION_NEW, function(features) {
if (features.length > 0) {
//store the current feature
updateFeature = features[0];
map.infoWindow.setTitle(features[0].getLayer().name);
map.infoWindow.show(evt.screenPoint, map.getInfoWindowAnchor(evt.screenPoint));
}
else {
map.infoWindow.hide();
}
});
});
map.infoWindow.on("hide", function() {
teamsFL.clearSelection();
});
var layerInfos = [
{
'featureLayer': teamsFL,
'showAttachments': false,
'isEditable': true,
'fieldInfos': [
{'fieldName': 'University', 'isEditable': false, 'label': 'School:'},
{'fieldName': 'WINPER', 'isEditable': true, 'tooltip': 'Win percentage', 'label': 'Win percentage:'},
{'fieldName': 'Rd_64_Venue', 'isEditable': false, 'label': 'Rd 1 Venue:'},
{'fieldName': 'Rd_64_Result', 'isEditable': true, 'tooltip': 'First round result (W/L)', 'label': 'Rd 1 Result:'},
{'fieldName': 'Rd_64_Margin', 'isEditable': true, 'tooltip': 'First round margin of victory/loss', 'label': 'Rd 1 Margin:'}
]
}
];
//Initialize Attribute Inspector
var attInspector = new AttributeInspector({
layerInfos: layerInfos
}, domConstruct.create("div"));
//add a save button next to the delete button
var saveButton = new Button({ label: "Save", "class": "saveButton"},domConstruct.create("div"));
domConstruct.place(saveButton.domNode, attInspector.deleteBtn.domNode, "after");
saveButton.on("click", function() {
updateFeature.getLayer().applyEdits(null, [updateFeature], null);
});
attInspector.on("attribute-change", function(evt) {
//store the updates to apply when the save button is clicked
updateFeature.attributes[evt.fieldName] = evt.fieldValue;
});
attInspector.on("next", function(evt) {
updateFeature = evt.feature;
console.log("Next " + updateFeature.attributes.OBJECTID);
});
attInspector.on("delete", function(evt) {
evt.feature.getLayer().applyEdits(null, null, [evt.feature]);
map.infoWindow.hide();
});
map.infoWindow.setContent(attInspector.domNode);
map.infoWindow.resize(350, 240);
}
});
</script>
</head>
<body class="claro">
<div id="detailPane">
Click to display the attribute inspector for all NCAA men's basketball tournament teams within 50 miles of click.
</div>
<div id="mapDiv"></div>
</body>
</html>
Output:-
Well, It seems quite straight forward to implement. You can use setter method of attribute for it. It will direct update the existing attributes/Values of feature on the map.
Use Below code for it-
var attributeObject = {"name":"updatedNmme","value":"updatedValue"};
graphicsObject.setAttributes(attributeObject );
Note- It will remove all the existing attributes and add new attributes(attributeObject ) to the graphics so if you want to keep some of the existing attributes as it is then pass those values also in attributeObject.
For complete reference please click here...
Hoping this will help you :)
P.S. It is always recommended to add complete code here if you are expecting the exact fix. However above code will fix your problem.

ArcGIS Javascript API - addLayers

I working on a project trying to add feature layers from ArcGIS online to a web map application using the JavaScript API where a user can toggle the layers on and off through a HTML tick box. The layers are importing correctly and are displayed when the tick boxes are bypassed but I can get it to work with the tickboxes. I have hacked code from ArcGIS samples etc so it must be some small thing I keep missing!
Here is the code - basically all I want is the layers to toggle on and off on top of a constant base map based on which checkboxes the user ticks on and off
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!--The viewport meta tag is used to improve the presentation and behavior of the samples
on iOS devices-->
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
<title>Select with feature layer</title>
<link rel="stylesheet" href="http://js.arcgis.com/3.10/js/dojo/dijit/themes/tundra/tundra.css">
<link rel="stylesheet" href="http://js.arcgis.com/3.10/js/esri/css/esri.css">
<style>
html, body, #mapDiv {
padding: 0;
margin: 0;
height: 100%;
}
#messages{
background-color: #fff;
box-shadow: 0 0 5px #888;
font-size: 1.1em;
max-width: 15em;
padding: 0.5em;
position: absolute;
right: 20px;
top: 20px;
z-index: 40;
}
</style>
<script src="http://js.arcgis.com/3.10/"></script>
<script>
var map;
require([
"esri/map", "esri/layers/FeatureLayer",
"esri/tasks/query", "esri/geometry/Circle",
"esri/graphic", "esri/InfoTemplate", "esri/symbols/SimpleMarkerSymbol",
"esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol", "esri/renderers/SimpleRenderer",
"esri/config", "esri/Color", "dojo/dom", "dojo/domReady!", "dojo/on", "dojo/query", "dojo/domReady!", "esri/layers/ArcGISDynamicMapServiceLayer", "esri/layers/ImageParameters",
], function (
Map, FeatureLayer,
Query, Circle,
Graphic, InfoTemplate, SimpleMarkerSymbol,
SimpleLineSymbol, SimpleFillSymbol, SimpleRenderer,
esriConfig, Color, dom, on, query, ArcGISDynamicMapServiceLayer, ImageParameters
) {
// use a proxy page if a URL generated by this page is greater than 2000 characters
//
// this should not be needed as nearly all query & select functions are performed on the client
esriConfig.defaults.io.proxyUrl = "/proxy";
map = new Map("mapDiv", {
basemap: "streets",
center: [-120.303130, 36.542750],
zoom: 5,
slider: false
});
//add the census block points in on demand mode. Note that an info template has been defined so when
//selected features are clicked a popup window will appear displaying the content defined in the info template.
var Offices = new FeatureLayer("URL", {
infoTemplate: new InfoTemplate("Block: ${BLOCK}", "${*}"),
outFields: ["*"]
});
var Northridge = new FeatureLayer("URL", {
infoTemplate: new InfoTemplate("Block: ${BLOCK}", "${*}"),
outFields: ["*"]
});
var Associates = new FeatureLayer("URL", {
infoTemplate: new InfoTemplate("Block: ${BLOCK}", "${*}"),
outFields: ["*"]
});
// selection symbol used to draw the selected census block points within the buffer polygon
var symbol = new SimpleMarkerSymbol(
SimpleMarkerSymbol.STYLE_CIRCLE,
12,
new SimpleLineSymbol(
SimpleLineSymbol.STYLE_NULL,
new Color([247, 34, 101, 0.9]),
1
),
new Color([207, 34, 171, 0.5])
);
Offices.setSelectionSymbol(symbol);
//make unselected features invisible
var nullSymbol = new SimpleMarkerSymbol().setSize(10);
var RedCircle = new SimpleMarkerSymbol().setSize(8);
Offices.setRenderer(new SimpleRenderer(nullSymbol));
on(dom.byId("layer0CheckBox"), "change", updateLayerVisibility);
on(dom.byId("layer1CheckBox"), "change", updateLayerVisibility);
on(dom.byId("layer2CheckBox"), "change", updateLayerVisibility);
function updateLayerVisibility() {
var inputs = query(".list_item");
var inputCount = inputs.length;
//in this application layer 2 is always on.
visibleLayerIds = [2];
for (var i = 0; i < inputCount; i++) {
if (inputs[i].checked) {
visibleLayerIds.push(inputs[i].value);
}
}
if (visibleLayerIds.length === 0) {
visibleLayerIds.push(-1);
}
map.addLayers(visibleLayerIds);
}
});
</script>
</head>
<body>
<br />
<br />
Layer List : <span id="layer_list"><input type='checkbox' class='list_item' id='layer0CheckBox' value="Northridge" />Earthquake
<input type='checkbox' class='list_item' id='layer1CheckBox' value="Offices" />Offices
<input type='checkbox' class='list_item' id='layer2CheckBox' value="Associates" />Associates
</span><br />
<br />
<div id="mapDiv"></div>
</body>
</html>
Done this long time ago
changeVLayerVisibility: function(names) {
Ext.Array.each(map.graphicsLayerIds, function(id) {
map.getLayer(id).setVisibility(names.indexOf(id) !== -1);
});
},
Check an example here: http://smart-tech-group.com/arcgismap/
The map-related logic is stored in http://smart-tech-group.com/arcgismap/APP/view/ArcMapViewer.js I was a js-newbie back then, so feel free to argue on my code style;)
In function updateLayerVisibility, the map.addLayers usage is wrong.
you should add featurelayers, graphic layers, dynamic layers or tiled layers, not the ids, unless you store them in the array visibleLayerIds.
You may consider use ArcGISDynamicMapServiceLayer to control visible layer ids. Then use setVisibleLayers API see https://developers.arcgis.com/javascript/jsapi/arcgisdynamicmapservicelayer-amd.html
FeatureLayer is usually for a single layer, use service like MapServer/2 or FeatureServer/2.

Google Maps API v2: MarkerManager clearMarkers(); doesn't work

I have GPS tracking server and problem with clearing markers added with MarkerManager from database. My truncated code:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<script src='http://maps.google.com/maps?file=api&v=2&hl=pl&key=my_key' type='text/javascript'></script>
</head>
<body onload='mapStart()' onunload='GUnload()'>
<script type='text/javascript'>
var map;
var mgr=false;
var timeOut=null;
function mapStart()
{
if(GBrowserIsCompatible())
{
map = new GMap2(document.getElementById("map"),{mapTypes: [G_NORMAL_MAP,G_HYBRID_MAP,G_SATELLITE_MAP,G_PHYSICAL_MAP]});
center = new GLatLng(52.536395, 13.42534);
map.setCenter(center, 6);
mgr = new GMarkerManager(map,{maxZoom: 19});
refreshMarkers();
}
}
function refreshMarkers()
{
clearTimeout(timeOut);
GDownloadUrl('dane2.php', function(dane,respCode)
{
if(respCode==200)
{
var xml = GXml.parse(dane);
var marker = dodajMarker(arguments, 15, 15);
}
else
{
alert('Cant open dane2.php');
}
});
mgr.clearMarkers(); // ???
timeOut=setInterval("refreshMarkers()",2000);
}
function dodajMarker(arguments, minZoom, maxZoom)
{
var ikona = new GIcon();
ikona.image = 'http://www.google.com/intl/en_ALL/mapfiles/dd-start.png';
ikona.iconSize = new GSize(20, 34);
ikona.iconAnchor = new GPoint(10, 34);
var marker = new GMarker(new GLatLng(latitude,longitude),{icon: ikona});
mgr.addMarker(marker,minZoom,maxZoom);
return marker;
}
</script>
<div id="map" style="align: center; width: 1000px; height: 490px; solid black; background: gray;"></div>
</body>
</html>
My page: http://m2mgsm.com/gps/index.php You can login: "admin", password: "12345" Click Test Map ("Mapatesty" - polish language only, english soon) in menu and then Select IMEI ("Wybierz IMEI") e.g. 355832010123229 and check Route ("Pokaż trasę:") and From/To ("Od/Do") date (e.g. 05.01.2012/05.01.2012) and "Filtruj". You can now view source of my map script in frame. I want to refresh ONLY markers with e.g. 3 sec. interval and it works, but new markers are OVERLAY on old markers...
Ps. Sorry for my English.
You have errors is your JS:
ReferenceError: kontener is not defined [http://m2mgsm.com/gps/mapatesty.php:259]
TypeError: Object #<yv> has no method 'clearMarkers' [http://m2mgsm.com/gps/mapatesty.php:459]
Try to use Firefox with Firebug extension or Chrome with its built-in Debugger to trace through your JavaScript code and eliminate the bugs.

Categories