一、需求分析

需要做一个类似于高德地图的搜索可以参考高德地图,用户输入地点,下拉列表自动弹出少量的相应地点,点击内容地点可以直接选择定位并且添加Cesium的广告牌(图标)和标注,点击标注可以弹出详细信息,点击搜索则通过输入地点查找出全部内容并且显示图片,搜索到的内容因为较多,所以内容增加分页功能。

二、后台接口SpringBoot+高德地图Web服务

高德服务地址:https://lbs.amap.com/api/webservice/summary/

用的高德搜索POI和输入提示

Controller

 /*** 查询输入位置数据* @param id* @return* @author ygc* @throws IOException */@RequestMapping("/queryInputPositionData")@SecurityParameter@ResponseBody@Transactional(propagation=Propagation.SUPPORTS)public Result  queryInputPositionData(@RequestBody RequestInfo requestInfo,HttpServletResponse response) throws IOException {    response.setContentType("text/html;charset=UTF-8");   response.setHeader("Content-type", "application/json;charset=UTF-8");if(RedisPool.checkToken(requestInfo.getToken())==false){return RedisTool.msgResult();}Map<?, ?> map= (Map<?, ?>) requestInfo.getData();String position=(String)map.get("position");Result temp=sysuserService.queryInputPositionDataByPosition(position,requestInfo.getUid());return temp; }/*** 查询输入搜索数据* @param id* @return* @author ygc* @throws IOException */@RequestMapping("/querySearchPositionData")@SecurityParameter@ResponseBody@Transactional(propagation=Propagation.SUPPORTS)public Result  querySearchPositionData(@RequestBody RequestInfo requestInfo,HttpServletResponse response) throws IOException {    response.setContentType("text/html;charset=UTF-8");   response.setHeader("Content-type", "application/json;charset=UTF-8");if(RedisPool.checkToken(requestInfo.getToken())==false){return RedisTool.msgResult();}Map<?, ?> map= (Map<?, ?>) requestInfo.getData();String position=(String)map.get("position");Integer currentPage=(Integer)map.get("currentPage");Result temp=sysuserService.querySearchPositionDataByPosition(position,requestInfo.getUid(),currentPage);return temp; }

