Commit d06a68ec6652741effa395633fb202ce34163a51

Authored by lsagona
1 parent 2b6c492d4d
Exists in master and in 1 other branch dev

add Leaflet Kotlin API

Showing 14 changed files with 879 additions and 0 deletions Inline Diff

src/main/kotlin/map/Circle.kt View file @ d06a68e
File was created 1 package fdit.leafletmap
2
3 import javafx.scene.paint.Color
4
5 class Circle private constructor(private var center: LatLong, private var title: String, private var zIndexOffset: Int) {
6 private var color = Color(0.0, 0.0, 0.0, 0.0)
7 private lateinit var map: LeafletMapView
8 private var isAttached = false
9 private var isDisplayed = false
10 private var radius = 0.0
11
12 constructor(position: LatLong, radius: Double, title: String, color: Color, zIndexOffset: Int) : this(position, title, zIndexOffset) {
13 this.color = color
14 this.title = title.replace("-", "")
15 this.center = position
16 this.radius = nauticalMilesToMeter(radius)
17 }
18
19 internal fun addToMap(map: LeafletMapView) {
20 this.map = map
21 if (map.execScript("typeof circle$title == 'undefined'") as Boolean) {
22 map.execScript("var circle$title;")
23 }
24 if (!this.isAttached) {
25 val hexColor = "%02x".format((color.red * 255).toInt()) + "%02x".format((color.green * 255).toInt()) + "%02x".format((color.blue * 255).toInt())
26 map.execScript("circle$title = L.circle([${center.latitude}, ${center.longitude}], $radius, {color:'#$hexColor'}).addTo(myMap);")
27 this.isAttached = true
28 this.isDisplayed = true
29 } else if (!this.isDisplayed) {
30 map.execScript("circle$title.addTo(myMap)")
31 this.isDisplayed = true
32 }
33 }
34
35 fun modifyCircle(latLong: LatLong, radius: Double) {
36 this.center = latLong
37 this.radius = radius
38 this.radius = nauticalMilesToMeter(radius)
39 }
40
41 fun uppdateMap() {
42 if (this.isAttached && !this.isDisplayed) {
43 map.execScript("myMap.removeLayer(circle$title);" +
44 "circle$title = L.circle([${center.latitude}, ${center.longitude}], $radius).addTo(myMap);")
45 this.isDisplayed = true
46 }
47 }
48
49 internal fun removeCircle(map: LeafletMapView) {
50 if (this.isAttached && this.isDisplayed) {
51 map.execScript("myMap.removeLayer(circle$title);")
src/main/kotlin/map/ColorMarker.kt View file @ d06a68e
File was created 1 package fdit.leafletmap
2
3 /**
4 * Enumeration for all marker colors of the leaflet-color-markers JavaScript library.
5 *
6 * @author Stefan Saring
7 */
8 enum class ColorMarker(val iconName: String) {
9
10 BLUE_MARKER("blueIcon"),
11 RED_MARKER("redIcon"),
12 GREEN_MARKER("greenIcon"),
13 ORANGE_MARKER("orangeIcon"),
14 YELLOW_MARKER("yellowIcon"),
15 VIOLET_MARKER("violetIcon"),
16 GREY_MARKER("greyIcon"),
src/main/kotlin/map/ControlPosition.kt View file @ d06a68e
File was created 1 package fdit.leafletmap
2
3 /**
4 * Enumeration for all possible map control positions.
5 *
6 * @author Stefan Saring
7 */
8 enum class ControlPosition(val positionName: String) {
9
10 TOP_LEFT("topleft"),
11 TOP_RIGHT("topright"),
12 BOTTOM_LEFT("bottomleft"),
src/main/kotlin/map/LatLong.kt View file @ d06a68e
File was created 1 package fdit.leafletmap
2
3 /**
4 * Immutable value class for defining a geo position.
5 *
6 * @author Stefan Saring
7 */
src/main/kotlin/map/LeafletMapView.kt View file @ d06a68e
File was created 1 package fdit.leafletmap
2
3 import fdit.leafletmap.events.*
4 import fdit.leafletmap.events.MapClickEventMaker
5 import fdit.leafletmap.events.MapMoveEventMaker
6 import fdit.leafletmap.events.MarkerClickEventMaker
7 import javafx.concurrent.Worker
8 import javafx.scene.layout.StackPane
9 import javafx.scene.paint.Color
10 import javafx.scene.shape.Polygon
11 import javafx.scene.web.WebEngine
12 import javafx.scene.web.WebView
13 import fdit.leafletmap.events.*
14 import netscape.javascript.JSObject
15 import java.io.ByteArrayOutputStream
16 import java.io.File
17 import java.io.IOException
18 import java.net.URL
19 import java.util.*
20 import java.util.concurrent.CompletableFuture
21 import javax.imageio.ImageIO
22
23
24 /**
25 * JavaFX component for displaying OpenStreetMap based maps by using the Leaflet.js JavaScript library inside a WebView
26 * browser component.<br/>
27 * This component can be embedded most easily by placing it inside a StackPane, the component uses then the size of the
28 * parent automatically.
29 *
30 * @author Stefan Saring
31 * @author Niklas Kellner
32 */
33 class LeafletMapView : StackPane() {
34
35 private val webView = WebView()
36 private val webEngine: WebEngine = webView.engine
37
38 private var varNameSuffix: Int = 1
39 private val mapClickEvent = MapClickEventMaker()
40 private val markerClickEvent = MarkerClickEventMaker()
41 private val mapMoveEvent = MapMoveEventMaker()
42 internal val zoomLimitSmallMarker = 8
43
44 /**
45 * Creates the LeafletMapView component, it does not show any map yet.
46 */
47 init {
48 this.children.add(webView)
49 }
50
51 /**
52 * Displays the initial map in the web view. Needs to be called and complete before adding any markers or tracks.
53 * The returned CompletableFuture will provide the final map load state, the map can be used when the load has
54 * completed with state SUCCEEDED (use CompletableFuture#whenComplete() for waiting to complete).
55 *
56 * @param mapConfig configuration of the map layers and controls
57 * @return the CompletableFuture which will provide the final map load state
58 */
59 fun displayMap(mapConfig: MapConfig): CompletableFuture<Worker.State> {
60 val finalMapLoadState = CompletableFuture<Worker.State>()
61
62 webEngine.loadWorker.stateProperty().addListener { _, _, newValue ->
63
64 if (newValue == Worker.State.SUCCEEDED) {
65 executeMapSetupScripts(mapConfig)
66 }
67
68 if (newValue == Worker.State.SUCCEEDED || newValue == Worker.State.FAILED) {
69 finalMapLoadState.complete(newValue)
70 }
71 }
72
73 val localFileUrl: URL = LeafletMapView::class.java.getResource("/leafletmap/leafletmap.html")
74 webEngine.load(localFileUrl.toExternalForm())
75 return finalMapLoadState
76 }
77
78 private fun executeMapSetupScripts(mapConfig: MapConfig) {
79
80 // execute scripts for layer definition
81 mapConfig.layers.forEachIndexed { i, layer ->
82 execScript("var layer${i + 1} = ${layer.javaScriptCode};")
83 }
84
85 val jsLayers = mapConfig.layers
86 .mapIndexed { i, layer -> "'${layer.displayName}': layer${i + 1}" }
87 .joinToString(", ")
88 execScript("var baseMaps = { $jsLayers };")
89
90 // execute script for map view creation (Leaflet attribution must not be a clickable link)
91 execScript("""
92 |var myMap = L.map('map', {
93 | center: new L.LatLng(${mapConfig.initialCenter.latitude}, ${mapConfig.initialCenter.longitude}),
94 | zoom: 5,
95 | zoomControl: false,
96 | layers: [layer1]
97 |});
98 |
99 |var markersGroup = L.featureGroup();
100 |myMap.addLayer(markersGroup);
101 |var trackGroup = L.featureGroup();
102 |myMap.addLayer(trackGroup);
103 |
104 |myMap.addEventListener("contextmenu", function(e){});
105 |var attribution = myMap.attributionControl;
106 |attribution.setPrefix('Leaflet');""".trimMargin())
107
108 eventZoomChangeIcon()
109
110 // execute script for layer control definition if there are multiple layers
111 if (mapConfig.layers.size > 1) {
112 execScript("""
113 |var overlayMaps = {};
114 |L.control.layers(baseMaps, overlayMaps).addTo(myMap);""".trimMargin())
115
116 }
117
118 // execute script for scale control definition
119 if (mapConfig.scaleControlConfig.show) {
120 execScript("L.control.scale({position: '${mapConfig.scaleControlConfig.position.positionName}', " +
121 "metric: ${mapConfig.scaleControlConfig.metric}, " +
122 "imperial: ${!mapConfig.scaleControlConfig.metric}})" +
123 ".addTo(myMap);")
124 }
125
126 // execute script for zoom control definition
127 if (mapConfig.zoomControlConfig.show) {
128 execScript("L.control.zoom({position: '${mapConfig.zoomControlConfig.position.positionName}'})" +
129 ".addTo(myMap);")
130 }
131 }
132
133 /**
134 * Sets the view of the map to the specified geographical center position and zoom level.
135 *
136 * @param position map center position
137 * @param zoomLevel zoom level (0 - 19 for OpenStreetMap)
138 */
139 fun setView(position: LatLong, zoomLevel: Int) =
140 execScript("myMap.setView([${position.latitude}, ${position.longitude}], $zoomLevel);")
141
142 /**
143 * Pans the map to the specified geographical center position.
144 *
145 * @param position map center position
146 */
147 fun panTo(position: LatLong) =
148 execScript("myMap.panTo([${position.latitude}, ${position.longitude}]);")
149
150 /**
151 * Sets the zoom of the map to the specified level.
152 *
153 * @param zoomLevel zoom level (0 - 19 for OpenStreetMap)
154 */
155 fun setZoom(zoomLevel: Int) =
156 execScript("myMap.setZoom([$zoomLevel]);")
157
158 /**
159 * Adds a Marker Object to a map
160 *
161 * @param marker the Marker Object
162 */
163 fun addMarker(marker: Marker) {
164 marker.addToMap(getNextMarkerName(), this)
165 }
166
167 fun addCircle(circle: Circle) {
168 circle.addToMap(this)
169 }
170
171 fun addZone(zone: Zone) {
172 zone.addToMap(this)
173 }
174
175 /**
176 * Removes an existing marker from the map
177 *
178 * @param marker the Marker object
179 */
180 fun removeMarker(marker: Marker) {
181 execScript("myMap.removeLayer(${marker.getName()});")
182 }
183
184 fun removeCircle(circle: Circle) {
185 circle.removeCircle(this)
186 }
187
188 fun removeZone(zone: Zone) {
189 zone.removeZone()
190 }
191
192 fun removeZone(id: String) {
193 val idSanitized = id.replace("-", "")
194 execScript("myMap.removeLayer(polygon$idSanitized);")
195 }
196
197
198 fun uppdateCircle(circle: Circle, latLong: LatLong, radius: Double) {
199 circle.modifyCircle(latLong, radius)
200 circle.uppdateMap()
201 }
202
203 fun setEventMousePosition() {
204 execScript("var lat=0.0, lng=0.0;\n" +
205 "myMap.addEventListener('mousemove', function(ev) {\n" +
206 " lat = ev.latlng.lat;\n" +
207 " lng = ev.latlng.lng;\n" +
208 "});"
209 )
210 }
211
212 fun getMousePosition(): LatLong {
213 val lat = execScript("lat;") as Double
214 val lng = execScript("lng;") as Double
215 return LatLong(lat, lng)
216 }
217
218 /**
219 * Adds a custom marker type
220 *
221 * @param markerName the name of the marker type
222 * @param iconUrl the url if the marker icon
223 */
224 fun addCustomMarker(markerName: String, iconUrl: String): String {
225 execScript("var $markerName = L.icon({\n" +
226 "iconUrl: '${createImage(iconUrl, "png")}',\n" +
227 "iconSize: [24, 24],\n" +
228 "iconAnchor: [12, 12],\n" +
229 "});")
230 return markerName
231 }
232
233 private fun createImage(path: String, type: String): String {
234 val image = ImageIO.read(File(path))
235 var imageString: String? = null
236 val bos = ByteArrayOutputStream()
237
238 try {
239 ImageIO.write(image, type, bos)
240 val imageBytes = bos.toByteArray()
241
242 val encoder = Base64.getEncoder()
243 imageString = encoder.encodeToString(imageBytes)
244
245 bos.close()
246 } catch (e: IOException) {
247 e.printStackTrace()
248 }
249 return "data:image/$type;base64,$imageString"
250 }
251
252 /**
253 * Sets the onMarkerClickListener
254 *
255 * @param listener the onMarerClickEventListener
256 */
257 fun onMarkerClick(listener: MarkerClickEventListener) {
258 val win = execScript("document") as JSObject
259 win.setMember("java", this)
260 markerClickEvent.addListener(listener)
261 }
262
263 /**
264 * Handles the callback from the markerClickEvent
265 */
266 fun markerClick(title: String) {
267 markerClickEvent.MarkerClickEvent(title)
268 }
269
270 /**
271 * Sets the onMapMoveListener
272 *
273 * @param listener the MapMoveEventListener
274 */
275 fun onMapMove(listener: MapMoveEventListener) {
276 val win = execScript("document") as JSObject
277 win.setMember("java", this)
278 execScript("myMap.on('moveend', function(e){ document.java.mapMove(myMap.getCenter().lat, myMap.getCenter().lng);});")
279 mapMoveEvent.addListener(listener)
280 }
281
282 /**
283 * Handles the callback from the mapMoveEvent
284 */
285 fun mapMove(lat: Double, lng: Double) {
286 val latlng = LatLong(lat, lng)
287 mapMoveEvent.MapMoveEvent(latlng)
288 }
289
290 /**
291 * Sets the onMapClickListener
292 *
293 * @param listener the onMapClickEventListener
294 */
295 fun onMapClick(listener: MapClickEventListener) {
296 val win = execScript("document") as JSObject
297 win.setMember("java", this)
298 execScript("myMap.on('click', function(e){ document.java.mapClick(e.latlng.lat, e.latlng.lng);});")
299 mapClickEvent.addListener(listener)
300 }
301
302 /**
303 * Handles the callback from the mapClickEvent
304 */
305 fun mapClick(lat: Double, lng: Double) {
306 val latlng = LatLong(lat, lng)
307 mapClickEvent.MapClickEvent(latlng)
308 }
309
310 /**
311 * Draws a track path along the specified positions.
312 *
313 * @param positions list of track positions
314 */
315 fun addTrack(positions: List<LatLong>) {
316
317 val jsPositions = positions
318 .map { " [${it.latitude}, ${it.longitude}]" }
319 .joinToString(", \n")
320
321 execScript("""
322 |var latLngs = [
323 |$jsPositions
324 |];
325 |var polyline = L.polyline(latLngs, {color: 'red', weight: 2}).addTo(myMap);""".trimMargin())
326 }
327
328 fun addTrack(positions: List<LatLong>, id: String, color: Color, tooltip: String) {
329
330 val jsPositions = positions
331 .map { " [${it.latitude}, ${it.longitude}]" }
332 .joinToString(", \n")
333
334 val cleanTooltip = tooltip.replace("'", "&apos;")
335 execScript("""
336 |var latLngs = [
337 |$jsPositions
338 |];
339 |var color = "rgb(${Math.floor(color.getRed() * 255).toInt()} ,${Math.floor(color.getGreen() * 255).toInt()},${Math.floor(color.getBlue() * 255).toInt()})";
340 |var polyline$id = L.polyline(latLngs, {color: color, weight: 2, zIndexOffset: 200}).bindTooltip('$cleanTooltip', {sticky: true}).addTo(trackGroup)""".trimMargin())
341 }
342
343 fun makeVesselTrackTransparent(id: String) {
344 execScript("polyline$id.setStyle({opacity: 0.5});")
345 }
346
347 fun highlightTrack(id: String) {
348 execScript("polyline$id.setStyle({weight: 4});")
src/main/kotlin/map/MapConfig.kt View file @ d06a68e
File was created 1 package fdit.leafletmap
2
3 /**
4 * Class for defining the layers and controls in the map to be shown.
5 *
6 * @property layers List of layers to be shown in the map, the default layer is OpenStreetMap. If more than one layer is
7 * specified, then a layer selection control will be shown in the top right corner.
8 * @property zoomControlConfig Zoom control definition, by default it's shown in the top left corner.
9 * @property scaleControlConfig Scale control definition, by default it's not shown.
10 * @property initialCenter Initial center position of the map (default is London city).
11 *
12 * @author Stefan Saring
13 */
14 class MapConfig @JvmOverloads constructor(
15
16 val layers: List<MapLayer> = listOf(MapLayer.OPENSTREETMAP),
17 val zoomControlConfig: ZoomControlConfig = ZoomControlConfig(),
18 val scaleControlConfig: ScaleControlConfig = ScaleControlConfig(),
src/main/kotlin/map/MapLayer.kt View file @ d06a68e
File was created 1 package fdit.leafletmap
2
3 /**
4 * Enumeration for all supported map layers.
5 *
6 * @author Stefan Saring
7 */
8 enum class MapLayer(val displayName: String, val javaScriptCode: String) {
9
10 /** OpenStreetMap layer. */
11 OPENSTREETMAP("OpenStreetMap", """
12 L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
13 attribution: 'Map data &copy; OpenStreetMap and contributors', noWrap: true
14 })"""),
15
16 /** OpenCycleMap layer. */
17 OPENCYCLEMAP("OpenCycleMap", """
18 L.tileLayer('http://{s}.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png', {
19 attribution: '&copy; OpenCycleMap, Map data &copy; OpenStreetMap contributors', noWrap: true
20 })"""),
21
22 /** Hike & bike maps layer (HikeBikeMap.org). */
23 HIKE_BIKE_MAP("Hike & Bike Map", """
24 L.tileLayer('http://{s}.tiles.wmflabs.org/hikebike/{z}/{x}/{y}.png', {
25 attribution: '&copy; HikeBikeMap.org, Map data &copy; OpenStreetMap and contributors', noWrap: true
26 })"""),
27
28 /** MTB map (mtbmap.cz). */
29 MTB_MAP("MTB Map", """
30 L.tileLayer('http://tile.mtbmap.cz/mtbmap_tiles/{z}/{x}/{y}.png', {
31 attribution: '&copy; OpenStreetMap and USGS', noWrap: true
32 })"""),
33
34 /** MapBox layer in streets mode (consider: a project specific access token is required!). */
src/main/kotlin/map/Marker.kt View file @ d06a68e
File was created 1 package fdit.leafletmap
2
3 import fdit.gui.graphicalScenarioEditor.GraphicalScenarioEditorContext
4 import fdit.gui.utils.tooltip.VesselTooltipUtils.formatVesselSnapshotTooltip
5 import fdit.metamodel.vessel.Vessel
6
7 /**
8 * Creates a marker at the specified geographical position.
9 *
10 * @author Niklas Kellner
11 *
12 * @param position marker position
13 * @param title marker title shown in tooltip (pass empty string when tooltip not needed)
14 * @param zIndexOffset zIndexOffset (higher number means on top)
15 *
16 */
17 class Marker private constructor(private var position: LatLong, private var zIndexOffset: Int) {
18 private var marker = "aircraftIcon"
19 private var markerSmall = "aircraftSmallIcon"
20 private lateinit var map: LeafletMapView
21 private var attached = false
22 private var clickable = false
23 private var name = ""
24 private var tooltip = ""
25 private var rotation = 0
26 private lateinit var aircraft: Vessel
27 private lateinit var context: GraphicalScenarioEditorContext
28 private var relativeDate: Double = 0.0
29
30
31 constructor(position: LatLong, aircraft: Vessel, relativeDate: Double, context: GraphicalScenarioEditorContext, aircraftIcon: String, zIndexOffset: Int) : this(position, zIndexOffset){
32 this.aircraft = aircraft
33 this.context = context
34 this.relativeDate = relativeDate
35 this.marker = aircraftIcon
36 }
37
38 /**
39 * Adds the marker to a map, gets called from the mapAddMarker
40 *
41 * @param nextMarkerName the variable name of the marker
42 * @param map the LeafetMapView
43 */
44 internal fun addToMap(nextMarkerName: String, map: LeafletMapView) {
45 this.name = nextMarkerName
46 this.map = map
47 this.attached = true
48 map.execScript("""
49 |var currentZoom = myMap.getZoom();
50 |var $name;
51 |if (currentZoom < ${map.zoomLimitSmallMarker}) {
52 |$name = L.marker([${position.latitude}, ${position.longitude}], {title: '', icon: $markerSmall, zIndexOffset: $zIndexOffset}).addTo(markersGroup);
53 |} else {
54 |$name = L.marker([${position.latitude}, ${position.longitude}], {title: '', icon: $marker, zIndexOffset: $zIndexOffset}).addTo(markersGroup);
55 |}
56 """.trimMargin())
57 setTooltip()
58 if (clickable) {
59 setClickable()
60 }
61 }
62
63 fun setTooltip() {
64 this.tooltip = formatVesselSnapshotTooltip(aircraft,
65 context.getGraphicalScenario().getRecording(),
66 relativeDate)
67 this.tooltip = tooltip.replace("\n", "<br>")
68 this.tooltip = tooltip.replace("'", "&apos;")
69 map.execScript("$name.bindTooltip('<div id=\"html_c92f9552ec164f36978869550cb44ffe\" style=\"width: 100.0%; height: 100.0%;\">${this.tooltip}</div>');")
70 }
71
72
73 /**
74 * Changes the icon of the marker
75 *
76 * @param newIcon the name of the new icon
77 */
78 fun changeIcon(newIcon: String) {
79 this.marker = newIcon
80 if (attached) {
81 map.execScript("$name.setIcon($marker);")
82 }
83 }
84
85 /**
86 * Changes the icon of the marker
87 *
88 * @param newIcon the new ColorMarker
89 */
90 fun changeIcon(newIcon: ColorMarker) {
91 this.marker = newIcon.iconName
92 if (attached) {
93 map.execScript("$name.setIcon(${newIcon.iconName});")
94 }
95 }
96
97 /**
98 * Moves the existing marker specified by the variable name to the new geographical position.
99 *
100 * @param position new marker position
101 */
102 fun move(position: LatLong) {
103 this.position = position
104 if (attached) {
105 map.execScript("$name.setLatLng([${this.position.latitude}, ${this.position.longitude}]);")
106 setTooltip()
107 }
108 }
109
110 fun move(position: LatLong, aircraft: Vessel, relativeDate: Double) {
111 this.aircraft = aircraft
112 this.relativeDate = relativeDate
113 this.position = position
114 if (attached) {
115 map.execScript("$name.setLatLng([${this.position.latitude}, ${this.position.longitude}]);")
116 }
117 }
118
119 fun setRotation(rotation: Int) {
120 if (rotation > 360 || rotation < 0) {
121 this.rotation = 0
122 } else {
123 this.rotation = rotation
124 }
125 if (attached) {
126 map.execScript("$name.setRotationAngle(${this.rotation})")
127 }
src/main/kotlin/map/ScaleControlConfig.kt View file @ d06a68e
File was created 1 package fdit.leafletmap
2
3 /**
4 * Class for defining the scale control of the map. The scale can show either metric or imperial units.
5
6 * @author Stefan Saring
7 */
8 class ScaleControlConfig @JvmOverloads constructor(
9 val show: Boolean = false,
src/main/kotlin/map/Zone.kt View file @ d06a68e
File was created 1 package fdit.leafletmap
2
3 class Zone constructor(private var title: String) {
4 private lateinit var map: LeafletMapView
5 private var isAttached = false
6 private var isDisplayed = false
7 private var positions = listOf<LatLong>()
8
9
10 fun addToMap(map: LeafletMapView) {
11 this.map = map
12
13 if (map.execScript("typeof zone$title == 'undefined';") as Boolean) {
14 map.execScript("var zone$title")
15 }
16 if (!this.isAttached) {
17
18 map.execScript("var points$title = [];" +
19 "zone$title = L.polygon(points$title).addTo(myMap);")
20 this.isAttached = true
21 this.isDisplayed = true
22 } else if (!this.isDisplayed) {
23 map.execScript("zone$title.addTo(myMap);")
24 this.isDisplayed = true
25 }
26 }
27
28 private fun addPoint(latLong: LatLong) {
29 map.execScript("points$title.push([${latLong.latitude}, ${latLong.longitude}]);")
30 }
31
32 fun updatePoints(positions: List<LatLong>) {
33 this.positions = positions
34 if (map.execScript("typeof points$title == 'undefined'") as Boolean) {
35 map.execScript("var points$title = [];")
36 } else {
37 map.execScript("points$title = [];")
38 }
39 for (position in positions) {
40 addPoint(position)
41 }
42 }
43
44 fun updateMap() {
45 if (this.isAttached) {
46 map.execScript("myMap.removeLayer(zone$title);" +
47 "zone$title = L.polygon(points$title).addTo(myMap);")
48 this.isDisplayed = true
49 }
src/main/kotlin/map/ZoomControlConfig.kt View file @ d06a68e
File was created 1 package fdit.leafletmap
2
3 /**
4 * Class for defining the zoom control of the map.
5
6 * @author Stefan Saring
7 */
8 class ZoomControlConfig @JvmOverloads constructor(
src/main/kotlin/map/events/MapClickEvent.kt View file @ d06a68e
File was created 1 package fdit.leafletmap.events
2
3 import fdit.leafletmap.LatLong
4 import java.util.*
5
6 /**
7 * Handles the MapClickEvent
8 * @author Niklas Kellner
9 */
10 interface MapClickEventListener {
11 fun onMapClick(latLong: LatLong)
12 }
13
14 internal class MapClickEventMaker {
15 private val listeners = ArrayList<MapClickEventListener>()
16
17 fun addListener(toAdd: MapClickEventListener) {
18 listeners.add(toAdd)
19 }
20
21 fun MapClickEvent(latLong: LatLong) {
src/main/kotlin/map/events/MapMoveEvent.kt View file @ d06a68e
File was created 1 package fdit.leafletmap.events
2
3 import fdit.leafletmap.LatLong
4 import java.util.*
5
6 /**
7 * Handles the MapMoveEvent
8 *
9 * @author Niklas Kellner
10 */
11 interface MapMoveEventListener {
12 fun onMapMove(center: LatLong)
13 }
14
15 internal class MapMoveEventMaker {
16 private val listeners = ArrayList<MapMoveEventListener>()
17
18 fun addListener(toAdd: MapMoveEventListener) {
19 listeners.add(toAdd)
20 }
21
22 fun MapMoveEvent(latLong: LatLong) {
src/main/kotlin/map/events/MarkerClickEvent.kt View file @ d06a68e
File was created 1 package fdit.leafletmap.events
2
3 import java.util.*
4
5 /**
6 * Handles the MarkerClickEvent
7 *
8 * @author Niklas Kellner
9 */
10 interface MarkerClickEventListener {
11 fun onMarkerClick(title: String)
12 }
13
14 internal class MarkerClickEventMaker {
15 private val listeners = ArrayList<MarkerClickEventListener>()
16 private var listenerSet = false
17
18 fun addListener(toAdd: MarkerClickEventListener) {
19 listeners.add(toAdd)
20 listenerSet = true
21 }
22
23 fun MarkerClickEvent(title: String){
24 // Notify everybody that may be interested.
25 for (hl in listeners)
26 hl.onMarkerClick(title)