|
|
@@ -88,14 +88,176 @@ class mapUtil
|
|
|
return $distances;
|
|
|
}
|
|
|
|
|
|
- //逆地址解析,根据经纬度解析出中文地址 ssh
|
|
|
- public static function resolveLocation($lat, $long)
|
|
|
+ /**
|
|
|
+ * 逆地址解析(高德),根据经纬度解析省市区与地址
|
|
|
+ * @param string|float $lat 纬度
|
|
|
+ * @param string|float $long 经度
|
|
|
+ * @param string $locationType gcj02|wgs84,wgs84 时传 coordsys=gps 给高德
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ public static function resolveLocation($lat, $long, $locationType = 'gcj02')
|
|
|
{
|
|
|
- $url = "https://apis.map.qq.com/ws/geocoder/v1/?location={$lat},{$long}&get_poi=0&key=" . self::$thirdMapKey;
|
|
|
+ $lat = (float)$lat;
|
|
|
+ $long = (float)$long;
|
|
|
+ if ($lat == 0 || $long == 0) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+
|
|
|
+ $domain = getenv('YII_ENV') == 'production' ? 'https://restapi.amap.com' : 'http://restapi.amap.com';
|
|
|
+ // 高德 location 参数:经度,纬度
|
|
|
+ $location = $long . ',' . $lat;
|
|
|
+ $url = $domain . '/v3/geocode/regeo?location=' . urlencode($location)
|
|
|
+ . '&key=' . self::$thirdMapKey
|
|
|
+ . '&extensions=base';
|
|
|
+ if ($locationType === 'wgs84' || $locationType === 'gps') {
|
|
|
+ $url .= '&coordsys=gps';
|
|
|
+ }
|
|
|
+
|
|
|
$curl = new curl\Curl();
|
|
|
$result = $curl->get($url);
|
|
|
$result = Json::decode($result);
|
|
|
- return $result;
|
|
|
+ return self::formatAmapRegeoResult($result);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 格式化高德逆地理编码结果
|
|
|
+ */
|
|
|
+ private static function formatAmapRegeoResult($result)
|
|
|
+ {
|
|
|
+ if (empty($result['status']) || (string)$result['status'] !== '1' || empty($result['regeocode'])) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+
|
|
|
+ $regeo = $result['regeocode'];
|
|
|
+ $component = $regeo['addressComponent'] ?? [];
|
|
|
+ $province = self::normalizeAmapRegionValue($component['province'] ?? '');
|
|
|
+ $city = self::normalizeAmapRegionValue($component['city'] ?? '');
|
|
|
+ $district = self::normalizeAmapRegionValue($component['district'] ?? '');
|
|
|
+
|
|
|
+ if (empty($city)) {
|
|
|
+ $city = $province;
|
|
|
+ }
|
|
|
+
|
|
|
+ $showAddress = $regeo['formatted_address'] ?? '';
|
|
|
+ $township = self::normalizeAmapRegionValue($component['township'] ?? '');
|
|
|
+ $streetNumber = $component['streetNumber'] ?? [];
|
|
|
+ $street = is_array($streetNumber) ? ($streetNumber['street'] ?? '') : '';
|
|
|
+ $number = is_array($streetNumber) ? ($streetNumber['number'] ?? '') : '';
|
|
|
+ $address = trim($township . $street . $number);
|
|
|
+
|
|
|
+ if (empty($address)) {
|
|
|
+ $address = $showAddress;
|
|
|
+ if ($province && mb_strpos($address, $province) === 0) {
|
|
|
+ $address = mb_substr($address, mb_strlen($province));
|
|
|
+ }
|
|
|
+ if ($city && $city !== $province && mb_strpos($address, $city) === 0) {
|
|
|
+ $address = mb_substr($address, mb_strlen($city));
|
|
|
+ }
|
|
|
+ if ($district && mb_strpos($address, $district) === 0) {
|
|
|
+ $address = mb_substr($address, mb_strlen($district));
|
|
|
+ }
|
|
|
+ $address = trim($address);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (empty($address) || empty($province) || empty($city)) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'province' => $province,
|
|
|
+ 'city' => $city,
|
|
|
+ 'district' => $district,
|
|
|
+ 'address' => $address,
|
|
|
+ 'showAddress' => $showAddress ?: ($province . $city . $district . $address),
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据经纬度获取当前位置及附近 POI 列表(高德逆地理 extensions=all)
|
|
|
+ */
|
|
|
+ public static function resolveNearby($lat, $long, $locationType = 'gcj02')
|
|
|
+ {
|
|
|
+ $lat = (float)$lat;
|
|
|
+ $long = (float)$long;
|
|
|
+ if ($lat == 0 || $long == 0) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+
|
|
|
+ $domain = getenv('YII_ENV') == 'production' ? 'https://restapi.amap.com' : 'http://restapi.amap.com';
|
|
|
+ $location = $long . ',' . $lat;
|
|
|
+ $url = $domain . '/v3/geocode/regeo?location=' . urlencode($location)
|
|
|
+ . '&key=' . self::$thirdMapKey
|
|
|
+ . '&extensions=all&radius=1000&roadlevel=0';
|
|
|
+ if ($locationType === 'wgs84' || $locationType === 'gps') {
|
|
|
+ $url .= '&coordsys=gps';
|
|
|
+ }
|
|
|
+
|
|
|
+ $curl = new curl\Curl();
|
|
|
+ $result = Json::decode($curl->get($url));
|
|
|
+ if (empty($result['status']) || (string)$result['status'] !== '1' || empty($result['regeocode'])) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+
|
|
|
+ $regeo = $result['regeocode'];
|
|
|
+ $component = $regeo['addressComponent'] ?? [];
|
|
|
+ $province = self::normalizeAmapRegionValue($component['province'] ?? '');
|
|
|
+ $city = self::normalizeAmapRegionValue($component['city'] ?? '');
|
|
|
+ $district = self::normalizeAmapRegionValue($component['district'] ?? '');
|
|
|
+ if (empty($city)) {
|
|
|
+ $city = $province;
|
|
|
+ }
|
|
|
+
|
|
|
+ $centerAddress = $regeo['formatted_address'] ?? '';
|
|
|
+ $centerName = self::normalizeAmapRegionValue($component['township'] ?? '');
|
|
|
+ if (empty($centerName)) {
|
|
|
+ $centerName = '当前位置';
|
|
|
+ }
|
|
|
+
|
|
|
+ $list = [[
|
|
|
+ 'name' => $centerName,
|
|
|
+ 'address' => $centerAddress,
|
|
|
+ 'province' => $province,
|
|
|
+ 'city' => $city,
|
|
|
+ 'district' => $district,
|
|
|
+ 'location' => $long . ',' . $lat,
|
|
|
+ 'showAddress' => $centerAddress,
|
|
|
+ ]];
|
|
|
+
|
|
|
+ $pois = $regeo['pois'] ?? [];
|
|
|
+ $exists = [$centerName];
|
|
|
+ foreach ($pois as $poi) {
|
|
|
+ $poiName = $poi['name'] ?? '';
|
|
|
+ if ($poiName === '' || in_array($poiName, $exists, true)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $exists[] = $poiName;
|
|
|
+ $poiAddress = $poi['address'] ?? '';
|
|
|
+ if ($poiAddress === '') {
|
|
|
+ $poiAddress = $centerAddress ? ($centerAddress . ' ' . $poiName) : $poiName;
|
|
|
+ }
|
|
|
+ $list[] = [
|
|
|
+ 'name' => $poiName,
|
|
|
+ 'address' => $poiAddress,
|
|
|
+ 'province' => $province,
|
|
|
+ 'city' => $city,
|
|
|
+ 'district' => $district,
|
|
|
+ 'location' => $poi['location'] ?? ($long . ',' . $lat),
|
|
|
+ 'showAddress' => $poiAddress,
|
|
|
+ ];
|
|
|
+ if (count($list) >= 21) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return $list;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static function normalizeAmapRegionValue($value)
|
|
|
+ {
|
|
|
+ if (is_array($value)) {
|
|
|
+ return !empty($value) ? (string)$value[0] : '';
|
|
|
+ }
|
|
|
+ return (string)$value;
|
|
|
}
|
|
|
|
|
|
/**
|