From 7aed6bea01e69709a468faf852d59b758e1bdfa2 Mon Sep 17 00:00:00 2001
From: muerwre <gotham48@gmail.com>
Date: Mon, 4 Mar 2019 12:46:30 +0700
Subject: [PATCH] Clustered middle markers

---
 src/modules/KmMarks.ts | 17 +++++------------
 src/styles/map.less    | 17 ++++++++++++-----
 src/utils/geom.ts      | 18 ++++++++++++++++--
 3 files changed, 33 insertions(+), 19 deletions(-)

diff --git a/src/modules/KmMarks.ts b/src/modules/KmMarks.ts
index 554087c..779b7ec 100644
--- a/src/modules/KmMarks.ts
+++ b/src/modules/KmMarks.ts
@@ -1,7 +1,7 @@
 import { divIcon, LatLngLiteral, LayerGroup, Map, marker, Marker } from "leaflet";
 import { arrowClusterIcon, createArrow } from "$utils/arrow";
 import { MarkerClusterGroup } from 'leaflet.markercluster/dist/leaflet.markercluster-src.js';
-import { angleBetweenPoints, dist2, distKm, middleCoord } from "$utils/geom";
+import { angleBetweenPoints, dist2, distKm, middleCoord, pointOnDistance } from "$utils/geom";
 
 interface KmMarksOptions {
   showMiddleMarkers: boolean,
@@ -16,7 +16,7 @@ class Component extends LayerGroup {
     this.options = {
       showMiddleMarkers: true,
       showEndMarker: true,
-      kmMarksStep: 5,
+      kmMarksStep: 10,
       ...(options || {}),
     } as KmMarksOptions;
   }
@@ -50,8 +50,6 @@ class Component extends LayerGroup {
           this.map.latLngToContainerPoint(next),
         );
 
-        console.log(`[${count}] found at ${index}`, dist, sum, rounded);
-
         for (let i = 1; i <= count; i += 1) {
           const step = last_km_mark + (i * this.options.kmMarksStep);
           const shift = (step - dist) / diff;
@@ -63,8 +61,6 @@ class Component extends LayerGroup {
 
           kmMarks[step] = { ...coords, angle };
           this.marksLayer.addLayer(this.createMiddleMarker(coords, angle, step));
-
-          console.log('-->', step, shift);
         }
 
         last_km_mark = rounded;
@@ -72,13 +68,11 @@ class Component extends LayerGroup {
 
       return sum;
     }, 0);
-
-    console.log(kmMarks);
   };
 
   createMiddleMarker = (latlng: LatLngLiteral, angle: number, distance: number): Marker => marker(latlng, {
     draggable: false,
-    interactive: false,
+    interactive: true,
     icon: divIcon({
       html: `
       <div class="leaflet-km-dist" style="transform: rotate(${angle}deg);">
@@ -91,7 +85,6 @@ class Component extends LayerGroup {
     })
   });
 
-
   drawEndMarker = (latlngs: LatLngLiteral[]): void => {
 
   };
@@ -103,8 +96,8 @@ class Component extends LayerGroup {
     showCoverageOnHover: false,
     zoomToBoundsOnClick: false,
     animate: false,
-    maxClusterRadius: 10,
-    // iconCreateFunction: arrowClusterIcon,
+    maxClusterRadius: 120,
+    iconCreateFunction: arrowClusterIcon,
   });
 }
 
diff --git a/src/styles/map.less b/src/styles/map.less
index 97be0a2..1051222 100644
--- a/src/styles/map.less
+++ b/src/styles/map.less
@@ -99,14 +99,14 @@
   height: 48px;
 }
 
-.leaflet-km-marker {
-  position: relative;
+.leaflet-km-marker, .leaflet-km-marker-2 {
   background: green;
+  position: absolute;
 
   .leaflet-km-dist {
-    background: blue;
+    background: @red_secondary;
     color: white;
-    border-radius: 11px;
+    border-radius: 2px;
     font-size: 9px;
     text-align: center;
     min-width: 20px;
@@ -115,8 +115,15 @@
     align-items: center;
     justify-content: center;
     position: relative;
-    top: -5px;
+    top: 0;
     left: -5px;
+
+  }
+}
+
+.leaflet-km-marker-2 {
+  .leaflet-km-dist {
+    background: green;
   }
 }
 
diff --git a/src/utils/geom.ts b/src/utils/geom.ts
index 103ea21..84ab861 100644
--- a/src/utils/geom.ts
+++ b/src/utils/geom.ts
@@ -1,4 +1,4 @@
-import { LatLng, LatLngLiteral, Point } from "leaflet";
+import { LatLng, LatLngLiteral, Point, PointExpression } from "leaflet";
 
 interface ILatLng {
   lat: number,
@@ -84,4 +84,18 @@ export const distToSegment = (A: LatLng, B: LatLng, C: LatLng): number => Math.s
 // if C between A and B
 export const pointBetweenPoints = (A: LatLng, B: LatLng, C: LatLng): boolean => (distToSegment(A, B, C) < 0.01);
 
-export const angleBetweenPoints = (A: Point, B: Point): number => parseFloat(((Math.atan2(B.y - A.y, B.x - A.x))* 180 / Math.PI).toFixed(6));
+export const angleBetweenPoints = (A: Point, B: Point): number => parseFloat(((Math.atan2(B.y - A.y, B.x - A.x))* 180 / Math.PI).toFixed());
+export const angleBetweenPointsRad = (A: Point, B: Point): number => ((Math.atan2(B.x - A.x, B.y - A.y)));
+
+export const pointOnDistance = (A: Point, B: Point, shift: number): Point => {
+  const c = Math.sqrt((((B.x - A.x) ** 2) + ((B.y - A.y) ** 2)));
+  const angle = angleBetweenPointsRad(A, B);
+
+  // console.log({ angle, c, shift });
+  const x = Math.floor(B.x - c * Math.sin(angle) * shift);
+  const y = Math.floor(B.y - c * Math.cos(angle) * shift);
+
+  // console.log({ x, y });
+
+  return new Point(x, y);
+};