I recently implemented a polygon drag function based on the Flutter_map open source plugin. I thought it was quite interesting, so I wrote it down.

Let’s show you what it does

1. You can draw points on the map according to where your finger falls

2. Drag and drop the points drawn, whether closed or not

3. When the number of dots is larger than 3, click the first dot to close the operation

4. If line segments intersect, they turn red

Unfortunately, Flutter_map (0.10.1+1) does not provide a marker that can be dragged, so to realize this function, we need to expand a drag_marker class first. Since it is a confidential project, we can only describe the general process. Refer to the implementation of other components of Flutter_map for code details. Wrap the marker with gestures, and then implement onPanDown,onPanEnd,OnTap events. The Listener is used here because LongPress is monitored in Flutter_map, but the closed switch is not exposed to the user. Therefore, if we press our finger on marker and stay for a while, then move on marker, we will not receive the move event. Since events can bubble up and be consumed by the Flutter_map, the original event Listerner is wrapped around this problem, listening for the Move.

Listener(
  onPointerMove: onPointerMove,
  child: GestureDetector(
    onPanDown: onPanDown,
    onPanEnd: onPanEnd,
    onTap: () {
      //marker onTap logic. }, child: Stack(children: [ Positioned( width: marker.width, height: marker.height, left: xxx, top: xxx, child: xxx, ), ]), ), );Copy the code

Repeat how to create an intermediate point between markers by looping over the drawn point, taking the current index point and the next point, calculating as follows, and then creating a marker to add to the dragMarkers list.

var intermediatePoint = LatLng(
    point1.latitude +
        (point2.latitude - point1.latitude) / 2,
    point1.longitude +
        (point2.longitude - point1.longitude) / 2);
Copy the code

After the marker extension is written, other functions will follow, such as monitoring the marker’s movement, updating the point position in real time, and then updating the marker and Polyline. The closure of line segment means that when defining marker, the index of marker is clicked back. If the first marker is clicked, add a firstPoint coordinate point to the points list.

So let’s talk about the intersection of line segments.

If the number of points is less than 3, there is no need to deal with the intersection. One detail needs to be noted, because the previous closure, in order to connect the ends, so that the first point is added, in order to determine the intersection, we need to copy a new list and removeLast().

The intersection algorithm uses fast rejection experiment and straddle experiment on the net.

Bloc was used for global state management throughout the project, so when line segments intersect, notifications were sent to the widget to change the color of the line segments in Polyline(flutter_map widget).