南山科技园的步行

这几天深圳晴天,我刚好在深圳,南山区科技园,南区。

住宿到公司的距离不到2公里,有点尴尬的距离,除非下雨天或者赶时间打车,其它时候我一般都是走路往返。

这几天很热,深圳的热不能只看温度,还要看湿度、体感温度,甚至还要看月份,基本从3月份,湿热一直能持续到11月份。

因为工作的原因,我常年在北京、武汉和深圳跑,其他地方也去。跑的多了,见的多了,总是会淡定一些。

但科技园这个地方,是一个充满悖论的地方。比如路边或者写字楼下,都有共享单车,但几乎没有非机动车道,为啥是几乎呢?因为有的地方近一年,修了一点点,也就是一点点而已。

至少在科技园,对于骑电动车或者自行车严禁上机动车道是执行的很严的,我的第一张骑自行车罚单,就在这里产生。

在深圳的几年,基本都在科技园区域多一些,能感受到深圳确实有钱,因为人行道基本每年都会封起来挖一遍,有时候是刚刚铺好不久的新地砖,不定什么时候又被围挡起来开挖了。同事笑说这也是为了解决就业,让大家有饭吃,这么想也对,在其他的一些地方,道路破的几年不修,主要原因也许还是没有经费吧。

这里工作的人多,所有靠非机动车出行的人、步行的人,都被迫挤在人行道上,窄窄的人行道,与那些步行的人抢道争路权。

可以想象一下,天气很热,你走在路上,原本不宽的人行道上已经有走路的人,你还要不停地忍受前后两边都来的自行车、电动车,有些人还各种按铃,这是让人很崩溃的场面。有时候我真想拿个扫帚,把这些在人行道上骑车的人全部扫入垃圾堆,让世界清净一会。但想到大家都是牛马,何须为难彼此,又淡定了一些。

这么糟糕的环境,大家为什么要来?都是为了生计,为了多挣一点,当然不排除有一部分是为了自己的事业。

所以每当看到有些老板在对员工谈情怀时,我都忍不住想吐,为啥要揣着明白装糊涂?

有很多人,很多老板,都喜欢这些空的虚的话,却不想好好做事,做点实事。

人的精力是有限的,一切用行动说话,何须多言?