Service

 public Result queryInputPositionDataByPosition(String position, String uid) {String key="68c16866958532b7b092f23a52ff6862";BufferedReader in = null;  String url="https://restapi.amap.com/v3/assistant/inputtips?output=json&keywords="+position+"&key="+key;try {  URL Url = new URL(url); // 打开和URL之间的连接  URLConnection connection = Url.openConnection();  // 设置通用的请求属性  connection.setConnectTimeout(5000);  connection.setReadTimeout(5000);  // 建立实际的连接  connection.connect();  // 定义 BufferedReader输入流来读取URL的响应  in = new BufferedReader(new InputStreamReader(connection.getInputStream()));  StringBuffer sb = new StringBuffer();  String line;  while ((line = in.readLine()) != null) {  sb.append(line);  }  JSONObject userJson = JSONObject.parseObject(sb.toString());com.alibaba.fastjson.JSONArray tips = userJson.getJSONArray("tips");//              String tips = (String) userJson.get("tips");
//              System.out.println(sb.toString()); Result result=new Result();result.setUid(uid);result.setCode(200); result.setData(tips);   result.setResult("成功"); result.setMessage("查询输入位置数据"); return result;} catch (Exception e1) { e1.printStackTrace();throw new RuntimeException(e1);     }  // 使用finally块来关闭输入流  finally {  try {  if (in != null) {  in.close();  }  } catch (Exception e2) {  e2.printStackTrace();  }  }}public Result querySearchPositionDataByPosition(String position, String uid, Integer currentPage) {String key="68c16866958532b7b092f23a52ff6862";BufferedReader in = null;  int pageSize=10;String url="https://restapi.amap.com/v3/place/text?keywords="+position+"&output=json&offset="+pageSize+"&page="+currentPage+"&key="+key+"&extensions=all";
//          String url="https://restapi.amap.com/v3/assistant/inputtips?output=json&keywords="+position+"&key="+key;try {  URL Url = new URL(url); // 打开和URL之间的连接  URLConnection connection = Url.openConnection();  // 设置通用的请求属性  connection.setConnectTimeout(5000);  connection.setReadTimeout(5000);  // 建立实际的连接  connection.connect();  // 定义 BufferedReader输入流来读取URL的响应  in = new BufferedReader(new InputStreamReader(connection.getInputStream()));  StringBuffer sb = new StringBuffer();  String line;  while ((line = in.readLine()) != null) {  sb.append(line);  }  JSONObject userJson = JSONObject.parseObject(sb.toString());System.out.println(userJson);JSONObject json=new JSONObject();if(currentPage==1) {Integer resultCount=Integer.valueOf(userJson.get("count").toString());int pageCount=(resultCount%pageSize==0)?resultCount/pageSize:(resultCount/pageSize+1); System.out.println("resultCount:"+resultCount);System.out.println("pageCount:"+pageCount);json.put("pageCount", pageCount);json.put("resultCount",resultCount);}com.alibaba.fastjson.JSONArray pois = userJson.getJSONArray("pois");System.out.println("pageIndex:"+currentPage);
//              String tips = (String) userJson.get("tips");
//              System.out.println(sb.toString()); json.put("pageIndex", currentPage);json.put("pageSize", pageSize);
//              pois.add(json);
//              System.out.println(pois);Result result=new Result();result.setUid(uid);result.setCode(200); result.setData(pois);   result.setResult(json.toString()); result.setMessage("查询输入位置数据"); return result;} catch (Exception e1) { e1.printStackTrace();throw new RuntimeException(e1);      }  // 使用finally块来关闭输入流  finally {  try {  if (in != null) {  in.close();  }  } catch (Exception e2) {  e2.printStackTrace();  }  }}

三、前端实现React+Antd+Dva+Cesium

Html+antd用的AutoComplete自动完成插件

import React, {Component} from "react";
import { Menu, Dropdown,Divider,Button } from 'antd';
import { DownOutlined } from '@ant-design/icons';
import DataSource from '@/assets/svg/DataSource.js'
import Measure from '@/assets/svg/Measure.js'
import Plot from '@/assets/svg/Plot.js'
import Remove from '@/assets/svg/Remove.js'
import { Input, AutoComplete,Icon,Select,Pagination  } from 'antd';
import { SelectProps } from 'antd/es/select';
import styles from '@/components/search/SearchPosition.css';
import config from '../../../public/config';
import { connect } from 'react-redux';
import * as Cesium from 'cesium';
import { removesDuplicates } from '@/components/utils/CommonTool';
const { Option, OptGroup } = AutoComplete;
/*** @author 于公成* @date 2020/6/30* @Description: 搜索位置*/
let flag=this
class SearchPosition extends  React.Component{constructor(props) {super(props);this.state = {dataSource:[],data:{position:undefined},status:false,pageIndex:1,pageCount:1,resultCount:undefined};}componentDidMount(){}renderOption=(item)=>{let str=[];if(item.phones!=null){for(let i=0;i<item.phones.length;i++){if(item.phones[i]!=null){str.push(<img style={{width:'70px',height:'70px'}} src={item.phones[i].url}/>);}}return (<Option  key={item.name+item.id} position={item.location} text={item.name}><div className="global-search-item"><span style={{color:'#999999',fontSize:'3px',float:'right'}}>{str.map((item)=><span>{item}</span>)}</span>{item.name}<br/>{item.district}</div></Option>);}else{return (<Option key={item.name+item.id} position={item.location} text={item.name}><div className="global-search-item">{item.name}<br/><span style={{color:'#999999',fontSize:'3px'}}>{item.district}{str}</span></div></Option>);}}onSelect=(value,option)=> {let flag=this;let position=option.props.position;let lon=position.split(",")[0];let lat=position.split(",")[1];let viewer=  this.props.viewer.ceViewer;viewer.entities.removeById(1)viewer.entities.add({id:1,name : 'test',position : Cesium.Cartesian3.fromDegrees(Number(lon),Number(lat), 0),color : Cesium.Color.fromCssColorString('#000000'),//圆//  ellipse: {//    semiMinorAxis: 50,//    semiMajorAxis: 50,//    height: 10,//    outlineColor: Cesium.Color.RED,//    zIndex:0,//    //rotation : Cesium.Math.toRadians(45),//旋转角//    material: new Cesium.ImageMaterialProperty({//      image: '../img/标记.png\',',//      // //指定图像在每个方向上重复的次数,默认为Cesium.Cartesian2(1.0, 1.0),{Cartesian2}类型//      // repeat: Cesium.Cartesian2(1.0, 1.0),//      // // 默认为false,当图像具有透明性时设置为true(例如,当png具有透明部分时)//      // transparent: true,//      // color: Cesium.Color.WHITE.withAlpha(0.5),  //透明度0.5//    })//  },//点样式// point : {//   pixelSize : 25,//   color : Cesium.Color.RED,//   outlineColor : Cesium.Color.WHITE,//   // outlineWidth : 5// },//立广告牌billboard :{image:'../img/标记.png',show : true, // defaultwidth : 50, // default: undefinedheight : 50 // default: undefined},//字体标签样式label : {// text : option.props.text,text : option.props.text,font : '14pt',// color : Cesium.Color.BLUE,style: Cesium.LabelStyle.FILL_AND_OUTLINE,outlineWidth : 200,//垂直位置// verticalOrigin : Cesium.VerticalOrigin.BUTTON,//中心位置// pixelOffset : new Cesium.Cartesian2(0,0),eyeOffset: new Cesium.Cartesian3(0, 0, -10),}});// viewer. entities.removeById(1)// let pinBuilder = new Cesium.PinBuilder();// let bluePin = viewer.entities.add({//   id:'1',//   name: "test",//   position: Cesium.Cartesian3.fromDegrees(Number(lon),Number(lat), 0),//   billboard: {//     image:'../img/标记.png',//     // image: pinBuilder.fromColor(Cesium.Color.ROYALBLUE, 48).toDataURL(),//     verticalOrigin: Cesium.VerticalOrigin.BOTTOM,//   },// });// Cesium.when.all(//   [bluePin],//   (pins)=> {//     viewer.zoomTo(pins);//   }// );// let loactionEntity;// if(loactionEntity)// viewer.entities.remove(loactionEntity);//  loactionEntity = new Cesium.Entity({//   id : 'flyTmp',//   position : Cesium.Cartesian3.fromDegrees(Number(lon),Number(lat), 2000.0),//   point : {//     pixelSize : 10,//     color : Cesium.Color.WHITE.withAlpha(0.9),//     outlineColor : Cesium.Color.WHITE.withAlpha(0.9),//     outlineWidth : 1//   }// });// viewer.entities.add(loactionEntity);// viewer.camera.flyTo(loactionEntity,{viewer.camera.flyTo({// viewer.flyTo(loactionEntity,{destination : Cesium.Cartesian3.fromDegrees(Number(lon),Number(lat), 5000.0),// orientation : {//   heading : Cesium.Math.toRadians(0.0),//   pitch : Cesium.Math.toRadians(-25.0),//   roll : 0.0// }});//添加点击事件let handler =new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);handler.setInputAction(function (movement) {let pick = viewer.scene.pick(movement.position);// if (Cesium.defined(pick) && (pick.id.id === cid)) {if (Cesium.defined(pick)) {// window.open('www.baidu.com');flag.markWin(null,position);}}, Cesium.ScreenSpaceEventType.LEFT_CLICK);// console.log('onSelect', value,option);//  let position=option.props.position;//  let lon=position.split(",")[0];//  let lat=position.split(",")[1];//  let viewer=  this.props.viewer.ceViewer;//  viewer.camera.flyTo({//    destination : Cesium.Cartesian3.fromDegrees(Number(lon),Number(lat), 5000.0),//    // orientation : {//    //   heading : Cesium.Math.toRadians(0.0),//    //   pitch : Cesium.Math.toRadians(-25.0),//    //   roll : 0.0//    // }//  });}markWin=(e,position)=>{alert("当前坐标:"+position)}//查询输入位置handleSearch=(position)=> {let data=this.state.data;data.position=positionthis.setState({data:data});this.props.dispatch({type:"query/querySecret",payload: {url:config.dataUrl+ "/userinfo/queryInputPositionData",data: {position:position}},callback:(result)=>{if(result.code==200){let list=[];// let list2=removesDuplicates(result.data,result.data.name);result.data.map((item)=>{if(item.location[0]!=null ){list.push({name:item.name,address:item.address,location:item.location,district:item.district,id:item.id});}})let position=this.state.data.position;this.setState({dataSource:list,status:false,});}}})};//点击搜索地点SearchPosition=(query)=>{let data=this.state.data;let position=data.positionconsole.log(query)this.props.dispatch({type:"query/querySecret",payload: {url:config.dataUrl+ "/userinfo/querySearchPositionData",data: {position:position,currentPage:1}},callback:(result)=>{if(result.code==200){let list=[];// let list2=removesDuplicates(result.data,result.data.name);result.data.map((item)=>{if(item.location[0]!=null ){list.push({name:item.name,address:item.address,location:item.location,district:item.cityname+item.adname,id:item.id,phones:item.photos});}})let position=this.state.data.position;let pageData=JSON.parse(result.result);this.setState({dataSource:list,status:true,pageIndex:1,pageCount:pageData.pageCount,resultCount:pageData.resultCount});}}})}InputText=(info)=>{console.log(info)}onChange=(info)=>{console.log(info)}changePage=(type,info)=>{let data=this.state.data;let position=data.positionlet flag=this;let page=this.state.pageIndex;if(type=="indexPage"){this.props.dispatch({type:"query/querySecret",payload: {url:config.dataUrl+ "/userinfo/querySearchPositionData",data: {position:position,currentPage:1}},callback:(result)=>{if(result.code==200){let list=[];// let list2=removesDuplicates(result.data,result.data.name);result.data.map((item)=>{if(item.location[0]!=null ){list.push({name:item.name,address:item.address,location:item.location,district:item.cityname+item.adname,id:item.id,phones:item.photos});}})let position=this.state.data.position;this.setState({dataSource:list,status:true,pageIndex:1});}}})}if(type=="upPage"){page=page-1;flag.props.dispatch({type:"query/querySecret",payload: {url:config.dataUrl+ "/userinfo/querySearchPositionData",data: {position:position,currentPage:page}},callback:(result)=>{if(result.code==200){let list=[];// let list2=removesDuplicates(result.data,result.data.name);result.data.map((item)=>{if(item.location[0]!=null ){list.push({name:item.name,address:item.address,location:item.location,district:item.cityname+item.adname,id:item.id,phones:item.photos});}})let position=this.state.data.position;flag.setState({dataSource:list,status:true,pageIndex:page});// flag.setState({//   currentPage:page-1// })}}})}if(type=="downPage"){page=page+1;flag.props.dispatch({type:"query/querySecret",payload: {url:config.dataUrl+ "/userinfo/querySearchPositionData",data: {position:position,currentPage:page}},callback:(result)=>{if(result.code==200){let list=[];// let list2=removesDuplicates(result.data,result.data.name);result.data.map((item)=>{if(item.location[0]!=null ){list.push({name:item.name,address:item.address,location:item.location,district:item.cityname+item.adname,id:item.id,phones:item.photos});}})let position=this.state.data.position;flag.setState({dataSource:list,status:true,pageIndex:page});// flag.setState({//   currentPage:page+1// })}}})}}render(){let dataSource=this.state.dataSource;console.log("dataSource:"+dataSource)let result;if(dataSource[0]!=undefined){result=dataSource.map(this.renderOption).concat([<Option    disabled key="all" className={this.state.status==false?styles.hide:styles.show}><div><span  onClick={this.changePage.bind(this,"indexPage")}>共找到{this.state.resultCount}条结果</span><span style={{marginLeft:'70px'}}>{this.state.pageIndex}/{this.state.pageCount}页</span><span style={{marginLeft:'20px',cursor:'pointer',borderStyle:'solid',borderWidth:'1px',width:20,height:20}} onClick={this.changePage.bind(this,"indexPage")}>首页</span><span style={{cursor:'pointer',borderStyle:'solid',borderWidth:'1px',width:20,height:20}}  className={this.state.pageIndex==1?styles.hideInput:styles.showInput} onClick={this.changePage.bind(this,"upPage")}>上一页</span><span style={{cursor:'pointer',borderStyle:'solid',borderWidth:'1px',width:20,height:20}} className={this.state.pageIndex==this.state.pageCount?styles.hideInput:styles.showInput} onClick={this.changePage.bind(this,"downPage")}>下一页</span></div></Option>,]);;console.log(result)}// const options = dataSource//   .map(group => (//     <OptGroup key={group.title}>//       {group.children.map(opt => (//         <Option key={opt.title} value={opt.title}>//           {opt.title}//         </Option>//       ))}//     </OptGroup>//   ))//   .concat([//     <Option disabled key="all" className="show-all">//       <div onClick={this.changePage}>//         首页//       </div>//     </Option>,//   ]);return(<div className={styles.Search}><div className="global-search-wrapper" style={{ width: 400 }}><AutoCompleteclassName="global-search"size="large"style={{ width: '100%' }}// dataSource={options}dataSource={result}// dataSource={this.state.dataSource==undefined?null:this.state.dataSource.map(this.renderOption)}onChange={this.onChange}onSelect={this.onSelect}onSearch={this.handleSearch}placeholder="请输入地名"optionLabelProp="text"><Input    allowClear={true}     onChange={this.InputText} suffix={<ButtonclassName="search-btn"style={{ marginRight: -12 }}size="large"type="primary"onClick={this.SearchPosition.bind(this)}><Icon type="search"     /></Button>}/></AutoComplete>{/*<div style={{backgroundColor:'white',width:500,height:200,position:'absolute',zIndex:200,top:'295px'}}>*/}{/*  <Pagination defaultCurrent={6} total={500}   />*/}{/*</div>*/}</div><div id="cesiumContainer"><div style={{position: "absolute",width: "100px",height: "100px",zIndex: 1000,display: "none",background: "rgba(255, 255, 255, 0.5)",border: "2px solid greenyellow",borderRadius: "4px"}}></div></div></div>)}
}
function mapStateToProps(state) {return {verify:state.verify,user:state.user,viewer:state.viewer,};
}
export default connect(mapStateToProps)(SearchPosition);

四、实现效果

1.输入地点下拉列表

2.点击内容定位

3.点击搜索详细内容

4.详细内容分页

5.点击标注弹出信息

Cesium调用高德地图服务实现搜索地点定位详解相关推荐

  1. C# 调用高德地图API获取经纬度以及定位,JS获取定位【万字详解附完整代码】

    最近有个需求,需要用到定位,本来打算用百度地图API定位,但是发现百度地图定位申请AppKey太麻烦了.因为是写的web端,百度地图定位API申请的Appkey需要网址过滤.索性就用高德定位了(有一说 ...

  2. Android之高德地图SDK配置及简单使用详解

    需要用到的东西请去高德地图API官网下载 本次教程是对比着高德官网的demo一步步添加东西,所以需要有一份demo就够了. 1.打开高德地图的demo(AMap3DDemo),同时新建一个项目 2.将 ...

  3. openlayers调用高德地图web服务绘制驾车路线规划

    openlayers调用高德地图web服务绘制驾车路线规划 使用ol.geom.Polygon()函数将坐标点连接成线时,只连接数组中首末两点的坐标,是因为数组中的值并非number类型,需要将其进行 ...

  4. Python调用高德地图API实现经纬度换算、地图可视化

    作者 | 糖甜甜甜 出品 | 经管人学数据分析 Python调用高德地图API实现经纬度换算.地图可视化 前地图可视化的工具和函数比较多,但是在不知道相关地点经纬度的情况下,通过python调用高德地 ...

  5. python 根据经纬度 调取和显示地图_Python调用高德地图API实现经纬度换算、地图可视化-站长资讯中心...

    目前地图可视化的工具和函数比较多,但是在不知道相关地点经纬度的情况下,通过python调用高德地图API实现经纬度换算,并且直接在高德地图新推出的轻量级可视化平台上实现一键式地图可视化,这其中需要申请 ...

  6. 你还在为高德地图找不到门牌号等详细地址而烦恼吗?你还在等什么——Python调用高德地图API实现经纬度换算、地图可视化

    Python调用高德地图API实现经纬度换算.地图可视化 前地图可视化的工具和函数比较多,但是在不知道相关地点经纬度的情况下,通过python调用高德地图API实现经纬度换算,并且直接在高德地图新推出 ...

  7. python调用高德地图api 可视化_Python调用高德地图API实现经纬度换算、地图可视化...

    前地图可视化的工具和函数比较多,但是在不知道相关地点经纬度的情况下,通过python调用高德地图API实现经纬度换算,并且直接在高德地图新推出的轻量级可视化平台上实现一键式地图可视化,这其中需要申请密 ...

  8. vue项目中调用高德地图vue-amap 插件 的AMap.PlaceSearch简用

    vue项目调用高德地图vue-amap 插件 的AMap.PlaceSearch简用 结合 elementui 的 el-input 直接下拉选取地点 不展示地图 1.下载 npm install v ...

  9. 高德地图api接口文档_在 R 语言里面调用高德地图接口:地理编码与路径规划

    你知道从广州南站去珠江新城怎么走么?今天就让我们一起使用 R 语言调用高德地图的地理编码(地址转经纬度)接口和路径规划接口来回答这个问题. 准备工作 注册高德地图,创建应用添加 Key(注意申请 Ke ...

最新文章

  1. apache 启动故障(httpd: apr_sockaddr_info_get() failed fo)
  2. TCP/IP 建立连接的过程
  3. Anaconda中安装pytorch,并在pycharm中配置【win10】
  4. 常见的面向对象的面试题(附答案)
  5. 天谕手游里的NPC真的很好看,画风特别的靓,背景音乐是万茜唱的
  6. JS时间戳和时间互转
  7. 装机之windows10和ubuntu双系统
  8. 【吼吼睡cocos2d学习笔记】第四章 - 第一个游戏
  9. java队列实现限流,java中应对高并发的两种策略
  10. 如何保护.net中的dll文件(防破解、反编译)
  11. Spark GraphX 的数据可视化
  12. linux boot命令用法,Linux基础命令介绍 - 2
  13. JAVA中jspinner设置选中内容_java – 如何在JSpinner中获取所选项的值?
  14. deepin驱动精灵_解决宏基笔记本没有Qualcomm_Atheros_QCA9377无线驱动
  15. 金融计算器 android,TVM金融计算器
  16. kaggle实战:Titanic
  17. 【毕设记录日记】深度学习|铝型材表面缺陷视觉检测算法:YOLOv5环境搭建、基础知识、问题解决、优化方法
  18. 一款app 开发在线工具:app inventor
  19. 东南大学计算机科学与网络,顾冠群
  20. win10用户名改了以后,C盘中用户文件夹下的以用户名命名的文件夹名字没有变化?还是之前的用户

热门文章

  1. 国家电子政务体系学习
  2. 计算机各按键的作用,【键盘各个键的功能图解】键盘各个键的功能介绍_键盘各个键的用途...
  3. 理论计算机科学杂志,理论计算机科学中的若干下界结果
  4. UVALive 5864 - Register Allocation
  5. Kafka - Zookeeper 服务器安装
  6. Centos7笔记之Postfix邮件服务器搭建
  7. 经济危机下,中国软件外包产业的走向
  8. 高德地图我的队伍查岗_高德地图查岗新功能 让你的行踪无所遁形
  9. “网上购车平台”又出低首付上私户新模式
  10. 日记侠:如何在微信赚钱?你要学会细分思维!