# map-basic

# Basic example

<template>
  <map-basic
    :zoom.sync="zoom"
    :center.sync="center"
    :layers="layers"
    style="height: 100%; width: 100%;"
  />
</template>

<script>
import MapBasic from '@eox/map-basic';

export default {
  components: {
    MapBasic,
  },
  data: () => ({
    zoom: 2,
    center: [0, 0],
    layers: [
      {
        type: 'tile',
        source: {
          type: 'wmts-capabilities',
          url: 'https://tiles.maps.eox.at/wmts/1.0.0/WMTSCapabilities.xml',
          layer: 's2cloudless-2021_3857',
        },
      },
    ],
  }),
};
</script>

# Simple layer selector

<template>
  <map-basic
    :zoom="zoom"
    :layers="layers"
    style="height: 100%; width: 100%;"
  >
    <v-card
      class="pa-3"
      style="position: absolute; z-index: 1; top: 20px; right: 20px"
    >
      <v-switch
        v-for="(layer, key) in layers"
        :key="key"
        v-model="layer.visible"
        :label="layer.title"
        hide-details
        class="mt-0"
      ></v-switch>
    </v-card>
  </map-basic>
</template>

<script>
import MapBasic from '@eox/map-basic';

export default {
  components: {
    MapBasic,
  },
  data: () => ({
    zoom: 2,
    layers: [
      {
        title: 'WMTS from Capabilities',
        type: 'tile',
        visible: true,
        source: {
          type: 'wmts-capabilities',
          url: 'https://tiles.maps.eox.at/wmts/1.0.0/WMTSCapabilities.xml',
          layer: 's2cloudless-2021_3857',
          attributions: (layer) => layer.Title, // default xml field is "Abstract";
          // attributions: 'foobar', // can also be overridden with string
        },
      },
      // Tile layer with WMTS source
      {
        title: 'WMTS',
        type: 'tile',
        visible: false,
        source: {
          type: 'wmts',
          url: 'https://tiles.maps.eox.at/wmts',
          layer: 's2cloudless-2021_3857',
          matrixSet: 'GoogleMapsCompatible',
          format: 'image/jpeg',
          style: 'default',
        },
      },
      // Tile layer with WMS source
      {
        title: 'Tile WMS',
        type: 'tile',
        visible: false,
        source: {
          type: 'tile-wms',
          url: 'https://ahocevar.com/geoserver/wms',
          layers: 'topp:states',
          extParams: {TILED: true},
          serverType: 'geoserver',
        },
      },
      {
        title: 'Image WMS',
        type: 'image',
        visible: false,
        source: {
          type: 'image-wms',
          url: 'https://ahocevar.com/geoserver/wms',
          layers: 'topp:states',
          serverType: 'geoserver',
          format: 'image/png', // default
          version: '1.3.0', // default
        },
      },
      {
        title: 'WFS',
        type: 'vector',
        visible: false,
        renderMode: 'image',
        source: {
          type: 'vector',
          features: [],
          url(extent, resolution, projection) {
            return 'https://ahocevar.com/geoserver/wfs?service=WFS&' +
              'version=1.1.0&request=GetFeature&typename=osm:water_areas&' +
              'outputFormat=application/json&srsname=' + projection + '&' +
              'bbox=' + extent.join(',') + ',' + projection
          },
          // strategyFactory() {
            //   return loadingBBox
          // },
        },
      },
      // Countries vector layer
      // loads GeoJSON data from remote server
      {
        title: 'Vector',
        type: 'vector',
        visible: false,
        source: {
          type: 'vector',
          url: 'https://openlayers.org/en/latest/examples/data/geojson/countries.geojson',
        },
        style: [
          {
            fill: {
              color: [255, 255, 255, 0.5],
            },
            stroke: {
              color: '#219e46',
              width: 2,
            },
            text: {
              text: '\uf041',
              font: '24px FontAwesome',
              fill: {
                color: '#2355af',
              },
              stroke: {
                color: 'white',
              },
            },
          },
        ],
      },
      {
        title: 'Vector tiles',
        type: 'vector-tile',
        visible: false,
        source: {
          type: 'vector-tile',
          url: 'https://basemaps.arcgis.com/v1/arcgis/rest/services/World_Basemap/VectorTileServer/tile/{z}/{y}/{x}.pbf',
        },
        style: [
          {
            stroke: {
              width: 2,
              color: '#2979ff',
            },
            circle: {
              radius: 5,
              stroke: {
                width: 1.5,
                color: '#2979ff',
              },
            },
          },
        ],
      },
      {
        title: 'XYZ',
        type: 'tile',
        visible: false,
        source: {
          type: 'xyz',
          url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png',
        },
      },
    ],
  }),
}
</script>

