场景:
话不多说后端提供数据实现步骤:
1.controller层
@Api(tags = {"[地区]-城市相关接口"})
@RestController
@RequestMapping("region")
@Slf4j
public class RegionController extends BaseController {
@Resource
private RegionService regionService;
@ApiOperation("城市列表[A-Z]")
@ApiImplicitParams({
@ApiImplicitParam(name = "condition", value = "城市名称", required = false, paramType = "query")})
@GetMapping("cityList")
public JsonResult<List<AppletCityListVO>> cityList(@RequestParam(value = "condition", required = false) String condition) {
return JsonResult.ok(this.regionService.smallProgramCityDisplayList(condition));
}
@ApiOperation("城市列表")
@ApiImplicitParams({
@ApiImplicitParam(name = "condition", value = "城市名称", required = false, paramType = "query")})
@GetMapping("queryCityList")
public JsonResult<List<AppletCityListVO.CityItem>> queryCityList(@RequestParam(value = "condition", required = false) String condition) {
return JsonResult.ok(this.regionService.queryCityList(condition));
}
@Resource
private TencentMapUtil tencentMapUtil;
@ApiOperation("根据经纬度查询地址")
@GetMapping("tencent/map/reGeoCoder")
public JsonResult<JSONObject> reGeoCoder(String lat, String lng) {
AssertUtil.notBlank(lat, "纬度不能为空");
AssertUtil.notBlank(lng, "经度不能为空");
JSONObject jsonObject = tencentMapUtil.reGeoCoder(lat, lng);
if (EntityConstant.INVALID != jsonObject.getInteger("status")) {
log.error("定位授权失败 , errorMsg = {}", jsonObject.getString("message"));
throw SimpleException.getInstance("定位授权失败");
}
JSONObject adInfo = jsonObject.getJSONObject("result").getJSONObject("ad_info");
String city_code = adInfo.getString("city_code");
String nation_code = adInfo.getString("nation_code");
jsonObject.getJSONObject("result").getJSONObject("ad_info").put("cityCode", city_code.replaceAll(nation_code, ""));
return JsonResult.ok(jsonObject);
}
}
2.service层
@Service
@Slf4j
@Primary
public class RegionServiceImpl extends BaseApplicationService implements RegionService {
@Resource
private RegionMapper regionMapper;
private static final char[] alphabet = new char[26];
static {
// 使用循环填充数组元素
for (int i = 0; i < alphabet.length; i++) {
alphabet[i] = (char) ('A' + i);
}
}
@Override
public List<AppletCityListVO> smallProgramCityDisplayList(String condition) {
List<Region> regionList = this.regionMapper.selectByExample(
new ExampleLambda<>(Region.class)
.andEqualTo(Region::getStatus, EntityConstant.NORMAL)
.andEqualTo(Region::getLevel, 2)
.andLike(Objects.nonNull(condition), Region::getName, condition)
.end()
);
Map<String, List<Region>> cityMap = regionList.stream().collect(Collectors.groupingBy(Region::getInitial));
List<AppletCityListVO> cityListVOList = new ArrayList<>(this.alphabet.length);
for (char c : this.alphabet) {
List<AppletCityListVO.CityItem> tempList = cityMap.containsKey(String.valueOf(c)) ? cityMap.get(String.valueOf(c)).stream().map(item -> {
AppletCityListVO.CityItem cityItem = new AppletCityListVO.CityItem();
cityItem.setCode(item.getCode());
cityItem.setName(item.getName());
return cityItem;
}).collect(Collectors.toList()) : new ArrayList<>(0);
cityListVOList.add(AppletCityListVO.builder().initial(String.valueOf(c)).itemList(tempList).build());
}
return cityListVOList;
}
@Override
public List<AppletCityListVO.CityItem> queryCityList(String condition) {
List<Region> regionList = this.regionMapper.selectByExample(
new ExampleLambda<>(Region.class)
.andEqualTo(Region::getStatus, EntityConstant.NORMAL)
.andEqualTo(Region::getLevel, 2)
.andLike(Objects.nonNull(condition), Region::getName, condition)
.end()
);
return regionList.stream().map(item -> {
AppletCityListVO.CityItem cityItem = new AppletCityListVO.CityItem();
cityItem.setCode(item.getCode());
cityItem.setName(item.getName());
return cityItem;
}).collect(Collectors.toList());
}
}
@Builder
@Data
public class AppletCityListVO implements Serializable {
@ApiModelProperty(value = "首字母")
private String initial;
@ApiModelProperty(value = "城市列表")
private List<CityItem> itemList;
@Data
public static class CityItem {
@ApiModelProperty(value = "code")
private String code;
@ApiModelProperty(value = "名称")
private String name;
public CityItem(String code, String name) {
this.code = code;
this.name = name;
}
public CityItem() {
}
}
}
3.mapper层
public interface RegionMapper extends CrudMapper<Region, Long> {
}
4.实体类
@Table(name = "`region`")
@Data
public class Region extends BaseEntity<Long> implements Serializable {
private static final long serialVersionUID = 1L;
/**
* Id
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
/**
* 1
*/
@Column(name = "level")
private Integer level;
/**
* code
*/
@Column(name = "code")
private String code;
/**
* 父级code
*/
@Column(name = "parent_code")
private String parentCode;
/**
* 名称
*/
@Column(name = "name")
private String name;
/**
* 名称拼音
*/
@Column(name = "pinyin")
private String pinyin;
/**
* 首字母
*/
@Column(name = "initial")
private String initial;
/**
* 状态
*/
@Column(name = "status")
private Integer status;
/**
* 创建时间
*/
@Column(name = "gmt_created")
@JsonFormat(locale = "zh", pattern = "yyyy-MM-dd HH:mm:ss")
private Date gmtCreated;
/**
* ModifyUser
*/
@Column(name = "modify_user")
private String modifyUser;
/**
* CreateUser
*/
@Column(name = "create_user")
private String createUser;
/**
* 更新时间
*/
@Column(name = "gmt_modified")
@JsonFormat(locale = "zh", pattern = "yyyy-MM-dd HH:mm:ss")
private Date gmtModified;
/**
* 是否删除
*/
@Column(name = "deleted")
private Integer deleted;
}
5.腾讯地图处理工具类
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Objects;
@Slf4j
@Component
public class TencentMapUtil {
private String qqAk = "xxxxx-xxxxx-xxxxx-xxxxx-xxxxx-xxxxx";
private String geoCoder = "https://apis.map.qq.com/ws/geocoder/v1/";
private String distance = "https://apis.map.qq.com/ws/distance/v1/";
private String translate = "https://apis.map.qq.com/ws/coord/v1/translate";
private String reGeoCoder = "https://apis.map.qq.com/ws/geocoder/v1/?location=";
/**
* 通过地址查询经纬度
*
* @param addr 地址
* @return
*/
public String geoCoder(String addr) {
JSONObject jsonObject = geoCoderRequest(addr);
if (null == jsonObject) {
return null;
}
JSONObject location = JSONUtil.parseObj(JSONUtil.toJsonStr(jsonObject.get("location")));
if (Objects.nonNull(location) && Objects.nonNull(location.get("lat")) && Objects.nonNull(location.get("lng"))) {
return location.get("lat").toString() + "," + location.get("lng").toString();
}
return null;
}
public JSONObject geoCoderRequest(String addr) {
try {
if (StringUtils.isNotEmpty(addr)) {
String url = geoCoder +
"?address=" + addr +
"&key=" + qqAk;// 腾讯地图ak
String resultStr = HttpUtil.get(url);
JSONObject tencentGeo = JSONUtil.parseObj(resultStr);
log.info("地址转坐标响应结果:" + JSONUtil.toJsonStr(tencentGeo));
if (Objects.nonNull(tencentGeo) && Objects.equals(0, tencentGeo.get("status"))) {
return JSONUtil.parseObj(JSONUtil.toJsonStr(tencentGeo.get("result")));
}
}
} catch (Exception e) {
log.error("地址转坐标失败,地址:" + addr + ", e: " + e);
}
return null;
}
/**
* 根据经纬度查询地址
*
* @param lat 纬度
* @param lng 经度
* @return
*/
public JSONObject reGeoCoder(String lat, String lng) {
StringBuilder url = new StringBuilder(reGeoCoder)
.append(lat).append(",").append(lng)
.append("&key=").append(qqAk);
String resultStr = HttpUtil.get(url.toString());
return JSONUtil.parseObj(resultStr);
}
/**
* 将微信小程序经纬度转换成腾讯地图经纬度
*
* @param lat 纬度
* @param lng 经度
* @return
*/
public JSONObject translate(String lat, String lng) {
StringBuilder url = new StringBuilder(translate)
.append("?key=").append(qqAk)// 腾讯地图ak
.append("&type=1")// 1.GPS坐标 2.sogou经纬度 3.baidu经纬度 4.mapbar经纬度 5.[默认]腾讯、google、高德坐标 6.sogou墨卡托
.append("&&locations=").append(lat).append(",").append(lng);
String resultStr = HttpUtil.get(url.toString());
return JSONUtil.parseObj(resultStr);
}
}
6.region.sql文件
链接: https://pan.baidu.com/s/1m1WEgQPGXbUzgZ4qusvegQ 提取码: ztr6 复制这段内容后打开百度网盘手机App,操作更方便哦