1

我正在使用 Vue2-Leaflet 的 L.CRS.Simple 开发地图应用程序,并且我想按照Leaflet 文档中的说明反转地图的 y 轴。我在这里找到了一个类似的问题,看来我的问题是一样的,所以我的问题是:我如何集成相同的解决方案来反转 y 轴但使用 vue2-leaflet 包?

这是我的代码:

<template>
<body>
  <div>
    <li v-for="(message, index) in messageList" :item="message" :key="index">
      {{ message }}
    </li>
  </div>
  <l-map class="map" ref="map" :min-zoom="minZoom" :crs="crs">
    <l-tile-layer :url="url"></l-tile-layer>
    <!-- <l-image-overlay :url="url" :bounds="bounds" /> -->
    <l-grid-layer class="grid" :tile-component="tileComponent"></l-grid-layer>
    <l-marker v-for="star in stars" :key="star.id" :lat-lng="star">
      <l-icon
        :icon-size="[25, 25]"
        icon-url="https://image.flaticon.com/icons/png/512/304/304378.png"
      ></l-icon>
      <!-- <l-icon :icon-size="[32, 37]" icon-url="/images/star.png"></l-icon> -->
      <l-popup class="popup">
        <em class="popup-bold">Name: </em>{{ star.name }}<br>
        <em class="popup-bold">Longitud: </em>{{ star.lng }}<br>
        <em class="popup-bold">Latitud: </em>-{{ star.lat }}<br>
      </l-popup>
    </l-marker>
  </l-map>  
</body>
</template>

<script>
import L from "leaflet";
import { CRS } from "leaflet";
import {
  LMap,
  LTileLayer,
  LMarker,
  LImageOverlay,
  LPopup,
  LPolyline,
  LIcon,
  LGridLayer
} from "vue2-leaflet";

export default {
  name: "Map",
  components: {
    LMap,
    LTileLayer,
    LMarker,
    LImageOverlay,
    LPopup,
    LPolyline,
    LIcon,
    LGridLayer
  },
  props: {
    msg: {
      type: String
    }
  },
  data() {
    return {
      url: "https://wallpaperboat.com/wp-content/uploads/2019/10/high-resolution-black-background-08.jpg",
      bounds: [
        [-2600, -2700],[1000, 3000]
      ],
      minZoom: 0.5,
      crs: L.CRS.Simple,
      stars: [],
      messageList: [],
      tileComponent: {
        name: "tile-component",
        props: {
          coords: {
            type: Object,
            required: true
          }
        },
        template: '<div style="outline:1px solid #38c9d386; height:40rem; width:40rem;"></div>'
      }
    };
  },
  watch: {
    msg: function() {
      this.messageList.push(this.msg);
    }
  },
  mounted() {
    this.$refs.map.mapObject.setView([526, -68], 1);

    this.$http
      .get("https://pyet2m3rzl.execute-api.us-east-1.amazonaws.com/test/outscapebackend")
      .then(response => {
        return response.json();
      })
      .then(data => {
        const resultArray = [];
        for (let key in data) {
          resultArray.push(data[key]);
        }
        this.stars = resultArray;
      });
  },
  methods: {}
};
</script>

<style scoped>
...
</style>

4

1 回答 1

4

如果我理解这一点,您想要反转所有L.LatLngs 的 Y 坐标,而不仅仅是 tile 坐标(这是TMS用例),以便 Y 坐标在down时增长。换句话说,如果我有类似...

L.marker([0,0]).addTo(map).bindPopup('y=0,x=0', {autoClose:false}).openPopup();
L.marker([100,50]).addTo(map).bindPopup('y=100,x=50', {autoClose:false}).openPopup();

...默认看起来像...

带有默认 L.CRS.Simple 的标记

...但您希望它看起来像...

倒 Y CRS 标记

(如果 Y 坐标首先以 s 的简写形式列出L.LatLng,请重新阅读L.CRS.Simple上解释问题的 Leaflet 教程,以及lon lat lon lat lon)。

关于 Leaflet 内部的一些解释:Leaflet CRS 将LatLng坐标转换为像素坐标。例如,在默认情况下L.CRS.EPSG3857,屏幕 Y 坐标取决于纬度的余弦来获得遍历圆柱投影

由于L.CRS.Simple奇怪的差异,这种翻译也存在。对于数学家来说,Y 坐标会上升,因为这就是笛卡尔平面的工作原理:

笛卡尔坐标系

但是,对于计算机程序员来说,Y 坐标会下降,因为这就是像素在屏幕上的索引方式(至少,这是几十年来的惯例):

像素坐标系

为了解决这个怪癖,Leaflet 实现了仿射变换(考虑到缩放级别的 Leaflet 怪癖),然后L.CRS.Simple使用这样的仿射变换来反转 Y 坐标(所以L.CRS.Simple像笛卡尔平面而不是像素平面一样工作) :

L.CRS.Simple = L.Util.extend({}, L.CRS, {
    projection: L.Projection.LonLat,
    transformation: L.Transformation(1, 0, -1, 0),
    /* snip */

这等效于指定仿射变换矩阵,例如

( 1  0 )
( 0 -1 )

因此,考虑到这一点,您的问题的答案变为“您应该使用自定义仿射变换定义一个新的 CRS,将 1 个«纬度»单位映射到 1 个向下像素”。

此时,您应该阅读有关扩展 Leaflet 类的 Leaflet 教程,但 TL;DR 版本是:

var CRSPixel = L.Util.extend(L.CRS.Simple, {
    transformation: new L.Transformation(1,0,1,0)
});

然后将通过该自定义 CRS 的地图定义为地图的crs选项,一切都应该正常工作。这是一个使用香草传单的工作示例(即 vue-less)

有了这些信息,您应该能够使该技术适应您的 Vue 代码,并注意import所有需要的 Leaflet 位。

于 2020-06-11T08:53:14.620 回答