# Vector layer and fill color function

<template>
  <map-basic
    :zoom="zoom"
    :center="center"
    :layers="layers"
    style="height: 100%; width: 100%;"
  >
  </map-basic>
</template>

<script>
import MapBasic from '@eox/map-basic'

export default {
  components: {
    MapBasic,
  },
  data: function() {
    return {
      zoom: 14,
      center: [1731756, 6228616],
      layers: [
        {
          type: 'group',
          layers: [
            // background layer
            {
              id: 'terrain',
              title: 'Terrain Light',
              type: 'tile',
              visible: true,
              source: {
                type: 'wmts-capabilities',
                url: 'https://tiles.maps.eox.at/wmts/1.0.0/WMTSCapabilities.xml',
                layer: 'terrain-light',
                matrixSet: 'WGS84',
              },
            },
            // vector layer with dynamic styling
            {
              id: 'parcels-dynamic',
              title: 'Agricultural Parcels',
              type: 'vector-tile',
              visible: true,
              source: {
                type: 'vector-tile',
                url: 'https://pg-tileserv.demo.hub.eox.at/demo.agri_data_declaration/{z}/{x}/{y}.pbf',
              },
              style: this.parcelStyleFunc,
              declutter: true,
            },
            // vector layer with static styling
            {
              id: 'parcels-static',
              title: 'Agricultural Parcels',
              type: 'vector-tile',
              visible: true,
              source: {
                type: 'vector-tile',
                url: 'https://pg-tileserv.demo.hub.eox.at/demo.agri_data_declaration/{z}/{x}/{y}.pbf',
              },
              style: [
                {
                  stroke: {
                    color: 'blue',
                    width: 3,
                    lineDash: [5, 5]
                  },
                },
              ],
            },
          ]
        },
      ],
    }
  },
  methods: {
    parcelStyleFunc(feature) {
      let fillColor = '#9999';
      if (feature.get('crop_id') < 90) {
        fillColor = '#ffff0099';
      }
      else if (feature.get('crop_id') < 120) {
        fillColor = '#fcba03';
      }
      else if (feature.get('crop_id') < 150) {
        fillColor = '#0ffc03';
      }
      const parcelStyle = {
        strokeColor: '#000',
        strokeWidth: 1,
        fillColor,
        textFillColor: "black",
        textStrokeColor: "white",
        textStrokeWidth: 3,
        textOverflow: true,
        text: `${feature.get('parcel_id')}`,
      };
      return parcelStyle;
    },
  },
}
</script>

# Map with a custom feature

<template>
  <map-basic
    :zoom="zoom"
    :center="center"
    showCenter
    :mapConfig="{
      'data-projection': 'EPSG:4326',
    }"
    :viewConfig="{
      'projection': 'EPSG:3857',
    }"
    :layers="layers"
    :features="features"
    style="height: 100%; width: 100%;"
  />
</template>

<script>
import MapBasic from '@eox/map-basic'

export default {
  components: {
    MapBasic
  },
  data: () => ({
    zoom: 16,
    center: [16.3602, 48.2190],
    layers: [
      {
        id: 'osm',
        title: 'Open Street Map',
        type: 'tile',
        visible: true,
        source: {
          type: 'wmts-capabilities',
          url: 'https://tiles.maps.eox.at/wmts/1.0.0/WMTSCapabilities.xml',
          layer: 'osm_3857',
          matrixSet: 'GoogleMapsCompatible',
        },
      },
    ],
    features: [
      {
        properties: {
          foo: 'bar'
        },
        coordinates: [
          16.3602,
          48.2188,
        ],
        icon: {
          src: 'https://eox.at/EOX-POI.png',
          scale: 0.3,
          anchor: [0.5, 1],
          size: [500, 258]
        }
      },
    ],
  })
}
</script>

# Map created from Mapbox style document

<template>
  <map-basic
    :zoom="zoom"
    :center="center"
    :layers="layers"
    showCenter
    style="height: 100%; width: 100%;"
    @featuresClicked="featuresClicked"
    ref='mapbasic'
  >
  </map-basic>
</template>

<script>
import MapBasic from '@eox/map-basic'

export default {
  components: {
    MapBasic
  },
  data: () => ({
    zoom: 13,
    center: [1783019, 6148052],
    layers: [
      {
        id: 'mapbox',
        type: 'group',
        'mapbox-style-layers': [
          'https://eox-a.github.io/elements/style_declarations.json',
        ],
      },
    ],
  }),
  methods: {
    featuresClicked(ftrs) {
      ftrs.forEach((item) => {
        console.log(item.feature.properties_);
      });
    },
  },
}
</script>

