likes
comments
collection
share

爱与勇气:L7VP 与塞尔达公主有个约定

作者站长头像
站长
· 阅读数 16

万众期待的《塞尔达——王国之泪》发布已经有一段时间了,相信各位小伙伴都已经开始在海拉鲁大陆上探索、解锁神庙了吧。为了让大家更好地享受游戏,我们基于 L7VP 开发了一款塞尔达王国之泪的地图攻略应用。快来扫描下方二维码,开始你的探险之旅吧!

爱与勇气:L7VP 与塞尔达公主有个约定

1. 地图概览

扫描上方二维码即可立即体验塞尔达王国之类收集地图,更多惊喜敬请探索

爱与勇气:L7VP 与塞尔达公主有个约定爱与勇气:L7VP 与塞尔达公主有个约定

爱与勇气:L7VP 与塞尔达公主有个约定

2. 背景

上面的地图是完全基于 L7VP 搭建的。那么什么是 L7VP ?为什么要选择 L7VP 呢?

简单来说 L7VP 是一款地理可视化研发平台,提供丰富的地理可视化效果、洞察分析功能、地图应用搭建工具和开放扩展能力。L7VP 的核心研发目标是提高地理空间智能应用的研发效率,并且可扩展、研发简单快。

基于 L7VP 提供的 SDK 强大能力,研发一个塞尔达收集小地图简直小菜一碟~下面开始一步一步介绍如何基于 L7VP 从 0 到 1 搭建塞尔达王国之泪收集地图,开始之前,先简单设计一个原型:

爱与勇气:L7VP 与塞尔达公主有个约定

3. 数据处理

3.1. 瓦片地图

感谢 TOTK-Interactive-Map 项目的作者提供了王国之泪的天空、陆地、地下全量瓦片图床,瓦片图片按照地图类型/地图缩放层级 z / x / y 坐标的路径存放。对地图瓦片不熟悉的同学可以了解下 Slippy map tilenames

爱与勇气:L7VP 与塞尔达公主有个约定

接着我们利用 jsDelivr 平台 作为 CDN 来加快瓦片图片的下载速度,得到一个瓦片服务的 URL :

https://fastly.jsdelivr.net/gh/Slluxx/TOTK-Interactive-Map@tiles/assets/tiles/{mapType}/{z}/{x}/{y}.png

有了塞尔达的地图服务,现在可以通过 L7VP 快速生成一个在线地图应用了,只需要两步:首先添加塞尔达的瓦片地图数据服务,连续添加天空、陆地、地下三个瓦片数据服务,添加成功后数据集列表可见。

爱与勇气:L7VP 与塞尔达公主有个约定爱与勇气:L7VP 与塞尔达公主有个约定

接着,添加三个瓦片图层把天空、陆地、地下分别添加到地图上去,效果如下:

爱与勇气:L7VP 与塞尔达公主有个约定

3.2. 标记物数据

我们收集整理了王国之泪中神庙、鸟望台、宝箱等标注点位的数据。

爱与勇气:L7VP 与塞尔达公主有个约定

点位标注数据使用的是平面坐标系来表示其位置信息,经过脚本对数据进行坐标系转换、数据平铺等一系列操作后,只需要将数据文件上传到 L7VP 里面,上传数据的目的是为了给资产消费,接下来就是研发资产。

爱与勇气:L7VP 与塞尔达公主有个约定

4. 资产研发

根据原型设计,我们需要自定义研发筛选面板、图层控制器、标记物这三个资产,瓦片图层和地图层级缩放器则使用 L7VP 官方提供的。

4.1. 图层控制器

图层控制器用于控制天空、陆地、地下三个地图的切换,考虑到灵活性,通过配置化的方式,控制组件渲染位置和渲染图层属性,需要注意的是,当地图切换的时候,上一个状态的标记物要通信绘制资产清除掉。整体实现逻辑如下所示

import type { ImplementWidgetProps } from '@antv/li-sdk';
import { useEventPublish, useLayerList } from '@antv/li-sdk';
import type { Properties } from './registerForm';

interface ZeldaLayerControlProps extends Properties, ImplementWidgetProps {}

