¡gratis! Mapa de mosaico sin conexión de descarga de paquete de front-end puro

Es sin palabras. El mapa de mosaicos es obviamente abierto y gratuito. Hay sitios web y programas que cobran tarifas. De hecho, también hay algunos programas conscientes que descargan mapas sin conexión de forma gratuita, pero debido a que las solicitudes de descarga de mosaicos son demasiado frecuentes, se congela al abrir el mapa y otros servidores lo recuerdan.

1. Proyección de Mercator

Es aplanar a la fuerza la textura que estaba originalmente en la tierra (asumiendo que es una esfera) en una textura rectangular, y luego hacer una conversión basada en la latitud y la longitud y las coordenadas xy

v2-00991c24c72667fccdab88740ad108e4_b.jpg

2. Mapa de mosaicos

De acuerdo con el nivel de zoom del mapa, correspondiente a diferentes tamaños de mapa, dividido en diferentes bloques según la proyección de Mercator, es el mapa de mosaico correspondiente, que se puede convertir de acuerdo con la siguiente fórmula para calcular en qué mosaico se encuentra la coordenada

function lon2tilex(lon, zoom) {
    return Math.floor(((lon + 180) / 360) * Math.pow(2, zoom));
  }
  function lat2tiley(lat, zoom) {
    return Math.floor(
      ((1 -
        Math.log(Math.tan((lat * Math.PI) / 180) + 1 / Math.cos((lat * Math.PI) / 180)) / Math.PI) /
        2) *
        Math.pow(2, zoom)
    );
  }

imagen.png

3. Bibliotecas utilizadas

  • jszipSe utiliza para escribir el mapa de mosaicos en el paquete comprimido y descargarlo uniformemente

  • 地图APIVaya al sitio web oficial para registrar una clave usted mismo. Aquí tomo el mapa de Gaode como ejemplo. Si es un mosaico de Baidu, Tencent y otros mapas, es mejor usar su mapa para evitar el problema de la latitud y conversión de longitud Nota: tanto Gaode como Tencent usan Marte La latitud y la longitud de gcj las establece el propio Baidu.

  • Mapa de tesela sin conexión relacionado Abrir referencia de dirección

www.cnblogs.com/feiquan/p/1… blog.csdn.net/qq_19689967…

4. Pasos de implementación

1. Posicionamiento, confirme el rango en el mapa

      drawRect() {
        this.clearRect();
        this.mouseTool.rectangle({
          fillColor: '#1e90ff',
          fillOpacity: 0.2,
          strokeColor: '#1e90ff'
        });
        this.mouseTool.on('draw', e => {
          this.rect = e.obj;
          this.mouseTool.close(false);
          this.rectangleEditor = new AMap.RectangleEditor(this.map, this.rect);

          this.rectangleEditor.open();
        });
      },

2. Calcule la cantidad de mosaicos según el rango de nivel de zoom

//获取某个等级的瓦片数量
getTileCount(zoom) {
        let b = this.rect.getOptions().bounds;
        let x = lon2tilex(b.northEast.lng, zoom);
        let y = lat2tiley(b.northEast.lat, zoom);

        let x1 = lon2tilex(b.southWest.lng, zoom);
        let y1 = lat2tiley(b.southWest.lat, zoom);

        let startx = Math.min(x, x1),
          endx = Math.max(x, x1);
        let starty = Math.min(y, y1),
          endy = Math.max(y, y1);

        return (endx - startx + 1) * (endy - starty + 1);
      },
      //获取不同缩放等级的数量
       getTileLayer() {
        let b = this.rect.getOptions().bounds;
        let list = [];
        for (let k in this.zoomMap) {
          if (this.zoomMap[k]) {
            let z = parseInt(k);
            let x = lon2tilex(b.northEast.lng, z);
            let y = lat2tiley(b.northEast.lat, z);

            let x1 = lon2tilex(b.southWest.lng, z);
            let y1 = lat2tiley(b.southWest.lat, z);

            let startx = Math.min(x, x1),
              endx = Math.max(x, x1);
            let starty = Math.min(y, y1),
              endy = Math.max(y, y1);

            for (let i = startx; i <= endx; i++) {
              for (let j = starty; j <= endy; j++) {
                list.push({ x: i, y: j, z });
              }
            }
          }
        }
        return list;
      },

3. De acuerdo con el nivel de zoom seleccionado, las reglas de escritura de archivos, el tipo de mosaico, descarga y escribe el paquete zip

Mapa de Gaode recursos de mapa de mosaico abierto

styles:[
        { label: '普通地图', value: '7' },
        { label: '卫星地图', value: '6' },
        { label: '路况地图', value: '8' }
      ]
      `http://wprd04.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=${this.selectStyle ||
              7}&x=${x}&y=${y}&z=${z}`

Obtenga el mapa de mosaicos del mapa de Gaode, la descarga es una imagen png de 256x256, si necesita escribir un archivo diferente en el directorio, cámbielo usted mismo, preste atención tiles/${z}/${y}/${x}.pngal tiempo de intervalo setTimeout antes de solicitar el siguiente, para evitar demasiado frecuente solicitudes, que están restringidas por el mapa de Gaode.

writeBlob(x, y, z) {
        return new Promise(resolve => {
          getBlob(
            `http://wprd04.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=${this.selectStyle ||
              7}&x=${x}&y=${y}&z=${z}`,
            res => {
              this.theZip.file(`tiles/${z}/${y}/${x}.png`, res);
              setTimeout(() => {
                resolve();
              }, 10);
            }
          );
        });
      },