# Highlighting features by attribute

<template>
  <map-basic
    :zoom="zoom"
    :center="center"
    :layers="allLayers"
    style="height: 100%; width: 100%;"
    ref='mapbasic'
  >
  <v-btn @click="btnclicked">
    HIGHLIGHT SOME FEATURES
  </v-btn>
  </map-basic>
</template>

<script>
import MapBasic from '@eox/map-basic'
import { Style, Stroke, Fill } from 'ol/style'; // eslint-disable-line

export default {
  components: {
    MapBasic
  },
  data: () => ({
    zoom: 13,
    center: [1783019, 6148052],
    allLayers: [
      {
        id: 'terrain-light',
        title: 'Terrain Light',
        type: 'tile',
        source: {
          type: 'wmts-capabilities',
          url: 'https://tiles.maps.eox.at/wmts/1.0.0/WMTSCapabilities.xml',
          layer: 'terrain-light',
          matrixSet: 'WGS84',

        },
      },
      {
        id: 'declarations',
        title: 'Declarations',
        type: 'vector-tile',
        source: {
          type: 'vector-tile',
          url: 'https://pg-tileserv.demo.hub.eox.at/demo.agri_data_declaration/{z}/{x}/{y}.pbf',
        },
        style: [
          {
            stroke: {
              color: 'black',
              width: 1,
            },
            fill: {
              color: 'blue',
            },
          }
        ],
      },
    ],
  }),
  computed: {
    basicStyle() {
      return new Style({
        stroke: new Stroke({
          color: 'black',
          width: 2,
        }),
        fill: new Fill({
          color: 'yellow',
        }),
      });
    },
  },
  methods: {
    btnclicked() {
      this.highlighted = {SNAR_BEZEICHNUNG: 'KÖRNERMAIS'};
      const layer = this.$refs.mapbasic.$refs.declarations[0].$children[0].$layer;
      // update style
      layer.setStyle(this.featureStyle);
    },
    featureStyle(feature) {
      const highlightedArr = Array.isArray(this.highlighted) ? this.highlighted : [this.highlighted];
      let style = undefined; // hides the feature by default
      highlightedArr.forEach((obj) => {
        Object.keys(obj).forEach((key) => {
          if (feature.properties_[key] === obj[key]) {
            style = this.basicStyle; // shows the feature with matching key/val
          }
        });
      });
      return style;
    },
  },
}
</script>

# Vector layer with tooltips

<template>
  <map-basic
    :zoom="zoom"
    :center="center"
    :layers="layers"
    style="height: 100%; width: 100%;"
  >
    <template slot-scope="{hoverFeature}">
      <component v-if="hoverFeature" :is="'vl-overlay'"
        :position="hoverFeature.coordinate" :offset="[7, 7]" :positioning="hoverFeature.tooltip.left ? 'top-right' : 'top-left'">
        <template slot-scope="scope">
          <div class="map-tooltip">
            <v-tooltip v-model="showTooltip" attach=".map-tooltip">
              <ul>
                <li>
                  position: {{ scope.position }}
                </li>
                <li>
                  id: {{ hoverFeature.feature.get("id") }}
                </li>
              </ul>
            </v-tooltip>
          </div>
        </template>
      </component>
    </template>
  </map-basic>
</template>

<script>
import MapBasic from '@eox/map-basic'
import { VTooltip } from 'vuetify/lib'

export default {
  components: {
    MapBasic,
    VTooltip,
  },
  data: function() {
    return {
      zoom: 14,
      center: [1731756, 6228616],
      showTooltip: true,
      layers: [
        {
          type: 'group',
          layers: [
            {
              id: 'terrain',
              title: 'Terrain Light',
              type: 'tile',
              visible: true,
              source: {
                type: 'wmts-capabilities',
                url: 'https://tiles.maps.eox.at/wmts/1.0.0/WMTSCapabilities.xml',
                layer: 'terrain-light',
                matrixSet: 'WGS84',
              },
            },
            {
              id: 'parcels-static',
              title: 'Agricultural Parcels',
              type: 'vector-tile',
              visible: true,
              source: {
                type: 'vector-tile',
                url: 'https://pg-tileserv.demo.hub.eox.at/demo.agri_data_declaration/{z}/{x}/{y}.pbf',
              },
              style: [
                {
                  stroke: {
                    color: 'black',
                    width: 1,
                  },
                  fill: {
                    color: 'grey',
                  },
                },
              ],
            },
          ]
        },
      ],
    }
  },
  methods: {
  },
}
</script>

