JavaScript - Add Graphics to an existing Arcgis map - arcgis

I have an ArcGis map created using following code. I have a button on the page which is supposed to add graphics to the map on click. But it throws a JavaScript error "Error: Tried to register widget with id==xxx but that id is already registered". Any clue is welcome.
<script>
var map;
require([
"esri/map",
// Map initialization code....
});
function addSecond() {
//add pre-defined geometries to map
var polygonSymbol = new SimpleFillSymbol();
var triangle = new Polygon({
"rings": [
[
[2426417, 8535508],
[4304933, 12292541],
[6183449, 8535508],
[2426417, 8535508]
]
],
"spatialReference": {
"wkid": 102100
}
});
map.graphics.add(new Graphic(triangle, polygonSymbol));
}
</script>
Jsfiddle - http://jsfiddle.net/L1peybqh/

The root problem as I mentioned in the question was, I should be able to add graphics to the map on click of a button. I was implementing the ArcGIS API incorrectly, I was supposed to add the event listener inside the required function. A simplified version of the code I ended up looked like this.
<script>
var map, editToolbar;
var mapObj;
require([
"esri/map",
"esri/toolbars/edit",
"esri/graphic",
"esri/geometry/Point",
"esri/geometry/Polyline",
"esri/geometry/Polygon",
"esri/symbols/SimpleLineSymbol",
"esri/symbols/SimpleFillSymbol",
"esri/symbols/TextSymbol",
"dojo/_base/event",
"dojo/parser",
"dojo/dom",
"dojo/dom-style",
"dijit/registry",
"dijit/Menu",
"dijit/form/ToggleButton",
"dijit/form/DropDownButton",
"dijit/CheckedMenuItem",
"dijit/layout/BorderContainer",
"dijit/layout/ContentPane",
"dojo/domReady!"
], function (
Map, Edit, Graphic,
Point, Polyline, Polygon,
SimpleLineSymbol, SimpleFillSymbol, TextSymbol,
event, parser, dom, domStyle, registry, Menu
) {
parser.parse();
domStyle.set(registry.byId("mainWindow").domNode, "visibility", "visible");
map = new Map("map", {
basemap: "streets",
center: [3.955, 59.338],
zoom: 3
});
map.on("load", createToolbar);
function addGraphics() {
//add pre-defined geometries to map
var polygonSymbol = new SimpleFillSymbol();
var polygon = new Polygon({
"rings": [
[
[-4226661, 8496372],
[-3835304, 8731187],
[-2269873, 9005137],
[-1213208, 8613780]
]
],
"spatialReference": {
"wkid": 102100
}
});
map.graphics.add(new Graphic(polygon, polygonSymbol));
}
function addSecond() {
var polygonSymbol = new SimpleFillSymbol();
console.log(mapObj.features[0].geometry.coordinates);
var triangle = new Polygon({
"rings":
mapObj.features[0].geometry.coordinates
,
"spatialReference": {
"wkid": 102100
}
});
map.graphics.add(new Graphic(triangle, polygonSymbol));
}
$('#x').click(function(){
addSecond();
});
});
</script>

Related

How can i add and remove the dynamic marker on esri map javascript api?