Primero coloque un paquete zip en la carpeta pública, obtenga el paquete zip y luego escriba el mosaico a través de JSZip


download() {
        let tiles = this.getTileLayer();
        this.$msgbox({
          title: '是否下载?',
          message: `大概需要${(tiles.length * 0.1).toFixed(2)}秒`,
          showConfirmButton: true,
          showCancelButton: true
        }).then(() => {
          this.isShow = false;
          this.isLoading = true;
          this.process = 0;
          //写入事先准备好的瓦片地图zip包
          getBlob('tiles.zip', res => {
            JSZip.loadAsync(res).then(async zip => {
              this.theZip = zip;

              for (let i = 0; i < tiles.length; i++) {
                let item = tiles[i];
                await this.writeBlob(item.x, item.y, item.z);
                this.process = ((i / tiles.length) * 100).toFixed(2);
              }
              //写入相关信息
              this.theZip.file(
                `README.md`,
                `# 文件夹目录\n${this.rule}\n\n# 当前地图瓦片 \n 范围:${this.rectLngLat}\n中心点:${this.centerLnglat}`
              );
              this.theZip.generateAsync({ type: 'blob' }).then(blob => {
                saveAs(blob, '离线高德地图瓦片' + new Date().format('yyyyMMddhhmmss') + '.zip');
              });
              this.isLoading = false;
            });
          });
        });
      },

dirección de código completo

github.com/xiaolidan00…

5. Usa mapas de mosaicos

dibujar un rango

Sogou captura de pantalla 20230421212506.png

Luego seleccione el nivel de zoom de descarga y luego espere el paquete zip descargado

Sogou captura de pantalla 20230421212924.png

Directorio del paquete zip: README.md es la información relevante al descargar

README.md
# 文件夹目录
tiles/[z]/[y]/[x].png

# 当前地图瓦片 
 范围:113.353114,23.02803;113.43286,23.074142
中心点:113.392987,23.051086 

Correspondiente a la dirección del mosaico, descomprima los mosaicos del paquete zip y colóquelo en una dirección de acceso

mosaicos/z/y/x/1234.png

Use el mapa de Gaode sin conexión maps.js para verificar el mapa de mosaico descargado

mapBox, mapTalks, Leaflet y otras verificaciones de mapas fuera de línea de uso común están bien, pero todas tienen un problema común, es decir, al cargar un mapa en mosaico, la tarjeta es enorme y habrá una situación en la que faltará una pieza sin razón (es decir, si abre una carpeta con imágenes, es rebelde. cargado). Luego elegí usar directamente el mapa de Gaode sin conexión maps.js, ¡y la fluidez supera a los demás! ¡Y también puedes usar la API de esos mapas de Gaode! ¡Esto es simplemente excepcional!

Aviso:

  1. getTileUrlDirección del mapa de mosaicos, debe usar la función, cadena directa, el https predeterminado es 404

  2. No use defaultLayer para cargar el mapa, no podrá cargar el mapa de mosaicos, debe superponer una capa

  3. Para evitar cargar espacios en blanco, asegúrese de limitar los zooms de rango de zoom y los límites de orientación de los límites

Dirección del archivo: public/offlineMap.html puede probar y verificar el mapa sin conexión


 <div id="container"></div>
    <script>
      function initMap() {
        var map = new AMap.Map('container', {
          zoom: 15,
          //下载范围的中心点
          center: [113.392987, 23.051086],
          zooms: [14, 15]
        });
        //一定要全地址,瓦片不走相对地址的
        let tileUrl = 'http://127.0.0.1:5500/public/tiles/[z]/[y]/[x].png';
        let xyzLayer = new AMap.TileLayer({
          // 瓦片地图地址,一定要用function,直接字符串,默认走https就404了
          getTileUrl: function (x, y, z) {
            return tileUrl.replace('[x]', x).replace('[y]', y).replace('[z]', z);
          },
          //限制缩放等级为下载的等级
          zooms: [14, 15],
          zIndex: 10,
          tileSize: 256
        });
        map.add(xyzLayer);
        let b = [113.353114, 23.02803, 113.43286, 23.074142];
        //限制范围,避免加载到空瓦片
        let bounds = new AMap.Bounds([b[2], b[3]], [b[0], b[1]]);

        map.setBounds(bounds);
        map.setLimitBounds(bounds);
      }
    </script>

Efecto

imagen.png

  • La imagen de arriba es el mapa de mosaicos del mapa de Gaode, y la imagen de abajo es el mapa de Gaode original. Puede ver que los caracteres en él son más grandes que el mapa vectorial de Gaode que se usa generalmente, y los colores también son diferentes.

imagen.png

En la actualidad, los estilos de mapas de mosaicos abiertos para AutoNavi son solo satélite, tráfico y común. Los estilos no pueden satisfacer sus necesidades. En este momento, solo puede cambiar manualmente los mosaicos del mapa a través del atributo de filtro a través de css manual. Pero esto tiene un efecto secundario, es decir, otros elementos, como el rectángulo cargado en el mapa, también se modifican mágicamente, por lo que debe tener cuidado al cambiar el estilo.

.amap-layer {
        filter: invert(100%);
      }

Sogou captura de pantalla 20230421220531.png

Si tiene una interfaz de usuario de paciente, puede cambiar manualmente el estilo de la interfaz de usuario en lotes (siempre que realmente no tenga muchos mosaicos, de lo contrario, la interfaz de usuario le disparará a la cabeza)

Supongo que te gusta

Origin juejin.im/post/7224503809890975801
Recomendado
Clasificación