const ZeldaLayerControl: React.FC<ZeldaLayerControlProps> = (props) => {
  const { position, undergroundLayerId, groundLayerId, skyLayerId } = props;
  const layerList = useLayerList();
  const eventPublisher = useEventPublish();

  const zeldaLayerList = // layerList filter underground,ground,sky

    const handleActiveLayer = (layer) => {
    // zeldaLayer show or hide, setActiveLayerId
  };

  const onClickLayer = (layer, value) => {
    // handleActiveLayer
    // eventPublisher('zelda-layer-change', value);
  };

  return (
    <CustomControl position={position}>
      {zeldaLayerList.map((layer) => (
      <div
        key={layer.id}
        onClick={() => onClickLayer(layer, layer.value)}
        />
    ))}
    </CustomControl>
  );
};

4.2. 标记物

考虑到标记物一般在地图上同时可以展示多个的情况,这里设计为同时可以渲染多个 Marker,点击其中一个 Marker 时,打开气泡信息框,比如展示鸟望台的位置描述信息和通关技巧视频。

const Marks = (props) => {
  const { locations } = props;
  const [activedMark, setActivedMark] = useState();

  const onClickMark = (mark) => {
    setActivedMark(mark);
  };


  return (
    <>
      {locations.map((location) => {
      return (
        <Marker
          lngLat={{ lng: location.longitude, lat: location.latitude }}
          onClick={() => onClickMark(location)}
          />
      );
    })}

      {activedMark !== undefined && (
      <Popup
        lngLat={{ lng: activedMark.longitude, lat: activedMark.latitude }}
        onHide={() => setActivedMark(undefined)}
        >
        <PopupContent location={activedMark} />
      </Popup>
    )}
    </>
  );
};

4.3. 筛选面板

筛选面板需要拿到所有的标记物数据,做分类筛选后,就可以在面板里面渲染出所有的种类了,当点击其中一个就把标记物渲染到地图上。除此之外,当地图切换到天空或陆地到时候,需要监听一下清除选择的标记物。考虑到 PC 端筛选面板的交互和移动端不太一样,我们给 PC 端做一个适配。

import { useDataset, useEventPublish, useEventSubscribe } from '@antv/li-sdk';

const FilterPanel: React.FC<FilterPanelProps> = (props) => {
  const { datasetId, onFilterChange } = props;
  const [dataset] = useDataset(datasetId);
  const [layerType, setLayerType] = useState('ground');
  const eventPublisher = useEventPublish();

  const handleSelected = (selectedGroups) => {
    // onFilterChange
  };

  // 监听图层切换
  useEventSubscribe('zelda-layer-change', (value) => {
    setLayerType(value);
  });


  const renderHeader = () => {
    //...
  };

  const renderMarkList = () => {
    //...
  };

  const renderBody = () => {
    if (showSearchPanel) {
      return <SearchBody />;
    }
    return renderMarkList();
  };

  const content = (
    <>
      {renderHeader()}
      {renderBody()}
    </>
  );

  return isMobile ? (
    <FloatingPanel>
      {content}
    </FloatingPanel>
  ) : content;
};

5. 上架与发布

完成了资产的研发后,将资产打包发布到 npm 上,回到 L7VP 上架研发的资产。

5.1. 资产上架

来到 L7VP 的资产市场,选择上传资产包,填写我们发布到 npm 上包的信息,信息填写完后,导入资产包到 L7VP。考虑到资产的研发不一定都适合发布到 npm 上,可以选择私有镜像的方式导入。

爱与勇气:L7VP 与塞尔达公主有个约定

5.2. 应用发布

完成资产的上架之后,我们就可以在 L7VP 上来完成塞尔达地图应用的配置发布了,在项目中添加上我们研发的资产,给资产绑定上数据信息,完成配置后应用就出来了。

爱与勇气:L7VP 与塞尔达公主有个约定

调试完应用的最终版后,可以点击预览按钮,从配置态切换到应用的预览态,检查应用的最终效果。除此之外,有私有化部署的需求,可以选择导出整个应用的代码。

爱与勇气:L7VP 与塞尔达公主有个约定

6. 最终效果

在移动端的效果如下图所示,支持地图的切换、模糊查询标记点、选择标记点、给去过的地方打标以及复制分享标记点位。各位塞尔达玩家可 🎮 在线体验,整体的 🛠 实现代码 放 Github 了,欢迎来 PR 新增功能~

爱与勇气:L7VP 与塞尔达公主有个约定

通过 L7VP 核心的能力,就这样快速上线了一个塞尔达地图应用,L7VP 在 7 月7 日也正式开源开放了,想了解更多,欢迎线上官网体验。

官网地址:li.antv.antgroup.comGithub: github.com/antvis/L7VP

欢迎加入 L7VP 用户交流群,可加微信 lvisei 备注暗号 L7VP 邀请进群,让我们一起努力,让开源的 L7VP 更加优秀!