How can I add and remove the dynamic marker on esri map using the javascript api? When I add the marker in the graphics layer, it's added but how can I remove it and add the new marker by another latitude longitude?
This is my code so far;
require(
["esri/map",
"esri/graphic",
"esri/symbols/PictureMarkerSymbol",
"esri/symbols/TextSymbol",
"esri/geometry/Point",
"esri/SpatialReference",
"esri/tasks/ProjectParameters",
"esri/tasks/GeometryService",
"dojo/dom",
"dojo/on",
"esri/dijit/HomeButton",
"dojo/domReady!"
],
function setupmap(Map, Graphic, PictureMarkerSymbol, TextSymbol, Point, SpatialReference, ProjectParameters, GeometryService, dom, on, HomeButton) {
var map = new Map("map-container", {
center: [83.0179802, 25.32327],
zoom: 13,
basemap: "streets"
});
map.graphics.clear();
map.on("load", function (evt) {
var home = new HomeButton({map: map}, "HomeButton");
home.startup();
picSymbol = new PictureMarkerSymbol(iconType, 20, 20);
$.each(detailsJSON, function (location, lstNodes) {
var locArr = location.split("--");
var latitude=locArr[0];
var longitude=locArr[1];
var geometryPoint = new Point(longitude, latitude,new SpatialReference(4326));
map.graphics.add(new Graphic(geometryPoint, picSymbol));
});
});
}
);
You can store a reference to the Graphic object you're adding and later remove it using the remove(graphic) method.
let graphic = new Graphic(geometryPoint, picSymbol);
map.graphics.add(graphic);
...
map.graphics.remove(graphic);
You can also remove all graphics from the layer using method removeAll().
See the arcgis-js-api reference for further info.
To make your component more stateless you can use the attributes collection of the Graphic to store a tag (or an Id or similar) and remove the item based on this value.
When adding;
let graphic = new Graphic(geometryPoint, picSymbol);
graphic.attributes = { "tag": "toBeRemovedLater" };
map.graphics.add(graphic);
When removing;
angular.forEach(map.graphics.graphics, (graphic: any) => {
if (graphic.attributes && graphic.attributes.tag == "toBeRemovedLater")
map.graphics.remove(graphic);
});
You can use Sketch Widget that simplifies the process of adding and updating graphics.
const sketch = new Sketch({
availableCreateTools: ['point'],
layer: graphicsLayer,
view,
});
view.ui.add(sketch, 'top-right');

I wrote this code to show the marker on my Esri's Arcgis map in javascript, but this doesn't work, Please describe the problem here in my code?

I need the explanation of proper implementation of Graphic and GraphicLayer into my arcgis map intergation
{ <script src="https://js.arcgis.com/4.12/"></script>
<script>
require([
"esri/Map",
"esri/graphic",
"esri/views/MapView",
"esri/geometry/Point",
"esri/graphic",
"esri/symbols/PictureMarkerSymbol",
"esri/layers/GraphicsLayer",
"esri/dijit/BasemapToggle",
"esri/dijit/HomeButton"],
function (Map, MapView, Point, Graphic, GraphicsLayer,
PictureMarkerSymbol) {
var map = new Map({
basemap: "hybrid"
});
on(map, "load",addgraphics);
var view = new MapView({
container: "viewDiv",
map: map,
center: [72.952335,19.180190],
zoom: 15
});
var marker = new PictureMarkerSymbol('http://static.arcgis.com/images/Symbols/Shapes/BluePin1LargeB.png', 32, 32);
function addgraphics(){
var markerPoint = new Point([72.952335,19.180190]);
var storepoint = new Graphic(markerPoint,marker);
var layer = new GraphicsLayer();
layer.add(storepoint);
view.addLayer(layer);
}
});
}
I expect the output should a map with the marker on the specified Latitude and Longitude.
The Output is the blank blank, which is i think wrong.
Check this example. https://codepen.io/mcantonbul/pen/vYBdVmQ
The error is that the layers are added to the "Map" object, not "MapView" object.
view.addLayer(layer);
to
map.add(layer);
and
var markerPoint = new Point([72.952335,19.180190]);
to
var markerPoint = new Point({x:72.952335,y:19.180190});

How can i solve the multidefine error in arcgis basemap toggle?