这样更改对吗?package com.example.bus; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.activity.OnBackPressedCallback; import com.amap.api.location.AMapLocation; import com.amap.api.location.AMapLocationClient; import com.amap.api.location.AMapLocationClientOption; import com.amap.api.location.AMapLocationListener; import com.amap.api.maps.AMap; import com.amap.api.maps.CameraUpdateFactory; import com.amap.api.maps.MapView; import com.amap.api.maps.model.LatLng; import com.amap.api.maps.model.LatLngBounds; import com.amap.api.maps.model.MarkerOptions; import com.amap.api.maps.model.PolylineOptions; import com.amap.api.services.core.AMapException; import com.amap.api.services.core.LatLonPoint; import com.amap.api.services.route.BusPath; import com.amap.api.services.route.BusRouteResult; import com.amap.api.services.route.BusStep; import com.amap.api.services.route.RouteSearch; import com.amap.api.maps.AMapUtils; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; // ... 前面的 import 和类声明保持不变 ... public class RoutePlanActivity extends AppCompatActivity implements AMapLocationListener { public static final String EXTRA_SOURCE = "extra_source"; public static final int SOURCE_FROM_HOME_SEARCH = 1001; public static final int SOURCE_FROM_MAP_DIRECT = 1002; // 定义三个策略对应的 Tab 索引 private static final int INDEX_FASTEST = 0; // BUS_DEFAULT private static final int INDEX_TRANSFER = 1; // BUS_LEASE_CHANGE private static final int INDEX_WALK = 2; // BUS_LEASE_WALK // 存储三种策略的路径:按固定索引存储 private final BusPath[] routePaths = new BusPath[3]; // [0]:最快, [1]:最少换乘, [2]:最少步行 private int resultCount = 0; private boolean isSearching = false; private int sourceType = -1; private MapView mapView; private AMap aMap; private RecyclerView recyclerSteps; private TextView tvRouteInfo; private AMapLocationClient locationClient; private LatLonPoint currentLocation; private LatLonPoint targetPoint; private boolean hasStartedSearch = false; private OnBackPressedCallback onBackPressedCallback; private TextView tabFastest, tabTransfer, tabWalk; public static class VirtualWalkStep { public final LatLonPoint from; public final LatLonPoint to; public final String description; public VirtualWalkStep(LatLonPoint from, LatLonPoint to, String desc) { this.from = from; this.to = to; this.description = desc; } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_route_plan); sourceType = getIntent().getIntExtra(EXTRA_SOURCE, -1); double startLat = getIntent().getDoubleExtra("start_lat", 0); double startLng = getIntent().getDoubleExtra("start_lng", 0); double targetLat = getIntent().getDoubleExtra("target_lat", 0); double targetLng = getIntent().getDoubleExtra("target_lng", 0); Log.d("RoutePlan", "📥 收到参数:"); Log.d("RoutePlan", " sourceType = " + sourceType); Log.d("RoutePlan", " start = " + startLat + "," + startLng); Log.d("RoutePlan", " target = " + targetLat + "," + targetLng); if (targetLat == 0 || targetLng == 0) { Toast.makeText(this, "目标位置无效", Toast.LENGTH_SHORT).show(); finish(); return; } targetPoint = new LatLonPoint(targetLat, targetLng); mapView = findViewById(R.id.map_view); recyclerSteps = findViewById(R.id.recycler_steps); tvRouteInfo = findViewById(R.id.tv_route_info); mapView.onCreate(savedInstanceState); if (aMap == null) { aMap = mapView.getMap(); } initLocation(); if (sourceType == SOURCE_FROM_MAP_DIRECT) { startRouteSearch(); } onBackPressedCallback = new OnBackPressedCallback(true) { @Override public void handleOnBackPressed() { if (sourceType == SOURCE_FROM_MAP_DIRECT) { Intent intent = new Intent(RoutePlanActivity.this, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.putExtra("open_tab", "map"); startActivity(intent); finish(); } else { setEnabled(false); getOnBackPressedDispatcher().onBackPressed(); setEnabled(true); } } }; getOnBackPressedDispatcher().addCallback(this, onBackPressedCallback); tabFastest = findViewById(R.id.tab_fastest); tabTransfer = findViewById(R.id.tab_transfer); tabWalk = findViewById(R.id.tab_walk); View.OnClickListener tabListener = v -> { if (v == tabFastest && routePaths[INDEX_FASTEST] != null) { displayRoute(INDEX_FASTEST); } else if (v == tabTransfer && routePaths[INDEX_TRANSFER] != null) { displayRoute(INDEX_TRANSFER); } else if (v == tabWalk && routePaths[INDEX_WALK] != null) { displayRoute(INDEX_WALK); } }; tabFastest.setOnClickListener(tabListener); tabTransfer.setOnClickListener(tabListener); tabWalk.setOnClickListener(tabListener); } private void initLocation() { try { locationClient = new AMapLocationClient(this); AMapLocationClientOption option = new AMapLocationClientOption(); option.setOnceLocation(true); option.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy); option.setMockEnable(false); locationClient.setLocationOption(option); locationClient.setLocationListener(this); locationClient.startLocation(); tvRouteInfo.setText("正在获取您的位置..."); } catch (Exception e) { Log.e("RoutePlan", "定位初始化失败", e); tvRouteInfo.setText("定位服务启动失败"); finish(); } } private void startRouteSearch() { if (isSearching || hasStartedSearch) return; hasStartedSearch = true; LatLonPoint start = null; if (sourceType == SOURCE_FROM_HOME_SEARCH) { if (currentLocation == null) { Log.e("RoutePlan", "📍 定位未完成,无法发起 HOME_SEARCH"); tvRouteInfo.setText("无法获取您的位置,请稍后重试"); finish(); return; } start = currentLocation; Log.d("RoutePlan", "🏠 使用定位位置作为起点: " + start.getLatitude() + "," + start.getLongitude()); } else if (sourceType == SOURCE_FROM_MAP_DIRECT) { double startLat = getIntent().getDoubleExtra("start_lat", 0); double startLng = getIntent().getDoubleExtra("start_lng", 0); if (Math.abs(startLat) < 1e-6 || Math.abs(startLng) < 1e-6) { Log.e("RoutePlan", "❌ MapDirect: 起点坐标无效 (" + startLat + ", " + startLng + ")"); tvRouteInfo.setText("起点坐标错误"); finish(); return; } start = new LatLonPoint(startLat, startLng); Log.d("RoutePlan", "🗺️ 使用地图中心作为起点: " + start.getLatitude() + "," + start.getLongitude()); } else { tvRouteInfo.setText("未知操作来源"); Log.e("RoutePlan", "❌ 未知来源: " + sourceType); finish(); return; } RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(start, targetPoint); isSearching = true; tvRouteInfo.setText("正在规划路线..."); sendRequestWithIndex(fromAndTo, RouteSearch.BUS_DEFAULT, INDEX_FASTEST); sendRequestWithIndex(fromAndTo, RouteSearch.BUS_LEASE_CHANGE, INDEX_TRANSFER); sendRequestWithIndex(fromAndTo, RouteSearch.BUS_LEASE_WALK, INDEX_WALK); } private void sendRequestWithIndex(RouteSearch.FromAndTo fromAndTo, int mode, int index) { RouteSearch search; try { search = new RouteSearch(this); } catch (AMapException e) { Log.e("RoutePlan", "创建 RouteSearch 失败 [mode=" + mode + "]", e); resultCount++; checkAllResultsAndDisplay(); return; } search.setRouteSearchListener(new RouteSearch.OnRouteSearchListener() { @Override public void onBusRouteSearched(BusRouteResult result, int rCode) { isSearching = false; if (rCode == 1000 && result != null && !result.getPaths().isEmpty()) { synchronized (routePaths) { routePaths[index] = result.getPaths().get(0); } } else { Log.w("RoutePlan", "公交路线查询失败 [mode=" + mode + "], rCode=" + rCode); } resultCount++; checkAllResultsAndDisplay(); } @Override public void onDriveRouteSearched(com.amap.api.services.route.DriveRouteResult r, int c) {} @Override public void onWalkRouteSearched(com.amap.api.services.route.WalkRouteResult r, int c) {} @Override public void onRideRouteSearched(com.amap.api.services.route.RideRouteResult r, int c) {} }); RouteSearch.BusRouteQuery query = new RouteSearch.BusRouteQuery(fromAndTo, mode, "全国", 0); search.calculateBusRouteAsyn(query); } private void addStartMarker(LatLonPoint startPoint) { if (startPoint == null || aMap == null) return; aMap.addMarker(new MarkerOptions() .position(new LatLng(startPoint.getLatitude(), startPoint.getLongitude())) .title("出发点")); } @Override public void onLocationChanged(AMapLocation loc) { if (loc != null && loc.getErrorCode() == 0) { currentLocation = new LatLonPoint(loc.getLatitude(), loc.getLongitude()); Log.d("RoutePlan", "✅ 定位成功: " + loc.getLatitude() + "," + loc.getLongitude()); if (sourceType == SOURCE_FROM_HOME_SEARCH && !hasStartedSearch) { startRouteSearch(); } } else { Log.e("RoutePlan", "❌ 定位失败: " + (loc != null ? loc.getErrorInfo() : "null")); tvRouteInfo.setText("定位失败,请检查权限"); Toast.makeText(this, "无法获取位置", Toast.LENGTH_LONG).show(); finish(); } } // ✅ 【核心修改】展示指定索引的路线(新增换乘步行) private void displayRoute(int index) { if (index < 0 || index >= 3 || routePaths[index] == null) return; BusPath bestPath = routePaths[index]; List<BusStep> originalSteps = bestPath.getSteps(); List<Object> enhancedSteps = new ArrayList<>(); LatLonPoint start = null; if (sourceType == SOURCE_FROM_HOME_SEARCH && currentLocation != null) { start = currentLocation; } else if (sourceType == SOURCE_FROM_MAP_DIRECT) { double slat = getIntent().getDoubleExtra("start_lat", 0); double slng = getIntent().getDoubleExtra("start_lng", 0); if (Math.abs(slat) > 1e-6 && Math.abs(slng) > 1e-6) { start = new LatLonPoint(slat, slng); } } // 首段步行 if (start != null && !originalSteps.isEmpty()) { LatLonPoint firstStation = getEntrancePoint(originalSteps.get(0)); if (firstStation != null && !start.equals(firstStation)) { String name = originalSteps.get(0).getBusLine() != null ? originalSteps.get(0).getBusLine().getDepartureBusStation().getBusStationName() : "站点"; enhancedSteps.add(new VirtualWalkStep(start, firstStation, "从当前位置步行至【" + name + "】")); } } // 主体步骤 + 插入换乘步行 for (int i = 0; i < originalSteps.size(); i++) { BusStep cur = originalSteps.get(i); enhancedSteps.add(cur); if (i < originalSteps.size() - 1) { BusStep next = originalSteps.get(i + 1); LatLonPoint exit = getExitPoint(cur); LatLonPoint entrance = getEntrancePoint(next); if (exit != null && entrance != null && !exit.equals(entrance)) { String name = next.getBusLine() != null ? next.getBusLine().getDepartureBusStation().getBusStationName() : (next.getRailway() != null ? "地铁站" : "站点"); enhancedSteps.add(new VirtualWalkStep(exit, entrance, "换乘步行至【" + name + "】")); } } } // 尾段步行 if (!originalSteps.isEmpty()) { LatLonPoint lastStation = getExitPoint(originalSteps.get(originalSteps.size() - 1)); if (lastStation != null && !lastStation.equals(targetPoint)) { String exitName = ""; BusStep last = originalSteps.get(originalSteps.size() - 1); if (last.getExit() != null && last.getExit().getName() != null) { exitName = last.getExit().getName(); } String name = last.getBusLine() != null ? last.getBusLine().getArrivalBusStation().getBusStationName() : "站点"; String desc = "从【" + name + "】下车后步行至目的地" + (exitName.isEmpty() ? "" : " (" + exitName + ")"); enhancedSteps.add(new VirtualWalkStep(lastStation, targetPoint, desc)); } } drawRouteOnMapEnhanced(enhancedSteps); StepAdapter adapter = new StepAdapter(enhancedSteps); recyclerSteps.setLayoutManager(new LinearLayoutManager(this)); recyclerSteps.setAdapter(adapter); calculateAndShowRouteInfo(enhancedSteps, bestPath); if (start != null) { addStartMarker(start); } updateTabSelection(index); } // ✅ 新增:获取当前步骤的下车/出口点 private LatLonPoint getExitPoint(BusStep step) { if (step.getBusLine() != null && step.getBusLine().getArrivalBusStation() != null) return step.getBusLine().getArrivalBusStation().getLatLonPoint(); if (step.getExit() != null) return step.getExit().getLatLonPoint(); if (step.getRailway() != null) return step.getRailway().getArrivalstop().getLatLonPoint(); return null; } // ✅ 新增:获取下一段的上车/入口点 private LatLonPoint getEntrancePoint(BusStep step) { if (step.getBusLine() != null && step.getBusLine().getDepartureBusStation() != null) return step.getBusLine().getDepartureBusStation().getLatLonPoint(); if (step.getEntrance() != null) return step.getEntrance().getLatLonPoint(); if (step.getRailway() != null) return step.getRailway().getDeparturestop().getLatLonPoint(); return null; } private void updateTabSelection(int selectedIndex) { TextView[] tabs = {tabFastest, tabTransfer, tabWalk}; int[] colors = {0xFFB2EBF2, 0xFFFFFFFF}; for (int i = 0; i < 3; i++) { tabs[i].setBackgroundColor(i == selectedIndex ? colors[0] : colors[1]); } } private void drawRouteOnMapEnhanced(List<Object> steps) { aMap.clear(); List<LatLng> allPoints = new ArrayList<>(); for (Object stepObj : steps) { if (stepObj instanceof BusStep) { BusStep step = (BusStep) stepObj; if (step.getBusLine() != null && step.getBusLine().getPolyline() != null) { for (LatLonPoint point : step.getBusLine().getPolyline()) { allPoints.add(new LatLng(point.getLatitude(), point.getLongitude())); } } else if (step.getWalk() != null && step.getWalk().getPolyline() != null) { for (LatLonPoint point : step.getWalk().getPolyline()) { allPoints.add(new LatLng(point.getLatitude(), point.getLongitude())); } } else { if (step.getEntrance() != null) { LatLonPoint p = step.getEntrance().getLatLonPoint(); allPoints.add(new LatLng(p.getLatitude(), p.getLongitude())); } if (step.getExit() != null) { LatLonPoint p = step.getExit().getLatLonPoint(); allPoints.add(new LatLng(p.getLatitude(), p.getLongitude())); } } } else if (stepObj instanceof VirtualWalkStep) { VirtualWalkStep vStep = (VirtualWalkStep) stepObj; allPoints.add(new LatLng(vStep.from.getLatitude(), vStep.from.getLongitude())); allPoints.add(new LatLng(vStep.to.getLatitude(), vStep.to.getLongitude())); } } if (!allPoints.isEmpty()) { PolylineOptions options = new PolylineOptions() .addAll(allPoints) .color(0xFF4A90E2) .width(12f); aMap.addPolyline(options); LatLngBounds.Builder builder = new LatLngBounds.Builder(); for (LatLng point : allPoints) { builder.include(point); } aMap.animateCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 100)); } else { tvRouteInfo.setText("路线数据为空"); } } // ✅ 计算并显示完整信息(时间、票价、步行距离、换乘次数) private void calculateAndShowRouteInfo(List<Object> steps, BusPath originalPath) { long totalDuration = 0; double totalWalkDistance = 0; int busRideCount = 0; for (Object obj : steps) { if (obj instanceof BusStep) { BusStep step = (BusStep) obj; if (step.getBusLine() != null && step.getBusLine().getDuration() > 0) { totalDuration += step.getBusLine().getDuration(); busRideCount++; } else if (step.getWalk() != null) { totalDuration += step.getWalk().getDuration(); totalWalkDistance += step.getWalk().getDistance(); } else if (step.getRailway() != null) { totalDuration += Long.parseLong(step.getRailway().getTime()); busRideCount++; } } else if (obj instanceof VirtualWalkStep) { VirtualWalkStep v = (VirtualWalkStep) obj; double dist = AMapUtils.calculateLineDistance( new LatLng(v.from.getLatitude(), v.from.getLongitude()), new LatLng(v.to.getLatitude(), v.to.getLongitude()) ); totalWalkDistance += dist; totalDuration += (dist / 80) * 60; // 步行速度约 80m/min } } int transferNum = Math.max(0, busRideCount - 1); double cost = originalPath.getCost(); String info = String.format( "⏱️ %d分钟 | 💰 ¥%.2f | 🚶 %d米 | 🚌 %d次换乘", (int)(totalDuration / 60), cost, (int)totalWalkDistance, transferNum ); tvRouteInfo.setText(info); tvRouteInfo.setVisibility(View.VISIBLE); // 确保可见 } // ✅ 【关键修复】不再隐藏 tvRouteInfo private void checkAllResultsAndDisplay() { if (resultCount >= 3) { runOnUiThread(() -> { for (int i = 0; i < 3; i++) { if (routePaths[i] != null) { displayRoute(i); return; } } tvRouteInfo.setText("未找到可用路线"); Toast.makeText(RoutePlanActivity.this, "抱歉,未找到可用的公交路线", Toast.LENGTH_LONG).show(); }); } } @Override public boolean onSupportNavigateUp() { getOnBackPressedDispatcher().onBackPressed(); return true; } @Override protected void onResume() { super.onResume(); mapView.onResume(); } @Override protected void onPause() { super.onPause(); mapView.onPause(); } @Override protected void onDestroy() { super.onDestroy(); mapView.onDestroy(); if (locationClient != null) { locationClient.onDestroy(); } } @Override protected void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); mapView.onSaveInstanceState(outState); } }
11-22
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值