高德開源API花式玩法:租房輔助工具
共 8424字,需瀏覽 17分鐘
·
2024-09-19 12:20
大家好,我是胖虎,給大家分享兩個產(chǎn)品
前言
做gis的同學(xué)肯定知道等時圈這個東西,即:在一定時間內(nèi)通過某種出行方式能到達(dá)的范圍
通過一些計算,我們可以做一些好玩的事情,比如上圖通過調(diào)用mapbox等時圈接口,計算在藍(lán)色點位附近騎車17分鐘可以到達(dá)哪些公司或?qū)W校。
可能由于國內(nèi)交通情況更為復(fù)雜,做實時性較差的等時圈意義不大,所以高德地圖提供了比較穩(wěn)當(dāng)?shù)腁PI:公交地鐵到達(dá)圈,其概念和等時圈類似,你可以選擇地鐵或公交出行,或者兩者兼可,高德接口將計算出可達(dá)范圍。
高德公交到達(dá)圈的好玩應(yīng)用
用了很久的高德,發(fā)現(xiàn)這個功能好像沒有被很好的應(yīng)用,其實高德早在1.4的API中就提供了此功能,最近正好要換個房子,突然想到這個東西正好可以拿來做一個很棒的輔助。
由于我跟我對象上班的地方離得比較遠(yuǎn),所以找個折中的地方租房是是很重要的,我準(zhǔn)備查詢到兩個到達(dá)圈后,再計算一下重合部分,在重合部分找房,就準(zhǔn)確多了。
使用AMap.ArrivalRange畫出到達(dá)圈
首先我做了一個簡單的頁面
左上角的面板用來設(shè)置參數(shù),可選地鐵+公交、地鐵、公交三種方式,出行耗時最大支持60分鐘(超過了接口會報錯),位置需要傳入經(jīng)緯度。
初始化地圖的步驟就不用說了,我講一下這個小應(yīng)用的使用邏輯。
首先,點擊地圖時,拾取該位置的經(jīng)緯度,并通過逆地理接口獲取到位置文本
function handleMapClick(e: any) {
if (!e.lnglat) return
if (currPositionList.value.length >= 2) {
autolog.log("最多添加 2 個位置", 'error') // 你不會想三個人一起住吧?
return
}
var lnglat = e.lnglat;
geocoder.getAddress(lnglat, (status: string, result: {
regeocode: any; info: string;
}) => {
if (status === "complete" && result.info === "OK") {
currPositionList.value.push({ name: result.regeocode.formattedAddress, lnglat: [lnglat.lng, lnglat.lat] })
}
});
}
可以看到,我把點選的位置信息,暫時存放到了currPositionList里面,比如你在西二旗上班,而你女朋友在國貿(mào),則點選后效果是這樣的
左側(cè)面板新增了兩個位置,點擊查詢時,我將依次查詢這兩個到達(dá)圈,并渲染到地圖上
function getArriveRange() {
let loopCount = 0
for (let item of currPositionList.value) {
arrivalRange.search(item.lnglat, currTime.value, (_status: any, result: { bounds: any; }) => {
map.remove(polygons);
if (!result.bounds) return
let currPolygons = []
loopCount++
for (let item of result.bounds) {
let polygon = new AMap.Polygon(polygonStyle[`normal${loopCount}` as "normal1" | "normal2"]);
polygon.setPath(item);
currPolygons.push(polygon)
}
map.add(currPolygons);
polygons.push({
lnglat: item.lnglat,
polygon: currPolygons,
bounds: result.bounds
})
if (loopCount === currPositionList.value.length) {
map.setFitView();
}
}, { policy: currStrategy.value });
}
}
由于接口調(diào)用方式是以回調(diào)函數(shù)的形式返回的,所以我這里記錄了一下回調(diào)次數(shù),當(dāng)次數(shù)滿足后,再去調(diào)整視角。這段邏輯運行之后,將是如下結(jié)果:
很遺憾,你和你的女朋友,下班后的一個小時內(nèi)見不成面了,這意味著,如果找一個折中的地方租房,你們上班單程通勤,無論如何都超過一個小時了,如果想盡量接近一個小時,那么看下兩者的交匯處
大鐘寺地鐵站將會是個很好的選擇。
這樣仍需要我們手動去觀察,那么能不能算一下兩者的交集呢?
在高德地圖中使用 turf.js 計算多多邊形交集
在上面提到的getArriveRange函數(shù)中,我新增了這樣的邏輯
if (loopCount === currPositionList.value.length) {
let poly1 = turf.multiPolygon(toNumber(polygons[0].bounds));
let poly2 = turf.multiPolygon(toNumber(polygons[1].bounds));
var intersection = turf.intersect(turf.featureCollection([poly1, poly2]));
if (intersection) {
let geojson = new AMap.GeoJSON({
geoJSON: {
type: "FeatureCollection",
features: [intersection]
},
getPolygon: (_: any, lnglats: any) => {
return new AMap.Polygon({
path: lnglats,
...polygonStyle.overlap
});
}
});
polygons.push({
lnglat: [0, 0],
polygon: geojson,
bounds: intersection.geometry.coordinates
})
map.add(geojson);
} else {
autolog.log("暫無交集,請自行查找", 'error')
}
map.setFitView();
}
由于高德地圖到達(dá)圈獲取到的經(jīng)緯度是字符串,放到 turf 里面會報錯,所以這里寫了一個簡單的遞歸,將多維數(shù)組所有的數(shù)據(jù)都轉(zhuǎn)化為數(shù)字。
// 遞歸的將多維數(shù)組內(nèi)的字符串轉(zhuǎn)為數(shù)字
function toNumber(arr: any) {
return arr.map((item: any) => {
if (Array.isArray(item)) {
return toNumber(item)
} else {
return Number(item)
}
})
}
使用turf.multiPolygon將獲取到的多維數(shù)組轉(zhuǎn)化為標(biāo)準(zhǔn)的 geojson 格式,以便于 turf 處理,在turf7.x中,turf.intersect的用法稍有改變,需要turf.featureCollection([poly1, poly2])作為參數(shù)傳入。
這一步操作 turf 將計算并返回兩個多多邊形的交集intersection(geojson),但是在高德地圖API2.0中,直接傳入這個geojson會報錯(1.4不會),看了下源碼,發(fā)現(xiàn)高德有一個操作是直接取第 0 個features,導(dǎo)致它識別不了這種格式的數(shù)據(jù),所以我們手動處理下,即:
let geojson = new AMap.GeoJSON({
geoJSON: {
type: "FeatureCollection",
features: [intersection]
},
getPolygon: (_: any, lnglats: any) => {
return new AMap.Polygon({
path: lnglats,
...polygonStyle.overlap
});
}
});
這樣,高德就可以正確渲染這個數(shù)據(jù)了,這里需要注意的是,geojson 雖然也是 AMap.Polygon 構(gòu)造的,但是需要一個特殊參數(shù):path,沒有的話,也不會報錯,但是渲染不出來。
渲染完成后是這樣的:
使用綠色代表重合部分,說明在這之中找房都是可以的。
通過 AMap.PlaceSearch 搜索交集區(qū)域的小區(qū)
高德提供了通過多邊形區(qū)域搜索POI的接口
placeSearch = new AMap.PlaceSearch({ //構(gòu)造地點查詢類
pageSize: 5, // 單頁顯示結(jié)果條數(shù)
pageIndex: 1, // 頁碼
map: map, // 展現(xiàn)結(jié)果的地圖實例
autoFitView: true // 是否自動調(diào)整地圖視野使繪制的 Marker點都處于視口的可見范圍
});
placeSearch.searchInBounds('小區(qū)', intersection.geometry.coordinates);
效果如上圖所示,這樣就可以輕松租房啦!
但是由于此接口是 get 請求,如果交集區(qū)域過大,會超出 get 請求長度限制:
結(jié)語
這個就叫產(chǎn)品思維,一個簡單的API可以延伸出很多有趣的應(yīng)用。
此倉庫已在 github 開源,地址:
https://github.com/LarryZhu-dev/amap_arrivalRange
番外
高德云鏡(高德云鏡三維重建平臺)目前已向企業(yè)和政府開放使用(暫未對個人開發(fā)者開放)
在web端,高德開發(fā)了 Cesium 插件用作展示,但目前來看要求配置過高
-
CesiumJS引擎:CesiumJS v1.117+(建議) -
瀏覽器:Chrome v126+(建議) -
顯卡:16GB顯存以上獨立顯卡,推薦 NVDIA RTX 4090 -
CPU:2.5 GHz 以上(建議) -
內(nèi)存:32GB 以上(建議)
看起來類似谷歌地球的全量城市建模。
-
官網(wǎng):yunjing.amap.com/#/ -
開發(fā)文檔:yunjing.amap.com/#/docs
—END—
普通人也能直接使用ChatGPT-4/ChatGPT4o

一次性買了幾百個ChatGPT官方賬號,放在一個系統(tǒng)的池子里。共享給大家使用。不需要翻墻,就可以體驗到官方正版賬號。而且突破官方提問次數(shù)的限制。正版保證!支持GPTs、語音、聯(lián)網(wǎng)、上傳文件等功能
更多介紹點這里,無需魔法使用官方ChatGPT-4(Plus)、ChatGPT-4o!
每月只需72元!
掃碼可以加我微信購買,備注:GPT
每天只要一瓶可樂錢