I want to use the basemap toggle of arcgis but when i am using this, I
am getting the error related "multidefine"
This is my function which is am using for invoking the map service
[![function handlerForVariableB (latt, longt, complaintid)
{
// execute code that is relevant when "$a" was set on the server-side.
$.ajax({
type: "GET",
url: "tools/nrega_v2.1/map.php",
data: 'complaintid='+complaintid,
success: function(data){
var data_array = JSON.parse(data);
$('.modal-info').html("");
var hrymap='<div id="hrymap"></div>';
$(".modal-info").append(hrymap);
$('#hrymap').html("");
$('#hrymap').html("<div id='map' style='width:850px;height:650px;'><div id='BasemapToggle'></div></div>");
var map;
define.amd.jQuery = true;
require(\[
"esri/map",
"esri/dijit/BasemapToggle",
"dojo/domReady!"
\], function(
Map, BasemapToggle
) {
map = new Map("map", {
center: \[-70.6508, 43.1452\],
zoom: 16,
basemap: "topo"
});
var toggle = new BasemapToggle({
map: map,
basemap: "satellite"
}, "BasemapToggle");
toggle.startup();
});
$("#detail_content").css({'display':'block'});
}
});
}][1]][1]
Please check the attached image which show confliction.
I am using jquery plus dojo in my application
My guess is the div Id is conflicting with the BasemapToggle declaration. Have you tried removing the div? I have BasemapToggle bound to my map without specifying a separate div for it and it works great.
// execute code that is relevant when "$a" was set on the server-side.
$.ajax({
type: "GET",
url: "tools/nrega_v2.1/map.php",
data: 'complaintid='+complaintid,
success: function(data){
var data_array = JSON.parse(data);
$('.modal-info').html("");
var hrymap='<div id="hrymap"></div>';
$(".modal-info").append(hrymap);
$('#hrymap').html("");
$('#hrymap').html("<div id='map' style='width:850px;height:650px;'></div>");
var map;
define.amd.jQuery = true;
require(\[
"esri/map",
"esri/dijit/BasemapToggle",
"dojo/domReady!"
\], function(
Map, BasemapToggle
) {
map = new Map("map", {
center: \[-70.6508, 43.1452\],
zoom: 16,
basemap: "topo"
});
var toggle = new BasemapToggle({
map: map,
basemap: "satellite"
});
toggle.startup();
});
$("#detail_content").css({'display':'block'});
}
});

Widgets inside Dojo dgrid OnDemandList

I'm trying to do something similar to this question but using an OnDemandList instead of an OnDemandGrid.
Here is what I have so far
define([
"dojo/_base/declare",
"dijit/_WidgetBase",
"dijit/_TemplatedMixin",
"dijit/_WidgetsInTemplateMixin",
"dgrid/OnDemandList",
"widget/CategoryItem",
"dojo/dom-construct",
"dojo/text!./templates/category-list.html"
], function(declare, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, OnDemandList, CategoryItem, domConstruct, template) {
var CatList = declare([OnDemandList]);
return declare([_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], {
templateString: template,
baseClass: "category-list",
postCreate: function() {
this.inherited(arguments);
// Create OnDemandList, place in div defined in template.
var cat1 = this.cat1 = new CatList({
store: this.store,
renderRow: this.renderItem
}, this.categoriesLevel0);
},
renderItem: function(item) {
return new CategoryItem({
title: item.title
});
}
});
});
The problem is my renderItems function needs to somehow return a dom containing my custom widget. As it is now I get this error Error on domReady callback: Error: NotFoundError: DOM Exception 8
Yeah it definitely needs to return a dom node from renderRow. Assuming you're using _WidgetBase for CategoryItem it should work like:
renderItem: function(item) {
var category = new CategoryItem({
title: item.title
});
return category.domNode;
}
The example here: https://github.com/SitePen/dgrid/wiki/OnDemandList-and-OnDemandGrid does pretty much the same thing, except it uses put-selector, which is just constructing a div, attaching the widget to it and returning the new div.

dojo nested Custom Widget undefined not a function

I've a Widget called stat.widget.Weekly that is a _Container and it require's stat.widget.Daily as Daily But Whenever I use new Daily() I get
Uncaught TypeError: undefined is not a function
My Code goes like this
require([
"dojo/_base/declare", "dojo/parser", ..., "stat/widget/Daily", "dijit/_Container"
], function(declare, ... , _WidgetBase, _TemplatedMixin, Daily, _Container){
declare("stat.widget.Weekly", [_WidgetBase, _TemplatedMixin, _Container], {
....
update: function(){
new Daily();//< Fires Error
},
postCreate: function(){
var self = this;
setTimeout(function(){
self.update();
}, 500);
}
});
});
But this stat/widget/Daily can be be instantiated in console with new
If your stat.widget.Weekly is placed in a file under stat-Modulepath/widget/Daily.js, this syntax would be more smooth to process in the classloader:
define([ // using define instead of require
"dojo/_base/declare", "dojo/parser", ..., "stat/widget/Daily", "dijit/_Container"
], function(declare, ... , _WidgetBase, _TemplatedMixin, Daily, _Container){
var myPrivates = declare("stat.widget._WeeklyResource", [], {
...
});
var myDefinition = declare("stat.widget.Weekly", [_WidgetBase, _TemplatedMixin, _Container], {
...
});
// returning the definition
return myDefinition;
});