|
|
- <template>
- <div id="map-wrap">
- <!-- <pre style="z-index: 500; position: fixed; right: 0;">
- airportsOrig: {{ airportsOrig.length }}
- airportsDest: {{ airportsDest.length }}
- selectedOrig: {{ selectedOrig.key }}
- selectedDest: {{ selectedDest.key }}
- </pre> -->
- <client-only>
- <l-map ref="flMap" v-bind="map" @ready="$emit('map-ready')">
- <v-marker-cluster v-if="!selectedOrigNorm.key">
- <l-marker
- v-for="airport in airportsOrig"
- :key="airport.iata"
- :lat-lng="[airport.lat, airport.long]"
- >
- <l-icon
- :icon-anchor="[16, 37]"
- class-name="airport-icon orig-icon unselected"
- >
- <div class="map__icon-muni">
- {{ airport.municipality }} ►
- </div>
- </l-icon>
- <l-popup class="map__popup">
- <div class="map__popup-iata">
- {{ airport.iata }}
- </div>
- <div class="map__popup-muni">
- {{ airport.municipality }}
- </div>
- <div class="map__popup-buttons">
- <button class="btn btn--primary btn--map" @click="$emit('make-origin', airport)">
- start here ►
- </button>
- </div>
- </l-popup>
- </l-marker>
- </v-marker-cluster>
- <v-marker-cluster v-if="selectedOrigNorm.key && !selectedDestNorm.key">
- <l-marker
- v-for="airport in airportsDest"
- :key="airport.iata"
- :lat-lng="[airport.lat, airport.long]"
- >
- <l-icon
- :icon-anchor="[16, 37]"
- class-name="airport-icon dest-icon unselected"
- >
- <div class="map__icon-muni">
- {{ airport.municipality }} ■
- </div>
- </l-icon>
- <l-popup class="map__popup">
- <div class="map__popup-iata">
- {{ airport.iata }}
- </div>
- <div class="map__popup-muni">
- {{ airport.municipality }}
- </div>
- <div class="map__popup-buttons">
- <button
- class="btn btn--primary btn--map"
- @click="$emit('make-destination', airport)"
- >
- land here ■
- </button>
- <button class="btn btn--secondary btn--map" @click="$emit('make-origin', airport)">
- start here ►
- </button>
- </div>
- </l-popup>
- </l-marker>
- </v-marker-cluster>
- <l-marker v-if="selectedOrigNorm.key" v-bind="selectedOrigNorm">
- <l-icon
- :icon-anchor="[16, 37]"
- class-name="airport-icon orig-icon selected"
- >
- <div class="map__icon-muni">
- {{ selectedOrig.municipality }}
- </div>
- </l-icon>
- <l-popup class="map__popup">
- <div class="map__popup-iata">
- {{ selectedOrig.iata }}
- </div>
- <div class="map__popup-muni">
- {{ selectedOrig.municipality }}
- </div>
- <div class="map__popup-buttons">
- <button class="btn btn--cancel btn--map" @click="$emit('clear-origin')">
- remove
- </button>
- </div>
- </l-popup>
- </l-marker>
- <l-marker v-if="selectedDestNorm.key" v-bind="selectedDestNorm">
- <l-icon
- :icon-anchor="[16, 37]"
- class-name="airport-icon dest-icon selected"
- >
- <div class="map__icon-muni">
- {{ selectedDest.municipality }}
- </div>
- </l-icon>
- <l-popup class="map__popup">
- <div class="map__popup-iata">
- {{ selectedDest.iata }}
- </div>
- <div class="map__popup-muni">
- {{ selectedDest.municipality }}
- </div>
- <div class="map__popup-buttons">
- <button class="btn btn--cancel btn--map" @click="$emit('clear-destination')">
- remove
- </button>
- </div>
- </l-popup>
- </l-marker>
- <l-polyline v-if="selectedOrigNorm.key && selectedDestNorm.key" :lat-lngs="[selectedOrigNorm['lat-lng'],selectedDestNorm['lat-lng']]" color="#007fff" />
- <!-- <l-tile-layer v-bind="tileLayer" :url="mapBoxUrl" /> -->
- <!-- <l-tile-layer :url="osmUrl" :attribution="osmAttribution" /> -->
- <l-tile-layer v-bind="tileLayer" />
- </l-map>
- </client-only>
- </div>
- </template>
-
- <script>
- export default {
- props: {
- airportsOrig: {
- type: [Array, Object],
- default () {
- return []
- }
- },
- airportsDest: {
- type: [Array, Object],
- default () {
- return []
- }
- },
- selectedOrig: {
- type: [Object],
- default () {
- return {}
- }
- },
- selectedDest: {
- type: [Object],
- default () {
- return {}
- }
- }
- },
- data () {
- return {
- map: {
- zoom: 3,
- minZoom: 3,
- maxZoom: 13,
- zoomSnap: 0.1,
- center: {
- lat: 63.8333,
- lng: -152
- },
- bounds: [
- [
- 71.0394374664382,
- -178.4706617597655
- ],
- [
- 50.44556513009691,
- -127.25240004101528
- ]
- ],
- options: {
- tap: false
- },
- // maxBounds: [
- // [74.8678, -180],
- // [50, -120]
- // ],
- // maxBoundsViscosity: 0.5
- },
- mapBoxAccessToken: 'pk.eyJ1IjoiZmx5bG9jYWwiLCJhIjoiY2t0OHUxZXB6MTVueTJ4cGVwOHRuc2s2NyJ9.YF9frLvISHfOuT7nqs3TNg',
- mapBoxAttribution: 'FlyLocal | Map data © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
- osmUrl: 'http://{s}.tile.osm.org/{z}/{x}/{y}.png',
- osmAttribution:
- '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
- mapBoxUrl: 'https://api.mapbox.com/styles/v1/flylocal/ckt9x8aho0igb18mmm9ks2fsv/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiZmx5bG9jYWwiLCJhIjoiY2t0OHUxZXB6MTVueTJ4cGVwOHRuc2s2NyJ9.YF9frLvISHfOuT7nqs3TNg',
- mapBinder: {
-
- }
- }
- },
- computed: {
- selectedOrigNorm () {
- return {
- key: this.selectedOrig.iata,
- iata: this.selectedOrig.iata,
- 'lat-lng': [this.selectedOrig.lat, this.selectedOrig.long],
- municipality: this.selectedOrig.municipality
- }
- },
- selectedDestNorm () {
- return {
- key: this.selectedDest.iata,
- iata: this.selectedDest.iata,
- 'lat-lng': [this.selectedDest.lat, this.selectedDest.long],
- municipality: this.selectedDest.municipality
- }
- },
- mapBoxApiUrl () {
- return `https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=${this.mapBoxAccessToken}`
- },
- tileLayer () {
- return {
- url: 'https://api.mapbox.com/styles/v1/flylocal/ckt9x8aho0igb18mmm9ks2fsv/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiZmx5bG9jYWwiLCJhIjoiY2t0OHUxZXB6MTVueTJ4cGVwOHRuc2s2NyJ9.YF9frLvISHfOuT7nqs3TNg',
- maxZoom: 18,
- id: 'flylocal/ckt9x8aho0igb18mmm9ks2fsv',
- tileSize: 256,
- zoomOffset: -1,
- token: 'pk.eyJ1IjoiZmx5bG9jYWwiLCJhIjoiY2t0OHUxZXB6MTVueTJ4cGVwOHRuc2s2NyJ9.YF9frLvISHfOuT7nqs3TNg',
- attribution: this.mapBoxAttribution,
- detectRetina: true
- // bounds: [
- // [74.8678, -180],
- // [38.5481, -90.8789]
- // ]
- }
- }
- },
- updated () {
- this.setBounds()
- // const o = this.airportsOrig.map((m) => { return [m.lat, m.long] })
- // const d = this.airportsDest.map((m) => { return [m.lat, m.long] })
- // const so = [this.selectedOrig.lat, this.selectedOrig.long]
- // const sd = [this.selectedDest.lat, this.selectedDest.long]
- // this.$refs.flMap.mapObject.fitBounds([...o, ...d, ...so, ...sd])
- // this.$refs.flMap.mapObject.fitBounds([[40, -73], [5, -55]])
- },
- methods: {
- resize () {
- this.$refs.flMap.mapObject.invalidateSize()
- },
- setBounds () {
- if (this.$refs.flMap && this.$refs.flMap.mapObject) {
- /* selected none */
- if (!this.selectedOrigNorm.key && !this.selectedDestNorm.key && this.airportsOrig.length > 0) {
- const o = this.airportsOrig.map((m) => { return [m.lat, m.long] })
- // console.log('origins:')
- // console.log(o)
- if (o) {
- this.$refs.flMap.mapObject.fitBounds([...o], { padding: [50, 70] })
- }
- }
- /* selected org */
- if (this.selectedOrigNorm.key && !this.selectedDestNorm.key) {
- const so = [this.selectedOrig.lat, this.selectedOrig.long]
- const d = this.airportsDest.map((m) => { return [m.lat, m.long] })
- // console.log('so:')
- // console.log(so)
- // console.log('dests:')
- // console.log(d)
- if (so && d) {
- this.$refs.flMap.mapObject.fitBounds([so, ...d], { padding: [50, 70] })
- }
- }
- /* selected both */
- if (this.selectedOrigNorm.key && this.selectedDestNorm.key) {
- const so = [this.selectedOrig.lat, this.selectedOrig.long]
- const sd = [this.selectedDest.lat, this.selectedDest.long]
- // console.log('so:')
- // console.log(so)
- // console.log('sd:')
- // console.log(sd)
- if (so && sd) {
- this.$refs.flMap.mapObject.fitBounds([so, sd], { padding: [50, 70] })
- }
- }
- }
- }
- }
- }
- </script>
-
- <style lang="css">
- :root {
- --map-shadow: 5px 3px 10px rgb(0 0 0 / 20%);
- }
-
- #map-wrap {
- height: 0;
- flex: 1 0 auto;
- }
-
- .map__icon-muni {
- white-space: nowrap;
- }
-
- .map__popup {
- font-size: 0.9rem;
- }
-
- .map__popup-iata {
- white-space: nowrap;
- font-size: 3em;
- line-height: 1;
- }
-
- .map__popup-muni {
- white-space: nowrap;
- margin-bottom: 0.5rem;
- }
-
- .map__popup-buttons {
- display: flex;
- flex-direction: row;
- gap: 0.5em;
- }
-
- .leaflet-container {
- font-size: 1rem;
- background: black;
- }
-
- .leaflet-popup {
- top: 0 !important;
- left: 0 !important;
- }
-
- .leaflet-popup-content-wrapper {
- border-radius: 0.2rem 1.5rem 1.5rem 1.5rem;
- box-shadow: var(--map-shadow);
- }
-
- .leaflet-popup-tip-container,
- .leaflet-popup-close-button {
- display: none;
- }
-
- .leaflet-popup-content {
- margin: 0.75rem;
- }
-
- /* TODO: change these? */
- .leaflet-top {
- top: auto;
- bottom: 0;
- }
-
- .leaflet-top .leaflet-control {
- margin-top: auto;
- margin-bottom: 10px;
- }
-
- .airport-icon {
- padding: 0.55rem;
- border-radius: 0.2rem 1.5rem 1.5rem 1.5rem;
- box-shadow: var(--map-shadow);
- text-align: center;
- width: auto !important;
- height: auto !important;
- margin: 0 !important;
- border: 0.2rem solid transparent;
- transition: all 0.2s;
- }
-
- .airport-icon.orig-icon {
- background-color: white;
- color: black;
- }
-
- .airport-icon.orig-icon:hover {
- border-color: #007fff;
- }
-
- .airport-icon.dest-icon {
- background-color: #ddd;
- color: black;
- }
-
- .airport-icon.orig-icon.selected {
- border-color: #007fff;
- }
-
- .airport-icon.dest-icon:hover {
- background-color: #007fff;
- color: white;
- }
-
- .airport-icon.dest-icon.selected {
- background-color: #007fff;
- color: white;
- }
-
- .marker-cluster {
- /* background-clip: padding-box;
- border-radius: 20px; */
- color: white;
- }
-
- .marker-cluster div {
- /* width: 30px;
- height: 30px;
- margin-left: 5px;
- margin-top: 5px;
- text-align: center;
- border-radius: 15px;
- font: 12px "Helvetica Neue", Arial, Helvetica, sans-serif; */
- }
-
- /* .marker-cluster span {
- line-height: 30px;
- } */
-
- /* #map-wrap .marker-cluster-small {
- background-color: rgba(47, 151, 255, 0.15);
- }
-
- #map-wrap .marker-cluster-small div {
- background-color: rgba(0, 127, 255, 0.15);
- }
-
- #map-wrap .marker-cluster-medium {
- background-color: rgba(47, 151, 255, 0.5);
- }
-
- #map-wrap .marker-cluster-medium div {
- background-color: rgba(0, 127, 255, 0.5);
- }
-
- #map-wrap .marker-cluster-large {
- background-color: rgba(47, 151, 255, 0.9);
- }
-
- #map-wrap .marker-cluster-large div {
- background-color: rgba(0, 127, 255, 0.9);
- } */
-
- #map-wrap .marker-cluster-small {
- background-color: rgba(47, 151, 255, 0.5);
- height: 30px !important;
- width: 30px !important;
- }
-
- #map-wrap .marker-cluster-small div {
- background-color: rgba(0, 127, 255, 0.9);
- height: 20px !important;
- width: 20px !important;
- }
-
- #map-wrap .marker-cluster-small div > span {
- line-height: 20px;
- }
-
- #map-wrap .marker-cluster-medium {
- background-color: rgba(47, 151, 255, 0.5);
- }
-
- #map-wrap .marker-cluster-medium div {
- background-color: rgba(0, 127, 255, 0.9);
- }
-
- #map-wrap .marker-cluster-medium div > span {
- line-height: 30px;
- }
-
- #map-wrap .marker-cluster-large {
- background-color: rgba(47, 151, 255, 0.5);
- height: 50px !important;
- width: 50px !important;
- }
-
- #map-wrap .marker-cluster-large div {
- background-color: rgba(0, 127, 255, 0.9);
- height: 40px !important;
- width: 40px !important;
- }
-
- #map-wrap .marker-cluster-large div > span {
- line-height: 40px;
- }
-
- </style>
|