# GeoTiff Example

<template>
  <map-basic
    ref="map"
    :zoom.sync="zoom"
    :center.sync="center"
    :layers="layers"
    :mapConfig="{
      'data-projection': 'EPSG:32630',
    }"
    :viewConfig="{
      'projection': 'EPSG:32630',
      'min-zoom': 13,
      'max-zoom': 15,
    }"
    style="height: 100%; width: 100%;"
  />
</template>

<script>
import MapBasic from '@eox/map-basic';

export default {
  components: {
    MapBasic,
  },
  data: () => ({
    zoom: 14,
    center: [307260, 4390400],
  }),
  computed: {
    layers() {
      return [
        {
          type: 'webgl',
          source: {
            type: 'geotiff',
            sources: [
              {
                url:
                  'https://s2gm-gmv-eox-samples.s3.eu-central-1.amazonaws.com/utm/30N/monthly/2021/06/no_brdf/5/1014/31.tif',
                bands: [1, 2, 3],
                min: 50,
                nodata: 0,
                max: 3100,
              },
            ],
            attribution: "<a href='https://s2maps.eu'>Sentinel-2 cloudless</a> by <a href='https://eox.at/'>EOX IT Services GmbH</a> (Contains modified Copernicus Sentinel data 2019)",
          },
        },
      ];
    },
  },
};
</script>

# GeoTiff Example With Styling

<template>
  <map-basic
    ref="map"
    :zoom.sync="zoom"
    :center.sync="center"
    :layers="layers"
    :mapConfig="{
      'data-projection': 'EPSG:4326',
    }"
    style="height: 100%; width: 100%;"
  >
    <div class="sliderContainer">
      <div
        v-for="(item, key) in Object.entries(styleVariables)"
        :key="key"
      >
        <span style="text-transform: capitalize">{{item[0]}}: {{item[1]}}</span><br />
        <input
          type="range"
          min="-0.5"
          max="0.5"
          step="0.01"
          :value="styleVariables[item[0]]"
          @input="(evt) => styleVariables[item[0]] = parseFloat(evt.target.value)"
        />
      </div>
    </div>
  </map-basic>
</template>

<script>
import MapBasic from '@eox/map-basic';

export default {
  components: {
    MapBasic,
  },
  data: () => ({
    zoom: 10,
    center: [16.97, 48 ],
    ndvi: [
      '/',
      ['-', ['band', 2], ['band', 1]],
      ['+', ['band', 2], ['band', 1]],
    ],
    ndwi: [
      '/',
      ['-', ['band', 3], ['band', 1]],
      ['+', ['band', 3], ['band', 1]],
    ],
    styleVariables: {
      exposure: 0,
      contrast: 0,
      saturation: 0,
    },
    baseLayers: [
      {
        type: 'tile',
        source: {
          type: 'wmts-capabilities',
          url: 'https://tiles.maps.eox.at/wmts/1.0.0/WMTSCapabilities.xml',
          layer: 'terrain-light_3857',
        },
      },
    ],
  }),
  computed: {
    layers() {
      return [
        ...this.baseLayers,
        {
          type: 'webgl',
          source: {
            type: 'geotiff',
            sources: [
              {
                url: 'https://s2downloads.eox.at/demo/Sentinel-2/3857/R10m.tif',
                bands: [3, 4],
                min: 0,
                nodata: 0,
                max: 65535,
              },
              {
                url: 'https://s2downloads.eox.at/demo/Sentinel-2/3857/R60m.tif',
                bands: [9],
                min: 0,
                nodata: 0,
                max: 65535,
              },
            ],
            attribution: "<a href='https://s2maps.eu'>Sentinel-2 cloudless</a> by <a href='https://eox.at/'>EOX IT Services GmbH</a> (Contains modified Copernicus Sentinel data 2019)",
          },
          style: {
            color: [
              'color',
              // red: | NDVI - NDWI |
              ['*', 255, ['abs', ['-', this.ndvi, this.ndwi]]],
              // green: NDVI
              ['*', 255, this.ndvi],
              // blue: NDWI
              ['*', 255, this.ndwi],
              // alpha
              ['band', 4],
            ],
            exposure: ['var', 'exposure'],
            contrast: ['var', 'contrast'],
            saturation: ['var', 'saturation'],
            variables: this.styleVariables,
          },
        },
      ];
    },
  },
};
</script>

<style scoped>
.sliderContainer {
  position: absolute;
  top: 0;
  right: 0;
  z-index: 9999;
  background: #fffc;
  padding: 20px;
  border-radius: 0 0 0 5px;
}
</style>