First, preface
Spit Groove, Baidu in the country in addition to Baidu Map is a conscience products, other really dare not compliment. In my previous note, I have implemented a custom map measurement module. In the Baidu map (other maps) there is a function of the surrounding search, drag and drop a circle, and then a circle radius to search (that is, buffer ╮ (╯_╰) ╭).
This time the goal is to cottage this drag-and-drop circle function, I first put one.
Second, the beginning of the cottage
Let's first think about what steps are required to implement this feature.
- Dragging
- Draw a Circle
- Notification Drag End
2.1 Implement drag and drop
What about drag-and-drop events with Graphicslayer and map drag events? Take a look at the official documents first.
Mouse events for Graphicslayer
Mouse Events for map
In graphic mouse events, the mouse event triggers the mouse to be on a graphic (red mark), but the Graphicslayer Mouse-drag event does not seem to require this condition, and the event description is the same as the map. We are taking a closer look at the documentation, and the ArcGIS documentation is especially worth learning in this detail. The mouse event document for Graphicslayer and map starts with Mouse-down (mouse button is pressed down) and ends with mouse-up (mouse button is released). Now everyone has found that the drag events are related to Mouse-down and mouse-up. First, pressing the mouse (Mouse-down) is the precondition for triggering the drag. Then, releasing the Mouse (mouse-up) is the identification of the end of the drag event. That is, if the drag event is to be triggered, the Mouse-down and mouse-up events will be triggered, so Graphicslayer's drag event also requires the mouse to be triggered on the graphic.
Well explained, I chose map!. Let's start with the two code below to see why you should choose the Drag event reason for the map.
Map of mouse events, added a graphicslayer and a graphic
Require (["Dojo/dom", "dojo/on", "Esri/map", "Esri/layers/graphicslayer", "Esri/geometry/poin T "," Esri/symbols/simplemarkersymbol "," Esri/symbols/simplelinesymbol "," esri/graphic "," Esri/color ", "dojo/domready!"], function (DOM, ON, Map, Graphicslayer,point, SIMPLEMARKERSYMB OL, Simplelinesymbol, Graphic, Color) {var map = new map ("map", {center: [103, 24.5], Zoom:9, Basemap: "OSM"}); var graphicslayer=new graphicslayer (); Map.addlayer (Graphicslayer); Map.on ("Load", function () {var SMS = new Simplemarkersymbol (Simplemarkersymbol.style_square, 20, New Simplelinesymbol (Simplelinesymbol.style_solid, New Color ([25 5, 0, 0]), 1), New Color ([0, 255, 0, 0.25])); var point = new Point (103, 24.5); var graphic = new Graphic (point, SMS); Map.graphics.add (graphic); Graphicslayer.add (graphic); }); Map.on ("Mouse-down", function (evt) {console.log ("Map:mouse-down"); }); Map.on ("Mouse-drag", function (evt) {console.log ("Map:mouse-drag"); }); Map.on ("mouse-up", function (evt) {console.log ("map:mouse-up"); }); });
When dragging on a map, the console output is as follows:
When you drag the mouse over the graphic, the console output is as follows:
It also triggers a drag-and-drop event on the map.
Then looking at Graphicslayer mouse events, I added a graphicslayer and a graphic.
Require ([ "dojo/on", "Esri/map", "Esri/layers/graphicslayer", "Esri/geometry/point", "esri/symbols/ Simplemarkersymbol ", " Esri/symbols/simplelinesymbol "," esri/graphic "," Esri/color ", " dojo/domready! "], function (on, map, Graphicslayer, point, Simplemarkersymbol, Simplelinesymbol, Graphic, Color) { var Map = n EW map ("map", { Center: [102, 24.5], zoom:9, basemap: "OSM" }); var graphicslayer=new graphicslayer ();
var graphic; Map.addlayer (Graphicslayer); Map.on ("Load", function () {var SMS = new Simplemarkersymbol (Simplemarkersymbol.style_square, 20, New Simplelinesymbol (Simplelinesymbol.style_solid, New Color ([25 5, 0, 0]), 1), New Color ([0, 255, 0, 0.25])); var point = new Point (102, 24.5); Graphic = new graphic (point, SMS); Graphicslayer.add (graphic); Console.log (Map.graphics)}); Graphicslayer.on ("Mouse-down", function (evt) {console.log ("Graphicslayer:mouse-down"); }); Graphicslayer.on ("Mouse-drag", function (evt) {console.log ("Graphicslayer:mouse-drag"); }); Graphicslayer.on ("mouse-up", function (evt) {Console.log ("graphicslayer:mOuse-up "); }); });
When dragging on a map, it is time to give the impression that Graphicslayer is also on the map and that it should trigger the drag-and-drop event of Graphicslayer, however, the output of the console is:
When you drag the mouse over the graphic, the console output is as follows:
At this point the Graphicslayer was finally triggered by the drag and drop event.
So far, it feels as if the two are not very different. But in the drag and drop, moving is the map, we want to achieve the effect is moving graphic, then we need to use the following methods:
Let's first implement moving graphic on Graphicslayer.
Graphicslayer.on ("Mouse-down", function (evt) { console.log ("Graphicslayer:mouse-down"); Map.disablemapnavigation (); }); Graphicslayer.on ("Mouse-drag", function (evt) { console.log ("Graphicslayer:mouse-drag"); Graphic.setgeometry (Evt.mappoint); }); Graphicslayer.on ("mouse-up", function (evt) { console.log ("graphicslayer:mouse-up"); Map.enablemapnavigation (); });
Let's move the graphic to Kunming and see the console output:
The graphic is moved in the drag-and-drop event, and the events occur in the desired order. But! But! But! This is the mouse has been graphic on the time to trigger the event, when we quickly move the mouse, so that the mouse is not on the graphic, then there will be strange behavior occurred.
Or move the graphic to Kunming (at a very fast pace) and see the console output:
When the mouse moves to the Kunming, release the mouse, and does not trigger the Mous-up event. Now in the bar Mouse moved to the graphic, you will find that without clicking the mouse graphic will also move with the mouse, to stop the words only click again and release, then the console output is as follows:
So if you choose Graphiclayer drag event to implement the Drag button, the user experience will be very bad, so graphicslayer drag event can not be used!
Next implement Map drag event, delete the original map Mouse-donw event, replace with Graphicslayerdmouse-down. And then added a graphic on the
Ismousedown property to determine if you want to drag this graphic.
Graphicslayer.on ("Mouse-down", function (evt) { console.log ("Graphicslayer:mouse-down"); Graphic.ismousedown=true; Map.disablemapnavigation (); }); Map.on ("Mouse-drag", function (evt) { console.log ("Map:mouse-drag"); if (graphic.ismousedown) { graphic.setgeometry (evt.mappoint); } }); Map.on ("mouse-up", function (evt) { console.log ("map:mouse-up"); Map.enablemapnavigation (); Graphic.ismousedown=false; });
This time will be able to solve the problem on the Graphicslayer very well.
2.2 Draw a Circle
Solve the problem of drag and drop, and then you can implement drag-and-drop drawing circle. We pass in the center point to draw the initialization circle, the default radius is 500 meters,
Startdrawcircle:function (centerpoint) { this._unregistmapevents (); This.centerpoint = CenterPoint; This.circle = This._createcircle (CenterPoint, n); var dragpoint = This._createdragbtnpoint (this.circle, centerpoint); This.circlegraphic = new Graphic (this.circle, this.defaults.fillSymbol); This.labelgraphic = new Graphic (Dragpoint, this._createdistancesymbol); var draggraphic = new Graphic (Dragpoint, this.defaults.dragButtonSymbol); This._measurelayer.add (this.circlegraphic); This._measurelayer.add (draggraphic); This._measurelayer.add (this.labelgraphic); This._initialmapevents (); },
The first step is to cancel the previous draw Circle registration map Mouse event, the second step is to add the initialization circle, the third Add the drag button and the radius of the text description. When calculating the drag button, the extent of the circle can be used for calculation.
_createdragbtnpoint:function (geometry, center) { var extent = Geometry.getextent (); var xmax = Extent.xmax; Returnnew Point ([Xmax, Center.y], center.spatialreference) },
OK, now that all the preparation is ready, in combination with the front of the graphic drag, you can easily and happily complete the drag drawing circle.
2.3 Notification Drag End
When each drag is finished, it is necessary to send a notification informing the user that the drawing is complete. This time, we use the map's Drag-end event to inform the user
Map.on ("Mouse-drag-end", lang.hitch (this, function (evt) { if (this.draggraphic && This.dragGraphic.isMouseDown) { this.emit ("Drag-end", {circle:this.circle}); This.dragGraphic.isMouseDown = false; This.defaults.map.enableMapNavigation (); This.defaults.map.setMapCursor ("Default");} )
Through This.emit ("Drag-end", {circle:this.circle}); We can send a notification to the outside of the drag end.
2.4 Source Code
/** * Created by Extra * Description: Implement drag Draw circle, imitation Baidu buffer search style * version:1.0.0 */define ("Dextra/dijit/drawdragcircle", [ "Require", "dojo/dom", "Dojo/query", "Dojo/_base/declare", "Dojo/_base/lang", "Dojo/ev Ented "," dojo/on "," esri/graphic "," Esri/layers/graphicslayer "," Esri/color "," Esri/sym Bols/font "," Esri/geometry/point "," esri/geometry/circle "," Esri/geometry/polyline "," Esri/sym Bols/simplemarkersymbol "," Esri/symbols/picturemarkersymbol "," Esri/symbols/simplelinesymbol "," esri/ Symbols/simplefillsymbol "," Esri/symbols/textsymbol "," Esri/geometry/geometryengine ",], function (req Uire, DOM, query, declare, Lang, evented, ON, Graphic, Graphicslayer, Color, Font, point, Circle , Polyline, Markersymbol, Picturemarkersymbol, Linesymbol, Fillsymbol, Textsymbol, geometryengine) {return declare (evented, {DEclaredclass: "Dextra.dijit.DrawDragCircle", defaults: {map:null, maxradius:50 XX, Markersymbol:new Markersymbol (Markersymbol.style_square, New Linesymbol (Linesym Bol. Style_solid, New color ("#DC143C"), 2), New color ("#FFA500")), DRA Gbuttonsymbol:new picturemarkersymbol ({"url": Require.tourl ("./images/dragbutton.png"), "Height": +, "width": linesymbol:new}), Linesymbol ( Linesymbol.style_solid, New Color ("#FFA500"), 2), Fillsymbol:new Fillsymbol (F Illsymbol.style_solid, New Linesymbol (Linesymbol.style_solid, New Color ([0, 155, 255, 0.55]), 2), New Color ([0, 155, 255, 0.55])),}, Circlegraphic:null, Circle:null, LabelgrapHic:null, Draggraphic:null, _measurelayer:null, _mapevents: [], constructor : function (Options) {declare.safemixin (this.defaults, Options); This._measurelayer = new Graphicslayer (); This.defaults.map.addLayer (This._measurelayer); This._initialmeasurelayer (); },//Initialize measurement layer event _initialmeasurelayer:function () {//start dragging to draw circle This._measurelayer.on ("Mo Use-down ", lang.hitch (this, function (evt) {var graphic = evt.graphic; if (Graphic.symbol.type = = "Picturemarkersymbol") {this.draggraphic = graphic; This.dragGraphic.isMouseDown = true; This.defaults.map.disableMapNavigation (); Graphic.getdojoshape (). Movetofront (); This.defaults.map.setMapCursor ("pointer"); } })); Tip You can drag This._measurelayer.on ("Mouse-over", lang.hitch (this, function (evt) {var graphic = Evt.graphic ; if (Graphic.symbol.type = = "Picturemarkersymbol") {this.defaults.map.setMapCursor ("pointer"); } })); Restore Mouse State This._measurelayer.on ("Mouse-out", lang.hitch (this, function (evt) {This.defaults.map.setMapCu Rsor ("Default"); })); }, _initialmapevents:function () {this._mapevents = []; Drag-and-drop Draw Circle This._mapevents.push (This.defaults.map.on ("Mouse-drag", lang.hitch (this, function (evt) {if (th Is.draggraphic = null && this.dragGraphic.isMouseDown) {var draggraphic = This.draggraphi C var dragpoint = Evt.mappoint; if (this.centerpoint.y! = dragpoint.y) {DRAGpoint.sety (THIS.CENTERPOINT.Y); } var radius = this._caldistance (This.centerpoint, dragpoint); if (radius <= this.defaults.maxRadius) {this._measurelayer.remove (this.circlegraphic); This.circle = this._createcircle (this.centerpoint, RADIUS); This.circlegraphic = new Graphic (this.circle, This.defaults.fillSymbol); Draggraphic.setgeometry (Dragpoint); This.labelGraphic.setGeometry (Dragpoint). Setsymbol (This._createdistancesymbol (RADIUS)) This._me Asurelayer.add (this.circlegraphic); This.circleGraphic.getDojoShape (). Movetoback (); Draggraphic.getdojoshape (). Movetofront (); } } }))); Trigger "Mouse-drag-end, notify drag end This._mapevents.push (this.defaUlts.map.on ("Mouse-drag-end", lang.hitch (this, function (evt) {if (this.draggraphic && this.dr Aggraphic.ismousedown) {this.emit ("Drag-end", {circle:this.circle}); This.dragGraphic.isMouseDown = false; This.defaults.map.enableMapNavigation (); This.defaults.map.setMapCursor ("Default"); } }))); },//Cancel the last registered map mouse event _unregistmapevents:function () {for (var i = 0; i < this._m apevents; i++) {if (This._mapevents[i]) {this._mapevents[i].remove (); }} this._mapevents=[]; }, Startdrawcircle:function (CenterPoint) {this._unregistmapevents (); This.centerpoint = CenterPoint; This.circle = This._createcircle (CenterPoint, 500); var dragpoint = This._createdragbtnpoint (this.circle, CenterPoint); This.circlegraphic = new Graphic (this.circle, This.defaults.fillSymbol); This.labelgraphic = new Graphic (Dragpoint, This._createdistancesymbol (500)); var draggraphic = new Graphic (Dragpoint, This.defaults.dragButtonSymbol); This._measurelayer.add (this.circlegraphic); This._measurelayer.add (draggraphic); This._measurelayer.add (this.labelgraphic); This._initialmapevents (); }, Removecircle:function () {this.centerpoint = null; This.circlegraphic = null; This.labelgraphic = null; This._measurelayer.clear (); }, _createcircle:function (point, distance) {returnnew Circle (point, {"Rad Ius ": distance}); }, _createdragbtnpoint:function (GeomEtry, center) {var extent = geometry.getextent (); var xmax = Extent.xmax; Returnnew Point ([Xmax, Center.y], center.spatialreference)}, _createdistancesymbol:function (Dista NCE) {distance = distance.tofixed (0) + "M"; var fontcolor = new Color ("#696969"); var holocolor = new Color ("#fff"); var font = new Font ("10pt", Font.style_italic, Font.variant_normal, Font.weight_bold, "Courier"); var textsymbol = new Textsymbol (distance, font, fontcolor); Textsymbol.setoffset (+). Sethalocolor (Holocolor). Sethalosize (2); Textsymbol.setalign (Textsymbol.align_middle); return textsymbol; }, _caldistance:function (Point1, Point2) {var line = new Polyline (this.defaults.map.spatialRe Ference); Line.addpath ([Point1, Point2]); Return GEOMETRYENGINE.DIstance (Point1, Point2, "meters"); }, }); })
ArcGIS JS Learning Note 2 to realize the imitation of Baidu drag-and-drop circle