分享一个能够在地图上展现表格信息的维格地图小程序。
已实现性能帮忙租房者在租房的时候在地图上进行租房信息比照选出本人心仪的小根据地。
我的项目地址
https://github.com/laboonly/w...
性能介绍
本小程序依据表格外面的出租房信息在地图上显示各个出租房的地位,到公司的路线布局,以及详细信息。帮忙租房的同学更加平面的比照各个出租房的优缺点,找出本人心仪的房子。
应用阐明
请先获取高德api的key高德地图apikey获取,填入src/map.tsx的securityCode和apiKey,启动小程序之后抉择,名称,地址,价格,联系方式对应表格的列,以及填入地图核心(公司)。
上面分享一下开发过程
开发过程
正好在寻找房子的我,想到如果能用维格表小程序管理租房信息可能实现我找到最优房子的需要的地图小组件就好了,顺便介绍一下维格小程序以及高德地图相干方面的开发。
打算需要
需要整顿,我冀望的是小程序可能在地图上依据表格中的地址展现不同的标点,同时点击标点之后展现标点的详细信息,以及各个出租房到公司的间隔。
筹备工作
首先依据官网文档疾速上手开发 | 维格表开发者核心,创立装置好小程序。
第二个是高德地图开发须要在高德开发者核心,注册号账号并且申请key,筹备-入门-教程-地图 JS API | 高德地图API。
第一步加载地图
高德JSAPI,更新了V2.0版本,一番尝试之后发现总是没方法加载胜利,在征询了维格的研发同学之后,才晓得可能是因为维格对iframe反对有问题,于是决定不实用新版本的api应用之前V.14版本的api。
然而v.14版本的api加载不反对npm,于是我借鉴了之前应用此版本api的react-amap开源框架,对于地图加载的局部。源码链接,大略思路就是用JS创立script标签加载。首先在小程序的框架下创立utils/ApiLoader.js文件。复制下面链接中的代码。这里的地图mapStyle我应用了高德的自定义主题,你能够抉择你喜爱的地图主题,或者本人配置.
// 局部代码 const DEFAULT_CONFIG = { v: ‘1.4.0’, // 版本号 hostAndPath: ‘webapi.amap.com/maps’, // 高德api加载地址 key: ‘’, // 高德apikey callback: ‘_amap_init_callback’, // 回调函数 useAmapUI: true // 是否应用高德UI }// 获取脚本链接 getScriptSrc(cfg) { return `${this.protocol}//${cfg.hostAndPath} ?v=${cfg.v}&key=${cfg.key}&callback=${cfg.callback}`; }// 创立脚本js buildScriptTag(src) { const script = document.createElement(‘script’); script.type = ‘text/javascript’; script.async = true; // 异步执行 script.defer = true; // 页面加载完之后执行 script.src = src; return script; }
接下来咱们在小程序工程src中创立map.tsx文件,引入APILoader,并且创立MapComponent函数组件。填入地图配置参数,这里要留神地图挂载的DOM要设置宽高.
import React, { useEffect, useState } from ‘react’;import { Setting } from ‘./setting’;import APILoader from ‘./utils/APILoader’;// 地图平安密钥const securityCode = ‘高德开发者核心申请key附带的平安密钥’;// 高德地图api keyconst apiKey = ‘高德开发者核心申请的key’;//设置地图平安密钥window[‘_AMapSecurityConfig’] = { securityJsCode: securityCode,}export const MapComponent: React.FC = () => { // 组件初始化时,加载 sdk 地图实例 useEffect(() => { new APILoader({ key: apiKey, version: null, protocol: ‘https’ }).load().then(() => { const lnglat = new window.AMap.LngLat(114.031040, 22.624386); const amap = new window.AMap.Map(‘container’, { zoom: 12,//级别 center: lnglat,//中心点坐标 viewMode: ‘3D’,//应用3D视图 mapStyle: ‘amap://styles/b379277160c9c3ce520627ad2e4bd22c’ }); window.amap = amap; }, []); return ( <div style={{ display: ‘flex’, height: ‘100%’ }}> <div style={{ flexGrow: 1, overflow: ‘auto’, padding: ‘0 8px’}}> <div id=“container” style={{ width: ‘100%’, height: ‘100%’ }}> </div> <Setting /> </div> );};
批改小程序index.tsx的默认代码.
import { initializeWidget } from '@vikadata/widget-sdk';import { MapComponent } from './map';initializeWidget(MapComponent, process.env.WIDGET_PACKAGE_ID!);
接下来咱们关上维格小程序开发的网页就能够看到地图曾经加载好了。
地图加载好了之后,接下来咱们须要依据表格中的地址创立好地图标点。
首先在维格表中创立好名称,地址,优缺点,价格,联系方式等列,填入本人的数据。
这里咱们须要应用到两个插件,地图编码插件geocoder,高德官网UI库,在utils上面新建commons.js。实现加载插件代码。同样思路的还有后续的路线布局插件加载。
// 加载高德地图地图插件function loadAmapUI() { return new Promise<object>(resolve => { window.AMapUI.loadUI(['overlay/SimpleMarker'], (SimpleMarker: any) => { resolve(SimpleMarker); }) })}/ 加载高德地图地图编码插件function loadGeocoder() { return new Promise<object>(resolve => { window.AMap.plugin('AMap.Geocoder', () => { const geocoder = new window.AMap.Geocoder({ // city 指定进行编码查问的城市,反对传入城市名、adcode 和 citycode city: '全国' }); resolve(geocoder); }); });}
因为这些插件以及高德地图api的加载是异步的所以咱们将这些性能与地图上的性能离开,将之前的地图挂载元素分成mapcontent的小组件,在src中创立components/mapcontent,并且依据维格小程序官网api批改src/seting.tsx. 而后应用useCloudStorage来获取用户设置名称地址等,对应的列的id。而后应用record.getCellValue来获取对应的值。接下来依据这个值通过下面提失去geocoder插件依据地址查问对应点的坐标值,最初应用高德AMapUI创立对应地址的标点。
mapcontent/index.tsx
// 以下是局部代码残缺源码请在github查看import React, { useState, useEffect } from 'react';import { useCloudStorage, useRecords } from '@vikadata/widget-sdk';import { getLocationAsync, creatTransfer } from '../../utils/common';export const MapContent: React.FC<mapContentProps> = ({ pluginStatus }) => { // 获取表格视图ID const [viewId] = useCloudStorage<string>('selectedViewId'); // 获取所有行的信息 const records = useRecords(viewId); // 解决完的表格信息 const [recordsData, setRecordsdata] = useState<any>(); // 名称 const [titleId] = useCloudStorage<string>('selectedtitleId'); // 地址 const [addressId] = useCloudStorage<string>('selectedAddressId'); // 优缺点 const [houseInfoId] = useCloudStorage<string>('selectedHouseInfoId'); // 价格 const [priceId] = useCloudStorage<string>('selectPrice'); // 联系方式 const [contactId] = useCloudStorage<string>('selectContact'); // 地图核心地址 const [mapCenter] = useCloudStorage<string>('mapCenter'); // 地址解决 useEffect(function getAddressList() { // 获取表格所有地址 const recordsData: any[] = records .map(record => { return { title: record.getCellValue(titleId), address: record.getCellValue(addressId), info: record.getCellValue(houseInfoId), price: record.getCellValue(priceId), contact: record.getCellValue(contactId) } }); setRecordsdata(recordsData); },[records, titleId, addressId, houseInfoId, priceId, contactId]); // 依据表格设置所有地图点 useEffect(function drawAddress() { console.log('pluginStatus', pluginStatus); if (!pluginStatus || !recordsData || !mapCenterLocation) { return; } markAddress(recordsData, markersLayer, mapCenterLocation, informationRef); }, [recordsData, mapCenterLocation, pluginStatus]); /* 创立标记点 record: 标点信息 markerConfig: 标点参数配置 transfer: 创立门路对象 informationRef: 信息窗体DOM援用 */ function creatMarker( record: any, markerConfig: markConfig, mapCenterLocation?: locationType, informationRef?: any, ) { const marker = new window.SimpleMarker({ ...markerConfig, //...其余Marker选项...,不包含content map: window.amap, clickable: true, position: [record.location.lng, record.location.lat] }); if(mapCenterLocation) { marker.on('click', () => { setHouseinfo(record); const infoWindow = new window.AMap.InfoWindow({ content: informationRef.current.innerHTML, //传入 dom 对象,或者 html 字符串 offset: new window.AMap.Pixel(0, -40), closeWhenClickMap: true, // 点击地图敞开 autoMove: true }); creatTransfer([mapCenterLocation.lng, mapCenterLocation.lat], [record.location.lng, record.location.lat]); infoWindow.open(window.amap, [record.location.lng, record.location.lat]); }); } return marker; } /* 依据地址搜寻减少marker点 recordsData: 表格数据 markersLayer: 之前曾经创立的marker图层 setHouseinfo: 设置标点信息函数 mapCenterLocation: 中心点坐标 informationRef: 信息窗口DOM */ async function markAddress( recordsData: Array<any>, markersLayer: Array<any>, mapCenterLocation: locationType, informationRef: any, ) { if(markersLayer) { window.amap.remove(markersLayer); } const asyncRecords = recordsData.map(record => getLocationAsync(record)); const Records = await Promise.all(asyncRecords); const markers = Records.map((record: any) => { return creatMarker(record, homeMarkerConfig, mapCenterLocation, informationRef); }); setMakerslayer(markers); } return ( <div style={{ width: '100%', height: '100%' }}> <div id="container" style={{ width: '100%', height: '100%' }}> </div> </div> );});
另外咱们须要在setting.tsx外面设置名称,地址等信念对应的列。通过useCloudStorage保留。应用小程序官网的FieldPicker组件抉择对应的字段获取ID。
// 以下是局部代码残缺源码请在github查看export const Setting: React.FC = () => { const [isSettingOpened] = useSettingsButton(); // 名称 const [titleId, settitleId] = useCloudStorage<string>('selectedtitleId'); // 地址 const [addressId, setAddressId] = useCloudStorage<string>('selectedAddressId'); // 优缺点 const [houseInfoId, setHouseInfoId] = useCloudStorage<string>('selectedHouseInfoId'); // 价格 const [priceId, setPriceId] = useCloudStorage<string>('selectPrice'); // 联系方式 const [contactId, setContactId] = useCloudStorage<string>('selectContact'); return isSettingOpened ? ( <div style={{ flexShrink: 0, width: '300px', borderLeft: 'solid 1px gainsboro'}}> <h1 style={{ paddingLeft: "5px", marginBottom: 0 }}>设置</h1> <div style={{ display: 'flex', height: '100%' }}> <div style={{ flexGrow: 1, overflow: 'auto'}}> <Box padding="30px 10px 60px 10px" borderBottom="2px solid lightgrey" > <FormItem label="View" > <ViewPicker viewId={viewId} onChange={option => setViewId(option.value)} /> </FormItem> <FormItem label="名称"> <FieldPicker viewId={viewId} fieldId={titleId} onChange={option => settitleId(option.value)} /> </FormItem> <FormItem label="地址"> <FieldPicker viewId={viewId} fieldId={addressId} onChange={option => setAddressId(option.value)} /> </FormItem> <FormItem label="优缺点"> <FieldPicker viewId={viewId} fieldId={houseInfoId} onChange={option => setHouseInfoId(option.value)} /> </FormItem> <FormItem label="价格"> <FieldPicker viewId={viewId} fieldId={priceId} onChange={option => setPriceId(option.value)} /> </FormItem> <FormItem label="联系方式"> <FieldPicker viewId={viewId} fieldId={contactId} onChange={option => setContactId(option.value)} /> </FormItem> <FormItem label="地图核心"> <TextInput style={{ width: '100%!important' }} size="small" value={inputCenter} onChange={ e => setInputcenter(e.target.value)} /> <Button style={{ marginTop: 8}} color="primary" size="small" onClick={confirmCenter}> 确定 </Button> </FormItem> </Box> </div> </div> </div> ) : null;});
到这里咱们基本上实现了从表格中获取值而后在地图上实现标点等性能,后续的详细信息展现以及路线布局也能够应用
相应的插件实现。我曾经将源码上传至https://github.com/laboonly/w... 欢送Star⭐️.
后续打算
- 将此小程序变得更加有拓展性。让用户能够自由选择标点详细信息展现等性能
- 增加更多地图功能