mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Remove the old map.
The new map has no open bugs.
This commit is contained in:
parent
3af3bd606c
commit
f72b2a21f7
@ -64,7 +64,7 @@ def on_game_load(game: Game | None) -> None:
|
||||
EventStream.put_nowait(GameUpdateEvents().game_loaded(game))
|
||||
|
||||
|
||||
def run_ui(game: Optional[Game], new_map: bool, dev: bool) -> None:
|
||||
def run_ui(game: Game | None, dev: bool) -> None:
|
||||
os.environ["QT_ENABLE_HIGHDPI_SCALING"] = "1" # Potential fix for 4K screens
|
||||
QApplication.setHighDpiScaleFactorRoundingPolicy(
|
||||
Qt.HighDpiScaleFactorRoundingPolicy.PassThrough
|
||||
@ -158,7 +158,7 @@ def run_ui(game: Optional[Game], new_map: bool, dev: bool) -> None:
|
||||
GameUpdateSignal.get_instance().game_loaded.connect(on_game_load)
|
||||
|
||||
# Start window
|
||||
window = QLiberationWindow(game, new_map, dev)
|
||||
window = QLiberationWindow(game, dev)
|
||||
window.showMaximized()
|
||||
splash.finish(window)
|
||||
qt_execution_code = app.exec_()
|
||||
@ -188,18 +188,8 @@ def parse_args() -> argparse.Namespace:
|
||||
|
||||
parser.add_argument("--dev", action="store_true", help="Enable development mode.")
|
||||
|
||||
parser.add_argument(
|
||||
"--new-map",
|
||||
action="store_true",
|
||||
default=True,
|
||||
help="Use the React based map. This is the default.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--old-map",
|
||||
dest="new_map",
|
||||
action="store_false",
|
||||
help="Use the legacy map. This will be removed before 6.0.0 is released.",
|
||||
)
|
||||
parser.add_argument("--new-map", help="Deprecated. Does nothing.")
|
||||
parser.add_argument("--old-map", help="Deprecated. Does nothing.")
|
||||
|
||||
new_game = subparsers.add_parser("new-game")
|
||||
|
||||
@ -374,7 +364,7 @@ def main():
|
||||
return
|
||||
|
||||
with Server().run_in_thread():
|
||||
run_ui(game, args.new_map, args.dev)
|
||||
run_ui(game, args.dev)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@ -2,22 +2,16 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from typing import (
|
||||
Optional,
|
||||
)
|
||||
|
||||
from PySide2.QtCore import QUrl
|
||||
from PySide2.QtWebChannel import QWebChannel
|
||||
from PySide2.QtWebEngineWidgets import (
|
||||
QWebEnginePage,
|
||||
QWebEngineSettings,
|
||||
QWebEngineView,
|
||||
)
|
||||
|
||||
from game import Game
|
||||
from game.server.settings import ServerSettings
|
||||
from qt_ui.models import GameModel
|
||||
from .model import MapModel
|
||||
|
||||
|
||||
class LoggingWebPage(QWebEnginePage):
|
||||
@ -37,14 +31,10 @@ class LoggingWebPage(QWebEnginePage):
|
||||
|
||||
|
||||
class QLiberationMap(QWebEngineView):
|
||||
def __init__(self, game_model: GameModel, new_map: bool, dev: bool, parent) -> None:
|
||||
def __init__(self, game_model: GameModel, dev: bool, parent) -> None:
|
||||
super().__init__(parent)
|
||||
self.game_model = game_model
|
||||
self.setMinimumSize(800, 600)
|
||||
self.map_model = MapModel(game_model)
|
||||
|
||||
self.channel = QWebChannel()
|
||||
self.channel.registerObject("game", self.map_model)
|
||||
|
||||
self.page = LoggingWebPage(self)
|
||||
# Required to allow "cross-origin" access from file:// scoped canvas.html to the
|
||||
@ -52,16 +42,11 @@ class QLiberationMap(QWebEngineView):
|
||||
self.page.settings().setAttribute(
|
||||
QWebEngineSettings.LocalContentCanAccessRemoteUrls, True
|
||||
)
|
||||
self.page.setWebChannel(self.channel)
|
||||
|
||||
if new_map and dev:
|
||||
if dev:
|
||||
url = QUrl("http://localhost:3000")
|
||||
elif new_map:
|
||||
url = QUrl.fromLocalFile(str(Path("client/build/index.html").resolve()))
|
||||
else:
|
||||
url = QUrl.fromLocalFile(
|
||||
str(Path("resources/ui/map/canvas.html").resolve())
|
||||
)
|
||||
url = QUrl.fromLocalFile(str(Path("client/build/index.html").resolve()))
|
||||
server_settings = ServerSettings.get()
|
||||
host = server_settings.server_bind_address
|
||||
if host.startswith("::"):
|
||||
@ -70,9 +55,3 @@ class QLiberationMap(QWebEngineView):
|
||||
url.setQuery(f"server={host}:{port}")
|
||||
self.page.load(url)
|
||||
self.setPage(self.page)
|
||||
|
||||
def set_game(self, game: Optional[Game]) -> None:
|
||||
if game is None:
|
||||
self.map_model.clear()
|
||||
else:
|
||||
self.map_model.reset()
|
||||
|
||||
@ -1 +0,0 @@
|
||||
from .mapmodel import MapModel
|
||||
@ -1,108 +0,0 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Optional
|
||||
|
||||
from PySide2.QtCore import Property, QObject, Signal, Slot
|
||||
from dcs import Point
|
||||
from dcs.mapping import LatLng
|
||||
|
||||
from game.theater import ConflictTheater, ControlPoint
|
||||
from game.utils import meters, nautical_miles
|
||||
from qt_ui.dialogs import Dialog
|
||||
from qt_ui.models import GameModel
|
||||
from qt_ui.windows.basemenu.QBaseMenu2 import QBaseMenu2
|
||||
from .leaflet import LeafletLatLon
|
||||
|
||||
MAX_SHIP_DISTANCE = nautical_miles(80)
|
||||
|
||||
|
||||
class ControlPointJs(QObject):
|
||||
nameChanged = Signal()
|
||||
blueChanged = Signal()
|
||||
positionChanged = Signal()
|
||||
mobileChanged = Signal()
|
||||
destinationChanged = Signal(list)
|
||||
sidcChanged = Signal()
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
control_point: ControlPoint,
|
||||
game_model: GameModel,
|
||||
theater: ConflictTheater,
|
||||
) -> None:
|
||||
super().__init__()
|
||||
self.control_point = control_point
|
||||
self.game_model = game_model
|
||||
self.theater = theater
|
||||
self.dialog: Optional[QBaseMenu2] = None
|
||||
|
||||
@Property(str, notify=nameChanged)
|
||||
def name(self) -> str:
|
||||
return self.control_point.name
|
||||
|
||||
@Property(bool, notify=blueChanged)
|
||||
def blue(self) -> bool:
|
||||
return self.control_point.captured
|
||||
|
||||
@Property(str, notify=sidcChanged)
|
||||
def sidc(self) -> str:
|
||||
return str(self.control_point.sidc())
|
||||
|
||||
@Property(list, notify=positionChanged)
|
||||
def position(self) -> LeafletLatLon:
|
||||
return self.control_point.position.latlng().as_list()
|
||||
|
||||
@Property(bool, notify=mobileChanged)
|
||||
def mobile(self) -> bool:
|
||||
return self.control_point.moveable and self.control_point.captured
|
||||
|
||||
@Property(list, notify=destinationChanged)
|
||||
def destination(self) -> LeafletLatLon:
|
||||
if self.control_point.target_position is None:
|
||||
# Qt seems to convert None to [] for list Properties :(
|
||||
return []
|
||||
return self.control_point.target_position.latlng().as_list()
|
||||
|
||||
def destination_in_range(self, destination: Point) -> bool:
|
||||
move_distance = meters(
|
||||
destination.distance_to_point(self.control_point.position)
|
||||
)
|
||||
return move_distance <= MAX_SHIP_DISTANCE
|
||||
|
||||
@Slot(list, result=bool)
|
||||
def destinationInRange(self, destination: LeafletLatLon) -> bool:
|
||||
return self.destination_in_range(
|
||||
Point.from_latlng(LatLng(*destination), self.theater.terrain)
|
||||
)
|
||||
|
||||
@Slot(list, result=str)
|
||||
def setDestination(self, destination: LeafletLatLon) -> str:
|
||||
if not self.control_point.moveable:
|
||||
return f"{self.control_point} is not mobile"
|
||||
if not self.control_point.captured:
|
||||
return f"{self.control_point} is not owned by player"
|
||||
|
||||
point = Point.from_latlng(LatLng(*destination), self.theater.terrain)
|
||||
if not self.destination_in_range(point):
|
||||
return (
|
||||
f"Cannot move {self.control_point} more than "
|
||||
f"{MAX_SHIP_DISTANCE.nautical_miles}nm."
|
||||
)
|
||||
self.control_point.target_position = point
|
||||
self.destinationChanged.emit(destination)
|
||||
return ""
|
||||
|
||||
@Slot()
|
||||
def cancelTravel(self) -> None:
|
||||
self.control_point.target_position = None
|
||||
self.destinationChanged.emit([])
|
||||
|
||||
@Slot()
|
||||
def showInfoDialog(self) -> None:
|
||||
if self.dialog is None:
|
||||
self.dialog = QBaseMenu2(None, self.control_point, self.game_model)
|
||||
self.dialog.show()
|
||||
|
||||
@Slot()
|
||||
def showPackageDialog(self) -> None:
|
||||
Dialog.open_new_package_dialog(self.control_point)
|
||||
@ -1,2 +0,0 @@
|
||||
LeafletLatLon = list[float]
|
||||
LeafletPoly = list[LeafletLatLon]
|
||||
@ -1,132 +0,0 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import List, Optional
|
||||
|
||||
from PySide2.QtCore import Property, QObject, Signal
|
||||
from dcs.mapping import LatLng
|
||||
|
||||
from game import Game
|
||||
from game.profiling import logged_duration
|
||||
from game.theater import (
|
||||
ConflictTheater,
|
||||
)
|
||||
from qt_ui.models import GameModel
|
||||
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
|
||||
from .controlpointjs import ControlPointJs
|
||||
from .leaflet import LeafletLatLon
|
||||
from .supplyroutejs import SupplyRouteJs
|
||||
|
||||
|
||||
# **EVERY PROPERTY NEEDS A NOTIFY SIGNAL**
|
||||
#
|
||||
# https://bugreports.qt.io/browse/PYSIDE-1426
|
||||
#
|
||||
# PySide2 5.15.2 released 6 days before the fix for this was merged, but presumably we
|
||||
# can clean up after 5.15.3 (or a future version) is released.
|
||||
#
|
||||
# Until then, all properties must use a notify signal. For some reason the error doesn't
|
||||
# show up when running from source, and member properties also are not sufficient.
|
||||
# Failing to do this will cause every sync of the property to emit an expensive log
|
||||
# message. This can prevent the UI from being responsive.
|
||||
#
|
||||
# A local signal (i.e. `@Property(t, notify=Signal())`) is not sufficient. The class
|
||||
# needs a named signal for every property, even if it is constant.
|
||||
|
||||
|
||||
class MapModel(QObject):
|
||||
cleared = Signal()
|
||||
|
||||
apiKeyChanged = Signal(str)
|
||||
mapCenterChanged = Signal(list)
|
||||
controlPointsChanged = Signal()
|
||||
supplyRoutesChanged = Signal()
|
||||
mapReset = Signal()
|
||||
|
||||
def __init__(self, game_model: GameModel) -> None:
|
||||
super().__init__()
|
||||
self.game_model = game_model
|
||||
self._map_center = LatLng(0, 0)
|
||||
self._control_points = []
|
||||
self._supply_routes = []
|
||||
|
||||
GameUpdateSignal.get_instance().game_loaded.connect(self.on_game_load)
|
||||
self.reset()
|
||||
|
||||
def clear(self) -> None:
|
||||
self._control_points = []
|
||||
self._supply_routes = []
|
||||
self.cleared.emit()
|
||||
|
||||
def reset(self) -> None:
|
||||
if self.game_model.game is None:
|
||||
self.clear()
|
||||
return
|
||||
with logged_duration("Map reset"):
|
||||
self.reset_control_points()
|
||||
self.reset_routes()
|
||||
self.mapReset.emit()
|
||||
|
||||
def on_game_load(self, game: Optional[Game]) -> None:
|
||||
if game is not None:
|
||||
self.reset_map_center(game.theater)
|
||||
|
||||
def reset_map_center(self, theater: ConflictTheater) -> None:
|
||||
self._map_center = theater.terrain.map_view_default.position.latlng()
|
||||
self.mapCenterChanged.emit(self._map_center.as_list())
|
||||
|
||||
@Property(list, notify=mapCenterChanged)
|
||||
def mapCenter(self) -> LeafletLatLon:
|
||||
return self._map_center.as_list()
|
||||
|
||||
def reset_control_points(self) -> None:
|
||||
self._control_points = [
|
||||
ControlPointJs(c, self.game_model, self.game.theater)
|
||||
for c in self.game.theater.controlpoints
|
||||
]
|
||||
self.controlPointsChanged.emit()
|
||||
|
||||
@Property(list, notify=controlPointsChanged)
|
||||
def controlPoints(self) -> List[ControlPointJs]:
|
||||
return self._control_points
|
||||
|
||||
def reset_routes(self) -> None:
|
||||
seen = set()
|
||||
self._supply_routes = []
|
||||
for control_point in self.game.theater.controlpoints:
|
||||
seen.add(control_point)
|
||||
for destination, convoy_route in control_point.convoy_routes.items():
|
||||
if destination in seen:
|
||||
continue
|
||||
self._supply_routes.append(
|
||||
SupplyRouteJs(
|
||||
control_point,
|
||||
destination,
|
||||
[p.latlng().as_list() for p in convoy_route],
|
||||
sea_route=False,
|
||||
game=self.game,
|
||||
)
|
||||
)
|
||||
for destination, shipping_lane in control_point.shipping_lanes.items():
|
||||
if destination in seen:
|
||||
continue
|
||||
if control_point.is_friendly(destination.captured):
|
||||
self._supply_routes.append(
|
||||
SupplyRouteJs(
|
||||
control_point,
|
||||
destination,
|
||||
[p.latlng().as_list() for p in shipping_lane],
|
||||
sea_route=True,
|
||||
game=self.game,
|
||||
)
|
||||
)
|
||||
self.supplyRoutesChanged.emit()
|
||||
|
||||
@Property(list, notify=supplyRoutesChanged)
|
||||
def supplyRoutes(self) -> List[SupplyRouteJs]:
|
||||
return self._supply_routes
|
||||
|
||||
@property
|
||||
def game(self) -> Game:
|
||||
if self.game_model.game is None:
|
||||
raise RuntimeError("No game loaded")
|
||||
return self.game_model.game
|
||||
@ -1,91 +0,0 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import List
|
||||
|
||||
from PySide2.QtCore import Property, QObject, Signal
|
||||
|
||||
from game import Game
|
||||
from game.theater import ControlPoint
|
||||
from game.transfers import MultiGroupTransport, TransportMap
|
||||
from .leaflet import LeafletLatLon
|
||||
|
||||
|
||||
class SupplyRouteJs(QObject):
|
||||
pointsChanged = Signal()
|
||||
frontActiveChanged = Signal()
|
||||
isSeaChanged = Signal()
|
||||
blueChanged = Signal()
|
||||
activeTransportsChanged = Signal()
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
a: ControlPoint,
|
||||
b: ControlPoint,
|
||||
points: List[LeafletLatLon],
|
||||
sea_route: bool,
|
||||
game: Game,
|
||||
) -> None:
|
||||
super().__init__()
|
||||
self.control_point_a = a
|
||||
self.control_point_b = b
|
||||
self._points = points
|
||||
self.sea_route = sea_route
|
||||
self.game = game
|
||||
|
||||
def find_in_transport_map(
|
||||
self, transport_map: TransportMap
|
||||
) -> List[MultiGroupTransport]:
|
||||
transports = []
|
||||
transport = transport_map.find_transport(
|
||||
self.control_point_a, self.control_point_b
|
||||
)
|
||||
if transport is not None:
|
||||
transports.append(transport)
|
||||
transport = transport_map.find_transport(
|
||||
self.control_point_b, self.control_point_a
|
||||
)
|
||||
if transport is not None:
|
||||
transports.append(transport)
|
||||
return transports
|
||||
|
||||
def find_transports(self) -> List[MultiGroupTransport]:
|
||||
if self.sea_route:
|
||||
return self.find_in_transport_map(
|
||||
self.game.blue.transfers.cargo_ships
|
||||
) + self.find_in_transport_map(self.game.red.transfers.cargo_ships)
|
||||
return self.find_in_transport_map(
|
||||
self.game.blue.transfers.convoys
|
||||
) + self.find_in_transport_map(self.game.red.transfers.convoys)
|
||||
|
||||
@Property(list, notify=activeTransportsChanged)
|
||||
def activeTransports(self) -> List[str]:
|
||||
transports = self.find_transports()
|
||||
if not transports:
|
||||
return []
|
||||
|
||||
descriptions = []
|
||||
for transport in transports:
|
||||
units = "units" if transport.size > 1 else "unit"
|
||||
descriptions.append(
|
||||
f"{transport.size} {units} transferring from {transport.origin} to "
|
||||
f"{transport.destination}"
|
||||
)
|
||||
return descriptions
|
||||
|
||||
@Property(list, notify=pointsChanged)
|
||||
def points(self) -> List[LeafletLatLon]:
|
||||
return self._points
|
||||
|
||||
@Property(bool, notify=frontActiveChanged)
|
||||
def frontActive(self) -> bool:
|
||||
if self.sea_route:
|
||||
return False
|
||||
return self.control_point_a.front_is_active(self.control_point_b)
|
||||
|
||||
@Property(bool, notify=isSeaChanged)
|
||||
def isSea(self) -> bool:
|
||||
return self.sea_route
|
||||
|
||||
@Property(bool, notify=blueChanged)
|
||||
def blue(self) -> bool:
|
||||
return self.control_point_a.captured
|
||||
@ -53,7 +53,7 @@ class QLiberationWindow(QMainWindow):
|
||||
tgo_info_signal = Signal(TheaterGroundObject)
|
||||
control_point_info_signal = Signal(ControlPoint)
|
||||
|
||||
def __init__(self, game: Optional[Game], new_map: bool, dev: bool) -> None:
|
||||
def __init__(self, game: Game | None, dev: bool) -> None:
|
||||
super().__init__()
|
||||
|
||||
self._uncaught_exception_handler = UncaughtExceptionHandler(self)
|
||||
@ -78,7 +78,7 @@ class QLiberationWindow(QMainWindow):
|
||||
Dialog.set_game(self.game_model)
|
||||
self.ato_panel = QAirTaskingOrderPanel(self.game_model)
|
||||
self.info_panel = QInfoPanel(self.game)
|
||||
self.liberation_map = QLiberationMap(self.game_model, new_map, dev, self)
|
||||
self.liberation_map = QLiberationMap(self.game_model, dev, self)
|
||||
|
||||
self.setGeometry(300, 100, 270, 100)
|
||||
self.updateWindowTitle()
|
||||
@ -374,7 +374,6 @@ class QLiberationWindow(QMainWindow):
|
||||
self.info_panel.setGame(game)
|
||||
self.sim_controller.set_game(game)
|
||||
self.game_model.set(self.game)
|
||||
self.liberation_map.set_game(game)
|
||||
except AttributeError:
|
||||
logging.exception("Incompatible save game")
|
||||
QMessageBox.critical(
|
||||
|
||||
@ -1,33 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>DCS Liberation Map</title>
|
||||
<script src="qrc:///qtwebchannel/qwebchannel.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="lib/leaflet/leaflet.css" />
|
||||
<script src="lib/leaflet/leaflet.js"></script>
|
||||
|
||||
<script src="lib/esri-leaflet/esri-leaflet.js"></script>
|
||||
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="lib/leaflet-groupedlayercontrol/leaflet.groupedlayercontrol.min.css" />
|
||||
<script
|
||||
src="lib/leaflet-groupedlayercontrol/leaflet.groupedlayercontrol.min.js">
|
||||
</script>
|
||||
|
||||
<link rel="stylesheet" href="lib/leaflet-ruler/leaflet-ruler.css">
|
||||
<script src="lib/leaflet-ruler/leaflet-ruler.js"></script>
|
||||
|
||||
<script src="lib/milsymbol/milsymbol.js"></script>
|
||||
|
||||
<script src="map.js" defer="defer"></script>
|
||||
<style>
|
||||
body { padding: 0; margin: 0; }
|
||||
html, body, #map { height: 100%; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
||||
.leaflet-control-layers-group-name{font-weight:700;margin-bottom:.2em;margin-left:3px}.leaflet-control-layers-group{margin-bottom:.5em}.leaflet-control-layers-scrollbar{overflow-y:scroll;padding-right:10px}
|
||||
File diff suppressed because one or more lines are too long
@ -1,22 +0,0 @@
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 Goker Tanrisever
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@ -1,41 +0,0 @@
|
||||
.leaflet-ruler{
|
||||
height: 35px;
|
||||
width: 35px;
|
||||
background-image: url("ruler.png"); /* <div>Icons made by <a href="https://www.flaticon.com/authors/monkik" title="monkik">monkik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a></div> */
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
.leaflet-ruler:hover{
|
||||
background-image: url("ruler.png"); /* <div>Icon made by <a href="https://www.flaticon.com/authors/monkik" title="monkik">monkik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a></div> */
|
||||
}
|
||||
.leaflet-ruler-clicked{
|
||||
height: 35px;
|
||||
width: 35px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-image: url("ruler.png");
|
||||
border-color: #5C863F !important;
|
||||
}
|
||||
.leaflet-bar{
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.leaflet-control {
|
||||
cursor: pointer;
|
||||
}
|
||||
.result-tooltip{
|
||||
background-color: white;
|
||||
border-width: medium;
|
||||
border-color: #435466;
|
||||
font-size: smaller;
|
||||
}
|
||||
.moving-tooltip{
|
||||
background-color: rgba(255, 255, 255, .7);
|
||||
background-clip: padding-box;
|
||||
opacity: 0.5;
|
||||
border: dotted;
|
||||
border-color: #435466;
|
||||
font-size: smaller;
|
||||
}
|
||||
.plus-length{
|
||||
padding-left: 45px;
|
||||
}
|
||||
@ -1,173 +0,0 @@
|
||||
(function(factory, window){
|
||||
"use strict";
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(['leaflet'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
module.exports = factory(require('leaflet'));
|
||||
}
|
||||
if (typeof window !== 'undefined' && window.L) {
|
||||
window.L.Ruler = factory(L);
|
||||
}
|
||||
}(function (L) {
|
||||
"use strict";
|
||||
L.Control.Ruler = L.Control.extend({
|
||||
options: {
|
||||
position: 'topright',
|
||||
circleMarker: {
|
||||
color: 'red',
|
||||
radius: 2
|
||||
},
|
||||
lineStyle: {
|
||||
color: 'red',
|
||||
dashArray: '1,6'
|
||||
},
|
||||
lengthUnit: {
|
||||
display: 'km',
|
||||
decimal: 2,
|
||||
factor: null,
|
||||
label: 'Distance:'
|
||||
},
|
||||
angleUnit: {
|
||||
display: '°',
|
||||
decimal: 2,
|
||||
factor: null,
|
||||
label: 'Bearing:'
|
||||
}
|
||||
},
|
||||
onAdd: function(map) {
|
||||
this._map = map;
|
||||
this._container = L.DomUtil.create('div', 'leaflet-bar');
|
||||
this._container.classList.add('leaflet-ruler');
|
||||
L.DomEvent.disableClickPropagation(this._container);
|
||||
L.DomEvent.on(this._container, 'click', this._toggleMeasure, this);
|
||||
this._choice = false;
|
||||
this._defaultCursor = this._map._container.style.cursor;
|
||||
this._allLayers = L.layerGroup();
|
||||
return this._container;
|
||||
},
|
||||
onRemove: function() {
|
||||
L.DomEvent.off(this._container, 'click', this._toggleMeasure, this);
|
||||
},
|
||||
_toggleMeasure: function() {
|
||||
this._choice = !this._choice;
|
||||
this._clickedLatLong = null;
|
||||
this._clickedPoints = [];
|
||||
this._totalLength = 0;
|
||||
if (this._choice){
|
||||
this._map.doubleClickZoom.disable();
|
||||
L.DomEvent.on(this._map._container, 'keydown', this._escape, this);
|
||||
L.DomEvent.on(this._map._container, 'dblclick', this._closePath, this);
|
||||
this._container.classList.add("leaflet-ruler-clicked");
|
||||
this._clickCount = 0;
|
||||
this._tempLine = L.featureGroup().addTo(this._allLayers);
|
||||
this._tempPoint = L.featureGroup().addTo(this._allLayers);
|
||||
this._pointLayer = L.featureGroup().addTo(this._allLayers);
|
||||
this._polylineLayer = L.featureGroup().addTo(this._allLayers);
|
||||
this._allLayers.addTo(this._map);
|
||||
this._map._container.style.cursor = 'crosshair';
|
||||
this._map.on('click', this._clicked, this);
|
||||
this._map.on('mousemove', this._moving, this);
|
||||
}
|
||||
else {
|
||||
this._map.doubleClickZoom.enable();
|
||||
L.DomEvent.off(this._map._container, 'keydown', this._escape, this);
|
||||
L.DomEvent.off(this._map._container, 'dblclick', this._closePath, this);
|
||||
this._container.classList.remove("leaflet-ruler-clicked");
|
||||
this._map.removeLayer(this._allLayers);
|
||||
this._allLayers = L.layerGroup();
|
||||
this._map._container.style.cursor = this._defaultCursor;
|
||||
this._map.off('click', this._clicked, this);
|
||||
this._map.off('mousemove', this._moving, this);
|
||||
}
|
||||
},
|
||||
_clicked: function(e) {
|
||||
this._clickedLatLong = e.latlng;
|
||||
this._clickedPoints.push(this._clickedLatLong);
|
||||
L.circleMarker(this._clickedLatLong, this.options.circleMarker).addTo(this._pointLayer);
|
||||
if(this._clickCount > 0 && !e.latlng.equals(this._clickedPoints[this._clickedPoints.length - 2])){
|
||||
if (this._movingLatLong){
|
||||
L.polyline([this._clickedPoints[this._clickCount-1], this._movingLatLong], this.options.lineStyle).addTo(this._polylineLayer);
|
||||
}
|
||||
var text;
|
||||
this._totalLength += this._result.Distance;
|
||||
if (this._clickCount > 1){
|
||||
text = '<b>' + this.options.angleUnit.label + '</b> ' + this._result.Bearing.toFixed(this.options.angleUnit.decimal) + ' ' + this.options.angleUnit.display + '<br><b>' + this.options.lengthUnit.label + '</b> ' + this._totalLength.toFixed(this.options.lengthUnit.decimal) + ' ' + this.options.lengthUnit.display;
|
||||
}
|
||||
else {
|
||||
text = '<b>' + this.options.angleUnit.label + '</b> ' + this._result.Bearing.toFixed(this.options.angleUnit.decimal) + ' ' + this.options.angleUnit.display + '<br><b>' + this.options.lengthUnit.label + '</b> ' + this._result.Distance.toFixed(this.options.lengthUnit.decimal) + ' ' + this.options.lengthUnit.display;
|
||||
}
|
||||
L.circleMarker(this._clickedLatLong, this.options.circleMarker).bindTooltip(text, {permanent: true, className: 'result-tooltip'}).addTo(this._pointLayer).openTooltip();
|
||||
}
|
||||
this._clickCount++;
|
||||
},
|
||||
_moving: function(e) {
|
||||
if (this._clickedLatLong){
|
||||
L.DomEvent.off(this._container, 'click', this._toggleMeasure, this);
|
||||
this._movingLatLong = e.latlng;
|
||||
if (this._tempLine){
|
||||
this._map.removeLayer(this._tempLine);
|
||||
this._map.removeLayer(this._tempPoint);
|
||||
}
|
||||
var text;
|
||||
this._addedLength = 0;
|
||||
this._tempLine = L.featureGroup();
|
||||
this._tempPoint = L.featureGroup();
|
||||
this._tempLine.addTo(this._map);
|
||||
this._tempPoint.addTo(this._map);
|
||||
this._calculateBearingAndDistance();
|
||||
this._addedLength = this._result.Distance + this._totalLength;
|
||||
L.polyline([this._clickedLatLong, this._movingLatLong], this.options.lineStyle).addTo(this._tempLine);
|
||||
if (this._clickCount > 1){
|
||||
text = '<b>' + this.options.angleUnit.label + '</b> ' + this._result.Bearing.toFixed(this.options.angleUnit.decimal) + ' ' + this.options.angleUnit.display + '<br><b>' + this.options.lengthUnit.label + '</b> ' + this._addedLength.toFixed(this.options.lengthUnit.decimal) + ' ' + this.options.lengthUnit.display + '<br><div class="plus-length">(+' + this._result.Distance.toFixed(this.options.lengthUnit.decimal) + ')</div>';
|
||||
}
|
||||
else {
|
||||
text = '<b>' + this.options.angleUnit.label + '</b> ' + this._result.Bearing.toFixed(this.options.angleUnit.decimal) + ' ' + this.options.angleUnit.display + '<br><b>' + this.options.lengthUnit.label + '</b> ' + this._result.Distance.toFixed(this.options.lengthUnit.decimal) + ' ' + this.options.lengthUnit.display;
|
||||
}
|
||||
L.circleMarker(this._movingLatLong, this.options.circleMarker).bindTooltip(text, {sticky: true, offset: L.point(0, -40) ,className: 'moving-tooltip'}).addTo(this._tempPoint).openTooltip();
|
||||
}
|
||||
},
|
||||
_escape: function(e) {
|
||||
if (e.keyCode === 27){
|
||||
if (this._clickCount > 0){
|
||||
this._closePath();
|
||||
}
|
||||
else {
|
||||
this._choice = true;
|
||||
this._toggleMeasure();
|
||||
}
|
||||
}
|
||||
},
|
||||
_calculateBearingAndDistance: function() {
|
||||
var f1 = this._clickedLatLong.lat, l1 = this._clickedLatLong.lng, f2 = this._movingLatLong.lat, l2 = this._movingLatLong.lng;
|
||||
var toRadian = Math.PI / 180;
|
||||
// haversine formula
|
||||
// bearing
|
||||
var y = Math.sin((l2-l1)*toRadian) * Math.cos(f2*toRadian);
|
||||
var x = Math.cos(f1*toRadian)*Math.sin(f2*toRadian) - Math.sin(f1*toRadian)*Math.cos(f2*toRadian)*Math.cos((l2-l1)*toRadian);
|
||||
var brng = Math.atan2(y, x)*((this.options.angleUnit.factor ? this.options.angleUnit.factor/2 : 180)/Math.PI);
|
||||
brng += brng < 0 ? (this.options.angleUnit.factor ? this.options.angleUnit.factor : 360) : 0;
|
||||
// distance
|
||||
var R = this.options.lengthUnit.factor ? 6371 * this.options.lengthUnit.factor : 6371; // kilometres
|
||||
var deltaF = (f2 - f1)*toRadian;
|
||||
var deltaL = (l2 - l1)*toRadian;
|
||||
var a = Math.sin(deltaF/2) * Math.sin(deltaF/2) + Math.cos(f1*toRadian) * Math.cos(f2*toRadian) * Math.sin(deltaL/2) * Math.sin(deltaL/2);
|
||||
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
|
||||
var distance = R * c;
|
||||
this._result = {
|
||||
Bearing: brng,
|
||||
Distance: distance
|
||||
};
|
||||
},
|
||||
_closePath: function() {
|
||||
this._map.removeLayer(this._tempLine);
|
||||
this._map.removeLayer(this._tempPoint);
|
||||
if (this._clickCount <= 1) this._map.removeLayer(this._pointLayer);
|
||||
this._choice = false;
|
||||
L.DomEvent.on(this._container, 'click', this._toggleMeasure, this);
|
||||
this._toggleMeasure();
|
||||
}
|
||||
});
|
||||
L.control.ruler = function(options) {
|
||||
return new L.Control.Ruler(options);
|
||||
};
|
||||
}, window));
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 684 B |
Binary file not shown.
|
Before Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 696 B |
Binary file not shown.
|
Before Width: | Height: | Size: 2.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 618 B |
@ -1,640 +0,0 @@
|
||||
/* required styles */
|
||||
|
||||
.leaflet-pane,
|
||||
.leaflet-tile,
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow,
|
||||
.leaflet-tile-container,
|
||||
.leaflet-pane > svg,
|
||||
.leaflet-pane > canvas,
|
||||
.leaflet-zoom-box,
|
||||
.leaflet-image-layer,
|
||||
.leaflet-layer {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
.leaflet-container {
|
||||
overflow: hidden;
|
||||
}
|
||||
.leaflet-tile,
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-user-drag: none;
|
||||
}
|
||||
/* Prevents IE11 from highlighting tiles in blue */
|
||||
.leaflet-tile::selection {
|
||||
background: transparent;
|
||||
}
|
||||
/* Safari renders non-retina tile on retina better with this, but Chrome is worse */
|
||||
.leaflet-safari .leaflet-tile {
|
||||
image-rendering: -webkit-optimize-contrast;
|
||||
}
|
||||
/* hack that prevents hw layers "stretching" when loading new tiles */
|
||||
.leaflet-safari .leaflet-tile-container {
|
||||
width: 1600px;
|
||||
height: 1600px;
|
||||
-webkit-transform-origin: 0 0;
|
||||
}
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow {
|
||||
display: block;
|
||||
}
|
||||
/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
|
||||
/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
|
||||
.leaflet-container .leaflet-overlay-pane svg,
|
||||
.leaflet-container .leaflet-marker-pane img,
|
||||
.leaflet-container .leaflet-shadow-pane img,
|
||||
.leaflet-container .leaflet-tile-pane img,
|
||||
.leaflet-container img.leaflet-image-layer,
|
||||
.leaflet-container .leaflet-tile {
|
||||
max-width: none !important;
|
||||
max-height: none !important;
|
||||
}
|
||||
|
||||
.leaflet-container.leaflet-touch-zoom {
|
||||
-ms-touch-action: pan-x pan-y;
|
||||
touch-action: pan-x pan-y;
|
||||
}
|
||||
.leaflet-container.leaflet-touch-drag {
|
||||
-ms-touch-action: pinch-zoom;
|
||||
/* Fallback for FF which doesn't support pinch-zoom */
|
||||
touch-action: none;
|
||||
touch-action: pinch-zoom;
|
||||
}
|
||||
.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.leaflet-container {
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
.leaflet-container a {
|
||||
-webkit-tap-highlight-color: rgba(51, 181, 229, 0.4);
|
||||
}
|
||||
.leaflet-tile {
|
||||
filter: inherit;
|
||||
visibility: hidden;
|
||||
}
|
||||
.leaflet-tile-loaded {
|
||||
visibility: inherit;
|
||||
}
|
||||
.leaflet-zoom-box {
|
||||
width: 0;
|
||||
height: 0;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
z-index: 800;
|
||||
}
|
||||
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
|
||||
.leaflet-overlay-pane svg {
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
.leaflet-pane { z-index: 400; }
|
||||
|
||||
.leaflet-tile-pane { z-index: 200; }
|
||||
.leaflet-overlay-pane { z-index: 400; }
|
||||
.leaflet-shadow-pane { z-index: 500; }
|
||||
.leaflet-marker-pane { z-index: 600; }
|
||||
.leaflet-tooltip-pane { z-index: 650; }
|
||||
.leaflet-popup-pane { z-index: 700; }
|
||||
|
||||
.leaflet-map-pane canvas { z-index: 100; }
|
||||
.leaflet-map-pane svg { z-index: 200; }
|
||||
|
||||
.leaflet-vml-shape {
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
}
|
||||
.lvml {
|
||||
behavior: url(#default#VML);
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
|
||||
/* control positioning */
|
||||
|
||||
.leaflet-control {
|
||||
position: relative;
|
||||
z-index: 800;
|
||||
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
|
||||
pointer-events: auto;
|
||||
}
|
||||
.leaflet-top,
|
||||
.leaflet-bottom {
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
pointer-events: none;
|
||||
}
|
||||
.leaflet-top {
|
||||
top: 0;
|
||||
}
|
||||
.leaflet-right {
|
||||
right: 0;
|
||||
}
|
||||
.leaflet-bottom {
|
||||
bottom: 0;
|
||||
}
|
||||
.leaflet-left {
|
||||
left: 0;
|
||||
}
|
||||
.leaflet-control {
|
||||
float: left;
|
||||
clear: both;
|
||||
}
|
||||
.leaflet-right .leaflet-control {
|
||||
float: right;
|
||||
}
|
||||
.leaflet-top .leaflet-control {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.leaflet-bottom .leaflet-control {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.leaflet-left .leaflet-control {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.leaflet-right .leaflet-control {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
|
||||
/* zoom and fade animations */
|
||||
|
||||
.leaflet-fade-anim .leaflet-tile {
|
||||
will-change: opacity;
|
||||
}
|
||||
.leaflet-fade-anim .leaflet-popup {
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 0.2s linear;
|
||||
-moz-transition: opacity 0.2s linear;
|
||||
transition: opacity 0.2s linear;
|
||||
}
|
||||
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
|
||||
opacity: 1;
|
||||
}
|
||||
.leaflet-zoom-animated {
|
||||
-webkit-transform-origin: 0 0;
|
||||
-ms-transform-origin: 0 0;
|
||||
transform-origin: 0 0;
|
||||
}
|
||||
.leaflet-zoom-anim .leaflet-zoom-animated {
|
||||
will-change: transform;
|
||||
}
|
||||
.leaflet-zoom-anim .leaflet-zoom-animated {
|
||||
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
-moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
transition: transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
}
|
||||
.leaflet-zoom-anim .leaflet-tile,
|
||||
.leaflet-pan-anim .leaflet-tile {
|
||||
-webkit-transition: none;
|
||||
-moz-transition: none;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.leaflet-zoom-anim .leaflet-zoom-hide {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
|
||||
/* cursors */
|
||||
|
||||
.leaflet-interactive {
|
||||
cursor: pointer;
|
||||
}
|
||||
.leaflet-grab {
|
||||
cursor: -webkit-grab;
|
||||
cursor: -moz-grab;
|
||||
cursor: grab;
|
||||
}
|
||||
.leaflet-crosshair,
|
||||
.leaflet-crosshair .leaflet-interactive {
|
||||
cursor: crosshair;
|
||||
}
|
||||
.leaflet-popup-pane,
|
||||
.leaflet-control {
|
||||
cursor: auto;
|
||||
}
|
||||
.leaflet-dragging .leaflet-grab,
|
||||
.leaflet-dragging .leaflet-grab .leaflet-interactive,
|
||||
.leaflet-dragging .leaflet-marker-draggable {
|
||||
cursor: move;
|
||||
cursor: -webkit-grabbing;
|
||||
cursor: -moz-grabbing;
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
/* marker & overlays interactivity */
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow,
|
||||
.leaflet-image-layer,
|
||||
.leaflet-pane > svg path,
|
||||
.leaflet-tile-container {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.leaflet-marker-icon.leaflet-interactive,
|
||||
.leaflet-image-layer.leaflet-interactive,
|
||||
.leaflet-pane > svg path.leaflet-interactive,
|
||||
svg.leaflet-image-layer.leaflet-interactive path {
|
||||
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* visual tweaks */
|
||||
|
||||
.leaflet-container {
|
||||
background: #ddd;
|
||||
outline: 0;
|
||||
}
|
||||
.leaflet-container a {
|
||||
color: #0078A8;
|
||||
}
|
||||
.leaflet-container a.leaflet-active {
|
||||
outline: 2px solid orange;
|
||||
}
|
||||
.leaflet-zoom-box {
|
||||
border: 2px dotted #38f;
|
||||
background: rgba(255,255,255,0.5);
|
||||
}
|
||||
|
||||
|
||||
/* general typography */
|
||||
.leaflet-container {
|
||||
font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
|
||||
/* general toolbar styles */
|
||||
|
||||
.leaflet-bar {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
|
||||
border-radius: 4px;
|
||||
}
|
||||
.leaflet-bar a,
|
||||
.leaflet-bar a:hover {
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #ccc;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
.leaflet-bar a,
|
||||
.leaflet-control-layers-toggle {
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
display: block;
|
||||
}
|
||||
.leaflet-bar a:hover {
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
.leaflet-bar a:first-child {
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
.leaflet-bar a:last-child {
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom: none;
|
||||
}
|
||||
.leaflet-bar a.leaflet-disabled {
|
||||
cursor: default;
|
||||
background-color: #f4f4f4;
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-bar a {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
.leaflet-touch .leaflet-bar a:first-child {
|
||||
border-top-left-radius: 2px;
|
||||
border-top-right-radius: 2px;
|
||||
}
|
||||
.leaflet-touch .leaflet-bar a:last-child {
|
||||
border-bottom-left-radius: 2px;
|
||||
border-bottom-right-radius: 2px;
|
||||
}
|
||||
|
||||
/* zoom control */
|
||||
|
||||
.leaflet-control-zoom-in,
|
||||
.leaflet-control-zoom-out {
|
||||
font: bold 18px 'Lucida Console', Monaco, monospace;
|
||||
text-indent: 1px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
|
||||
/* layers control */
|
||||
|
||||
.leaflet-control-layers {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.4);
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.leaflet-control-layers-toggle {
|
||||
background-image: url(images/layers.png);
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
.leaflet-retina .leaflet-control-layers-toggle {
|
||||
background-image: url(images/layers-2x.png);
|
||||
background-size: 26px 26px;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-layers-toggle {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
}
|
||||
.leaflet-control-layers .leaflet-control-layers-list,
|
||||
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
|
||||
display: none;
|
||||
}
|
||||
.leaflet-control-layers-expanded .leaflet-control-layers-list {
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
.leaflet-control-layers-expanded {
|
||||
padding: 6px 10px 6px 6px;
|
||||
color: #333;
|
||||
background: #fff;
|
||||
}
|
||||
.leaflet-control-layers-scrollbar {
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
padding-right: 5px;
|
||||
}
|
||||
.leaflet-control-layers-selector {
|
||||
margin-top: 2px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
.leaflet-control-layers label {
|
||||
display: block;
|
||||
}
|
||||
.leaflet-control-layers-separator {
|
||||
height: 0;
|
||||
border-top: 1px solid #ddd;
|
||||
margin: 5px -10px 5px -6px;
|
||||
}
|
||||
|
||||
/* Default icon URLs */
|
||||
.leaflet-default-icon-path {
|
||||
background-image: url(images/marker-icon.png);
|
||||
}
|
||||
|
||||
|
||||
/* attribution and scale controls */
|
||||
|
||||
.leaflet-container .leaflet-control-attribution {
|
||||
background: #fff;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
margin: 0;
|
||||
}
|
||||
.leaflet-control-attribution,
|
||||
.leaflet-control-scale-line {
|
||||
padding: 0 5px;
|
||||
color: #333;
|
||||
}
|
||||
.leaflet-control-attribution a {
|
||||
text-decoration: none;
|
||||
}
|
||||
.leaflet-control-attribution a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.leaflet-container .leaflet-control-attribution,
|
||||
.leaflet-container .leaflet-control-scale {
|
||||
font-size: 11px;
|
||||
}
|
||||
.leaflet-left .leaflet-control-scale {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.leaflet-bottom .leaflet-control-scale {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.leaflet-control-scale-line {
|
||||
border: 2px solid #777;
|
||||
border-top: none;
|
||||
line-height: 1.1;
|
||||
padding: 2px 5px 1px;
|
||||
font-size: 11px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
|
||||
background: #fff;
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.leaflet-control-scale-line:not(:first-child) {
|
||||
border-top: 2px solid #777;
|
||||
border-bottom: none;
|
||||
margin-top: -2px;
|
||||
}
|
||||
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
|
||||
border-bottom: 2px solid #777;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-attribution,
|
||||
.leaflet-touch .leaflet-control-layers,
|
||||
.leaflet-touch .leaflet-bar {
|
||||
box-shadow: none;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-layers,
|
||||
.leaflet-touch .leaflet-bar {
|
||||
border: 2px solid rgba(0,0,0,0.2);
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
|
||||
/* popup */
|
||||
|
||||
.leaflet-popup {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.leaflet-popup-content-wrapper {
|
||||
padding: 1px;
|
||||
text-align: left;
|
||||
border-radius: 12px;
|
||||
}
|
||||
.leaflet-popup-content {
|
||||
margin: 13px 19px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.leaflet-popup-content p {
|
||||
margin: 18px 0;
|
||||
}
|
||||
.leaflet-popup-tip-container {
|
||||
width: 40px;
|
||||
height: 20px;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
margin-left: -20px;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
.leaflet-popup-tip {
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
padding: 1px;
|
||||
|
||||
margin: -10px auto 0;
|
||||
|
||||
-webkit-transform: rotate(45deg);
|
||||
-moz-transform: rotate(45deg);
|
||||
-ms-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
.leaflet-popup-content-wrapper,
|
||||
.leaflet-popup-tip {
|
||||
background: white;
|
||||
color: #333;
|
||||
box-shadow: 0 3px 14px rgba(0,0,0,0.4);
|
||||
}
|
||||
.leaflet-container a.leaflet-popup-close-button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: 4px 4px 0 0;
|
||||
border: none;
|
||||
text-align: center;
|
||||
width: 18px;
|
||||
height: 14px;
|
||||
font: 16px/14px Tahoma, Verdana, sans-serif;
|
||||
color: #c3c3c3;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
background: transparent;
|
||||
}
|
||||
.leaflet-container a.leaflet-popup-close-button:hover {
|
||||
color: #999;
|
||||
}
|
||||
.leaflet-popup-scrolled {
|
||||
overflow: auto;
|
||||
border-bottom: 1px solid #ddd;
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-popup-content-wrapper {
|
||||
-ms-zoom: 1;
|
||||
}
|
||||
.leaflet-oldie .leaflet-popup-tip {
|
||||
width: 24px;
|
||||
margin: 0 auto;
|
||||
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
|
||||
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
|
||||
}
|
||||
.leaflet-oldie .leaflet-popup-tip-container {
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-control-zoom,
|
||||
.leaflet-oldie .leaflet-control-layers,
|
||||
.leaflet-oldie .leaflet-popup-content-wrapper,
|
||||
.leaflet-oldie .leaflet-popup-tip {
|
||||
border: 1px solid #999;
|
||||
}
|
||||
|
||||
|
||||
/* div icon */
|
||||
|
||||
.leaflet-div-icon {
|
||||
background: #fff;
|
||||
border: 1px solid #666;
|
||||
}
|
||||
|
||||
|
||||
/* Tooltip */
|
||||
/* Base styles for the element that has a tooltip */
|
||||
.leaflet-tooltip {
|
||||
position: absolute;
|
||||
padding: 6px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #fff;
|
||||
border-radius: 3px;
|
||||
color: #222;
|
||||
white-space: nowrap;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.4);
|
||||
}
|
||||
.leaflet-tooltip.leaflet-clickable {
|
||||
cursor: pointer;
|
||||
pointer-events: auto;
|
||||
}
|
||||
.leaflet-tooltip-top:before,
|
||||
.leaflet-tooltip-bottom:before,
|
||||
.leaflet-tooltip-left:before,
|
||||
.leaflet-tooltip-right:before {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
border: 6px solid transparent;
|
||||
background: transparent;
|
||||
content: "";
|
||||
}
|
||||
|
||||
/* Directions */
|
||||
|
||||
.leaflet-tooltip-bottom {
|
||||
margin-top: 6px;
|
||||
}
|
||||
.leaflet-tooltip-top {
|
||||
margin-top: -6px;
|
||||
}
|
||||
.leaflet-tooltip-bottom:before,
|
||||
.leaflet-tooltip-top:before {
|
||||
left: 50%;
|
||||
margin-left: -6px;
|
||||
}
|
||||
.leaflet-tooltip-top:before {
|
||||
bottom: 0;
|
||||
margin-bottom: -12px;
|
||||
border-top-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-bottom:before {
|
||||
top: 0;
|
||||
margin-top: -12px;
|
||||
margin-left: -6px;
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-left {
|
||||
margin-left: -6px;
|
||||
}
|
||||
.leaflet-tooltip-right {
|
||||
margin-left: 6px;
|
||||
}
|
||||
.leaflet-tooltip-left:before,
|
||||
.leaflet-tooltip-right:before {
|
||||
top: 50%;
|
||||
margin-top: -6px;
|
||||
}
|
||||
.leaflet-tooltip-left:before {
|
||||
right: 0;
|
||||
margin-right: -12px;
|
||||
border-left-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-right:before {
|
||||
left: 0;
|
||||
margin-left: -12px;
|
||||
border-right-color: #fff;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user