|
@@ -69,14 +69,14 @@
|
|
|
<FlexCol :gap="20">
|
|
<FlexCol :gap="20">
|
|
|
<Text color="text.second">路线规划</Text>
|
|
<Text color="text.second">路线规划</Text>
|
|
|
<FlexCol
|
|
<FlexCol
|
|
|
- v-for="item in routeInfo?.items || []" :key="item.id"
|
|
|
|
|
|
|
+ v-for="(item, index) in routeInfo?.items || []" :key="item.id"
|
|
|
:gap="20"
|
|
:gap="20"
|
|
|
>
|
|
>
|
|
|
<Touchable direction="row" justify="space-between" :gap="20" @click="onItemClick(item)">
|
|
<Touchable direction="row" justify="space-between" :gap="20" @click="onItemClick(item)">
|
|
|
<FlexRow :gap="20">
|
|
<FlexRow :gap="20">
|
|
|
<Image :src="item.scenicSpot.image" :radius="20" :width="80" :height="80" mode="aspectFill" />
|
|
<Image :src="item.scenicSpot.image" :radius="20" :width="80" :height="80" mode="aspectFill" />
|
|
|
<FlexCol>
|
|
<FlexCol>
|
|
|
- <Text bold :color="routeColors[item.atDay]">第 {{ item.atDay }} 天</Text>
|
|
|
|
|
|
|
+ <Text bold :color="routeColors[index]">打卡点 {{ (index + 1) }}</Text><!-- //如果显示天数则用 item.atDay -->
|
|
|
<Text>{{ item.scenicSpot.name }}</Text>
|
|
<Text>{{ item.scenicSpot.name }}</Text>
|
|
|
<Text color="text.second">{{ item.scenicSpot.address }}</Text>
|
|
<Text color="text.second">{{ item.scenicSpot.address }}</Text>
|
|
|
</FlexCol>
|
|
</FlexCol>
|
|
@@ -85,7 +85,7 @@
|
|
|
<Button type="text" icon="navigation" text="导航" @click="openLocation(item)" />
|
|
<Button type="text" icon="navigation" text="导航" @click="openLocation(item)" />
|
|
|
<template v-if="currentLocationGeted">
|
|
<template v-if="currentLocationGeted">
|
|
|
<Text color="text.second" :fontSize="22">距您约</Text>
|
|
<Text color="text.second" :fontSize="22">距您约</Text>
|
|
|
- <Text color="text.second" :fontSize="28">{{ getDistance(item) }}</Text>
|
|
|
|
|
|
|
+ <Text color="text.second" :fontSize="28" :text="getDistance(item)" />
|
|
|
</template>
|
|
</template>
|
|
|
</FlexCol>
|
|
</FlexCol>
|
|
|
</Touchable>
|
|
</Touchable>
|
|
@@ -220,10 +220,10 @@ const { querys } = useLoadQuerys({
|
|
|
loadRoute();
|
|
loadRoute();
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
-const routeColors = [ '', '#22ac38', '#00a0e9', '#8957a1', '#eb6877', '#f39800', '#e60012' ];
|
|
|
|
|
|
|
+const routeColors = [ '#22ac38', '#00a0e9', '#8957a1', '#eb6877', '#f39800', '#e60012' ];
|
|
|
const preferredWays = ['', 'driving', 'walking', 'bicycling', 'ebicycling', 'transit'];
|
|
const preferredWays = ['', 'driving', 'walking', 'bicycling', 'ebicycling', 'transit'];
|
|
|
function getMakerImage(day: number) {
|
|
function getMakerImage(day: number) {
|
|
|
- return `https://mncdn.wenlvti.net/app_static/minnan/images/IcoMaker${day}.png`;
|
|
|
|
|
|
|
+ return `https://mncdn.wenlvti.net/app_static/minnan/images/IcoMaker${(day + 1)}.png`;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/** 根据两点经纬度计算直线距离(米),Haversine 公式 */
|
|
/** 根据两点经纬度计算直线距离(米),Haversine 公式 */
|
|
@@ -243,11 +243,27 @@ function getDistanceMeters(
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function goToCurrentLocation() {
|
|
function goToCurrentLocation() {
|
|
|
- if (!myLocation.value[0] || !myLocation.value[1]) return;
|
|
|
|
|
- currentLocation.value = myLocation.value;
|
|
|
|
|
- mapCtx.moveToLocation({
|
|
|
|
|
- latitude: myLocation.value[1],
|
|
|
|
|
- longitude: myLocation.value[0],
|
|
|
|
|
|
|
+ uni.showLoading({
|
|
|
|
|
+ title: '获取位置中...',
|
|
|
|
|
+ });
|
|
|
|
|
+ uni.getLocation({
|
|
|
|
|
+ type: 'wgs84',
|
|
|
|
|
+ success: (res) => {
|
|
|
|
|
+ uni.hideLoading();
|
|
|
|
|
+ myLocation.value = [res.longitude, res.latitude];
|
|
|
|
|
+ currentLocation.value = myLocation.value;
|
|
|
|
|
+ mapCtx.moveToLocation({
|
|
|
|
|
+ latitude: myLocation.value[1],
|
|
|
|
|
+ longitude: myLocation.value[0],
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+ fail: (err) => {
|
|
|
|
|
+ uni.hideLoading();
|
|
|
|
|
+ alert({
|
|
|
|
|
+ title: '获取位置失败',
|
|
|
|
|
+ content: '请检查是否开启定位权限',
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
function getDistance(item: RouteInfo['items'][number]): string {
|
|
function getDistance(item: RouteInfo['items'][number]): string {
|
|
@@ -302,6 +318,49 @@ function getSegmentLabel(way: RouteToNextBestWay, atDay: number, duration?: numb
|
|
|
const dur = duration != null ? ` 约${formatDuration(duration)}` : '';
|
|
const dur = duration != null ? ` 约${formatDuration(duration)}` : '';
|
|
|
return `第${atDay}天 ${wayName}${dur}`;
|
|
return `第${atDay}天 ${wayName}${dur}`;
|
|
|
}
|
|
}
|
|
|
|
|
+function getSegmentTransitLabel(transitData: RouteInfo['items'][0]['toNextRoute']['transit'], index: number): string {
|
|
|
|
|
+ if (!transitData?.steps?.length) return `公交路段${index + 1}`;
|
|
|
|
|
+
|
|
|
|
|
+ let segIndex = 0;
|
|
|
|
|
+ for (const step of transitData.steps) {
|
|
|
|
|
+ if (step.mode === 'WALKING') {
|
|
|
|
|
+ if (!step.polyline?.length) continue;
|
|
|
|
|
+ const current = segIndex++;
|
|
|
|
|
+ if (current !== index) continue;
|
|
|
|
|
+
|
|
|
|
|
+ const d = step.distance != null ? formatDistance(step.distance) : '';
|
|
|
|
|
+ const t = step.duration != null ? formatDuration(step.duration) : '';
|
|
|
|
|
+ if (d && t) return `步行 ${d}·约${t}`;
|
|
|
|
|
+ if (d) return `步行 ${d}`;
|
|
|
|
|
+ if (t) return `步行 约${t}`;
|
|
|
|
|
+ return '步行';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (step.mode === 'TRANSIT') {
|
|
|
|
|
+ for (const line of (step.lines || [])) {
|
|
|
|
|
+ if (!line.polyline?.length) continue;
|
|
|
|
|
+ const current = segIndex++;
|
|
|
|
|
+ if (current !== index) continue;
|
|
|
|
|
+
|
|
|
|
|
+ const vehicle = (line.vehicle || '').toUpperCase();
|
|
|
|
|
+ const vehicleName =
|
|
|
|
|
+ vehicle === 'BUS' ? '公交' :
|
|
|
|
|
+ vehicle === 'SUBWAY' ? '地铁' :
|
|
|
|
|
+ vehicle === 'RAIL' ? '火车' :
|
|
|
|
|
+ '线路';
|
|
|
|
|
+
|
|
|
|
|
+ const title = line.title ? `${vehicleName} ${line.title}` : vehicleName;
|
|
|
|
|
+ const fromTo = (line.geton?.title && line.getoff?.title) ? ` ${line.geton.title}→${line.getoff.title}` : '';
|
|
|
|
|
+ const stations = line.station_count != null ? `·${line.station_count}站` : '';
|
|
|
|
|
+ const d = line.distance != null ? `·${formatDistance(line.distance)}` : '';
|
|
|
|
|
+ const t = line.duration != null ? `·约${formatDuration(line.duration)}` : '';
|
|
|
|
|
+ return `${title}${fromTo}${stations}${d}${t}`.trim();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return `公交路段${index + 1}`;
|
|
|
|
|
+}
|
|
|
/** 根据 toNextRoute 与 toNextBestWay 生成地图 polyline 数组(含 segmentTexts 折线说明) */
|
|
/** 根据 toNextRoute 与 toNextBestWay 生成地图 polyline 数组(含 segmentTexts 折线说明) */
|
|
|
function buildPolylineFromRouteInfo(info: RouteInfo) {
|
|
function buildPolylineFromRouteInfo(info: RouteInfo) {
|
|
|
const segments: Array<{
|
|
const segments: Array<{
|
|
@@ -319,7 +378,7 @@ function buildPolylineFromRouteInfo(info: RouteInfo) {
|
|
|
const item = items[i];
|
|
const item = items[i];
|
|
|
const way: RouteToNextBestWay = (userPreferredWay.value || item.toNextBestWay || 'driving') as RouteToNextBestWay;
|
|
const way: RouteToNextBestWay = (userPreferredWay.value || item.toNextBestWay || 'driving') as RouteToNextBestWay;
|
|
|
const routeData = item.toNextRoute?.[way];
|
|
const routeData = item.toNextRoute?.[way];
|
|
|
- const color = routeColors[item.atDay];
|
|
|
|
|
|
|
+ const color = routeColors[i]; //如果显示天数则用 item.atDay
|
|
|
const width = 6;
|
|
const width = 6;
|
|
|
|
|
|
|
|
if (way === 'transit') {
|
|
if (way === 'transit') {
|
|
@@ -329,7 +388,11 @@ function buildPolylineFromRouteInfo(info: RouteInfo) {
|
|
|
for (let k = 0; k < polylines.length; k++) {
|
|
for (let k = 0; k < polylines.length; k++) {
|
|
|
const points = polylineToPoints(polylines[k]);
|
|
const points = polylineToPoints(polylines[k]);
|
|
|
if (points.length < 2) continue;
|
|
if (points.length < 2) continue;
|
|
|
- const segmentTexts = k === 0 ? [{ name: label, startIndex: 0, endIndex: points.length - 1 }] : undefined;
|
|
|
|
|
|
|
+ const segmentTexts = k === 0 ? [
|
|
|
|
|
+ { name: label, startIndex: 0, endIndex: points.length - 1 }
|
|
|
|
|
+ ] : [
|
|
|
|
|
+ { name: getSegmentTransitLabel(transitData!, k), startIndex: 0, endIndex: points.length - 1 }
|
|
|
|
|
+ ];
|
|
|
segments.push({
|
|
segments.push({
|
|
|
points,
|
|
points,
|
|
|
color,
|
|
color,
|
|
@@ -394,17 +457,17 @@ async function loadMap() {
|
|
|
|
|
|
|
|
// 生成标记点
|
|
// 生成标记点
|
|
|
const tempMarkers = routeInfo.value.items
|
|
const tempMarkers = routeInfo.value.items
|
|
|
- .map(p => ({
|
|
|
|
|
|
|
+ .map((p, index) => ({
|
|
|
latitude: p.scenicSpot.latitude,
|
|
latitude: p.scenicSpot.latitude,
|
|
|
longitude: p.scenicSpot.longitude,
|
|
longitude: p.scenicSpot.longitude,
|
|
|
- iconPath: getMakerImage(p.atDay),
|
|
|
|
|
|
|
+ iconPath: getMakerImage(index),
|
|
|
callout: {
|
|
callout: {
|
|
|
content: p.scenicSpot.name,
|
|
content: p.scenicSpot.name,
|
|
|
color: "#ffffff",
|
|
color: "#ffffff",
|
|
|
fontSize: 15,
|
|
fontSize: 15,
|
|
|
borderRadius: 15,
|
|
borderRadius: 15,
|
|
|
padding: "10",
|
|
padding: "10",
|
|
|
- bgColor: routeColors[p.atDay],
|
|
|
|
|
|
|
+ bgColor: routeColors[index],
|
|
|
display: "ALWAYS",
|
|
display: "ALWAYS",
|
|
|
},
|
|
},
|
|
|
width: 40,
|
|
width: 40,
|