├── WebGisDemo ├── README.md ├── picture │ └── map-demo.png ├── src │ └── main │ │ ├── resources │ │ ├── static │ │ │ ├── css │ │ │ │ ├── mobile.css │ │ │ │ ├── images │ │ │ │ │ ├── layers.png │ │ │ │ │ ├── layers-2x.png │ │ │ │ │ ├── spritesheet.png │ │ │ │ │ └── spritesheet-2x.png │ │ │ │ ├── locate-ie.css │ │ │ │ ├── leaflet.mouseposition.css │ │ │ │ ├── locate.css │ │ │ │ ├── leaflet-ie.css │ │ │ │ ├── leaflet-search.css │ │ │ │ └── leaflet.draw.css │ │ │ ├── images │ │ │ │ ├── loader.gif │ │ │ │ ├── locate.png │ │ │ │ ├── spinner.gif │ │ │ │ ├── marker-icon.png │ │ │ │ ├── search-icon.png │ │ │ │ ├── locate_active.png │ │ │ │ ├── marker-shadow.png │ │ │ │ ├── marker-icon@2x.png │ │ │ │ └── locate.svg │ │ │ └── js │ │ │ │ └── leafletjs │ │ │ │ ├── images │ │ │ │ ├── marker-icon.png │ │ │ │ ├── marker-shadow.png │ │ │ │ └── marker-icon-2x.png │ │ │ │ ├── leaflet.map.js │ │ │ │ ├── leaflet.mouseposition.js │ │ │ │ ├── leaflet.draw.cn.js │ │ │ │ ├── leaflet.animatedmarker.js │ │ │ │ ├── proj4leaflet.js │ │ │ │ └── locate.js │ │ ├── application.properties │ │ ├── log4j │ │ │ ├── log4j2-prd.xml │ │ │ └── log4j2-dev.xml │ │ └── mapper │ │ │ └── StationMapper.xml │ │ └── java │ │ └── com │ │ └── luxx │ │ └── gis │ │ ├── model │ │ ├── request │ │ │ ├── DataInCircleRequest.java │ │ │ └── DataInRectangleRequest.java │ │ ├── PoiPoint.java │ │ ├── Station.java │ │ ├── PoiData.java │ │ ├── HotspotData.java │ │ ├── ResultData.java │ │ └── EndpointData.java │ │ ├── dao │ │ └── StationMapper.java │ │ ├── controller │ │ ├── MapController.java │ │ ├── DataIndexController.java │ │ └── StationController.java │ │ ├── service │ │ ├── StationService.java │ │ ├── IndexSearchService.java │ │ ├── IndexDataSource.java │ │ ├── RedshiftIndexService.java │ │ └── PoiIndexService.java │ │ ├── executor │ │ ├── IndexExecutor.java │ │ ├── PoiIndexExecutor.java │ │ ├── MysqlIndexExecutor.java │ │ └── RedshiftIndexExecutor.java │ │ ├── config │ │ ├── SwaggerConfig.java │ │ └── IndexConfig.java │ │ ├── WebGisApp.java │ │ └── util │ │ ├── JsonUtil.java │ │ └── DateFormatUtil.java ├── db_table │ └── db_table.sql └── pom.xml ├── MapHttpService ├── README.md ├── src │ └── main │ │ ├── resources │ │ ├── mapConfig.properties │ │ └── log4j.properties │ │ └── java │ │ └── com │ │ └── luxx │ │ └── map │ │ ├── config │ │ └── DbTypeEnum.java │ │ ├── service │ │ ├── MapRequestParam.java │ │ ├── MapCache.java │ │ ├── MapDbOperation.java │ │ └── HttpServerInboundHandler.java │ │ ├── util │ │ └── PropertiesUtil.java │ │ └── MapHttpServer.java └── pom.xml ├── LogCollector ├── src │ └── main │ │ ├── resources │ │ ├── application-prod.properties │ │ ├── application-staging.properties │ │ ├── application-dev.properties │ │ ├── application.properties │ │ ├── log4j2-dev.xml │ │ └── log4j2-prod.xml │ │ └── java │ │ └── com │ │ └── luxx │ │ └── log │ │ ├── executor │ │ ├── DataIndexExecutor.java │ │ ├── MainExecutor.java │ │ └── LogIndexExecutor.java │ │ ├── LogApp.java │ │ ├── util │ │ ├── DateTimeUtil.java │ │ └── JsonUtil.java │ │ ├── model │ │ └── AuditLog.java │ │ └── client │ │ └── ElasticSearchClient.java ├── entrypoint.sh ├── build.sh ├── Dockerfile ├── README.md ├── .gitignore ├── docker-compose.yml └── pom.xml ├── NettyMqService ├── src │ ├── main │ │ ├── resources │ │ │ ├── config.properties │ │ │ └── log4j.properties │ │ └── java │ │ │ └── com │ │ │ └── luxx │ │ │ └── mq │ │ │ ├── MainServer.java │ │ │ ├── config │ │ │ └── MqConfig.java │ │ │ ├── message │ │ │ ├── Message.java │ │ │ └── Header.java │ │ │ ├── handler │ │ │ ├── NettyMqServerChannelInitializer.java │ │ │ ├── HeartBeatHandler.java │ │ │ ├── MessageDecoder.java │ │ │ └── EchoServerHandler.java │ │ │ ├── util │ │ │ └── PropertiesUtil.java │ │ │ └── server │ │ │ ├── MqSender.java │ │ │ ├── NettyMqServer.java │ │ │ └── MqReceiver.java │ └── test │ │ └── java │ │ └── test │ │ ├── ClientMsgSender.java │ │ └── TcpClient.java ├── README.md └── pom.xml ├── pom.xml ├── .gitignore └── README.md /WebGisDemo/README.md: -------------------------------------------------------------------------------- 1 | # Web GIS Demo 2 | A simple web GIS page based on leaflet. -------------------------------------------------------------------------------- /MapHttpService/README.md: -------------------------------------------------------------------------------- 1 | # MapHttpService 2 | A simple Http Map Service providing tile image for Map. -------------------------------------------------------------------------------- /LogCollector/src/main/resources/application-prod.properties: -------------------------------------------------------------------------------- 1 | logging.config=classpath:log4j2-prod.xml 2 | -------------------------------------------------------------------------------- /LogCollector/src/main/resources/application-staging.properties: -------------------------------------------------------------------------------- 1 | logging.config=classpath:log4j2-prod.xml 2 | -------------------------------------------------------------------------------- /LogCollector/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | java $JAVA_OPTS -jar log-collector.jar --spring.profiles.active=${ENV} -------------------------------------------------------------------------------- /WebGisDemo/picture/map-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luxiaoxun/Code4Java/HEAD/WebGisDemo/picture/map-demo.png -------------------------------------------------------------------------------- /LogCollector/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | mvn clean 3 | mvn package -Dmaven.test.skip=true 4 | docker build . -t log-collector 5 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/css/mobile.css: -------------------------------------------------------------------------------- 1 | html, body, #map { 2 | margin: 0; 3 | padding: 0; 4 | width: 100%; 5 | height: 100%; 6 | } -------------------------------------------------------------------------------- /NettyMqService/src/main/resources/config.properties: -------------------------------------------------------------------------------- 1 | rabbitmq.host=192.8.125.202 2 | rabbitmq.port=5672 3 | rabbitmq.username=guest 4 | rabbitmq.password=guest -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/images/loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luxiaoxun/Code4Java/HEAD/WebGisDemo/src/main/resources/static/images/loader.gif -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/images/locate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luxiaoxun/Code4Java/HEAD/WebGisDemo/src/main/resources/static/images/locate.png -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/images/spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luxiaoxun/Code4Java/HEAD/WebGisDemo/src/main/resources/static/images/spinner.gif -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/css/images/layers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luxiaoxun/Code4Java/HEAD/WebGisDemo/src/main/resources/static/css/images/layers.png -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/images/marker-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luxiaoxun/Code4Java/HEAD/WebGisDemo/src/main/resources/static/images/marker-icon.png -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/images/search-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luxiaoxun/Code4Java/HEAD/WebGisDemo/src/main/resources/static/images/search-icon.png -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/css/images/layers-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luxiaoxun/Code4Java/HEAD/WebGisDemo/src/main/resources/static/css/images/layers-2x.png -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/images/locate_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luxiaoxun/Code4Java/HEAD/WebGisDemo/src/main/resources/static/images/locate_active.png -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/images/marker-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luxiaoxun/Code4Java/HEAD/WebGisDemo/src/main/resources/static/images/marker-shadow.png -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/css/images/spritesheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luxiaoxun/Code4Java/HEAD/WebGisDemo/src/main/resources/static/css/images/spritesheet.png -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/images/marker-icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luxiaoxun/Code4Java/HEAD/WebGisDemo/src/main/resources/static/images/marker-icon@2x.png -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/css/images/spritesheet-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luxiaoxun/Code4Java/HEAD/WebGisDemo/src/main/resources/static/css/images/spritesheet-2x.png -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/js/leafletjs/images/marker-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luxiaoxun/Code4Java/HEAD/WebGisDemo/src/main/resources/static/js/leafletjs/images/marker-icon.png -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/js/leafletjs/images/marker-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luxiaoxun/Code4Java/HEAD/WebGisDemo/src/main/resources/static/js/leafletjs/images/marker-shadow.png -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/js/leafletjs/images/marker-icon-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luxiaoxun/Code4Java/HEAD/WebGisDemo/src/main/resources/static/js/leafletjs/images/marker-icon-2x.png -------------------------------------------------------------------------------- /LogCollector/src/main/java/com/luxx/log/executor/DataIndexExecutor.java: -------------------------------------------------------------------------------- 1 | package com.luxx.log.executor; 2 | 3 | public abstract class DataIndexExecutor { 4 | public abstract void start(); 5 | 6 | public abstract void stop(); 7 | } 8 | -------------------------------------------------------------------------------- /LogCollector/src/main/resources/application-dev.properties: -------------------------------------------------------------------------------- 1 | logging.config=classpath:log4j2-dev.xml 2 | logging.level.root=info 3 | es.address=10.10.10.10:9200 4 | es.username=username 5 | es.password=password 6 | es.index=my_index 7 | kafka.url=10.10.10.20:9092 8 | kafka.topic=my_topic -------------------------------------------------------------------------------- /WebGisDemo/src/main/java/com/luxx/gis/model/request/DataInCircleRequest.java: -------------------------------------------------------------------------------- 1 | package com.luxx.gis.model.request; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class DataInCircleRequest { 7 | private double radius; 8 | private double lat; 9 | private double lng; 10 | } 11 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/css/locate-ie.css: -------------------------------------------------------------------------------- 1 | /* Conditional stylesheet for IE. */ 2 | .leaflet-control-locate { 3 | border: 3px solid #999; 4 | } 5 | 6 | .leaflet-control-locate a { 7 | background-color: #eee; 8 | } 9 | 10 | .leaflet-control-locate a:hover { 11 | background-color: #fff; 12 | } -------------------------------------------------------------------------------- /WebGisDemo/src/main/java/com/luxx/gis/model/request/DataInRectangleRequest.java: -------------------------------------------------------------------------------- 1 | package com.luxx.gis.model.request; 2 | 3 | import com.luxx.gis.model.PoiPoint; 4 | import lombok.Data; 5 | 6 | import java.util.List; 7 | 8 | @Data 9 | public class DataInRectangleRequest { 10 | private List points; 11 | } 12 | -------------------------------------------------------------------------------- /MapHttpService/src/main/resources/mapConfig.properties: -------------------------------------------------------------------------------- 1 | port=8899 2 | # Which database to use 0:SQLite 1:MySQL 3 | database.type=0 4 | database.mysql.url=jdbc:mysql://127.0.0.1/gmapcache 5 | database.mysql.username=luxx 6 | database.mysql.password=123456 7 | database.sqlite.path=E:\\GIS\\MapDownloader\\MapCache\\TileDBv5\\en\\Data.gmdb 8 | -------------------------------------------------------------------------------- /LogCollector/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | logging.config=classpath:log4j2-prod.xml 2 | logging.level.root=${LOG_LEVEL} 3 | spring.profiles.active=dev 4 | es.address=${ES_ADDRESS} 5 | es.username=${ES_USERNAME} 6 | es.password=${ES_PASSWORD} 7 | es.index=${ES_INDEX} 8 | kafka.url=${KAFKA_URL} 9 | kafka.topic=${KAFKA_TOPIC} 10 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/css/leaflet.mouseposition.css: -------------------------------------------------------------------------------- 1 | .leaflet-container .leaflet-control-mouseposition { 2 | background-color: rgba(255, 255, 255, 0.7); 3 | box-shadow: 0 0 5px #bbb; 4 | padding: 0 5px; 5 | margin:0; 6 | color: #333; 7 | font: 11px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif; 8 | } 9 | 10 | -------------------------------------------------------------------------------- /MapHttpService/src/main/java/com/luxx/map/config/DbTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.luxx.map.config; 2 | 3 | public enum DbTypeEnum { 4 | sqlite(0), mysql(1); 5 | private int type; 6 | 7 | DbTypeEnum(int type) { 8 | this.type = type; 9 | } 10 | 11 | public int getType() { 12 | return type; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /LogCollector/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM adoptopenjdk/openjdk8:alpine 2 | WORKDIR /service 3 | COPY target/log-collector-1.0.jar /service/log-collector.jar 4 | COPY entrypoint.sh /service/entrypoint.sh 5 | RUN chmod +x entrypoint.sh 6 | ENV LANG zh_CN.UTF-8 7 | ENTRYPOINT [ "./entrypoint.sh" ] 8 | #CMD ["java", "-jar", "log-collector.jar","--spring.profiles.active=${ENV}"] -------------------------------------------------------------------------------- /NettyMqService/src/main/java/com/luxx/mq/MainServer.java: -------------------------------------------------------------------------------- 1 | package com.luxx.mq; 2 | 3 | import com.luxx.mq.server.NettyMqServer; 4 | 5 | /** 6 | * Main Program 7 | */ 8 | public class MainServer { 9 | public static void main(String[] args) { 10 | NettyMqServer server = new NettyMqServer(); 11 | server.doStart(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /NettyMqService/src/main/java/com/luxx/mq/config/MqConfig.java: -------------------------------------------------------------------------------- 1 | package com.luxx.mq.config; 2 | 3 | public class MqConfig { 4 | public static String MQ_HOST = "rabbitmq.host"; 5 | public static String MQ_PORT = "rabbitmq.port"; 6 | public static String MQ_USERNAME = "rabbitmq.username"; 7 | public static String MQ_PASSWORD = "rabbitmq.password"; 8 | } 9 | -------------------------------------------------------------------------------- /LogCollector/README.md: -------------------------------------------------------------------------------- 1 | # 环境变量 2 | | 变量名 | 描述 | 是否必须 | 示例 | 3 | | ---- | ---- | ---- | ---- | 4 | | JAVA_OPTS | java 启动参数 | 否 | "-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8899" | 5 | | KAFKA_URL | 审计日志发送到 kafka 服务的地址。不配置时,审计日志输出到标准输出流 | 否 | 10.10.10.10:9092 | 6 | | KAFKA_TOPIC | 审计日志发送到 kafka 服务的 topic。如果 KAFKA_URL 没有配置,该项不生效,也可以不配置 | 否 | topic_test | 7 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/java/com/luxx/gis/model/PoiPoint.java: -------------------------------------------------------------------------------- 1 | package com.luxx.gis.model; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class PoiPoint { 7 | private double lat; 8 | private double lon; 9 | 10 | public PoiPoint() { 11 | } 12 | 13 | public PoiPoint(double lat, double lon) { 14 | this.lat = lat; 15 | this.lon = lon; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/java/com/luxx/gis/dao/StationMapper.java: -------------------------------------------------------------------------------- 1 | package com.luxx.gis.dao; 2 | 3 | import com.luxx.gis.model.Station; 4 | import org.apache.ibatis.annotations.Mapper; 5 | 6 | import java.util.List; 7 | 8 | @Mapper 9 | public interface StationMapper { 10 | List getStation(); 11 | 12 | int insert(Station station); 13 | 14 | int delete(int id); 15 | 16 | int update(Station station); 17 | } 18 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/java/com/luxx/gis/model/Station.java: -------------------------------------------------------------------------------- 1 | package com.luxx.gis.model; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class Station { 7 | private long id; 8 | 9 | private String countryCode; 10 | 11 | private String provider; 12 | 13 | private String lac; 14 | 15 | private String cell; 16 | 17 | private double latitude; 18 | 19 | private double longitude; 20 | 21 | private String address; 22 | } 23 | -------------------------------------------------------------------------------- /NettyMqService/README.md: -------------------------------------------------------------------------------- 1 | # NettyMqService 2 | A simple project demonstrates how to use Netty with RabbitMQ. 3 | 中文详情:[Chinese Details](http://www.cnblogs.com/luxiaoxun/p/4257105.html) 4 | ### Design: 5 | ![design](http://images.cnitblog.com/blog/434101/201501/282041130971204.jpg) 6 | ### Features: 7 | * Receive TCP packets from different clients and decode the message. 8 | * Send the TCP message to the third parts with rabbit mq. 9 | * Consume rabbit mq messages and send the message to TCP clients. 10 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/java/com/luxx/gis/controller/MapController.java: -------------------------------------------------------------------------------- 1 | package com.luxx.gis.controller; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.stereotype.Controller; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.servlet.ModelAndView; 7 | 8 | @Controller 9 | @Slf4j 10 | public class MapController { 11 | 12 | @GetMapping("/map") 13 | public ModelAndView map() { 14 | return new ModelAndView("map"); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /LogCollector/.gitignore: -------------------------------------------------------------------------------- 1 | logs/ 2 | HELP.md 3 | target/ 4 | !.mvn/wrapper/maven-wrapper.jar 5 | !**/src/main/** 6 | !**/src/test/** 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | 23 | ### NetBeans ### 24 | /nbproject/private/ 25 | /nbbuild/ 26 | /dist/ 27 | /nbdist/ 28 | /.nb-gradle/ 29 | build/ 30 | 31 | ### VS Code ### 32 | .vscode/ 33 | 34 | ### MAC OS ### 35 | .DS_Store 36 | -------------------------------------------------------------------------------- /LogCollector/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | log-collector: 4 | container_name: log-collector 5 | image: log-collector 6 | build: ./ 7 | environment: 8 | - JAVA_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8899 9 | - _JAVA_OPTIONS=-Xms1024m -Xmx2048m 10 | - LOG_LEVEL=info 11 | - ENV=dev 12 | - ES_ADDRESS=10.10.10.10:9200 13 | - ES_USERNAME=username 14 | - ES_PASSWORD=password 15 | - ES_INDEX=my_index 16 | - KAFKA_URL=10.10.10.20:9092 17 | - KAFKA_TOPIC=my_topic 18 | ports: 19 | - "9899:8899" 20 | - "9090:8080" -------------------------------------------------------------------------------- /WebGisDemo/src/main/java/com/luxx/gis/model/PoiData.java: -------------------------------------------------------------------------------- 1 | package com.luxx.gis.model; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | 7 | @Data 8 | public class PoiData implements Serializable { 9 | private static final long serialVersionUID = -3978597686509612192L; 10 | 11 | private long id; 12 | private String address; 13 | private PoiPoint poiPoint; 14 | 15 | public PoiData() { 16 | } 17 | 18 | public PoiData(long id, String address, double lat, double lng) { 19 | this.id = id; 20 | this.address = address; 21 | this.poiPoint = new PoiPoint(lat, lng); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/css/locate.css: -------------------------------------------------------------------------------- 1 | .leaflet-bar-part-single { 2 | -webkit-border-radius: 4px 4px 4px 4px; 3 | border-radius: 4px 4px 4px 4px; 4 | border-bottom: none; 5 | } 6 | 7 | .leaflet-touch .leaflet-bar-part-single { 8 | -webkit-border-radius: 7px 7px 7px 7px; 9 | border-radius: 7px 7px 7px 7px; 10 | border-bottom: none; 11 | } 12 | 13 | .leaflet-control-locate a { 14 | background-image: url(images/locate.png); 15 | } 16 | 17 | .leaflet-control-locate.requesting a { 18 | background-image: url(images/spinner.gif); 19 | } 20 | 21 | .leaflet-control-locate.active a { 22 | background-image: url(images/locate_active.png); 23 | } -------------------------------------------------------------------------------- /WebGisDemo/src/main/java/com/luxx/gis/model/HotspotData.java: -------------------------------------------------------------------------------- 1 | package com.luxx.gis.model; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | import java.util.Date; 7 | 8 | @Data 9 | public class HotspotData implements Serializable { 10 | private static final long serialVersionUID = -2132799122365334550L; 11 | 12 | private Long id; 13 | private int seqNum; 14 | private Date collectTime; 15 | 16 | private String imsi; 17 | private String imei; 18 | private String tmsi; 19 | 20 | private String srcLac; 21 | private String deviceID; 22 | private String teleOper; 23 | private String ownArea; 24 | private String teleSevenNum; 25 | private String teleBrand; 26 | } 27 | -------------------------------------------------------------------------------- /LogCollector/src/main/java/com/luxx/log/LogApp.java: -------------------------------------------------------------------------------- 1 | package com.luxx.log; 2 | 3 | import org.springframework.boot.Banner; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.SpringBootConfiguration; 6 | import org.springframework.boot.autoconfigure.SpringBootApplication; 7 | 8 | 9 | import java.util.TimeZone; 10 | 11 | @SpringBootApplication 12 | @SpringBootConfiguration 13 | public class LogApp { 14 | public static void main(String[] args) { 15 | TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai")); 16 | SpringApplication springApplication = new SpringApplication(LogApp.class); 17 | springApplication.setBannerMode(Banner.Mode.LOG); 18 | springApplication.run(args); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/java/com/luxx/gis/model/ResultData.java: -------------------------------------------------------------------------------- 1 | package com.luxx.gis.model; 2 | 3 | public class ResultData { 4 | private String msg; 5 | private Object data; 6 | 7 | public ResultData() { 8 | } 9 | 10 | public String getMsg() { 11 | return msg; 12 | } 13 | 14 | public void setMsg(String msg) { 15 | this.msg = msg; 16 | } 17 | 18 | public Object getData() { 19 | return data; 20 | } 21 | 22 | public void setData(Object data) { 23 | this.data = data; 24 | } 25 | 26 | @Override 27 | public String toString() { 28 | return "ResultData{" + 29 | "msg='" + msg + '\'' + 30 | ", data=" + data + 31 | '}'; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /LogCollector/src/main/java/com/luxx/log/executor/MainExecutor.java: -------------------------------------------------------------------------------- 1 | package com.luxx.log.executor; 2 | 3 | import org.springframework.beans.factory.DisposableBean; 4 | import org.springframework.beans.factory.InitializingBean; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Component; 7 | 8 | @Component 9 | public class MainExecutor implements InitializingBean, DisposableBean { 10 | @Autowired 11 | private DataIndexExecutor dataIndexExecutor; 12 | 13 | @Override 14 | public void afterPropertiesSet() throws Exception { 15 | dataIndexExecutor.start(); 16 | } 17 | 18 | @Override 19 | public void destroy() throws Exception { 20 | dataIndexExecutor.stop(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /MapHttpService/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # Root logger option 2 | log4j.rootLogger=info, stdout, file 3 | 4 | # Direct log messages to stdout 5 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 6 | log4j.appender.stdout.Target=System.out 7 | log4j.appender.stdout.Threshold=info 8 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 9 | log4j.appender.stdout.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} %5p %c{1}:%L - %m%n 10 | 11 | # Direct log messages to file 12 | log4j.appender.file=org.apache.log4j.DailyRollingFileAppender 13 | log4j.appender.file.File=logs/map.log 14 | log4j.appender.file.Append=true 15 | log4j.appender.file.Threshold=info 16 | log4j.appender.file.layout=org.apache.log4j.PatternLayout 17 | log4j.appender.file.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} %5p %c{1}:%L - %m%n 18 | -------------------------------------------------------------------------------- /NettyMqService/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # Root logger option 2 | log4j.rootLogger=info, stdout, file 3 | 4 | # Direct log messages to stdout 5 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 6 | log4j.appender.stdout.Target=System.out 7 | log4j.appender.stdout.Threshold=info 8 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 9 | log4j.appender.stdout.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} %5p %c{1}:%L - %m%n 10 | 11 | # Direct log messages to file 12 | log4j.appender.file=org.apache.log4j.DailyRollingFileAppender 13 | log4j.appender.file.File=logs/mq-service.log 14 | log4j.appender.file.Append=true 15 | log4j.appender.file.Threshold=info 16 | log4j.appender.file.layout=org.apache.log4j.PatternLayout 17 | log4j.appender.file.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} %5p %c{1}:%L - %m%n 18 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/java/com/luxx/gis/service/StationService.java: -------------------------------------------------------------------------------- 1 | package com.luxx.gis.service; 2 | 3 | import java.util.List; 4 | 5 | import com.luxx.gis.dao.StationMapper; 6 | import com.luxx.gis.model.Station; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Service; 9 | 10 | @Service 11 | public class StationService { 12 | @Autowired 13 | private StationMapper stationMapper; 14 | 15 | public List getStation() { 16 | return stationMapper.getStation(); 17 | } 18 | 19 | public int insert(Station station) { 20 | return stationMapper.insert(station); 21 | } 22 | 23 | public int update(Station station) { 24 | return stationMapper.update(station); 25 | } 26 | 27 | public int delete(int id) { 28 | return stationMapper.delete(id); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/java/com/luxx/gis/executor/IndexExecutor.java: -------------------------------------------------------------------------------- 1 | package com.luxx.gis.executor; 2 | 3 | import java.sql.Connection; 4 | import java.sql.ResultSet; 5 | import java.sql.Statement; 6 | 7 | public abstract class IndexExecutor { 8 | public abstract void start(); 9 | 10 | public abstract void stop(); 11 | 12 | public void attemptClose(ResultSet o) { 13 | try { 14 | if (o != null) 15 | o.close(); 16 | } catch (Exception e) { 17 | } 18 | } 19 | 20 | public void attemptClose(Statement o) { 21 | try { 22 | if (o != null) 23 | o.close(); 24 | } catch (Exception e) { 25 | } 26 | } 27 | 28 | public void attemptClose(Connection o) { 29 | try { 30 | if (o != null) 31 | o.close(); 32 | } catch (Exception e) { 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/java/com/luxx/gis/controller/DataIndexController.java: -------------------------------------------------------------------------------- 1 | package com.luxx.gis.controller; 2 | 3 | import com.luxx.gis.executor.IndexExecutor; 4 | import com.luxx.gis.model.ResultData; 5 | import io.swagger.annotations.Api; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.beans.factory.annotation.Qualifier; 9 | import org.springframework.web.bind.annotation.*; 10 | 11 | @RestController 12 | @RequestMapping("/data") 13 | @Api(tags = "data") 14 | @Slf4j 15 | public class DataIndexController { 16 | @Autowired 17 | @Qualifier("poiIndexExecutor") 18 | private IndexExecutor indexExecutor; 19 | 20 | @PostMapping(value = "/index") 21 | public ResultData indexData() { 22 | log.info("Start to index data"); 23 | indexExecutor.start(); 24 | ResultData msg = new ResultData(); 25 | msg.setMsg("ok"); 26 | return msg; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/java/com/luxx/gis/service/IndexSearchService.java: -------------------------------------------------------------------------------- 1 | package com.luxx.gis.service; 2 | 3 | import com.luxx.gis.model.PoiData; 4 | import org.springframework.beans.factory.DisposableBean; 5 | import org.springframework.beans.factory.InitializingBean; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.context.annotation.Lazy; 8 | import org.springframework.stereotype.Service; 9 | 10 | import java.util.List; 11 | 12 | @Service 13 | public class IndexSearchService { 14 | @Autowired 15 | private PoiIndexService poiIndexService; 16 | 17 | public List searchPoiInCircle(double lng, double lat, double radius) { 18 | return poiIndexService.searchPoiInCircle(lng, lat, String.valueOf(radius)); 19 | } 20 | 21 | public List searchPoiInRectangle(double minLng, double minLat, 22 | double maxLng, double maxLat) { 23 | return poiIndexService.searchPoiInRectangle(minLng, minLat, maxLng, maxLat); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /NettyMqService/src/main/java/com/luxx/mq/message/Message.java: -------------------------------------------------------------------------------- 1 | package com.luxx.mq.message; 2 | 3 | public class Message { 4 | private Header header; 5 | private byte[] data; 6 | 7 | public Header getHeader() { 8 | return header; 9 | } 10 | 11 | public void setHeader(Header header) { 12 | this.header = header; 13 | } 14 | 15 | public byte[] getData() { 16 | return data; 17 | } 18 | 19 | public void setData(byte[] data) { 20 | this.data = data; 21 | } 22 | 23 | public byte[] getBytes() { 24 | if (header != null) { 25 | int len = header.getMsgLength(); 26 | byte[] buffer = new byte[len]; 27 | byte[] headerBytes = header.getBytes(); 28 | System.arraycopy(headerBytes, 0, buffer, 0, headerBytes.length); 29 | if (data != null) { 30 | System.arraycopy(data, 0, buffer, headerBytes.length, data.length); 31 | } 32 | return buffer; 33 | } 34 | return null; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /LogCollector/src/main/java/com/luxx/log/util/DateTimeUtil.java: -------------------------------------------------------------------------------- 1 | package com.luxx.log.util; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.apache.logging.log4j.Logger; 5 | import org.joda.time.DateTime; 6 | import org.joda.time.format.DateTimeFormat; 7 | import org.joda.time.format.DateTimeFormatter; 8 | 9 | public class DateTimeUtil { 10 | 11 | private static Logger logger = LogManager.getLogger(DateTimeUtil.class); 12 | 13 | private static final DateTimeFormatter YYYY_MM = DateTimeFormat.forPattern("yyyy_MM"); 14 | private static final DateTimeFormatter YMD_HMS_SSS = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSS"); 15 | private static final DateTimeFormatter YMD_HMS_Z = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); 16 | 17 | public static String currentYM() { 18 | return YYYY_MM.print(DateTime.now()); 19 | } 20 | 21 | public static String getEsString(long timestamp) { 22 | return YMD_HMS_Z.print(timestamp); 23 | } 24 | 25 | public static DateTime convertToDateTime(String timestamp) { 26 | return YMD_HMS_SSS.parseDateTime(timestamp); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /NettyMqService/src/main/java/com/luxx/mq/message/Header.java: -------------------------------------------------------------------------------- 1 | package com.luxx.mq.message; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | public class Header { 6 | private int msgLength; // The whole message length includes header 7 | private byte msgType; // one byte for message type 8 | 9 | public int getMsgLength() { 10 | // ByteBuffer b = ByteBuffer.wrap(msgLength); 11 | // return b.getInt(); 12 | return msgLength; 13 | } 14 | 15 | public void setMsgLength(int msgLength) { 16 | // ByteBuffer b = ByteBuffer.allocate(4); 17 | // b.putInt(msgLength); 18 | // this.msgLength = b.array(); 19 | this.msgLength = msgLength; 20 | } 21 | 22 | public byte getMsgType() { 23 | return msgType; 24 | } 25 | 26 | public void setMsgType(byte msgType) { 27 | this.msgType = msgType; 28 | } 29 | 30 | public byte[] getBytes() { 31 | byte[] buffer = new byte[5]; 32 | ByteBuffer b = ByteBuffer.allocate(4); 33 | b.putInt(msgLength); 34 | System.arraycopy(b.array(), 0, buffer, 0, 4); 35 | buffer[4] = msgType; 36 | return buffer; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | #spring.profiles.active=dev 2 | server.port=9090 3 | # resources 4 | spring.mvc.servlet.load-on-startup=0 5 | spring.mvc.static-path-pattern=/static/** 6 | spring.mvc.servlet.path=/ 7 | # freemarker 8 | spring.freemarker.templateLoaderPath=classpath:/templates/ 9 | spring.freemarker.suffix=.ftl 10 | spring.freemarker.charset=UTF-8 11 | spring.freemarker.request-context-attribute=request 12 | spring.freemarker.settings.number_format=0.########## 13 | # spring mybatis 14 | mybatis.mapper-locations=classpath*:/mapper/*.xml 15 | logging.config=classpath:log4j/log4j2-dev.xml 16 | # spring datasource 17 | spring.datasource.url=jdbc:mysql://127.0.0.1:3306/data_db?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&allowPublicKeyRetrieval=true&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8 18 | spring.datasource.username=root 19 | spring.datasource.password=admin 20 | # ES 21 | es.address=127.0.0.1:9200 22 | # POI index DB 23 | index.db.url=jdbc:mysql://127.0.0.1:3306/data_db?useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai 24 | index.db.username=root 25 | index.db.password=admin 26 | index.db.table=station 27 | index.db.type=mysql 28 | -------------------------------------------------------------------------------- /NettyMqService/src/main/java/com/luxx/mq/handler/NettyMqServerChannelInitializer.java: -------------------------------------------------------------------------------- 1 | package com.luxx.mq.handler; 2 | 3 | import com.luxx.mq.server.MqSender; 4 | import io.netty.channel.ChannelInitializer; 5 | import io.netty.channel.socket.SocketChannel; 6 | import io.netty.handler.codec.LengthFieldBasedFrameDecoder; 7 | import io.netty.handler.timeout.IdleStateHandler; 8 | 9 | /** 10 | * Netty ChannelInitializer 11 | */ 12 | public class NettyMqServerChannelInitializer extends ChannelInitializer { 13 | 14 | // private EventBus eventBus; 15 | private MqSender mqSender; 16 | 17 | public NettyMqServerChannelInitializer(MqSender mqSender) { 18 | this.mqSender = mqSender; 19 | } 20 | 21 | @Override 22 | public void initChannel(SocketChannel ch) throws Exception { 23 | // Reader idle time 3 minutes 24 | ch.pipeline().addLast(new IdleStateHandler(3 * 60, 0, 0)); 25 | ch.pipeline().addLast(new HeartBeatHandler()); 26 | ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(65536, 0, 4, -4, 0)); 27 | ch.pipeline().addLast(new MessageDecoder()); 28 | ch.pipeline().addLast(new EchoServerHandler(mqSender)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/java/com/luxx/gis/config/SwaggerConfig.java: -------------------------------------------------------------------------------- 1 | package com.luxx.gis.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import springfox.documentation.builders.ApiInfoBuilder; 6 | import springfox.documentation.builders.PathSelectors; 7 | import springfox.documentation.builders.RequestHandlerSelectors; 8 | import springfox.documentation.service.ApiInfo; 9 | import springfox.documentation.spi.DocumentationType; 10 | import springfox.documentation.spring.web.plugins.Docket; 11 | 12 | @Configuration 13 | public class SwaggerConfig { 14 | @Bean 15 | public Docket createRestApi() { 16 | return new Docket(DocumentationType.SWAGGER_2) 17 | .apiInfo(apiInfo()) 18 | .select() 19 | .apis(RequestHandlerSelectors.basePackage("com.luxx.gis")) 20 | .paths(PathSelectors.any()) 21 | .build(); 22 | } 23 | 24 | // 构建 api文档的详细信息函数 25 | private ApiInfo apiInfo() { 26 | return new ApiInfoBuilder() 27 | .title("WEB GIS平台") 28 | .version("1.0") 29 | .build(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /LogCollector/src/main/java/com/luxx/log/model/AuditLog.java: -------------------------------------------------------------------------------- 1 | package com.luxx.log.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.Data; 5 | 6 | @Data 7 | public class AuditLog { 8 | @JsonProperty("log_type") 9 | private String logType = "audit_log"; 10 | 11 | @JsonProperty("request_type") 12 | private String requestType = "service-backend"; 13 | 14 | @JsonProperty("user_name") 15 | private String userName; 16 | 17 | @JsonProperty("source_ip") 18 | private String sourceIp; 19 | 20 | @JsonProperty("request_uri") 21 | private String requestUri; 22 | 23 | @JsonProperty("request_params") 24 | private String requestParams; 25 | 26 | @JsonProperty("request_method") 27 | private String requestMethod; 28 | 29 | @JsonProperty("request_body") 30 | private String requestBody; 31 | 32 | @JsonProperty("request_time") 33 | private String requestTime; 34 | 35 | @JsonProperty("response_http_code") 36 | private int responseHttpCode; 37 | 38 | @JsonProperty("response_body_code") 39 | private int responseBodyCode; 40 | 41 | @JsonProperty("response_body_msg") 42 | private String responseBodyMsg; 43 | } 44 | -------------------------------------------------------------------------------- /NettyMqService/src/main/java/com/luxx/mq/handler/HeartBeatHandler.java: -------------------------------------------------------------------------------- 1 | package com.luxx.mq.handler; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelInboundHandlerAdapter; 8 | import io.netty.handler.timeout.IdleState; 9 | import io.netty.handler.timeout.IdleStateEvent; 10 | 11 | /** 12 | * Handler implementation for heart beating. 13 | */ 14 | public class HeartBeatHandler extends ChannelInboundHandlerAdapter { 15 | private static final Logger log = LoggerFactory.getLogger(HeartBeatHandler.class); 16 | 17 | @Override 18 | public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { 19 | if (evt instanceof IdleStateEvent) { 20 | IdleStateEvent event = (IdleStateEvent) evt; 21 | if (event.state() == IdleState.READER_IDLE) { 22 | // Read timeout 23 | // System.out.println("READER_IDLE: read timeout from "+ctx.channel().remoteAddress()); 24 | // ctx.disconnect(); //Channel disconnect 25 | log.info("READER_IDLE: read idle from " + ctx.channel().remoteAddress()); 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /NettyMqService/src/test/java/test/ClientMsgSender.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import java.io.IOException; 4 | import java.io.OutputStream; 5 | import java.util.concurrent.Executors; 6 | import java.util.concurrent.ScheduledExecutorService; 7 | import java.util.concurrent.TimeUnit; 8 | 9 | public class ClientMsgSender { 10 | 11 | private final ScheduledExecutorService scheduler = Executors 12 | .newScheduledThreadPool(1); 13 | 14 | private OutputStream out; 15 | 16 | public ClientMsgSender(OutputStream out) { 17 | this.out = out; 18 | } 19 | 20 | public void stop() { 21 | scheduler.shutdown(); 22 | } 23 | 24 | public void start() { 25 | scheduler.scheduleWithFixedDelay(new Runnable() { 26 | public void run() { 27 | String msg = new String("Test Msg"); 28 | byte[] msgBytes = TcpClient.getMessageBytes(msg); 29 | if (msgBytes != null) { 30 | try { 31 | out.write(msgBytes); 32 | } catch (IOException e) { 33 | e.printStackTrace(); 34 | } 35 | } 36 | } 37 | }, 3, 1, TimeUnit.SECONDS); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/js/leafletjs/leaflet.map.js: -------------------------------------------------------------------------------- 1 | var googleNormalUrl = 'http://127.0.0.1:8899/1818940751/{z}/{x}/{y}'; 2 | var googleNormalLayer = new L.TileLayer(googleNormalUrl, { 3 | minZoom : 1, 4 | maxZoom : 18, 5 | attribution : '谷歌普通地图' 6 | }); 7 | 8 | var googleSateliteUrl = 'http://127.0.0.1:8899/47626774/{z}/{x}/{y}'; 9 | var googleSateliteLayer = new L.TileLayer(googleSateliteUrl, { 10 | minZoom : 1, 11 | maxZoom : 18, 12 | attribution : '谷歌卫星地图' 13 | }); 14 | 15 | var baiduNormalUrl = 'http://127.0.0.1:8899/1082287436/{z}/{x}/{y}'; 16 | var baiduNormalLayer = new L.TileLayer(baiduNormalUrl, { 17 | minZoom : 1, 18 | maxZoom : 18, 19 | attribution : '百度普通地图' 20 | }); 21 | 22 | var amapNormalUrl = 'http://127.0.0.1:8899/788865972/{z}/{x}/{y}'; 23 | var amapNormalLayer = new L.TileLayer(amapNormalUrl, { 24 | minZoom : 1, 25 | maxZoom : 18, 26 | attribution : '高德普通地图' 27 | }); 28 | 29 | var amapSateliteUrl = 'http://127.0.0.1:8899/1542757547/{z}/{x}/{y}'; 30 | var amapSateliteLayer = new L.TileLayer(amapSateliteUrl, { 31 | minZoom : 1, 32 | maxZoom : 18, 33 | attribution : '高德卫星地图' 34 | }); 35 | 36 | var amapSateliteAnnoUrl = 'http://127.0.0.1:8899/1447870524/{z}/{x}/{y}'; 37 | var amapSateliteAnnoLayer = new L.TileLayer(amapSateliteAnnoUrl, { 38 | minZoom : 1, 39 | maxZoom : 18, 40 | attribution : '高德卫星地图(标注)' 41 | }); 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.luxx 7 | Code4Java 8 | 1.0.0 9 | pom 10 | 11 | 12 | MapHttpService 13 | NettyMqService 14 | WebGisDemo 15 | LogCollector 16 | 17 | 18 | 19 | UTF-8 20 | 1.8 21 | 1.8 22 | 23 | 24 | 25 | 26 | 27 | org.apache.maven.plugins 28 | maven-compiler-plugin 29 | 3.8.1 30 | 31 | 8 32 | 8 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /NettyMqService/src/main/java/com/luxx/mq/util/PropertiesUtil.java: -------------------------------------------------------------------------------- 1 | package com.luxx.mq.util; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | import java.io.InputStream; 7 | import java.util.Properties; 8 | 9 | public class PropertiesUtil { 10 | private static Logger log = LoggerFactory.getLogger(PropertiesUtil.class); 11 | 12 | private static final String propertiesFile = "/config.properties"; 13 | private Properties prop; 14 | 15 | private PropertiesUtil() { 16 | prop = new Properties(System.getProperties()); 17 | try { 18 | InputStream propFile = PropertiesUtil.class.getResourceAsStream(propertiesFile); 19 | prop.load(propFile); 20 | } catch (Exception e) { 21 | log.error("Load properties file " + propertiesFile + " failed. " + e.getMessage()); 22 | } 23 | } 24 | 25 | private static class PropertiesUtilHolder { 26 | static final PropertiesUtil instance = new PropertiesUtil(); 27 | } 28 | 29 | public static PropertiesUtil getInstance() { 30 | return PropertiesUtilHolder.instance; 31 | } 32 | 33 | public String getProperty(String key) { 34 | String value = prop.getProperty(key); 35 | return value; 36 | } 37 | 38 | public Integer getPropertyAsInt(String key) { 39 | String value = prop.getProperty(key); 40 | return Integer.valueOf(value); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /NettyMqService/src/main/java/com/luxx/mq/handler/MessageDecoder.java: -------------------------------------------------------------------------------- 1 | package com.luxx.mq.handler; 2 | 3 | import java.util.List; 4 | 5 | import com.luxx.mq.message.Header; 6 | import com.luxx.mq.message.Message; 7 | 8 | import io.netty.buffer.ByteBuf; 9 | import io.netty.channel.ChannelHandlerContext; 10 | import io.netty.handler.codec.ByteToMessageDecoder; 11 | 12 | public class MessageDecoder extends ByteToMessageDecoder { 13 | 14 | @Override 15 | protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { 16 | // At least 5 bytes to decode 17 | if (in.readableBytes() < 5) { 18 | return; 19 | } 20 | 21 | in.markReaderIndex(); 22 | int msgLength = in.readInt(); 23 | if (in.readableBytes() < msgLength) { 24 | in.resetReaderIndex(); 25 | return; 26 | } 27 | 28 | byte msgType = in.readByte(); 29 | if (msgLength >= 5) { 30 | ByteBuf bf = in.readBytes(msgLength - 5); 31 | byte[] data = bf.array(); 32 | Header header = new Header(); 33 | header.setMsgLength(msgLength); 34 | header.setMsgType(msgType); 35 | 36 | Message message = new Message(); 37 | message.setHeader(header); 38 | message.setData(data); 39 | 40 | out.add(message); // Decode one message successfully 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/css/leaflet-ie.css: -------------------------------------------------------------------------------- 1 | .leaflet-vml-shape { 2 | width: 1px; 3 | height: 1px; 4 | } 5 | .lvml { 6 | behavior: url(#default#VML); 7 | display: inline-block; 8 | position: absolute; 9 | } 10 | 11 | .leaflet-control { 12 | display: inline; 13 | } 14 | 15 | .leaflet-popup-tip { 16 | width: 21px; 17 | _width: 27px; 18 | margin: 0 auto; 19 | _margin-top: -3px; 20 | 21 | filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678); 22 | -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)"; 23 | } 24 | .leaflet-popup-tip-container { 25 | margin-top: -1px; 26 | } 27 | .leaflet-popup-content-wrapper, .leaflet-popup-tip { 28 | border: 1px solid #999; 29 | } 30 | .leaflet-popup-content-wrapper { 31 | zoom: 1; 32 | } 33 | 34 | .leaflet-control-zoom, 35 | .leaflet-control-layers { 36 | border: 3px solid #999; 37 | } 38 | .leaflet-control-zoom a { 39 | background-color: #eee; 40 | } 41 | .leaflet-control-zoom a:hover { 42 | background-color: #fff; 43 | } 44 | .leaflet-control-layers-toggle { 45 | } 46 | .leaflet-control-attribution, 47 | .leaflet-control-layers, 48 | .leaflet-control-scale-line { 49 | background: white; 50 | } 51 | .leaflet-zoom-box { 52 | filter: alpha(opacity=50); 53 | } 54 | .leaflet-control-attribution { 55 | border-top: 1px solid #bbb; 56 | border-left: 1px solid #bbb; 57 | } 58 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/java/com/luxx/gis/WebGisApp.java: -------------------------------------------------------------------------------- 1 | package com.luxx.gis; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.SpringBootConfiguration; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.context.annotation.ComponentScan; 7 | import org.springframework.web.servlet.config.annotation.EnableWebMvc; 8 | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 9 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 10 | 11 | @SpringBootApplication 12 | @SpringBootConfiguration 13 | @EnableWebMvc 14 | @ComponentScan(basePackages = "com.luxx") 15 | public class WebGisApp implements WebMvcConfigurer { 16 | private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { 17 | "classpath:/META-INF/resources/", "classpath:/resources/", 18 | "classpath:/static/", "classpath:/public/"}; 19 | 20 | public static void main(String[] args) { 21 | SpringApplication.run(WebGisApp.class, args); 22 | } 23 | 24 | @Override 25 | public void addResourceHandlers(ResourceHandlerRegistry registry) { 26 | registry.addResourceHandler("swagger-ui.html") 27 | .addResourceLocations("classpath:/META-INF/resources/"); 28 | registry.addResourceHandler("/webjars/**") 29 | .addResourceLocations("classpath:/META-INF/resources/webjars/"); 30 | registry.addResourceHandler("/static/**") 31 | .addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /WebGisDemo/db_table/db_table.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE `data_db`; 2 | 3 | USE `data_db`; 4 | 5 | DROP TABLE IF EXISTS `station`; 6 | CREATE TABLE `station` ( 7 | `id` bigint(20) NOT NULL AUTO_INCREMENT, 8 | `country_code` varchar(16) DEFAULT '', 9 | `provider` varchar(32) DEFAULT '', 10 | `lac` varchar(32) DEFAULT '', 11 | `cell` varchar(32) DEFAULT '', 12 | `latitude` DOUBLE(20,8) DEFAULT NULL, 13 | `longitude` DOUBLE(20,8) DEFAULT NULL, 14 | `address` varchar(512) DEFAULT '', 15 | PRIMARY KEY (`id`) 16 | ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='station table' 17 | 18 | INSERT INTO `station` (`id`, `country_code`, `provider`, `lac`, `cell`, `latitude`, `longitude`, `address`) 19 | VALUES ('1', '406', '0', '111', '222', '32.12800000', '118.77420000', '南京测试点1'); 20 | 21 | INSERT INTO `station` (`id`, `country_code`, `provider`, `lac`, `cell`, `latitude`, `longitude`, `address`) 22 | VALUES ('2', '406', '1', '123', '234', '32.22700000', '118.86420000', '南京测试点2'); 23 | 24 | INSERT INTO `station` (`id`, `country_code`, `provider`, `lac`, `cell`, `latitude`, `longitude`, `address`) 25 | VALUES ('3', '406', '0', '222', '333', '30.32600000', '118.78420000', '南京测试点3'); 26 | 27 | INSERT INTO `station` (`id`, `country_code`, `provider`, `lac`, `cell`, `latitude`, `longitude`, `address`) 28 | VALUES ('4', '406', '1', '123', '234', '31.22700000', '118.56420000', '南京测试点4'); 29 | 30 | INSERT INTO `station` (`id`, `country_code`, `provider`, `lac`, `cell`, `latitude`, `longitude`, `address`) 31 | VALUES ('5', '406', '0', '222', '333', '32.32600000', '118.68420000', '南京测试点5'); 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # .gitignore for intellij,java,maven,windows,osx 2 | 3 | ### Intellij ### 4 | .idea 5 | .idea_modules/ 6 | /out/ 7 | output/ 8 | 9 | ####eclipse####### 10 | .project 11 | .classpath 12 | .settings 13 | 14 | ### log ### 15 | logs/ 16 | log/ 17 | *.log 18 | 19 | *.iws 20 | *.iml 21 | 22 | ### Java ### 23 | *.class 24 | 25 | # Mobile Tools for Java (J2ME) 26 | .mtj.tmp/ 27 | 28 | # Package Files # 29 | *.jar 30 | *.war 31 | *.ear 32 | 33 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 34 | hs_err_pid* 35 | 36 | ### Maven ### 37 | target/ 38 | pom.xml.tag 39 | pom.xml.releaseBackup 40 | pom.xml.versionsBackup 41 | pom.xml.next 42 | release.properties 43 | dependency-reduced-pom.xml 44 | buildNumber.properties 45 | .mvn/timing.properties 46 | 47 | ### Windows ### 48 | # Windows image file caches 49 | Thumbs.db 50 | ehthumbs.db 51 | 52 | # Folder config file 53 | Desktop.ini 54 | 55 | # Recycle Bin used on file shares 56 | $RECYCLE.BIN/ 57 | 58 | # Windows Installer files 59 | *.cab 60 | *.msi 61 | *.msm 62 | *.msp 63 | 64 | # Windows shortcuts 65 | *.lnk 66 | 67 | ### OSX ### 68 | *~ 69 | .DS_Store 70 | .AppleDouble 71 | .LSOverride 72 | 73 | # Icon must end with two \r 74 | Icon 75 | 76 | # Thumbnails 77 | ._* 78 | 79 | # Files that might appear in the root of a volume 80 | .DocumentRevisions-V100 81 | .fseventsd 82 | .Spotlight-V100 83 | .TemporaryItems 84 | .Trashes 85 | .VolumeIcon.icns 86 | 87 | # Directories potentially created on remote AFP share 88 | .AppleDB 89 | .AppleDesktop 90 | Network Trash Folder 91 | Temporary Items 92 | .apdisk 93 | 94 | ### Commitizen ### 95 | node_modules/ 96 | package.json 97 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Code4Java 2 | Repository for my java projects 3 | 4 | ## 1. NettyMqService 5 | How to implement a message queue service with Netty and RabbitMQ. 6 | ##### 中文详情(Chinese Details): 7 | * [Message Queue Service based on Netty and RabbitMQ](http://www.cnblogs.com/luxiaoxun/p/4257105.html) 8 | 9 | ## 2. MapHttpService 10 | A simple Http Map Service providing tile image for Map. 11 | 12 | ## 3. WebGisDemo 13 | A simple web GIS page based on [leaflet](https://github.com/Leaflet/Leaflet). 14 | ##### 中文详情([Chinese Details](http://www.cnblogs.com/luxiaoxun/p/5022333.html)) 15 | 1. How to use Elasticsearch. 16 | 2. How to use Solr or Lucene to index and query data. 17 | 3. How to use Elasticsearch to index and query POI(GEO data). 18 | 19 | * [Lucene index and query POI data](http://www.cnblogs.com/luxiaoxun/p/5020247.html) 20 | * [Solr index and query MYSQL data](http://www.cnblogs.com/luxiaoxun/p/4442770.html) 21 | * [Solr index and query GEO data](http://www.cnblogs.com/luxiaoxun/p/4477591.html) 22 | * [Elasticsearch index and query data](http://www.cnblogs.com/luxiaoxun/p/4869509.html) 23 | * [SQL to Elasticsearch Java Code](http://www.cnblogs.com/luxiaoxun/p/6826211.html) 24 | 25 | How to use WebGisDemo with MapHttpService: 26 | 1. Download map tile image with [MapDownloader](https://github.com/luxiaoxun/MapDownloader) 27 | 2. Start MapHttpService with right data source, an example: 28 | >port=8899 29 | >database.type=0 # Use SQLite 30 | >database.sqlite.path=E:\\GIS\\MapDownloader\\MapCache\\TileDBv5\\en\\Data.gmdb 31 | 3. Start WebGISDemo: http://localhost:9090/map 32 | 33 | ![map](https://github.com/luxiaoxun/Code4Java/blob/master/WebGisDemo/picture/map-demo.png) 34 | 35 | -------------------------------------------------------------------------------- /LogCollector/src/main/resources/log4j2-dev.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ${sys:user.dir}/logs/ 5 | log-collector 6 | 7 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /LogCollector/src/main/resources/log4j2-prod.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ${sys:user.dir}/logs/ 5 | log-collector 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/log4j/log4j2-prd.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ${sys:user.dir}/logs/ 5 | app 6 | 7 | 8 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/java/com/luxx/gis/config/IndexConfig.java: -------------------------------------------------------------------------------- 1 | package com.luxx.gis.config; 2 | 3 | import org.springframework.beans.factory.annotation.Value; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | @Configuration 8 | @ConditionalOnProperty(prefix = "index.db", name = "url") 9 | public class IndexConfig { 10 | 11 | @Value("${index.db.url}") 12 | private String dbUrl; 13 | 14 | @Value("${index.db.username}") 15 | private String dbUserName; 16 | 17 | @Value("${index.db.password}") 18 | private String dbPassword; 19 | 20 | @Value("${index.db.table}") 21 | private String dbTable; 22 | 23 | @Value("${index.db.type}") 24 | private String dbType; 25 | 26 | public String getDbUrl() { 27 | return dbUrl; 28 | } 29 | 30 | public void setDbUrl(String dbUrl) { 31 | this.dbUrl = dbUrl; 32 | } 33 | 34 | public String getDbUserName() { 35 | return dbUserName; 36 | } 37 | 38 | public void setDbUserName(String dbUserName) { 39 | this.dbUserName = dbUserName; 40 | } 41 | 42 | public String getDbPassword() { 43 | return dbPassword; 44 | } 45 | 46 | public void setDbPassword(String dbPassword) { 47 | this.dbPassword = dbPassword; 48 | } 49 | 50 | public String getDbTable() { 51 | return dbTable; 52 | } 53 | 54 | public void setDbTable(String dbTable) { 55 | this.dbTable = dbTable; 56 | } 57 | 58 | public String getDbType() { 59 | return dbType; 60 | } 61 | 62 | public void setDbType(String dbType) { 63 | this.dbType = dbType; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/js/leafletjs/leaflet.mouseposition.js: -------------------------------------------------------------------------------- 1 | L.Control.MousePosition = L.Control.extend({ 2 | options: { 3 | position: 'bottomleft', 4 | separator: ' : ', 5 | emptyString: 'Unavailable', 6 | lngFirst: false, 7 | numDigits: 5, 8 | lngFormatter: undefined, 9 | latFormatter: undefined, 10 | prefix: "" 11 | }, 12 | 13 | onAdd: function (map) { 14 | this._container = L.DomUtil.create('div', 'leaflet-control-mouseposition'); 15 | L.DomEvent.disableClickPropagation(this._container); 16 | map.on('mousemove', this._onMouseMove, this); 17 | this._container.innerHTML=this.options.emptyString; 18 | return this._container; 19 | }, 20 | 21 | onRemove: function (map) { 22 | map.off('mousemove', this._onMouseMove) 23 | }, 24 | 25 | _onMouseMove: function (e) { 26 | var lng = this.options.lngFormatter ? this.options.lngFormatter(e.latlng.lng) : L.Util.formatNum(e.latlng.lng, this.options.numDigits); 27 | var lat = this.options.latFormatter ? this.options.latFormatter(e.latlng.lat) : L.Util.formatNum(e.latlng.lat, this.options.numDigits); 28 | var value = this.options.lngFirst ? lng + this.options.separator + lat : lat + this.options.separator + lng; 29 | var prefixAndValue = this.options.prefix + ' ' + value; 30 | this._container.innerHTML = prefixAndValue; 31 | } 32 | 33 | }); 34 | 35 | L.Map.mergeOptions({ 36 | positionControl: false 37 | }); 38 | 39 | L.Map.addInitHook(function () { 40 | if (this.options.positionControl) { 41 | this.positionControl = new L.Control.MousePosition(); 42 | this.addControl(this.positionControl); 43 | } 44 | }); 45 | 46 | L.control.mousePosition = function (options) { 47 | return new L.Control.MousePosition(options); 48 | }; 49 | -------------------------------------------------------------------------------- /MapHttpService/src/main/java/com/luxx/map/service/MapRequestParam.java: -------------------------------------------------------------------------------- 1 | package com.luxx.map.service; 2 | 3 | public class MapRequestParam { 4 | private boolean isOk; 5 | private String dbType; 6 | private int zoom; 7 | private int x; 8 | private int y; 9 | 10 | public boolean isOk() { 11 | return isOk; 12 | } 13 | 14 | public void setOk(boolean isOk) { 15 | this.isOk = isOk; 16 | } 17 | 18 | public String getDbType() { 19 | return dbType; 20 | } 21 | 22 | public void setDbType(String dbType) { 23 | this.dbType = dbType; 24 | } 25 | 26 | public int getZoom() { 27 | return zoom; 28 | } 29 | 30 | public void setZoom(int zoom) { 31 | this.zoom = zoom; 32 | } 33 | 34 | public int getX() { 35 | return x; 36 | } 37 | 38 | public void setX(int x) { 39 | this.x = x; 40 | } 41 | 42 | public int getY() { 43 | return y; 44 | } 45 | 46 | public void setY(int y) { 47 | this.y = y; 48 | } 49 | 50 | @Override 51 | public int hashCode() { 52 | return this.dbType.hashCode() ^ this.x ^ this.y ^ this.zoom; 53 | } 54 | 55 | @Override 56 | public boolean equals(Object obj) { 57 | if (!(obj instanceof MapRequestParam)) { 58 | return false; 59 | } 60 | MapRequestParam that = (MapRequestParam) obj; 61 | return this.isOk == that.isOk() 62 | && this.dbType == that.getDbType() 63 | && this.zoom == that.getZoom() 64 | && this.x == that.getX() 65 | && this.y == that.getY(); 66 | } 67 | 68 | @Override 69 | public String toString() { 70 | return "IsOk:" + this.isOk + " DbType:" + this.dbType + " Zoom:" + this.zoom + " X:" + this.x + " Y:" + this.y; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/js/leafletjs/leaflet.draw.cn.js: -------------------------------------------------------------------------------- 1 | L.drawLocal.draw.toolbar.buttons.polyline = '线条'; 2 | L.drawLocal.draw.toolbar.buttons.circle = '圆形'; 3 | L.drawLocal.draw.toolbar.buttons.rectangle = '矩形'; 4 | L.drawLocal.draw.toolbar.buttons.polygon = '多边形'; 5 | L.drawLocal.draw.toolbar.buttons.marker = '图标'; 6 | L.drawLocal.draw.toolbar.actions.title = '取消画图'; 7 | L.drawLocal.draw.toolbar.actions.text = '取消'; 8 | L.drawLocal.draw.toolbar.undo.title = '删除最后一个点画图'; 9 | L.drawLocal.draw.toolbar.undo.text = '删除最后一个点'; 10 | 11 | L.drawLocal.draw.handlers.circle.tooltip.start = '点击拖动画圆'; 12 | L.drawLocal.draw.handlers.marker.tooltip.start = '点击地图添加图标'; 13 | L.drawLocal.draw.handlers.polygon.tooltip.start = '点击开始画多边形'; 14 | L.drawLocal.draw.handlers.polygon.tooltip.cont = '点击继续画多边形'; 15 | L.drawLocal.draw.handlers.polygon.tooltip.end = '点击第一个点完成画多边形'; 16 | L.drawLocal.draw.handlers.polyline.error = '错误: 图形边界不能交叉!'; 17 | L.drawLocal.draw.handlers.polyline.tooltip.start = '点击开始画线'; 18 | L.drawLocal.draw.handlers.polyline.tooltip.cont = '点击继续画线'; 19 | L.drawLocal.draw.handlers.polyline.tooltip.end = '点击最后一个点完成画线'; 20 | L.drawLocal.draw.handlers.rectangle.tooltip.start = '点击拖动画矩形'; 21 | L.drawLocal.draw.handlers.simpleshape.tooltip.end = '释放鼠标完成画图'; 22 | 23 | L.drawLocal.edit.toolbar.actions.save.text = '保存'; 24 | L.drawLocal.edit.toolbar.actions.save.title = '保存修改'; 25 | L.drawLocal.edit.toolbar.actions.cancel.text = '取消'; 26 | L.drawLocal.edit.toolbar.actions.cancel.title = '取消修改'; 27 | L.drawLocal.edit.toolbar.buttons.edit = '修改图形'; 28 | L.drawLocal.edit.toolbar.buttons.editDisabled = '没有图形可以修改'; 29 | L.drawLocal.edit.toolbar.buttons.remove = '删除图形'; 30 | L.drawLocal.edit.toolbar.buttons.removeDisabled = '没有图形可以删除'; 31 | L.drawLocal.edit.handlers.edit.tooltip.text = '拖动图形或图标来修改'; 32 | L.drawLocal.edit.handlers.edit.tooltip.subtext = '点击取消放弃修改'; 33 | L.drawLocal.edit.handlers.remove.tooltip.text = '点击图形来删除'; -------------------------------------------------------------------------------- /MapHttpService/src/main/java/com/luxx/map/util/PropertiesUtil.java: -------------------------------------------------------------------------------- 1 | package com.luxx.map.util; 2 | 3 | import java.io.InputStream; 4 | import java.util.Properties; 5 | 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | public class PropertiesUtil { 10 | private static Logger log = LoggerFactory.getLogger(PropertiesUtil.class); 11 | 12 | private Properties prop = null; 13 | private static String propertiesFile = "/mapConfig.properties"; 14 | 15 | private PropertiesUtil() { 16 | prop = new Properties(System.getProperties()); 17 | try { 18 | InputStream propFile = PropertiesUtil.class.getResourceAsStream(propertiesFile); 19 | prop.load(propFile); 20 | } catch (Exception e) { 21 | log.error("Load properties file " + propertiesFile + " failed. " + e.getMessage()); 22 | } 23 | } 24 | 25 | private static class PropertiesUtilHolder { 26 | static final PropertiesUtil instance = new PropertiesUtil(); 27 | } 28 | 29 | public static PropertiesUtil getInstance() { 30 | return PropertiesUtilHolder.instance; 31 | } 32 | 33 | public String GetListenPort() { 34 | String port = prop.getProperty("port"); 35 | return port; 36 | } 37 | 38 | 39 | public int GetDbType() { 40 | String dbType = prop.getProperty("database.type"); 41 | return Integer.valueOf(dbType); 42 | } 43 | 44 | public String GetSqliteDbPath() { 45 | String dbPath = prop.getProperty("database.sqlite.path"); 46 | return dbPath; 47 | } 48 | 49 | public String GetMysqlUrl() { 50 | String url = prop.getProperty("database.mysql.url"); 51 | return url; 52 | } 53 | 54 | public String GetMysqlUser() { 55 | String user = prop.getProperty("database.mysql.username"); 56 | return user; 57 | } 58 | 59 | public String GetMysqlPassword() { 60 | String pswd = prop.getProperty("database.mysql.password"); 61 | return pswd; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /NettyMqService/src/main/java/com/luxx/mq/server/MqSender.java: -------------------------------------------------------------------------------- 1 | package com.luxx.mq.server; 2 | 3 | import com.luxx.mq.config.MqConfig; 4 | import com.luxx.mq.util.PropertiesUtil; 5 | import com.rabbitmq.client.Channel; 6 | import com.rabbitmq.client.Connection; 7 | import com.rabbitmq.client.ConnectionFactory; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import java.io.IOException; 12 | 13 | /** 14 | * RabbitMQ Sender based on Spring AMQP 15 | */ 16 | public class MqSender { 17 | private static final Logger log = LoggerFactory.getLogger(MqSender.class); 18 | private ConnectionFactory connectionFactory; 19 | private String exchangeName = "NettyMqServerSenderExchange"; 20 | private Channel channel = null; 21 | 22 | public MqSender() { 23 | String host = PropertiesUtil.getInstance().getProperty(MqConfig.MQ_HOST); 24 | int port = PropertiesUtil.getInstance().getPropertyAsInt(MqConfig.MQ_PORT); 25 | String username = PropertiesUtil.getInstance().getProperty(MqConfig.MQ_USERNAME); 26 | String password = PropertiesUtil.getInstance().getProperty(MqConfig.MQ_PASSWORD); 27 | connectionFactory = new ConnectionFactory(); 28 | connectionFactory.setHost(host); 29 | connectionFactory.setUsername(username); 30 | connectionFactory.setPassword(password); 31 | connectionFactory.setPort(port); 32 | connectionFactory.setVirtualHost("/"); 33 | 34 | Connection connection = null; 35 | try { 36 | connection = connectionFactory.newConnection(); 37 | channel = connection.createChannel(); 38 | channel.exchangeDeclare(exchangeName, "fanout"); 39 | } catch (Exception e) { 40 | log.error("Exception: " + e.toString()); 41 | } 42 | } 43 | 44 | public void send(String data) { 45 | try { 46 | channel.basicPublish(exchangeName, "", null, data.getBytes()); 47 | } catch (IOException e) { 48 | log.error("Mq sender error: " + e.toString()); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/log4j/log4j2-dev.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ${sys:user.dir}/logs/ 5 | app 6 | 7 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/java/com/luxx/gis/util/JsonUtil.java: -------------------------------------------------------------------------------- 1 | package com.luxx.gis.util; 2 | 3 | import java.io.IOException; 4 | import java.text.SimpleDateFormat; 5 | import java.util.HashMap; 6 | 7 | import com.fasterxml.jackson.databind.JavaType; 8 | import com.fasterxml.jackson.databind.ObjectMapper; 9 | 10 | public class JsonUtil { 11 | 12 | private static ObjectMapper objMapper = new ObjectMapper(); 13 | 14 | static { 15 | SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 16 | objMapper.setDateFormat(dateFormat); 17 | } 18 | 19 | public static type jsonToObject(String json, Class cls) { 20 | type obj = null; 21 | JavaType javaType = objMapper.getTypeFactory().constructType(cls); 22 | try { 23 | obj = objMapper.readValue(json, javaType); 24 | } catch (IOException e) { 25 | e.printStackTrace(); 26 | } 27 | return obj; 28 | } 29 | 30 | public static type jsonToObjectList(String json, Class collectionClass, Class... elementClass) { 31 | type obj = null; 32 | JavaType javaType = objMapper.getTypeFactory().constructParametricType(collectionClass, elementClass); 33 | try { 34 | obj = objMapper.readValue(json, javaType); 35 | } catch (IOException e) { 36 | e.printStackTrace(); 37 | } 38 | return obj; 39 | } 40 | 41 | public static type jsonToObjectHashMap(String json, Class keyClass, Class valueClass) { 42 | type obj = null; 43 | JavaType javaType = objMapper.getTypeFactory().constructParametricType(HashMap.class, keyClass, valueClass); 44 | try { 45 | obj = objMapper.readValue(json, javaType); 46 | } catch (IOException e) { 47 | e.printStackTrace(); 48 | } 49 | return obj; 50 | } 51 | 52 | public static String objectToJson(Object o) { 53 | String json = ""; 54 | try { 55 | json = objMapper.writeValueAsString(o); 56 | } catch (IOException e) { 57 | e.printStackTrace(); 58 | } 59 | return json; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /MapHttpService/src/main/java/com/luxx/map/service/MapCache.java: -------------------------------------------------------------------------------- 1 | package com.luxx.map.service; 2 | 3 | import java.sql.SQLException; 4 | import java.util.concurrent.Callable; 5 | 6 | import com.google.common.cache.Cache; 7 | import com.google.common.cache.CacheBuilder; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | /** 12 | * Map服务,地图缓存 13 | * 14 | * @author luxiaoxun 15 | * @version 1.0 16 | * @since 2015.06.1 17 | */ 18 | public class MapCache { 19 | private static Logger log = LoggerFactory.getLogger(MapCache.class); 20 | 21 | private Cache mapCacheLoader = null; 22 | 23 | private static class MapCacheHolder { 24 | private static final MapCache instance = new MapCache(); 25 | } 26 | 27 | public static MapCache getInstance() { 28 | return MapCacheHolder.instance; 29 | } 30 | 31 | private MapCache() { 32 | // mapCacheLoader = 33 | // CacheBuilder.newBuilder().maximumSize(1000).expireAfterAccess(5, 34 | // TimeUnit.MINUTES).build(); 35 | mapCacheLoader = CacheBuilder.newBuilder().maximumSize(5000).build(); 36 | } 37 | 38 | public byte[] getMapCacheTile(final MapRequestParam mapRequestParam) { 39 | byte[] tileBytes = null; 40 | try { 41 | tileBytes = mapCacheLoader.get(mapRequestParam, new Callable() { 42 | public byte[] call() throws SQLException { 43 | return getMapTile(mapRequestParam); 44 | } 45 | }); 46 | } catch (Exception e) { 47 | log.error(e.getMessage()); 48 | } 49 | return tileBytes; 50 | } 51 | 52 | private byte[] getMapTile(final MapRequestParam mapRequestParam) throws SQLException { 53 | byte[] allBytesInBlob = null; 54 | if (mapRequestParam.isOk()) { 55 | String dbId = mapRequestParam.getDbType(); 56 | int zoom = mapRequestParam.getZoom(); 57 | int x = mapRequestParam.getX(); 58 | int y = mapRequestParam.getY(); 59 | allBytesInBlob = MapDbOperation.getTile(x, y, zoom, dbId); 60 | } 61 | return allBytesInBlob; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/java/com/luxx/gis/service/IndexDataSource.java: -------------------------------------------------------------------------------- 1 | package com.luxx.gis.service; 2 | 3 | import java.sql.Connection; 4 | import java.sql.SQLException; 5 | 6 | import com.luxx.gis.config.IndexConfig; 7 | import com.zaxxer.hikari.HikariConfig; 8 | import com.zaxxer.hikari.HikariDataSource; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 11 | import org.springframework.stereotype.Service; 12 | 13 | import javax.annotation.PostConstruct; 14 | 15 | @Service 16 | @ConditionalOnProperty(name = "index.db.url") 17 | public class IndexDataSource { 18 | private static final Long HIKARI_MAX_LIFE_TIME_MS = 1800000L; // 30 min 19 | private static final Long HIKARI_LEAK_DETECTION_THRESHOLD_MS = 60000L; 20 | private static final int HIKARI_POOL_SIZE = 5; 21 | private static HikariDataSource dataSource = null; 22 | 23 | @Autowired 24 | private IndexConfig indexConfig; 25 | 26 | @PostConstruct 27 | public void init() { 28 | String dbUrl = indexConfig.getDbUrl(); 29 | String username = indexConfig.getDbUserName(); 30 | String password = indexConfig.getDbPassword(); 31 | String dbType = indexConfig.getDbType(); 32 | 33 | HikariConfig config = new HikariConfig(); 34 | config.setJdbcUrl(dbUrl); 35 | config.setUsername(username); 36 | config.setPassword(password); 37 | if (dbType.equals("redshift")) { 38 | config.setDriverClassName("com.amazon.redshift.jdbc.Driver"); 39 | } else if (dbType.equals("mysql")) { 40 | config.setDriverClassName("com.mysql.cj.jdbc.Driver"); 41 | } 42 | config.addDataSourceProperty("cachePrepStmts", "true"); 43 | config.addDataSourceProperty("prepStmtCacheSize", "250"); 44 | config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); 45 | config.setMaxLifetime(HIKARI_MAX_LIFE_TIME_MS); 46 | config.setMaximumPoolSize(HIKARI_POOL_SIZE); 47 | config.setMinimumIdle(HIKARI_POOL_SIZE); 48 | config.setLeakDetectionThreshold(HIKARI_LEAK_DETECTION_THRESHOLD_MS); 49 | 50 | dataSource = new HikariDataSource(config); 51 | } 52 | 53 | public Connection getConnection() throws SQLException { 54 | if (dataSource != null) { 55 | return dataSource.getConnection(); 56 | } else { 57 | return null; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /NettyMqService/src/main/java/com/luxx/mq/handler/EchoServerHandler.java: -------------------------------------------------------------------------------- 1 | package com.luxx.mq.handler; 2 | 3 | import com.luxx.mq.server.MqSender; 4 | import com.luxx.mq.message.Message; 5 | import io.netty.channel.group.ChannelGroup; 6 | import io.netty.channel.group.DefaultChannelGroup; 7 | import io.netty.util.CharsetUtil; 8 | import io.netty.util.ReferenceCountUtil; 9 | import io.netty.util.concurrent.GlobalEventExecutor; 10 | import io.netty.buffer.Unpooled; 11 | import io.netty.channel.ChannelHandlerContext; 12 | import io.netty.channel.ChannelInboundHandlerAdapter; 13 | 14 | import org.slf4j.Logger; 15 | import org.slf4j.LoggerFactory; 16 | 17 | 18 | /** 19 | * Handler implementation for the echo server. 20 | */ 21 | public class EchoServerHandler extends ChannelInboundHandlerAdapter { 22 | private static final Logger log = LoggerFactory.getLogger(EchoServerHandler.class); 23 | 24 | public static final ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); 25 | 26 | private MqSender mqSender; 27 | 28 | public EchoServerHandler(MqSender mqSender) { 29 | this.mqSender = mqSender; 30 | } 31 | 32 | @Override 33 | public void channelRead(ChannelHandlerContext ctx, Object msg) { 34 | try { 35 | // ByteBuf in = (ByteBuf) msg; 36 | // String data = in.toString(io.netty.util.CharsetUtil.UTF_8); 37 | Message message = (Message) (msg); 38 | 39 | // Receive message from client 40 | // Send message to rabbit MQ who wants to subscribe 41 | String dataString = new String(message.getData(), CharsetUtil.UTF_8); 42 | mqSender.send(dataString); 43 | 44 | // Echo server: send back the msg to client (just for test) 45 | log.debug(String.format("Receive message: %s", dataString)); 46 | ctx.writeAndFlush(Unpooled.copiedBuffer(message.getData())); 47 | } finally { 48 | ReferenceCountUtil.release(msg); 49 | } 50 | } 51 | 52 | @Override 53 | public void channelActive(ChannelHandlerContext ctx) throws Exception { 54 | // A closed channel will be removed from ChannelGroup automatically 55 | channels.add(ctx.channel()); 56 | } 57 | 58 | @Override 59 | public void channelInactive(ChannelHandlerContext ctx) throws Exception { 60 | // System.out.println("Disconnected client "+ctx.channel().remoteAddress()); 61 | log.debug("Disconnected client " + ctx.channel().remoteAddress()); 62 | } 63 | 64 | @Override 65 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 66 | ctx.close(); 67 | log.warn(cause.getMessage()); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /NettyMqService/src/main/java/com/luxx/mq/server/NettyMqServer.java: -------------------------------------------------------------------------------- 1 | package com.luxx.mq.server; 2 | 3 | import com.luxx.mq.handler.NettyMqServerChannelInitializer; 4 | import io.netty.bootstrap.ServerBootstrap; 5 | import io.netty.channel.Channel; 6 | import io.netty.channel.ChannelFuture; 7 | import io.netty.channel.ChannelOption; 8 | import io.netty.channel.EventLoopGroup; 9 | import io.netty.channel.nio.NioEventLoopGroup; 10 | import io.netty.channel.socket.nio.NioServerSocketChannel; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | /** 15 | * Netty RabbitMQ Server 16 | */ 17 | public class NettyMqServer { 18 | private static final Logger log = LoggerFactory.getLogger(NettyMqServer.class); 19 | 20 | private EventLoopGroup bossGroup; 21 | private EventLoopGroup workerGroup; 22 | private Channel serverChannel; 23 | private MqSender mqSender; 24 | 25 | public NettyMqServer() { 26 | bossGroup = new NioEventLoopGroup(); 27 | workerGroup = new NioEventLoopGroup(); 28 | mqSender = new MqSender(); 29 | } 30 | 31 | private void start(int port) { 32 | try { 33 | // start server 34 | ServerBootstrap b = new ServerBootstrap(); 35 | b.group(bossGroup, workerGroup) 36 | .channel(NioServerSocketChannel.class) 37 | .childHandler(new NettyMqServerChannelInitializer(mqSender)); 38 | b.option(ChannelOption.SO_BACKLOG, 128); 39 | b.childOption(ChannelOption.SO_KEEPALIVE, false); 40 | b.childOption(ChannelOption.TCP_NODELAY, true); 41 | b.childOption(ChannelOption.SO_REUSEADDR, true); 42 | ChannelFuture f = b.bind(port).sync(); 43 | serverChannel = f.channel(); 44 | 45 | // start mq listener 46 | startMqListener(); 47 | 48 | log.info("Server start OK!"); 49 | } catch (Exception ex) { 50 | log.error("Server start error: " + ex.getMessage()); 51 | stop(); 52 | } 53 | } 54 | 55 | private void startMqListener() { 56 | MqReceiver mqReceiver = new MqReceiver(); 57 | mqReceiver.start(); 58 | } 59 | 60 | private void stop() { 61 | if (serverChannel != null) { 62 | serverChannel.close(); 63 | } 64 | if (workerGroup != null) { 65 | workerGroup.shutdownGracefully(); 66 | } 67 | if (bossGroup != null) { 68 | bossGroup.shutdownGracefully(); 69 | } 70 | 71 | log.info("Server is shut down"); 72 | } 73 | 74 | public void doStart() { 75 | int port = 18866; 76 | try { 77 | start(port); 78 | } catch (Exception e) { 79 | log.error("Server start error: " + e.getMessage()); 80 | } 81 | } 82 | 83 | public void doStop() { 84 | stop(); 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/java/com/luxx/gis/model/EndpointData.java: -------------------------------------------------------------------------------- 1 | package com.luxx.gis.model; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | public class EndpointData implements Serializable { 7 | private static final long serialVersionUID = 1493676048457257941L; 8 | 9 | private int org_id; 10 | private long endpoint_id; 11 | 12 | private long ds_bytes; 13 | private double ds_max_bytes; 14 | private double ds_avg_bytes; 15 | private int ds_mwt; 16 | 17 | private long us_bytes; 18 | private double us_max_bytes; 19 | private double us_avg_bytes; 20 | private int us_mwt; 21 | 22 | private Date date_time; 23 | 24 | public int getOrg_id() { 25 | return org_id; 26 | } 27 | 28 | public void setOrg_id(int org_id) { 29 | this.org_id = org_id; 30 | } 31 | 32 | public long getEndpoint_id() { 33 | return endpoint_id; 34 | } 35 | 36 | public void setEndpoint_id(long endpoint_id) { 37 | this.endpoint_id = endpoint_id; 38 | } 39 | 40 | public long getDs_bytes() { 41 | return ds_bytes; 42 | } 43 | 44 | public void setDs_bytes(long ds_bytes) { 45 | this.ds_bytes = ds_bytes; 46 | } 47 | 48 | public double getDs_max_bytes() { 49 | return ds_max_bytes; 50 | } 51 | 52 | public void setDs_max_bytes(double ds_max_bytes) { 53 | this.ds_max_bytes = ds_max_bytes; 54 | } 55 | 56 | public double getDs_avg_bytes() { 57 | return ds_avg_bytes; 58 | } 59 | 60 | public void setDs_avg_bytes(double ds_avg_bytes) { 61 | this.ds_avg_bytes = ds_avg_bytes; 62 | } 63 | 64 | public int getDs_mwt() { 65 | return ds_mwt; 66 | } 67 | 68 | public void setDs_mwt(int ds_mwt) { 69 | this.ds_mwt = ds_mwt; 70 | } 71 | 72 | public long getUs_bytes() { 73 | return us_bytes; 74 | } 75 | 76 | public void setUs_bytes(long us_bytes) { 77 | this.us_bytes = us_bytes; 78 | } 79 | 80 | public double getUs_max_bytes() { 81 | return us_max_bytes; 82 | } 83 | 84 | public void setUs_max_bytes(double us_max_bytes) { 85 | this.us_max_bytes = us_max_bytes; 86 | } 87 | 88 | public double getUs_avg_bytes() { 89 | return us_avg_bytes; 90 | } 91 | 92 | public void setUs_avg_bytes(double us_avg_bytes) { 93 | this.us_avg_bytes = us_avg_bytes; 94 | } 95 | 96 | public int getUs_mwt() { 97 | return us_mwt; 98 | } 99 | 100 | public void setUs_mwt(int us_mwt) { 101 | this.us_mwt = us_mwt; 102 | } 103 | 104 | public Date getDate_time() { 105 | return date_time; 106 | } 107 | 108 | public void setDate_time(Date date_time) { 109 | this.date_time = date_time; 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/java/com/luxx/gis/util/DateFormatUtil.java: -------------------------------------------------------------------------------- 1 | package com.luxx.gis.util; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.util.Date; 5 | import java.util.TimeZone; 6 | 7 | /** 8 | * Date Format Helper 9 | * 10 | * @author luxiaoxun 11 | * @version 1.0 12 | * @since 2015.05.18 13 | */ 14 | public class DateFormatUtil { 15 | 16 | public static String ISO_FORMAT_UTC = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; 17 | public static String ISO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS zzz"; 18 | public static String LEGACY_FORMAT = "EEE MMM dd hh:mm:ss zzz yyyy"; 19 | private static final TimeZone utc = TimeZone.getTimeZone("UTC"); 20 | private static final SimpleDateFormat legacyFormatter = new SimpleDateFormat(LEGACY_FORMAT); 21 | private static final SimpleDateFormat isoFormatter = new SimpleDateFormat(ISO_FORMAT); 22 | private static final SimpleDateFormat isoFormatterUtc = new SimpleDateFormat(ISO_FORMAT_UTC); 23 | 24 | static { 25 | legacyFormatter.setTimeZone(utc); 26 | isoFormatter.setTimeZone(utc); 27 | isoFormatterUtc.setTimeZone(utc); 28 | } 29 | 30 | /* 31 | * Convert date to string "yyyy-MM-dd HH:mm:ss" 32 | */ 33 | public static String DateToString(Date date) { 34 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 35 | sdf.setTimeZone(utc); 36 | return sdf.format(date); 37 | } 38 | 39 | /* 40 | * Convert current date to string "yyyy-MM-dd'T'HH:mm:ss.SSS zzz" 41 | */ 42 | public static String now() { 43 | return DateFormatUtil.toString(new Date()); 44 | } 45 | 46 | /* 47 | * Convert date to string "yyyy-MM-dd'T'HH:mm:ss.SSS zzz" 48 | */ 49 | public static String toString(final Date date) { 50 | return isoFormatter.format(date); 51 | } 52 | 53 | /* 54 | * Convert date to string "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" 55 | */ 56 | public static String toUtcString(final Date date) { 57 | return isoFormatterUtc.format(date); 58 | } 59 | 60 | /* 61 | * Convert date to string "EEE MMM dd hh:mm:ss zzz yyyy" 62 | */ 63 | public static String toLegacyString(final Date date) { 64 | return legacyFormatter.format(date); 65 | } 66 | 67 | /* 68 | * Convert date to string use format, timezone is "UTC" 69 | */ 70 | public static String toString(final Date date, final String format) { 71 | return toString(date, format, "UTC"); 72 | } 73 | 74 | /* 75 | * Convert date to string use format and timezone 76 | */ 77 | public static String toString(final Date date, final String format, final String timezone) { 78 | final TimeZone tz = TimeZone.getTimeZone(timezone); 79 | final SimpleDateFormat formatter = new SimpleDateFormat(format); 80 | formatter.setTimeZone(tz); 81 | return formatter.format(date); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/css/leaflet-search.css: -------------------------------------------------------------------------------- 1 | 2 | .leaflet-container .leaflet-control-search { 3 | position:relative; 4 | float:left; 5 | background:#fff; 6 | color:#1978cf; 7 | -moz-border-radius: 4px; 8 | -webkit-border-radius: 4px; 9 | border-radius: 4px; 10 | background-color: rgba(255, 255, 255, 0.8); 11 | z-index:1000; 12 | box-shadow: 0 1px 7px rgba(0,0,0,0.65); 13 | margin-left: 10px; 14 | margin-top: 10px; 15 | } 16 | .leaflet-control-search.search-exp {/*expanded*/ 17 | box-shadow: 0 1px 7px #999; 18 | background: #fff; 19 | } 20 | .leaflet-control-search .search-input { 21 | display:block; 22 | float:left; 23 | background: #fff; 24 | border:1px solid #666; 25 | border-radius:2px; 26 | height:18px; 27 | padding:0 18px 0 2px; 28 | margin:3px 0 3px 3px; 29 | } 30 | .leaflet-control-search.search-load .search-input { 31 | background: url('../images/loader.gif') no-repeat center right #fff; 32 | } 33 | .leaflet-control-search.search-load .search-cancel { 34 | visibility:hidden; 35 | } 36 | .leaflet-control-search .search-cancel { 37 | display:block; 38 | width:22px; 39 | height:18px; 40 | position:absolute; 41 | right:22px; 42 | margin:3px 0; 43 | background: url('../images/search-icon.png') no-repeat 0 -46px; 44 | text-decoration:none; 45 | filter: alpha(opacity=80); 46 | opacity: 0.8; 47 | } 48 | .leaflet-control-search .search-cancel:hover { 49 | filter: alpha(opacity=100); 50 | opacity: 1; 51 | } 52 | .leaflet-control-search .search-cancel span { 53 | display:none;/* comment for cancel button imageless */ 54 | font-size:18px; 55 | line-height:20px; 56 | color:#ccc; 57 | font-weight:bold; 58 | } 59 | .leaflet-control-search .search-cancel:hover span { 60 | color:#aaa; 61 | } 62 | .leaflet-control-search .search-button { 63 | display:block; 64 | float:left; 65 | width:26px; 66 | height:26px; 67 | background: url('../images/search-icon.png') no-repeat 2px 2px; 68 | border-radius:4px; 69 | } 70 | .leaflet-control-search .search-button:hover { 71 | background: url('../images/search-icon.png') no-repeat 2px -22px; 72 | } 73 | .leaflet-control-search .search-tooltip { 74 | position:absolute; 75 | top:100%; 76 | left:0; 77 | float:left; 78 | list-style: none; 79 | padding-left: 0; 80 | min-width:120px; 81 | max-height:122px; 82 | box-shadow: 1px 1px 6px rgba(0,0,0,0.4); 83 | background-color: rgba(0, 0, 0, 0.25); 84 | z-index:1010; 85 | overflow-y:auto; 86 | overflow-x:hidden; 87 | cursor: pointer; 88 | } 89 | .leaflet-control-search .search-tip { 90 | margin:2px; 91 | padding:2px 4px; 92 | display:block; 93 | color:black; 94 | background: #eee; 95 | border-radius:.25em; 96 | text-decoration:none; 97 | white-space:nowrap; 98 | vertical-align:center; 99 | } 100 | .leaflet-control-search .search-tip-select, 101 | .leaflet-control-search .search-tip:hover, 102 | .leaflet-control-search .search-button:hover { 103 | background-color: #fff; 104 | } 105 | .leaflet-control-search .search-alert { 106 | cursor:pointer; 107 | clear:both; 108 | font-size:.75em; 109 | margin-bottom:5px; 110 | padding:0 .25em; 111 | color:#e00; 112 | font-weight:bold; 113 | border-radius:.25em; 114 | } 115 | 116 | 117 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/java/com/luxx/gis/controller/StationController.java: -------------------------------------------------------------------------------- 1 | package com.luxx.gis.controller; 2 | 3 | import com.github.pagehelper.PageHelper; 4 | import com.github.pagehelper.PageInfo; 5 | import com.luxx.gis.model.Station; 6 | import com.luxx.gis.model.PoiData; 7 | import com.luxx.gis.model.PoiPoint; 8 | import com.luxx.gis.model.ResultData; 9 | import com.luxx.gis.model.request.DataInCircleRequest; 10 | import com.luxx.gis.model.request.DataInRectangleRequest; 11 | import com.luxx.gis.service.StationService; 12 | import com.luxx.gis.service.IndexSearchService; 13 | import io.swagger.annotations.Api; 14 | import lombok.extern.slf4j.Slf4j; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.web.bind.annotation.*; 17 | 18 | import javax.validation.constraints.Min; 19 | import java.util.List; 20 | 21 | @RestController 22 | @RequestMapping("/station") 23 | @Api(tags = "station") 24 | @Slf4j 25 | public class StationController { 26 | @Autowired 27 | private StationService stationService; 28 | 29 | @Autowired 30 | private IndexSearchService indexSearchService; 31 | 32 | @GetMapping("/loadData") 33 | public ResultData loadData(@RequestParam(defaultValue = "1") @Min(1) int pageNum, 34 | @RequestParam(defaultValue = "10") int pageSize) { 35 | PageHelper.startPage(pageNum, pageSize); 36 | List stationList = stationService.getStation(); 37 | PageInfo pageInfo = new PageInfo<>(stationList); 38 | ResultData msg = new ResultData(); 39 | msg.setMsg("ok"); 40 | msg.setData(pageInfo); 41 | return msg; 42 | } 43 | 44 | @PostMapping("/dataInCircle") 45 | public ResultData getDataInCircle(@RequestBody DataInCircleRequest request) { 46 | log.info("Query data in circle: " + request); 47 | double radius = request.getRadius(); 48 | double lat = request.getLat(); 49 | double lng = request.getLng(); 50 | List dataList = indexSearchService.searchPoiInCircle(lng, lat, radius); 51 | ResultData msg = new ResultData(); 52 | msg.setMsg("ok"); 53 | msg.setData(dataList); 54 | return msg; 55 | } 56 | 57 | @PostMapping("/dataInRectangle") 58 | public ResultData getDataInRectangle(@RequestBody DataInRectangleRequest request) { 59 | log.info("Query data in rectangle: " + request); 60 | List points = request.getPoints(); 61 | ResultData msg = new ResultData(); 62 | if (points != null && points.size() >= 4) { 63 | double minLat = points.get(0).getLat(); 64 | double maxLat = points.get(1).getLat(); 65 | double minLng = points.get(0).getLon(); 66 | double maxLng = points.get(1).getLon(); 67 | 68 | for (PoiPoint poiPoint : points) { 69 | double lat = poiPoint.getLat(); 70 | double lng = poiPoint.getLon(); 71 | maxLat = Math.max(maxLat, lat); 72 | minLat = Math.min(minLat, lat); 73 | maxLng = Math.max(maxLng, lng); 74 | minLng = Math.min(minLng, lng); 75 | } 76 | List dataList = indexSearchService.searchPoiInRectangle(minLng, minLat, maxLng, maxLat); 77 | msg.setMsg("ok"); 78 | msg.setData(dataList); 79 | } else { 80 | msg.setMsg("failed"); 81 | } 82 | 83 | return msg; 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/js/leafletjs/leaflet.animatedmarker.js: -------------------------------------------------------------------------------- 1 | L.AnimatedMarker = L.Marker.extend({ 2 | options: { 3 | // meters 4 | distance: 200, 5 | // ms 6 | interval: 1000, 7 | // animate on add? 8 | autoStart: true, 9 | // callback onend 10 | onEnd: function(){}, 11 | clickable: false 12 | }, 13 | 14 | initialize: function (latlngs, options) { 15 | this.setLine(latlngs); 16 | L.Marker.prototype.initialize.call(this, latlngs[0], options); 17 | }, 18 | 19 | // Breaks the line up into tiny chunks (see options) ONLY if CSS3 animations 20 | // are not supported. 21 | _chunk: function(latlngs) { 22 | var i, 23 | len = latlngs.length, 24 | chunkedLatLngs = []; 25 | 26 | for (i=1;i this.options.distance) { 35 | while (dist > this.options.distance) { 36 | cur = new L.LatLng(cur.lat + dLat, cur.lng + dLng); 37 | dist = cur.distanceTo(next); 38 | chunkedLatLngs.push(cur); 39 | } 40 | } else { 41 | chunkedLatLngs.push(cur); 42 | } 43 | } 44 | chunkedLatLngs.push(latlngs[len-1]); 45 | 46 | return chunkedLatLngs; 47 | }, 48 | 49 | onAdd: function (map) { 50 | L.Marker.prototype.onAdd.call(this, map); 51 | 52 | // Start animating when added to the map 53 | if (this.options.autoStart) { 54 | this.start(); 55 | } 56 | }, 57 | 58 | animate: function() { 59 | var self = this, 60 | len = this._latlngs.length, 61 | speed = this.options.interval; 62 | 63 | // Normalize the transition speed from vertex to vertex 64 | if (this._i < len && this.i > 0) { 65 | speed = this._latlngs[this._i-1].distanceTo(this._latlngs[this._i]) / this.options.distance * this.options.interval; 66 | } 67 | 68 | // Only if CSS3 transitions are supported 69 | if (L.DomUtil.TRANSITION) { 70 | if (this._icon) { this._icon.style[L.DomUtil.TRANSITION] = ('all ' + speed + 'ms linear'); } 71 | if (this._shadow) { this._shadow.style[L.DomUtil.TRANSITION] = 'all ' + speed + 'ms linear'; } 72 | } 73 | 74 | // Move to the next vertex 75 | this.setLatLng(this._latlngs[this._i]); 76 | this._i++; 77 | 78 | // Queue up the animation to the next next vertex 79 | this._tid = setTimeout(function(){ 80 | if (self._i === len) { 81 | self.options.onEnd.apply(self, Array.prototype.slice.call(arguments)); 82 | } else { 83 | self.animate(); 84 | } 85 | }, speed); 86 | }, 87 | 88 | // Start the animation 89 | start: function() { 90 | this.animate(); 91 | }, 92 | 93 | // Stop the animation in place 94 | stop: function() { 95 | if (this._tid) { 96 | clearTimeout(this._tid); 97 | } 98 | }, 99 | 100 | setLine: function(latlngs){ 101 | if (L.DomUtil.TRANSITION) { 102 | // No need to to check up the line if we can animate using CSS3 103 | this._latlngs = latlngs; 104 | } else { 105 | // Chunk up the lines into options.distance bits 106 | this._latlngs = this._chunk(latlngs); 107 | this.options.distance = 10; 108 | this.options.interval = 30; 109 | } 110 | this._i = 0; 111 | } 112 | 113 | }); 114 | 115 | L.animatedMarker = function (latlngs, options) { 116 | return new L.AnimatedMarker(latlngs, options); 117 | }; 118 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/mapper/StationMapper.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | id, 18 | country_code, 19 | provider, 20 | lac, 21 | cell, 22 | latitude, 23 | longitude, 24 | address 25 | 26 | 27 | 32 | 33 | 35 | INSERT INTO station 36 | 37 | 38 | country_code, 39 | 40 | 41 | provider, 42 | 43 | 44 | lac, 45 | 46 | 47 | cell, 48 | 49 | 50 | latitude, 51 | 52 | 53 | longitude, 54 | 55 | 56 | address 57 | 58 | 59 | 60 | 61 | #{countryCode}, 62 | 63 | 64 | #{provider}, 65 | 66 | 67 | #{lac}, 68 | 69 | 70 | #{cell}, 71 | 72 | 73 | #{latitude}, 74 | 75 | 76 | #{longitude}, 77 | 78 | 79 | #{address} 80 | 81 | 82 | 83 | 84 | 85 | DELETE FROM station 86 | WHERE id = #{id} 87 | 88 | 89 | 90 | UPDATE station 91 | 92 | country_code = #{countryCode}, 93 | provider = #{provider}, 94 | lac = #{lac}, 95 | cell = #{cell}, 96 | latitude = #{latitude}, 97 | longitude = #{longitude}, 98 | address = #{address} 99 | 100 | WHERE id = #{id} 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /NettyMqService/src/main/java/com/luxx/mq/server/MqReceiver.java: -------------------------------------------------------------------------------- 1 | package com.luxx.mq.server; 2 | 3 | import com.luxx.mq.config.MqConfig; 4 | import com.luxx.mq.handler.EchoServerHandler; 5 | import com.luxx.mq.util.PropertiesUtil; 6 | import com.rabbitmq.client.*; 7 | 8 | import io.netty.buffer.ByteBuf; 9 | import io.netty.buffer.Unpooled; 10 | import io.netty.channel.group.ChannelGroupFutureListener; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | import java.nio.charset.StandardCharsets; 15 | 16 | /** 17 | * RabbitMQ Receiver based on RabbitMQ java client API 18 | */ 19 | public class MqReceiver { 20 | private static final Logger log = LoggerFactory.getLogger(MqReceiver.class); 21 | private ConnectionFactory connectionFactory; 22 | private String exchangeName = "NettyMqServerListenerExchange"; 23 | private String queueName = "MqListenerQueue"; 24 | private String routeKey = "mqListener"; 25 | 26 | private Thread listenThread; 27 | 28 | public MqReceiver() { 29 | String host = PropertiesUtil.getInstance().getProperty(MqConfig.MQ_HOST); 30 | int port = PropertiesUtil.getInstance().getPropertyAsInt(MqConfig.MQ_PORT); 31 | String username = PropertiesUtil.getInstance().getProperty(MqConfig.MQ_USERNAME); 32 | String password = PropertiesUtil.getInstance().getProperty(MqConfig.MQ_PASSWORD); 33 | connectionFactory = new ConnectionFactory(); 34 | connectionFactory.setHost(host); 35 | connectionFactory.setUsername(username); 36 | connectionFactory.setPassword(password); 37 | connectionFactory.setPort(port); 38 | connectionFactory.setVirtualHost("/"); 39 | } 40 | 41 | public void start() { 42 | listenThread = new Thread(() -> { 43 | try { 44 | Connection connection = connectionFactory.newConnection(); 45 | final Channel channel = connection.createChannel(); 46 | channel.exchangeDeclare(exchangeName, "direct", true, false, null); 47 | channel.queueDeclare(queueName, true, false, false, null); 48 | channel.queueBind(queueName, exchangeName, routeKey); 49 | // process the message one by one 50 | channel.basicQos(1); 51 | 52 | Consumer consumer = new DefaultConsumer(channel) { 53 | @Override 54 | public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) { 55 | String message = new String(body, StandardCharsets.UTF_8); 56 | broadcastMsgAndAck(message, channel, envelope); 57 | } 58 | }; 59 | channel.basicConsume(queueName, false, consumer); 60 | } catch (Exception ex) { 61 | log.error("Create Rabbit MQ listener error: " + ex.getMessage()); 62 | } 63 | }); 64 | 65 | listenThread.setDaemon(true); 66 | listenThread.start(); 67 | } 68 | 69 | private void broadcastMsgAndAck(String message, final Channel channel, final Envelope envelope) { 70 | // Broadcast message to all connected clients 71 | // If you want to send to a specified client, just add your own logic and ack manually 72 | // Be aware that ChannelGroup is thread safe 73 | log.info("Connected client number: " + EchoServerHandler.channels.size()); 74 | ByteBuf msg = Unpooled.copiedBuffer(message.getBytes()); 75 | EchoServerHandler.channels.writeAndFlush(msg).addListener( 76 | (ChannelGroupFutureListener) arg0 -> { 77 | // manually ack to MQ server when message is consumed. 78 | channel.basicAck(envelope.getDeliveryTag(), false); 79 | log.debug("Mq Receiver get message"); 80 | }); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /NettyMqService/src/test/java/test/TcpClient.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.io.InputStreamReader; 7 | import java.io.OutputStream; 8 | import java.io.UnsupportedEncodingException; 9 | import java.net.Socket; 10 | 11 | import com.luxx.mq.message.Header; 12 | import com.luxx.mq.message.Message; 13 | 14 | /** 15 | * Tcp client for echo server. This client also receive message forwarded by 16 | * netty MQ server 17 | */ 18 | public class TcpClient { 19 | 20 | private final static String serverString = "127.0.0.1"; 21 | private final static int servPort = 18866; 22 | 23 | public static void main(String[] args) { 24 | 25 | Socket socket = null; 26 | try { 27 | // Create socket that is connected to server on specified port 28 | socket = new Socket(serverString, servPort); 29 | System.out.println("Connected to server...send echo string (quit to end)"); 30 | 31 | final InputStream in = socket.getInputStream(); 32 | OutputStream out = socket.getOutputStream(); 33 | 34 | startReceiveThread(in); 35 | 36 | // sendMsgToServerFromInput(out); 37 | sendMsgToServerFromThread(out); 38 | } catch (IOException ex) { 39 | ex.printStackTrace(); 40 | } 41 | } 42 | 43 | private static void startReceiveThread(final InputStream in) { 44 | Thread receiveThread = new Thread() { 45 | public void run() { 46 | while (true) { 47 | byte[] readBytes = new byte[2048]; 48 | int ret = 0; 49 | try { 50 | ret = in.read(readBytes); 51 | } catch (IOException e) { 52 | break; 53 | } 54 | if (ret == -1) { 55 | break; 56 | } 57 | String retString = new String(readBytes); 58 | System.out.println("Received : " + retString); 59 | } 60 | } 61 | }; 62 | 63 | receiveThread.setDaemon(true); 64 | receiveThread.start(); 65 | } 66 | 67 | private static void sendMsgToServerFromInput(OutputStream out) { 68 | BufferedReader inFromUser = new BufferedReader(new InputStreamReader( 69 | System.in)); 70 | while (true) { 71 | String msg = new String(); 72 | try { 73 | msg = inFromUser.readLine(); 74 | } catch (IOException e) { 75 | e.printStackTrace(); 76 | } 77 | if (msg.equals("quit")) { 78 | break; 79 | } 80 | byte[] msgBytes = getMessageBytes(msg); 81 | if (msgBytes != null) { 82 | try { 83 | out.write(msgBytes); 84 | } catch (IOException e) { 85 | e.printStackTrace(); 86 | } 87 | } 88 | } 89 | } 90 | 91 | private static void sendMsgToServerFromThread(final OutputStream out) { 92 | ClientMsgSender msgSender = new ClientMsgSender(out); 93 | msgSender.start(); 94 | } 95 | 96 | public static byte[] getMessageBytes(String msg) { 97 | msg = msg.trim(); 98 | if (!msg.isEmpty()) { 99 | byte[] data = msg.getBytes(); 100 | 101 | Header header = new Header(); 102 | byte msgType = new Byte("1"); 103 | header.setMsgType(msgType); 104 | header.setMsgLength(5 + data.length); 105 | 106 | Message message = new Message(); 107 | try { 108 | message.setData(msg.getBytes("UTF-8")); 109 | } catch (UnsupportedEncodingException e) { 110 | e.printStackTrace(); 111 | } 112 | message.setHeader(header); 113 | return message.getBytes(); 114 | } 115 | 116 | return null; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /LogCollector/src/main/java/com/luxx/log/client/ElasticSearchClient.java: -------------------------------------------------------------------------------- 1 | package com.luxx.log.client; 2 | 3 | import com.luxx.log.util.DateTimeUtil; 4 | import org.apache.http.HttpHost; 5 | import org.apache.http.auth.AuthScope; 6 | import org.apache.http.auth.UsernamePasswordCredentials; 7 | import org.apache.http.client.CredentialsProvider; 8 | import org.apache.http.impl.client.BasicCredentialsProvider; 9 | import org.apache.http.impl.nio.client.HttpAsyncClientBuilder; 10 | import org.apache.logging.log4j.LogManager; 11 | import org.apache.logging.log4j.Logger; 12 | import org.elasticsearch.action.bulk.BulkRequest; 13 | import org.elasticsearch.action.bulk.BulkResponse; 14 | import org.elasticsearch.action.index.IndexRequest; 15 | import org.elasticsearch.client.RequestOptions; 16 | import org.elasticsearch.client.RestClient; 17 | import org.elasticsearch.client.RestClientBuilder; 18 | import org.elasticsearch.client.RestHighLevelClient; 19 | import org.elasticsearch.common.xcontent.XContentType; 20 | import org.springframework.beans.factory.annotation.Value; 21 | import org.springframework.context.annotation.Lazy; 22 | import org.springframework.stereotype.Component; 23 | 24 | import javax.annotation.PostConstruct; 25 | import javax.annotation.PreDestroy; 26 | import java.io.IOException; 27 | import java.net.UnknownHostException; 28 | import java.util.List; 29 | 30 | @Component 31 | @Lazy 32 | public class ElasticSearchClient { 33 | private static Logger logger = LogManager.getLogger(ElasticSearchClient.class); 34 | 35 | @Value("${es.address}") 36 | private String esAddress; 37 | 38 | @Value("${es.username}") 39 | private String username; 40 | 41 | @Value("${es.password}") 42 | private String password; 43 | 44 | @Value("${es.index}") 45 | private String indexName; 46 | 47 | // ES Client 48 | private RestHighLevelClient client; 49 | 50 | @PostConstruct 51 | public void init() throws UnknownHostException { 52 | logger.info("es.address: " + esAddress); 53 | logger.info("es.index: " + indexName); 54 | 55 | String[] hostPort = esAddress.split(":"); 56 | client = new RestHighLevelClient(RestClient.builder(new HttpHost(hostPort[0], Integer.parseInt(hostPort[1]))) 57 | .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() { 58 | @Override 59 | public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) { 60 | CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); 61 | credentialsProvider.setCredentials(AuthScope.ANY, 62 | new UsernamePasswordCredentials(username, password)); 63 | return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider); 64 | } 65 | })); 66 | } 67 | 68 | @PreDestroy 69 | public void close() { 70 | if (client != null) { 71 | try { 72 | client.close(); 73 | } catch (IOException e) { 74 | logger.error(e.toString()); 75 | } 76 | } 77 | } 78 | 79 | public void indexLog(List logList) { 80 | if (logList != null && logList.size() > 0) { 81 | BulkRequest request = new BulkRequest(); 82 | for (String data : logList) { 83 | String month = DateTimeUtil.currentYM(); 84 | String index = this.indexName + "_" + month; 85 | request.add(new IndexRequest(index).source(data, XContentType.JSON).type("_doc")); 86 | } 87 | BulkResponse bulkResponse; 88 | try { 89 | bulkResponse = client.bulk(request, RequestOptions.DEFAULT); 90 | if (bulkResponse.hasFailures()) { 91 | logger.error(bulkResponse.buildFailureMessage()); 92 | } 93 | } catch (IOException e) { 94 | logger.error(e.toString()); 95 | } 96 | logger.info("Index {} log to ES", logList.size()); 97 | } 98 | } 99 | 100 | 101 | } 102 | -------------------------------------------------------------------------------- /MapHttpService/src/main/java/com/luxx/map/MapHttpServer.java: -------------------------------------------------------------------------------- 1 | package com.luxx.map; 2 | 3 | import com.luxx.map.service.HttpServerInboundHandler; 4 | import com.luxx.map.service.MapDbOperation; 5 | import com.luxx.map.util.PropertiesUtil; 6 | import io.netty.bootstrap.ServerBootstrap; 7 | import io.netty.channel.ChannelFuture; 8 | import io.netty.channel.ChannelInitializer; 9 | import io.netty.channel.ChannelOption; 10 | import io.netty.channel.EventLoopGroup; 11 | import io.netty.channel.nio.NioEventLoopGroup; 12 | import io.netty.channel.socket.SocketChannel; 13 | import io.netty.channel.socket.nio.NioServerSocketChannel; 14 | import io.netty.handler.codec.http.HttpObjectAggregator; 15 | import io.netty.handler.codec.http.HttpRequestDecoder; 16 | import io.netty.handler.codec.http.HttpResponseEncoder; 17 | import io.netty.util.concurrent.DefaultEventExecutorGroup; 18 | import io.netty.util.concurrent.EventExecutorGroup; 19 | import org.slf4j.Logger; 20 | import org.slf4j.LoggerFactory; 21 | 22 | /** 23 | * Map服务,主程序 24 | * 25 | * @author luxiaoxun 26 | * @version 1.0 27 | * @since 2015.06.1 28 | */ 29 | public class MapHttpServer { 30 | private static Logger log = LoggerFactory.getLogger(MapHttpServer.class); 31 | 32 | private EventLoopGroup bossGroup; 33 | private EventLoopGroup workerGroup; 34 | private EventExecutorGroup eventExecutorGroup; 35 | 36 | public void start(int port) throws Exception { 37 | bossGroup = new NioEventLoopGroup(); 38 | workerGroup = new NioEventLoopGroup(); 39 | eventExecutorGroup = new DefaultEventExecutorGroup(32); 40 | try { 41 | ServerBootstrap b = new ServerBootstrap(); 42 | b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) 43 | .childHandler(new ChannelInitializer() { 44 | @Override 45 | public void initChannel(SocketChannel ch) throws Exception { 46 | ch.pipeline().addLast(new HttpResponseEncoder()); 47 | ch.pipeline().addLast(new HttpRequestDecoder()); 48 | //aggregates an HttpMessage and its following HttpContents into a single FullHttpRequest or FullHttpResponse 49 | //with no following HttpContents. 50 | ch.pipeline().addLast(new HttpObjectAggregator(65536)); 51 | ch.pipeline().addLast(eventExecutorGroup, new HttpServerInboundHandler()); 52 | } 53 | }).option(ChannelOption.SO_BACKLOG, 128) 54 | .childOption(ChannelOption.SO_KEEPALIVE, false) 55 | .childOption(ChannelOption.TCP_NODELAY, true); 56 | 57 | ChannelFuture f = b.bind(port).sync(); 58 | 59 | f.channel().closeFuture().sync(); 60 | } finally { 61 | destroy(); 62 | } 63 | } 64 | 65 | public void destroy() { 66 | if (eventExecutorGroup != null) { 67 | eventExecutorGroup.shutdownGracefully(); 68 | } 69 | if (workerGroup != null) { 70 | workerGroup.shutdownGracefully(); 71 | } 72 | if (bossGroup != null) { 73 | bossGroup.shutdownGracefully(); 74 | } 75 | 76 | log.info("Map Http Server is shut down"); 77 | } 78 | 79 | public static void main(String[] args) { 80 | final String portString = PropertiesUtil.getInstance().GetListenPort(); 81 | final int port = Integer.parseInt(portString); 82 | boolean isOK = MapDbOperation.init(); 83 | if (isOK) { 84 | final MapHttpServer server = new MapHttpServer(); 85 | try { 86 | log.info("Listening for connections on port " + port); 87 | server.start(port); 88 | Runtime.getRuntime().addShutdownHook(new Thread() { 89 | @Override 90 | public void run() { 91 | server.destroy(); 92 | } 93 | }); 94 | } catch (Exception e) { 95 | log.error("Map Http Service failed! " + e.getMessage()); 96 | } 97 | } else { 98 | log.error("Connect database failed!"); 99 | } 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/java/com/luxx/gis/executor/PoiIndexExecutor.java: -------------------------------------------------------------------------------- 1 | package com.luxx.gis.executor; 2 | 3 | import com.luxx.gis.config.IndexConfig; 4 | import com.luxx.gis.model.PoiData; 5 | import com.luxx.gis.service.IndexDataSource; 6 | import com.luxx.gis.service.PoiIndexService; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 9 | import org.springframework.stereotype.Component; 10 | import org.apache.logging.log4j.LogManager; 11 | import org.apache.logging.log4j.Logger; 12 | 13 | import javax.annotation.PostConstruct; 14 | import java.util.List; 15 | import java.util.ArrayList; 16 | import java.sql.Connection; 17 | import java.sql.ResultSet; 18 | import java.sql.SQLException; 19 | import java.sql.Statement; 20 | 21 | @Component 22 | @ConditionalOnProperty(name = "index.db.url") 23 | public class PoiIndexExecutor extends IndexExecutor { 24 | private static Logger log = LogManager.getLogger(PoiIndexExecutor.class); 25 | 26 | @Autowired 27 | private PoiIndexService poiIndexService; 28 | 29 | @Autowired 30 | private IndexDataSource indexDataSource; 31 | 32 | @Autowired 33 | private IndexConfig indexConfig; 34 | 35 | // 读取数据分页 36 | private long pageNum = 0; 37 | private int pageCount = 1000; 38 | private String dataTableName; 39 | 40 | @PostConstruct 41 | public void init() { 42 | dataTableName = indexConfig.getDbTable(); 43 | } 44 | 45 | @Override 46 | public void start() { 47 | log.info("Start index POI"); 48 | try { 49 | poiIndexService.clear(); 50 | poiIndexService.createIndexMapping(); 51 | poiIndexService.createIndex(); 52 | 53 | Thread exportThread = new Thread(new Runnable() { 54 | public void run() { 55 | boolean isRunning = true; 56 | while (isRunning) { 57 | List dataList = getDataFromDataBase(); 58 | if (dataList == null || dataList.isEmpty()) { 59 | log.info("Index POI finished"); 60 | break; 61 | } 62 | int len = dataList.size(); 63 | poiIndexService.indexPoiDataList(dataList); 64 | log.info("Index POI max id:" + dataList.get(len - 1).getId()); 65 | } 66 | } 67 | }); 68 | exportThread.start(); 69 | } catch (Exception ex) { 70 | log.error("Index POI exception:" + ex.toString()); 71 | } 72 | } 73 | 74 | private List getDataFromDataBase() { 75 | List dataList = new ArrayList<>(pageCount); 76 | Connection dbConnection = null; 77 | Statement stm = null; 78 | ResultSet res = null; 79 | try { 80 | dbConnection = indexDataSource.getConnection(); 81 | if (dbConnection != null) { 82 | stm = dbConnection.createStatement(); 83 | ++pageNum; 84 | long startNum = (pageNum - 1) * pageCount; 85 | res = stm.executeQuery(String.format( 86 | "SELECT * FROM %s LIMIT %s,%s ", dataTableName, 87 | startNum, pageCount)); 88 | if (res != null) { 89 | while (res.next()) { 90 | int id = res.getInt("id"); 91 | String address = res.getString("address"); 92 | double lat = res.getDouble("latitude"); 93 | double lng = res.getDouble("longitude"); 94 | PoiData data = new PoiData(id, address, lat, lng); 95 | dataList.add(data); 96 | } 97 | } 98 | } else { 99 | log.error("Get connection fail"); 100 | return null; 101 | } 102 | } catch (SQLException e) { 103 | e.printStackTrace(); 104 | log.error(e.toString()); 105 | } finally { 106 | attemptClose(res); 107 | attemptClose(stm); 108 | attemptClose(dbConnection); 109 | } 110 | 111 | return dataList; 112 | } 113 | 114 | 115 | @Override 116 | public void stop() { 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/images/locate.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 26 | 30 | 34 | 35 | 44 | 45 | 63 | 70 | 71 | 73 | 74 | 76 | image/svg+xml 77 | 79 | 80 | 81 | 82 | 83 | 88 | 98 | 108 | 115 | 122 | 129 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/js/leafletjs/proj4leaflet.js: -------------------------------------------------------------------------------- 1 | L.Proj = {}; 2 | 3 | L.Proj._isProj4Proj = function(a) { 4 | return typeof a['projName'] !== 'undefined'; 5 | } 6 | 7 | L.Proj.Projection = L.Class.extend({ 8 | initialize: function(a, def) { 9 | if (L.Proj._isProj4Proj(a)) { 10 | this._proj = a; 11 | } else { 12 | var code = a; 13 | Proj4js.defs[code] = def; 14 | this._proj = new Proj4js.Proj(code); 15 | } 16 | }, 17 | 18 | project: function (latlng) { 19 | var point = new L.Point(latlng.lng, latlng.lat); 20 | return Proj4js.transform(Proj4js.WGS84, this._proj, point); 21 | }, 22 | 23 | unproject: function (point, unbounded) { 24 | var point2 = Proj4js.transform(this._proj, Proj4js.WGS84, point.clone()); 25 | return new L.LatLng(point2.y, point2.x, unbounded); 26 | } 27 | }); 28 | 29 | L.Proj.CRS = L.Class.extend({ 30 | includes: L.CRS, 31 | 32 | options: { 33 | transformation: new L.Transformation(1, 0, -1, 0) 34 | }, 35 | 36 | initialize: function(a, b, c) { 37 | var code, proj, def, options; 38 | 39 | if (L.Proj._isProj4Proj(a)) { 40 | proj = a; 41 | code = proj.srsCode; 42 | options = b || {}; 43 | 44 | this.projection = new L.Proj.Projection(proj); 45 | } else { 46 | code = a; 47 | def = b; 48 | options = c || {}; 49 | this.projection = new L.Proj.Projection(code, def); 50 | } 51 | 52 | L.Util.setOptions(this, options); 53 | this.code = code; 54 | this.transformation = this.options.transformation; 55 | 56 | if (this.options.origin) { 57 | this.transformation = 58 | new L.Transformation(1, -this.options.origin[0], 59 | -1, this.options.origin[1]); 60 | } 61 | 62 | if (this.options.scales) { 63 | this.scale = function(zoom) { 64 | return this.options.scales[zoom]; 65 | } 66 | } else if (this.options.resolutions) { 67 | this.scale = function(zoom) { 68 | return 1 / this.options.resolutions[zoom]; 69 | } 70 | } 71 | } 72 | }); 73 | 74 | L.Proj.CRS.TMS = L.Proj.CRS.extend({ 75 | initialize: function(a, b, c, d) { 76 | if (L.Proj._isProj4Proj(a)) { 77 | var proj = a, 78 | projectedBounds = b, 79 | options = c || {}; 80 | options.origin = [projectedBounds[0], projectedBounds[3]]; 81 | L.Proj.CRS.prototype.initialize(proj, options); 82 | } else { 83 | var code = a, 84 | def = b, 85 | projectedBounds = c, 86 | options = d || {}; 87 | options.origin = [projectedBounds[0], projectedBounds[3]]; 88 | L.Proj.CRS.prototype.initialize(code, def, options); 89 | } 90 | 91 | this.projectedBounds = projectedBounds; 92 | } 93 | }); 94 | 95 | L.Proj.TileLayer = {}; 96 | 97 | L.Proj.TileLayer.TMS = L.TileLayer.extend({ 98 | options: { 99 | tms: true, 100 | continuousWorld: true 101 | }, 102 | 103 | initialize: function(urlTemplate, crs, options) { 104 | if (!(crs instanceof L.Proj.CRS.TMS)) { 105 | throw new Error("CRS is not L.Proj.CRS.TMS."); 106 | } 107 | 108 | L.TileLayer.prototype.initialize.call(this, urlTemplate, options); 109 | this.crs = crs; 110 | 111 | // Verify grid alignment 112 | for (var i = this.options.minZoom; i < this.options.maxZoom; i++) { 113 | var gridHeight = (this.crs.projectedBounds[3] - this.crs.projectedBounds[1]) / 114 | this._projectedTileSize(i); 115 | if (Math.abs(gridHeight - Math.round(gridHeight)) > 1e-3) { 116 | throw new Error("Projected bounds does not match grid at zoom " + i); 117 | } 118 | } 119 | }, 120 | 121 | getTileUrl: function(tilePoint) { 122 | var gridHeight = 123 | Math.round((this.crs.projectedBounds[3] - this.crs.projectedBounds[1]) / 124 | this._projectedTileSize(this._map.getZoom())); 125 | 126 | // TODO: relies on some of TileLayer's internals 127 | return L.Util.template(this._url, L.Util.extend({ 128 | s: this._getSubdomain(tilePoint), 129 | z: this._getZoomForUrl(), 130 | x: tilePoint.x, 131 | y: gridHeight - tilePoint.y - 1 132 | }, this.options)); 133 | }, 134 | 135 | _projectedTileSize: function(zoom) { 136 | return (this.options.tileSize / this.crs.scale(zoom)); 137 | } 138 | }); 139 | 140 | if (typeof module !== 'undefined') module.exports = L.Proj; 141 | 142 | if (typeof L !== 'undefined' && typeof L.CRS !== 'undefined') { 143 | // This is left here for backwards compatibility 144 | L.CRS.proj4js = (function () { 145 | return function (code, def, transformation, options) { 146 | options = options || {}; 147 | if (transformation) options.transformation = transformation; 148 | 149 | return new L.Proj.CRS(code, def, options); 150 | }; 151 | }()); 152 | } 153 | -------------------------------------------------------------------------------- /LogCollector/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.5.12 9 | 10 | 11 | 12 | com.luxx 13 | LogCollector 14 | 1.0 15 | log-collector 16 | 17 | 18 | true 19 | 1.8 20 | 2.5.12 21 | 1.18.16 22 | 7.17.14 23 | 2.14.0 24 | 32.0.0-jre 25 | 2.8.9 26 | 4.13.1 27 | 28 | 29 | 30 | 31 | junit 32 | junit 33 | ${junit.version} 34 | 35 | 36 | 37 | 38 | org.springframework.boot 39 | spring-boot-starter 40 | ${spring-boot.version} 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-starter-logging 45 | 46 | 47 | 48 | 49 | org.springframework.boot 50 | spring-boot-starter-log4j2 51 | ${spring-boot.version} 52 | 53 | 54 | org.springframework.boot 55 | spring-boot-starter-test 56 | ${spring-boot.version} 57 | test 58 | 59 | 60 | 61 | org.elasticsearch 62 | elasticsearch 63 | ${es.version} 64 | 65 | 66 | org.elasticsearch.client 67 | elasticsearch-rest-client 68 | ${es.version} 69 | 70 | 71 | org.elasticsearch.client 72 | elasticsearch-rest-high-level-client 73 | ${es.version} 74 | 75 | 76 | 77 | org.projectlombok 78 | lombok 79 | ${lombok.version} 80 | true 81 | 82 | 83 | 84 | org.apache.kafka 85 | kafka-clients 86 | 1.1.1 87 | 88 | 89 | 90 | com.google.guava 91 | guava 92 | ${guava.version} 93 | 94 | 95 | 96 | 97 | com.fasterxml.jackson.core 98 | jackson-databind 99 | ${jackson.version} 100 | 101 | 102 | 103 | com.google.code.gson 104 | gson 105 | ${gson.version} 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | org.springframework.boot 114 | spring-boot-maven-plugin 115 | ${spring-boot.version} 116 | 117 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/java/com/luxx/gis/executor/MysqlIndexExecutor.java: -------------------------------------------------------------------------------- 1 | package com.luxx.gis.executor; 2 | 3 | import java.sql.Connection; 4 | import java.sql.ResultSet; 5 | import java.sql.SQLException; 6 | import java.sql.Statement; 7 | import java.util.ArrayList; 8 | import java.util.Date; 9 | import java.util.List; 10 | 11 | import com.luxx.gis.config.IndexConfig; 12 | import com.luxx.gis.model.HotspotData; 13 | import com.luxx.gis.service.IndexDataSource; 14 | import com.luxx.gis.service.MysqlIndexService; 15 | import org.apache.logging.log4j.LogManager; 16 | import org.apache.logging.log4j.Logger; 17 | 18 | import org.springframework.beans.factory.annotation.Autowired; 19 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 20 | import org.springframework.stereotype.Component; 21 | 22 | import javax.annotation.PostConstruct; 23 | 24 | @Component 25 | @ConditionalOnProperty(name = "index.es.cluster.address") 26 | public class MysqlIndexExecutor extends IndexExecutor { 27 | private static Logger log = LogManager.getLogger(MysqlIndexExecutor.class); 28 | 29 | @Autowired 30 | private MysqlIndexService mysqlIndexService; 31 | 32 | @Autowired 33 | private IndexDataSource indexDataSource; 34 | 35 | @Autowired 36 | private IndexConfig indexConfig; 37 | 38 | // 读取数据分页 39 | private long pageNum = 0; 40 | private int pageCount = 30000; 41 | private volatile boolean isFinished = false; 42 | private String dataTableName; 43 | 44 | @PostConstruct 45 | public void init() { 46 | dataTableName = indexConfig.getDbTable(); 47 | } 48 | 49 | @Override 50 | public void start() { 51 | log.info("Start index mysql data to ES"); 52 | 53 | //indexService.deleteIndex(); 54 | mysqlIndexService.createIndex(); 55 | mysqlIndexService.createIndexMapping(); 56 | 57 | Thread exportThread = new Thread(new Runnable() { 58 | public void run() { 59 | while (!isFinished) { 60 | List dataList = getDataFromDataBase(); 61 | if (dataList != null && !dataList.isEmpty()) { 62 | mysqlIndexService.indexHotSpotDataList(dataList); 63 | log.info(String.format("Index data complete %s pages", pageNum)); 64 | } 65 | } 66 | log.info("Index mysql data to ES complete "); 67 | } 68 | }); 69 | exportThread.start(); 70 | } 71 | 72 | private List getDataFromDataBase() { 73 | List dataList = new ArrayList<>(pageCount); 74 | Connection dbConnection = null; 75 | Statement stm = null; 76 | ResultSet res = null; 77 | try { 78 | dbConnection = indexDataSource.getConnection(); 79 | stm = dbConnection.createStatement(); 80 | ++pageNum; 81 | long startNum = (pageNum - 1) * pageCount; 82 | log.info(String.format("Geting data from database, offset %s limit %s", startNum, pageCount)); 83 | res = stm.executeQuery(String.format("SELECT * FROM %s LIMIT %s,%s ", dataTableName, startNum, pageCount)); 84 | if (res.next()) { 85 | do { 86 | HotspotData datagram = new HotspotData(); 87 | datagram.setId(res.getLong("id")); 88 | datagram.setDeviceID(res.getString("deviceID")); 89 | datagram.setImei(res.getString("IMEI")); 90 | datagram.setImsi(res.getString("IMSI")); 91 | datagram.setTmsi(res.getString("TMSI")); 92 | datagram.setSeqNum(Integer.parseInt(res.getString("seqNum"))); 93 | datagram.setSrcLac(res.getString("sourceLac")); 94 | Date date = res.getDate("timeStamp"); 95 | datagram.setCollectTime(date); 96 | datagram.setOwnArea(res.getString("ownerArea")); 97 | datagram.setTeleOper(res.getString("teleOper")); 98 | datagram.setTeleSevenNum(res.getString("telNum")); 99 | 100 | dataList.add(datagram); 101 | } while (res.next()); 102 | } else { 103 | isFinished = true; 104 | } 105 | } catch (SQLException e) { 106 | e.printStackTrace(); 107 | log.error(e.toString()); 108 | } finally { 109 | attemptClose(res); 110 | attemptClose(stm); 111 | attemptClose(dbConnection); 112 | } 113 | 114 | return dataList; 115 | } 116 | 117 | @Override 118 | public void stop() { 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/java/com/luxx/gis/executor/RedshiftIndexExecutor.java: -------------------------------------------------------------------------------- 1 | package com.luxx.gis.executor; 2 | 3 | import java.sql.Connection; 4 | import java.sql.ResultSet; 5 | import java.sql.SQLException; 6 | import java.sql.Statement; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | import com.luxx.gis.config.IndexConfig; 11 | import com.luxx.gis.model.EndpointData; 12 | import com.luxx.gis.service.RedshiftIndexService; 13 | import com.luxx.gis.service.IndexDataSource; 14 | import org.apache.logging.log4j.LogManager; 15 | import org.apache.logging.log4j.Logger; 16 | import org.springframework.beans.factory.annotation.Autowired; 17 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 18 | import org.springframework.stereotype.Component; 19 | 20 | import javax.annotation.PostConstruct; 21 | 22 | @Component 23 | @ConditionalOnProperty(name = "index.es.cluster.address") 24 | public class RedshiftIndexExecutor extends IndexExecutor { 25 | private static Logger log = LogManager.getLogger(RedshiftIndexExecutor.class); 26 | 27 | @Autowired 28 | private RedshiftIndexService indexService; 29 | 30 | @Autowired 31 | private IndexDataSource indexDataSource; 32 | 33 | @Autowired 34 | private IndexConfig indexConfig; 35 | 36 | // 读取数据分页 37 | private long pageNum = 1; 38 | private int pageCount = 30000; 39 | private volatile boolean isFinished = false; 40 | private String dataTableName; 41 | 42 | @PostConstruct 43 | public void init() { 44 | dataTableName = indexConfig.getDbTable(); 45 | } 46 | 47 | @Override 48 | public void start() { 49 | // log.info("Delete old index"); 50 | //indexService.deleteIndex(); 51 | 52 | log.info("Create new index"); 53 | indexService.createIndex(); 54 | 55 | log.info("Create new index type mapping"); 56 | indexService.createIndexMapping(); 57 | 58 | log.info("Start index redshift data to ES"); 59 | Thread exportThread = new Thread(new Runnable() { 60 | public void run() { 61 | while (!isFinished) { 62 | List dataList = getDataFromDataBase(); 63 | if (dataList != null && !dataList.isEmpty()) { 64 | indexService.indexHotSpotDataListForRedshift(dataList); 65 | log.info(String.format("Index data complete %s pages", pageNum)); 66 | } 67 | } 68 | log.info("Index redshift data to ES complete"); 69 | } 70 | }); 71 | exportThread.start(); 72 | } 73 | 74 | private List getDataFromDataBase() { 75 | List dataList = new ArrayList(pageCount); 76 | Connection dbConnection = null; 77 | Statement stm = null; 78 | ResultSet res = null; 79 | try { 80 | dbConnection = indexDataSource.getConnection(); 81 | stm = dbConnection.createStatement(); 82 | ++pageNum; 83 | long startNum = (pageNum - 1) * pageCount; 84 | log.info(String.format("Geting data from database, offset %s limit %s", startNum, pageCount)); 85 | res = stm.executeQuery( 86 | String.format("SELECT * FROM %s where date_time > '2017-03-13 16:00:00' OFFSET %s LIMIT %s", 87 | dataTableName, startNum, pageCount)); 88 | if (res.next()) { 89 | do { 90 | EndpointData data = new EndpointData(); 91 | data.setOrg_id(Integer.parseInt(res.getString("org_id"))); 92 | data.setEndpoint_id(Long.parseLong(res.getString("endpoint_id"))); 93 | 94 | data.setDs_bytes(Long.parseLong(res.getString("ds_bytes"))); 95 | data.setDs_max_bytes(Double.parseDouble(res.getString("ds_max_bps"))); 96 | data.setDs_avg_bytes(Double.parseDouble(res.getString("ds_avg_bps"))); 97 | data.setDs_mwt(Integer.parseInt(res.getString("ds_mwt"))); 98 | 99 | data.setUs_bytes(Long.parseLong(res.getString("us_bytes"))); 100 | data.setUs_max_bytes(Double.parseDouble(res.getString("us_max_bps"))); 101 | data.setUs_avg_bytes(Double.parseDouble(res.getString("us_avg_bps"))); 102 | data.setUs_mwt(Integer.parseInt(res.getString("us_mwt"))); 103 | 104 | data.setDate_time(res.getDate("date_time")); 105 | 106 | dataList.add(data); 107 | } while (res.next()); 108 | } else { 109 | isFinished = true; 110 | } 111 | } catch (SQLException e) { 112 | e.printStackTrace(); 113 | log.error(e.toString()); 114 | } finally { 115 | attemptClose(res); 116 | attemptClose(stm); 117 | attemptClose(dbConnection); 118 | } 119 | 120 | return dataList; 121 | } 122 | 123 | @Override 124 | public void stop() { 125 | } 126 | } -------------------------------------------------------------------------------- /NettyMqService/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Code4Java 7 | com.luxx 8 | 1.0.0 9 | 10 | 4.0.0 11 | 12 | NettyMqService 13 | jar 14 | 15 | 16 | UTF-8 17 | UTF-8 18 | UTF-8 19 | 1.7.31 20 | 4.1.42.Final 21 | 32.0.0-jre 22 | 23 | 24 | 25 | 26 | 27 | junit 28 | junit 29 | 4.13.1 30 | test 31 | 32 | 33 | 34 | 35 | org.slf4j 36 | slf4j-api 37 | ${slf4j.version} 38 | 39 | 40 | org.slf4j 41 | slf4j-log4j12 42 | ${slf4j.version} 43 | 44 | 45 | 46 | 47 | com.rabbitmq 48 | amqp-client 49 | 4.8.0 50 | 51 | 52 | 53 | 54 | io.netty 55 | netty-all 56 | ${netty.version} 57 | 58 | 59 | 60 | 61 | com.google.guava 62 | guava 63 | ${guava.version} 64 | 65 | 66 | 67 | 68 | 69 | 70 | org.apache.maven.plugins 71 | maven-compiler-plugin 72 | 3.8.1 73 | 74 | 8 75 | 8 76 | 77 | 78 | 79 | 80 | org.apache.maven.plugins 81 | maven-shade-plugin 82 | 3.2.1 83 | 84 | 85 | package 86 | 87 | shade 88 | 89 | 90 | 91 | 93 | META-INF/spring.handlers 94 | 95 | 97 | META-INF/spring.schemas 98 | 99 | 101 | com.luxx.mq.MainServer 102 | 103 | 104 | 105 | 106 | *:* 107 | 108 | META-INF/*.SF 109 | META-INF/*.DSA 110 | META-INF/*.RSA 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /MapHttpService/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Code4Java 7 | com.luxx 8 | 1.0.0 9 | 10 | 4.0.0 11 | 12 | MapHttpService 13 | jar 14 | 15 | 16 | UTF-8 17 | UTF-8 18 | UTF-8 19 | 1.7.31 20 | 4.1.42.Final 21 | 32.0.0-jre 22 | 3.4.5 23 | 8.0.28 24 | 25 | 26 | 27 | 28 | 29 | junit 30 | junit 31 | 4.13.1 32 | test 33 | 34 | 35 | 36 | 37 | org.slf4j 38 | slf4j-api 39 | ${slf4j.version} 40 | 41 | 42 | org.slf4j 43 | slf4j-log4j12 44 | ${slf4j.version} 45 | 46 | 47 | 48 | 49 | io.netty 50 | netty-all 51 | ${netty.version} 52 | 53 | 54 | 55 | 56 | com.google.guava 57 | guava 58 | ${guava.version} 59 | 60 | 61 | 62 | 63 | org.xerial 64 | sqlite-jdbc 65 | 3.41.2.2 66 | 67 | 68 | 69 | 70 | com.zaxxer 71 | HikariCP 72 | ${hikaricp.version} 73 | 74 | 75 | 76 | 77 | mysql 78 | mysql-connector-java 79 | ${mysql.version} 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | org.apache.maven.plugins 88 | maven-compiler-plugin 89 | 3.8.1 90 | 91 | 8 92 | 8 93 | 94 | 95 | 96 | 97 | org.apache.maven.plugins 98 | maven-shade-plugin 99 | 3.2.1 100 | 101 | 102 | package 103 | 104 | shade 105 | 106 | 107 | 108 | 110 | com.luxx.map.MapHttpServer 111 | 112 | 113 | 114 | 115 | *:* 116 | 117 | META-INF/*.SF 118 | META-INF/*.DSA 119 | META-INF/*.RSA 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /LogCollector/src/main/java/com/luxx/log/executor/LogIndexExecutor.java: -------------------------------------------------------------------------------- 1 | package com.luxx.log.executor; 2 | 3 | import com.fasterxml.jackson.databind.JsonNode; 4 | import com.fasterxml.jackson.databind.node.ObjectNode; 5 | import com.luxx.log.client.ElasticSearchClient; 6 | import com.luxx.log.util.JsonUtil; 7 | import com.luxx.log.util.DateTimeUtil; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.apache.kafka.clients.consumer.ConsumerConfig; 10 | import org.apache.kafka.clients.consumer.ConsumerRecord; 11 | import org.apache.kafka.clients.consumer.ConsumerRecords; 12 | import org.apache.kafka.clients.consumer.KafkaConsumer; 13 | import org.apache.kafka.common.serialization.StringDeserializer; 14 | import org.joda.time.DateTime; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.beans.factory.annotation.Value; 17 | import org.springframework.stereotype.Component; 18 | 19 | import javax.annotation.PostConstruct; 20 | import java.util.ArrayList; 21 | import java.util.Collections; 22 | import java.util.List; 23 | import java.util.Properties; 24 | 25 | @Component 26 | @Slf4j 27 | public class LogIndexExecutor extends DataIndexExecutor { 28 | 29 | @Autowired 30 | private ElasticSearchClient elasticSearchClient; 31 | 32 | @Value("${kafka.url}") 33 | private String kafkaUrl; 34 | 35 | @Value("${kafka.topic}") 36 | private String kafkaTopic; 37 | 38 | private String groupId = "log-collector"; 39 | 40 | private volatile boolean isRunning = true; 41 | private Thread worker; 42 | private KafkaConsumer kafkaConsumer; 43 | 44 | 45 | @PostConstruct 46 | public void init() { 47 | log.info("kafka.url: " + kafkaUrl); 48 | log.info("kafka.topic: " + kafkaTopic); 49 | 50 | Properties p = new Properties(); 51 | p.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaUrl); 52 | p.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); 53 | p.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); 54 | p.put(ConsumerConfig.GROUP_ID_CONFIG, groupId); 55 | 56 | kafkaConsumer = new KafkaConsumer<>(p); 57 | kafkaConsumer.subscribe(Collections.singletonList(kafkaTopic)); 58 | } 59 | 60 | @Override 61 | public void start() { 62 | log.info("Start index log service"); 63 | try { 64 | worker = new Thread(new Runnable() { 65 | public void run() { 66 | while (isRunning) { 67 | try { 68 | ConsumerRecords records = kafkaConsumer.poll(1000); 69 | List logList = new ArrayList<>(1000); 70 | for (ConsumerRecord record : records) { 71 | log.debug("topic: {}, offset: {}, log: {}", record.topic(), record.offset(), record.value()); 72 | try { 73 | String data = record.value(); 74 | if (JsonUtil.isValidJson(data)) { 75 | JsonNode json = JsonUtil.decode(data, JsonNode.class); 76 | if (json.has("message")) { 77 | String msg = json.get("message").asText(); 78 | JsonNode msgNode = JsonUtil.decode(msg, JsonNode.class); 79 | ObjectNode objectNode = (ObjectNode) json; 80 | objectNode.replace("message", msgNode); 81 | String timestamp = DateTimeUtil.getEsString(DateTime.now().getMillis()); 82 | objectNode.put("@timestamp", timestamp); 83 | logList.add(objectNode.toString()); 84 | } 85 | } else { 86 | ObjectNode objectNode = JsonUtil.createObjectNode(); 87 | String timestamp = DateTimeUtil.getEsString(DateTime.now().getMillis()); 88 | objectNode.put("@timestamp", timestamp); 89 | objectNode.put("message", data); 90 | logList.add(objectNode.toString()); 91 | } 92 | } catch (Exception ex) { 93 | log.error("Process log error: " + ex.toString()); 94 | } 95 | } 96 | elasticSearchClient.indexLog(logList); 97 | } catch (Exception ex) { 98 | log.error("Log index exception:" + ex.toString()); 99 | } 100 | } 101 | } 102 | }); 103 | worker.start(); 104 | } catch (Exception ex) { 105 | log.error("Start index service exception:" + ex.toString()); 106 | } 107 | } 108 | 109 | 110 | @Override 111 | public void stop() { 112 | if (worker != null) { 113 | isRunning = false; 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /MapHttpService/src/main/java/com/luxx/map/service/MapDbOperation.java: -------------------------------------------------------------------------------- 1 | package com.luxx.map.service; 2 | 3 | import com.luxx.map.config.DbTypeEnum; 4 | import com.luxx.map.util.PropertiesUtil; 5 | import com.zaxxer.hikari.HikariConfig; 6 | import com.zaxxer.hikari.HikariDataSource; 7 | 8 | import java.sql.*; 9 | 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | /** 14 | * Map服务,数据库操作 15 | * 16 | * @author luxiaoxun 17 | * @version 1.0 18 | * @since 2015.06.1 19 | */ 20 | public class MapDbOperation { 21 | private static Logger log = LoggerFactory.getLogger(MapDbOperation.class); 22 | 23 | private static int dbType; 24 | private static String sqliteDbPath; 25 | private static HikariDataSource dataSource; 26 | 27 | private static final String querySqlite = "select Tile from TilesData where id = " + 28 | "(select id from Tiles where X = %s and Y = %s and Zoom = %s and Type = %s)"; 29 | private static final String queryMysql = "select Tile from gmapnetcache where " + 30 | "X = %s and Y = %s and Zoom = %s and Type = %s"; 31 | 32 | public static boolean init() { 33 | try { 34 | dbType = PropertiesUtil.getInstance().GetDbType(); 35 | if (dbType == DbTypeEnum.sqlite.getType()) { 36 | sqliteDbPath = PropertiesUtil.getInstance().GetSqliteDbPath(); 37 | Class.forName("org.sqlite.JDBC"); 38 | return true; 39 | } else if (dbType == DbTypeEnum.mysql.getType()) { 40 | String url = PropertiesUtil.getInstance().GetMysqlUrl(); 41 | String user = PropertiesUtil.getInstance().GetMysqlUser(); 42 | String pswd = PropertiesUtil.getInstance().GetMysqlPassword(); 43 | HikariConfig config = new HikariConfig(); 44 | config.setJdbcUrl(url); 45 | config.setUsername(user); 46 | config.setPassword(pswd); 47 | config.addDataSourceProperty("cachePrepStmts", "true"); 48 | config.addDataSourceProperty("prepStmtCacheSize", "250"); 49 | config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); 50 | config.setMaximumPoolSize(32); 51 | dataSource = new HikariDataSource(config); 52 | return true; 53 | } 54 | return false; 55 | } catch (Exception e) { 56 | log.error(e.toString()); 57 | return false; 58 | } 59 | } 60 | 61 | public static byte[] getTile(int x, int y, int zoom, String dbId) { 62 | try { 63 | if (dbType == DbTypeEnum.sqlite.getType()) { 64 | return getTileFromSqlite(x, y, zoom, dbId); 65 | } 66 | if (dbType == DbTypeEnum.mysql.getType()) { 67 | return getTileFromMySql(x, y, zoom, dbId); 68 | } else { 69 | return null; 70 | } 71 | } catch (Exception ex) { 72 | log.error(ex.getMessage()); 73 | return null; 74 | } 75 | } 76 | 77 | public static byte[] getTileFromSqlite(int x, int y, int zoom, String dbId) throws SQLException { 78 | byte[] allBytesInBlob = null; 79 | Connection dbConnection = null; 80 | Statement stm = null; 81 | ResultSet res = null; 82 | try { 83 | dbConnection = DriverManager.getConnection("jdbc:sqlite:" + sqliteDbPath); 84 | stm = dbConnection.createStatement(); 85 | res = stm.executeQuery(String.format(querySqlite, x, y, zoom, dbId)); 86 | if (res != null) { 87 | if (res.next()) { 88 | allBytesInBlob = res.getBytes("Tile"); 89 | } 90 | } 91 | } finally { 92 | attemptClose(res); 93 | attemptClose(stm); 94 | attemptClose(dbConnection); 95 | } 96 | return allBytesInBlob; 97 | } 98 | 99 | public static byte[] getTileFromMySql(int x, int y, int zoom, String dbId) throws SQLException { 100 | byte[] allBytesInBlob = null; 101 | Connection dbConnection = null; 102 | Statement stm = null; 103 | ResultSet res = null; 104 | try { 105 | dbConnection = dataSource.getConnection(); 106 | stm = dbConnection.createStatement(); 107 | res = stm.executeQuery(String.format(queryMysql, x, y, zoom, dbId)); 108 | if (res != null) { 109 | if (res.next()) { 110 | allBytesInBlob = res.getBytes("Tile"); 111 | } 112 | } 113 | } finally { 114 | attemptClose(res); 115 | attemptClose(stm); 116 | attemptClose(dbConnection); 117 | } 118 | 119 | return allBytesInBlob; 120 | } 121 | 122 | private static void attemptClose(ResultSet o) { 123 | try { 124 | if (o != null) { 125 | o.close(); 126 | } 127 | } catch (Exception e) { 128 | } 129 | } 130 | 131 | private static void attemptClose(Statement o) { 132 | try { 133 | if (o != null) { 134 | o.close(); 135 | } 136 | } catch (Exception e) { 137 | } 138 | } 139 | 140 | private static void attemptClose(Connection o) { 141 | try { 142 | if (o != null) { 143 | o.close(); 144 | } 145 | } catch (Exception e) { 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /LogCollector/src/main/java/com/luxx/log/util/JsonUtil.java: -------------------------------------------------------------------------------- 1 | package com.luxx.log.util; 2 | 3 | import com.fasterxml.jackson.core.JsonProcessingException; 4 | import com.fasterxml.jackson.core.type.TypeReference; 5 | import com.fasterxml.jackson.databind.DeserializationFeature; 6 | import com.fasterxml.jackson.databind.JavaType; 7 | import com.fasterxml.jackson.databind.ObjectMapper; 8 | import com.fasterxml.jackson.databind.SerializationFeature; 9 | import com.fasterxml.jackson.databind.node.ObjectNode; 10 | import com.google.common.base.Strings; 11 | import com.google.gson.JsonElement; 12 | import com.google.gson.JsonParser; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | 16 | import java.io.IOException; 17 | import java.util.HashMap; 18 | 19 | public class JsonUtil { 20 | private static Logger logger = LoggerFactory.getLogger(JsonUtil.class); 21 | 22 | private static final ObjectMapper mapper = new ObjectMapper(); 23 | 24 | static { 25 | mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 26 | mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); 27 | } 28 | 29 | public static Boolean isValidJson(String jsonStr) { 30 | if (Strings.isNullOrEmpty(jsonStr)) { 31 | return false; 32 | } 33 | if (Strings.isNullOrEmpty(jsonStr.replace(" ", ""))) { 34 | return false; 35 | } 36 | 37 | JsonElement jsonElement; 38 | try { 39 | jsonElement = JsonParser.parseString(jsonStr); 40 | } catch (Exception e) { 41 | return false; 42 | } 43 | if (jsonElement == null) { 44 | return false; 45 | } 46 | 47 | if (jsonElement.isJsonObject()) { 48 | return true; 49 | } 50 | if (jsonElement.isJsonArray()) { 51 | for (JsonElement j : jsonElement.getAsJsonArray()) { 52 | if (!j.isJsonArray() && !j.isJsonObject()) { 53 | return false; 54 | } 55 | } 56 | return true; 57 | } 58 | return false; 59 | } 60 | 61 | 62 | public static ObjectNode createObjectNode() { 63 | return mapper.createObjectNode(); 64 | } 65 | 66 | public static T convertValue(Object o, Class valueType) { 67 | return mapper.convertValue(o, valueType); 68 | } 69 | 70 | public static T decode(String jsonStr, Class valueType) { 71 | try { 72 | return mapper.readValue(jsonStr, valueType); 73 | } catch (Exception e) { 74 | logger.error("jsonStr={}||valueType={}||error=", jsonStr, valueType, e); 75 | return null; 76 | } 77 | } 78 | 79 | public static T decode(String jsonStr, TypeReference valueTypeRef) { 80 | try { 81 | return (T) mapper.readValue(jsonStr, valueTypeRef); 82 | } catch (Exception e) { 83 | logger.error("jsonStr={}||valueTypeRef={}||error=", jsonStr, valueTypeRef, e); 84 | return null; 85 | } 86 | } 87 | 88 | public static String encode(Object o) { 89 | try { 90 | return mapper.writeValueAsString(o); 91 | } catch (Exception e) { 92 | logger.error("object={}||error=", o, e); 93 | return null; 94 | } 95 | } 96 | 97 | public static byte[] serialize(T obj) { 98 | byte[] bytes = new byte[0]; 99 | try { 100 | bytes = mapper.writeValueAsBytes(obj); 101 | } catch (JsonProcessingException e) { 102 | throw new IllegalStateException(e.getMessage(), e); 103 | } 104 | return bytes; 105 | } 106 | 107 | public static T deserialize(byte[] data, Class cls) { 108 | T obj = null; 109 | try { 110 | obj = mapper.readValue(data, cls); 111 | } catch (IOException e) { 112 | throw new IllegalStateException(e.getMessage(), e); 113 | } 114 | return obj; 115 | } 116 | 117 | public static String objectToJson(Object o) { 118 | String json = ""; 119 | try { 120 | json = mapper.writeValueAsString(o); 121 | } catch (IOException e) { 122 | throw new IllegalStateException(e.getMessage(), e); 123 | } 124 | return json; 125 | } 126 | 127 | public static T jsonToObject(String json, Class cls) { 128 | T obj = null; 129 | JavaType javaType = mapper.getTypeFactory().constructType(cls); 130 | try { 131 | obj = mapper.readValue(json, javaType); 132 | } catch (IOException e) { 133 | throw new IllegalStateException(e.getMessage(), e); 134 | } 135 | return obj; 136 | } 137 | 138 | public static T jsonToObjectList(String json, 139 | Class collectionClass, 140 | Class... elementClass) { 141 | T obj = null; 142 | JavaType javaType = mapper.getTypeFactory().constructParametricType(collectionClass, elementClass); 143 | try { 144 | obj = mapper.readValue(json, javaType); 145 | } catch (IOException e) { 146 | throw new IllegalStateException(e.getMessage(), e); 147 | } 148 | return obj; 149 | } 150 | 151 | public static T jsonToObjectHashMap(String json, 152 | Class keyClass, 153 | Class valueClass) { 154 | T obj = null; 155 | JavaType javaType = mapper.getTypeFactory().constructParametricType(HashMap.class, keyClass, valueClass); 156 | try { 157 | obj = mapper.readValue(json, javaType); 158 | } catch (IOException e) { 159 | throw new IllegalStateException(e.getMessage(), e); 160 | } 161 | return obj; 162 | } 163 | 164 | } 165 | -------------------------------------------------------------------------------- /MapHttpService/src/main/java/com/luxx/map/service/HttpServerInboundHandler.java: -------------------------------------------------------------------------------- 1 | package com.luxx.map.service; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import io.netty.handler.codec.http.HttpVersion; 10 | import io.netty.buffer.Unpooled; 11 | import io.netty.channel.ChannelFutureListener; 12 | import io.netty.channel.ChannelHandlerContext; 13 | import io.netty.channel.ChannelInboundHandlerAdapter; 14 | import io.netty.handler.codec.http.DefaultFullHttpResponse; 15 | import io.netty.handler.codec.http.FullHttpRequest; 16 | import io.netty.handler.codec.http.FullHttpResponse; 17 | import io.netty.handler.codec.http.HttpHeaders; 18 | import io.netty.handler.codec.http.HttpResponseStatus; 19 | import io.netty.handler.codec.http.QueryStringDecoder; 20 | 21 | /** 22 | * Map服务,Netty的Http请求处理 23 | * 24 | * @author luxiaoxun 25 | * @version 1.0 26 | * @since 2015.06.1 27 | */ 28 | public class HttpServerInboundHandler extends ChannelInboundHandlerAdapter { 29 | private static Logger log = LoggerFactory.getLogger(HttpServerInboundHandler.class); 30 | 31 | @Override 32 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 33 | if (msg instanceof FullHttpRequest) { 34 | FullHttpRequest request = (FullHttpRequest) msg; 35 | final String uri = request.getUri(); 36 | byte[] responseContent = null; 37 | try { 38 | FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.NO_CONTENT); 39 | boolean isKeepAlive = HttpHeaders.isKeepAlive(request); 40 | MapRequestParam mapRequestParam = getMapRequestParam(uri); 41 | if (!mapRequestParam.isOk()) { 42 | if (!isKeepAlive) { 43 | ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); 44 | } else { 45 | response.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE); 46 | ctx.writeAndFlush(response); 47 | } 48 | } else { 49 | responseContent = MapCache.getInstance().getMapCacheTile(mapRequestParam); 50 | if (responseContent != null) { 51 | response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, 52 | Unpooled.wrappedBuffer(responseContent)); 53 | response.headers().set(HttpHeaders.Names.CONTENT_TYPE, "image/jpeg"); 54 | response.headers().set(HttpHeaders.Names.CONTENT_LENGTH, response.content().readableBytes()); 55 | } 56 | 57 | if (!isKeepAlive) { 58 | ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); 59 | } else { 60 | response.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE); 61 | ctx.writeAndFlush(response); 62 | } 63 | } 64 | } catch (Exception e) { 65 | log.error(e.getMessage()); 66 | } finally { 67 | request.release(); 68 | } 69 | } 70 | } 71 | 72 | //检测请求Url是否合法,以下两种情况合法: 73 | //1: http://192.1.114.11:8899/788865972/{z}/{x}/{y} (http://192.1.114.11:8899/788865972/6/50/25) 74 | //2: http://192.1.114.11:8899/FileService/image?map=quanguo&type=web&x=5&y=3&z=3 75 | private MapRequestParam getMapRequestParam(String url) { 76 | MapRequestParam mapRequestParam = new MapRequestParam(); 77 | QueryStringDecoder queryStringDecoder = new QueryStringDecoder(url); 78 | Map> paramsMap = queryStringDecoder.parameters(); 79 | if (paramsMap.isEmpty()) { 80 | String[] params = url.split("/"); 81 | if (params != null && params.length == 5) { 82 | String dbId = params[1]; 83 | mapRequestParam.setDbType(dbId); 84 | try { 85 | int zoom = Integer.parseInt(params[2]); 86 | mapRequestParam.setZoom(zoom); 87 | int x = Integer.parseInt(params[3]); 88 | mapRequestParam.setX(x); 89 | int y = Integer.parseInt(params[4]); 90 | mapRequestParam.setY(y); 91 | mapRequestParam.setOk(true); 92 | } catch (NumberFormatException e) { 93 | log.warn("请求Url:" + url + "不合法,异常:" + e.toString()); 94 | mapRequestParam.setOk(false); 95 | } 96 | } 97 | } else { 98 | if (paramsMap.containsKey("z") && paramsMap.containsKey("x") 99 | && paramsMap.containsKey("y")) { 100 | try { 101 | List zoomList = paramsMap.get("z"); 102 | if (zoomList.size() > 0) { 103 | mapRequestParam.setZoom(Integer.parseInt(zoomList.get(0))); 104 | } 105 | List xList = paramsMap.get("x"); 106 | if (xList.size() > 0) { 107 | mapRequestParam.setX(Integer.parseInt(xList.get(0))); 108 | } 109 | List yList = paramsMap.get("y"); 110 | if (yList.size() > 0) { 111 | mapRequestParam.setY(Integer.parseInt(yList.get(0))); 112 | } 113 | mapRequestParam.setDbType("788865972"); 114 | mapRequestParam.setOk(true); 115 | } catch (NumberFormatException e) { 116 | log.warn("请求Url:" + url + "不合法.异常:" + e.toString()); 117 | mapRequestParam.setOk(false); 118 | } 119 | } 120 | } 121 | 122 | return mapRequestParam; 123 | } 124 | 125 | @Override 126 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 127 | log.debug(cause.getMessage()); 128 | ctx.close(); 129 | } 130 | 131 | } 132 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/js/leafletjs/locate.js: -------------------------------------------------------------------------------- 1 | L.Control.Locate = L.Control.extend({ 2 | options: { 3 | position: 'topleft', 4 | drawCircle: true, 5 | follow: false, // follow with zoom and pan the user's location 6 | // range circle 7 | circleStyle: { 8 | color: '#136AEC', 9 | fillColor: '#136AEC', 10 | fillOpacity: 0.15, 11 | weight: 2, 12 | opacity: 0.5 13 | }, 14 | // inner marker 15 | markerStyle: { 16 | color: '#136AEC', 17 | fillColor: '#2A93EE', 18 | fillOpacity: 0.7, 19 | weight: 2, 20 | opacity: 0.9, 21 | radius: 4 22 | }, 23 | metric: true, 24 | debug: false, 25 | onLocationError: function(err) { 26 | alert(err.message); 27 | }, 28 | title: "Show me where I am", 29 | popupText: ["You are within ", " from this point"], 30 | setView: true, // automatically sets the map view to the user's location 31 | locateOptions: {} 32 | }, 33 | 34 | onAdd: function (map) { 35 | var className = 'leaflet-control-locate', 36 | classNames = className + ' leaflet-control-zoom leaflet-bar leaflet-control', 37 | container = L.DomUtil.create('div', classNames); 38 | 39 | var self = this; 40 | this._layer = new L.LayerGroup(); 41 | this._layer.addTo(map); 42 | this._event = undefined; 43 | // nested extend so that the first can overwrite the second 44 | // and the second can overwrite the third 45 | this._locateOptions = L.extend(L.extend({ 46 | 'setView': false // have to set this to false because we have to 47 | // do setView manually 48 | }, this.options.locateOptions), { 49 | 'watch': true // if you overwrite this, visualization cannot be updated 50 | }); 51 | 52 | var link = L.DomUtil.create('a', 'leaflet-bar-part leaflet-bar-part-single', container); 53 | link.href = '#'; 54 | link.title = this.options.title; 55 | 56 | var _log = function(data) { 57 | if (self.options.debug) { 58 | console.log(data); 59 | } 60 | }; 61 | 62 | L.DomEvent 63 | .on(link, 'click', L.DomEvent.stopPropagation) 64 | .on(link, 'click', L.DomEvent.preventDefault) 65 | .on(link, 'click', function() { 66 | if (self._active && (map.getBounds().contains(self._event.latlng) || !self.options.setView)) { 67 | stopLocate(); 68 | } else { 69 | if (self.options.setView) { 70 | self._locateOnNextLocationFound = true; 71 | } 72 | if(!self._active) { 73 | map.locate(self._locateOptions); 74 | } 75 | self._active = true; 76 | if (!self._event) { 77 | self._container.className = classNames + " requesting"; 78 | } else { 79 | visualizeLocation(); 80 | } 81 | } 82 | }) 83 | .on(link, 'dblclick', L.DomEvent.stopPropagation); 84 | 85 | var onLocationFound = function (e) { 86 | _log('onLocationFound'); 87 | 88 | self._active = true; 89 | 90 | if (self._event && 91 | (self._event.latlng.lat != e.latlng.lat || 92 | self._event.latlng.lng != e.latlng.lng)) { 93 | _log('location has changed'); 94 | } 95 | 96 | self._event = e; 97 | 98 | if (self.options.follow) { 99 | self._locateOnNextLocationFound = true; 100 | } 101 | 102 | visualizeLocation(); 103 | }; 104 | 105 | var visualizeLocation = function() { 106 | _log('visualizeLocation,' + 'setView:' + self._locateOnNextLocationFound); 107 | 108 | var radius = self._event.accuracy / 2; 109 | 110 | if (self._locateOnNextLocationFound) { 111 | map.fitBounds(self._event.bounds); 112 | self._locateOnNextLocationFound = false; 113 | } 114 | 115 | self._layer.clearLayers(); 116 | 117 | // circle with the radius of the location's accuracy 118 | if (self.options.drawCircle) { 119 | L.circle(self._event.latlng, radius, self.options.circleStyle) 120 | .addTo(self._layer); 121 | } 122 | 123 | var distance, unit; 124 | if (self.options.metric) { 125 | distance = radius.toFixed(0); 126 | unit = "meters"; 127 | } else { 128 | distance = (radius * 3.2808399).toFixed(0); 129 | unit = "feet"; 130 | } 131 | 132 | // small inner marker 133 | var t = self.options.popupText; 134 | L.circleMarker(self._event.latlng, self.options.markerStyle) 135 | .bindPopup(t[0] + distance + " " + unit + t[1]) 136 | .addTo(self._layer); 137 | 138 | if (!self._container) 139 | return; 140 | self._container.className = classNames + " active"; 141 | }; 142 | 143 | var resetVariables = function() { 144 | self._active = false; 145 | self._locateOnNextLocationFound = true; 146 | }; 147 | 148 | resetVariables(); 149 | 150 | var stopLocate = function() { 151 | _log('stopLocate'); 152 | map.stopLocate(); 153 | 154 | self._container.className = classNames; 155 | resetVariables(); 156 | 157 | self._layer.clearLayers(); 158 | }; 159 | 160 | 161 | var onLocationError = function (err) { 162 | _log('onLocationError'); 163 | 164 | // ignore timeout error if the location is watched 165 | if (err.code==3 && this._locateOptions.watch) { 166 | return; 167 | } 168 | 169 | stopLocate(); 170 | self.options.onLocationError(err); 171 | }; 172 | 173 | // event hooks 174 | map.on('locationfound', onLocationFound, self); 175 | map.on('locationerror', onLocationError, self); 176 | 177 | return container; 178 | } 179 | }); 180 | 181 | L.Map.addInitHook(function () { 182 | if (this.options.locateControl) { 183 | this.locateControl = L.control.locate(); 184 | this.addControl(this.locateControl); 185 | } 186 | }); 187 | 188 | L.control.locate = function (options) { 189 | return new L.Control.Locate(options); 190 | }; 191 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/resources/static/css/leaflet.draw.css: -------------------------------------------------------------------------------- 1 | /* ================================================================== */ 2 | /* Toolbars 3 | /* ================================================================== */ 4 | 5 | .leaflet-draw-section { 6 | position: relative; 7 | } 8 | 9 | .leaflet-draw-toolbar { 10 | margin-top: 12px; 11 | } 12 | 13 | .leaflet-draw-toolbar-top { 14 | margin-top: 0; 15 | } 16 | 17 | .leaflet-draw-toolbar-notop a:first-child { 18 | border-top-right-radius: 0; 19 | } 20 | 21 | .leaflet-draw-toolbar-nobottom a:last-child { 22 | border-bottom-right-radius: 0; 23 | } 24 | 25 | .leaflet-draw-toolbar a { 26 | background-image: url('images/spritesheet.png'); 27 | background-repeat: no-repeat; 28 | } 29 | 30 | .leaflet-retina .leaflet-draw-toolbar a { 31 | background-image: url('images/spritesheet-2x.png'); 32 | background-size: 270px 30px; 33 | } 34 | 35 | .leaflet-draw a { 36 | display: block; 37 | text-align: center; 38 | text-decoration: none; 39 | } 40 | 41 | /* ================================================================== */ 42 | /* Toolbar actions menu 43 | /* ================================================================== */ 44 | 45 | .leaflet-draw-actions { 46 | display: none; 47 | list-style: none; 48 | margin: 0; 49 | padding: 0; 50 | position: absolute; 51 | left: 26px; /* leaflet-draw-toolbar.left + leaflet-draw-toolbar.width */ 52 | top: 0; 53 | white-space: nowrap; 54 | } 55 | 56 | .leaflet-right .leaflet-draw-actions { 57 | right:26px; 58 | left:auto; 59 | } 60 | 61 | .leaflet-draw-actions li { 62 | display: inline-block; 63 | } 64 | 65 | .leaflet-draw-actions li:first-child a { 66 | border-left: none; 67 | } 68 | 69 | .leaflet-draw-actions li:last-child a { 70 | -webkit-border-radius: 0 4px 4px 0; 71 | border-radius: 0 4px 4px 0; 72 | } 73 | 74 | .leaflet-right .leaflet-draw-actions li:last-child a { 75 | -webkit-border-radius: 0; 76 | border-radius: 0; 77 | } 78 | 79 | .leaflet-right .leaflet-draw-actions li:first-child a { 80 | -webkit-border-radius: 4px 0 0 4px; 81 | border-radius: 4px 0 0 4px; 82 | } 83 | 84 | .leaflet-draw-actions a { 85 | background-color: #919187; 86 | border-left: 1px solid #AAA; 87 | color: #FFF; 88 | font: 11px/19px "Helvetica Neue", Arial, Helvetica, sans-serif; 89 | line-height: 28px; 90 | text-decoration: none; 91 | padding-left: 10px; 92 | padding-right: 10px; 93 | height: 28px; 94 | } 95 | 96 | .leaflet-draw-actions-bottom { 97 | margin-top: 0; 98 | } 99 | 100 | .leaflet-draw-actions-top { 101 | margin-top: 1px; 102 | } 103 | 104 | .leaflet-draw-actions-top a, 105 | .leaflet-draw-actions-bottom a { 106 | height: 27px; 107 | line-height: 27px; 108 | } 109 | 110 | .leaflet-draw-actions a:hover { 111 | background-color: #A0A098; 112 | } 113 | 114 | .leaflet-draw-actions-top.leaflet-draw-actions-bottom a { 115 | height: 26px; 116 | line-height: 26px; 117 | } 118 | 119 | /* ================================================================== */ 120 | /* Draw toolbar 121 | /* ================================================================== */ 122 | 123 | .leaflet-draw-toolbar .leaflet-draw-draw-polyline { 124 | background-position: -2px -2px; 125 | } 126 | 127 | .leaflet-draw-toolbar .leaflet-draw-draw-polygon { 128 | background-position: -31px -2px; 129 | } 130 | 131 | .leaflet-draw-toolbar .leaflet-draw-draw-rectangle { 132 | background-position: -62px -2px; 133 | } 134 | 135 | .leaflet-draw-toolbar .leaflet-draw-draw-circle { 136 | background-position: -92px -2px; 137 | } 138 | 139 | .leaflet-draw-toolbar .leaflet-draw-draw-marker { 140 | background-position: -122px -2px; 141 | } 142 | 143 | /* ================================================================== */ 144 | /* Edit toolbar 145 | /* ================================================================== */ 146 | 147 | .leaflet-draw-toolbar .leaflet-draw-edit-edit { 148 | background-position: -152px -2px; 149 | } 150 | 151 | .leaflet-draw-toolbar .leaflet-draw-edit-remove { 152 | background-position: -182px -2px; 153 | } 154 | 155 | .leaflet-draw-toolbar .leaflet-draw-edit-edit.leaflet-disabled { 156 | background-position: -212px -2px; 157 | } 158 | 159 | .leaflet-draw-toolbar .leaflet-draw-edit-remove.leaflet-disabled { 160 | background-position: -242px -2px; 161 | } 162 | 163 | /* ================================================================== */ 164 | /* Drawing styles 165 | /* ================================================================== */ 166 | 167 | .leaflet-mouse-marker { 168 | background-color: #fff; 169 | cursor: crosshair; 170 | } 171 | 172 | .leaflet-draw-tooltip { 173 | background: rgb(54, 54, 54); 174 | background: rgba(0, 0, 0, 0.5); 175 | border: 1px solid transparent; 176 | -webkit-border-radius: 4px; 177 | border-radius: 4px; 178 | color: #fff; 179 | font: 12px/18px "Helvetica Neue", Arial, Helvetica, sans-serif; 180 | margin-left: 20px; 181 | margin-top: -21px; 182 | padding: 4px 8px; 183 | position: absolute; 184 | visibility: hidden; 185 | white-space: nowrap; 186 | z-index: 6; 187 | } 188 | 189 | .leaflet-draw-tooltip:before { 190 | border-right: 6px solid black; 191 | border-right-color: rgba(0, 0, 0, 0.5); 192 | border-top: 6px solid transparent; 193 | border-bottom: 6px solid transparent; 194 | content: ""; 195 | position: absolute; 196 | top: 7px; 197 | left: -7px; 198 | } 199 | 200 | .leaflet-error-draw-tooltip { 201 | background-color: #F2DEDE; 202 | border: 1px solid #E6B6BD; 203 | color: #B94A48; 204 | } 205 | 206 | .leaflet-error-draw-tooltip:before { 207 | border-right-color: #E6B6BD; 208 | } 209 | 210 | .leaflet-draw-tooltip-single { 211 | margin-top: -12px 212 | } 213 | 214 | .leaflet-draw-tooltip-subtext { 215 | color: #f8d5e4; 216 | } 217 | 218 | .leaflet-draw-guide-dash { 219 | font-size: 1%; 220 | opacity: 0.6; 221 | position: absolute; 222 | width: 5px; 223 | height: 5px; 224 | } 225 | 226 | /* ================================================================== */ 227 | /* Edit styles 228 | /* ================================================================== */ 229 | 230 | .leaflet-edit-marker-selected { 231 | background: rgba(254, 87, 161, 0.1); 232 | border: 4px dashed rgba(254, 87, 161, 0.6); 233 | -webkit-border-radius: 4px; 234 | border-radius: 4px; 235 | } 236 | 237 | .leaflet-edit-move { 238 | cursor: move; 239 | } 240 | 241 | .leaflet-edit-resize { 242 | cursor: pointer; 243 | } 244 | 245 | /* ================================================================== */ 246 | /* Old IE styles 247 | /* ================================================================== */ 248 | 249 | .leaflet-oldie .leaflet-draw-toolbar { 250 | border: 3px solid #999; 251 | } 252 | 253 | .leaflet-oldie .leaflet-draw-toolbar a { 254 | background-color: #eee; 255 | } 256 | 257 | .leaflet-oldie .leaflet-draw-toolbar a:hover { 258 | background-color: #fff; 259 | } 260 | 261 | .leaflet-oldie .leaflet-draw-actions { 262 | left: 32px; 263 | margin-top: 3px; 264 | } 265 | 266 | .leaflet-oldie .leaflet-draw-actions li { 267 | display: inline; 268 | zoom: 1; 269 | } 270 | 271 | .leaflet-oldie .leaflet-edit-marker-selected { 272 | border: 4px dashed #fe93c2; 273 | } 274 | 275 | .leaflet-oldie .leaflet-draw-actions a { 276 | background-color: #999; 277 | } 278 | 279 | .leaflet-oldie .leaflet-draw-actions a:hover { 280 | background-color: #a5a5a5; 281 | } 282 | 283 | .leaflet-oldie .leaflet-draw-actions-top a { 284 | margin-top: 1px; 285 | } 286 | 287 | .leaflet-oldie .leaflet-draw-actions-bottom a { 288 | height: 28px; 289 | line-height: 28px; 290 | } 291 | 292 | .leaflet-oldie .leaflet-draw-actions-top.leaflet-draw-actions-bottom a { 293 | height: 27px; 294 | line-height: 27px; 295 | } -------------------------------------------------------------------------------- /WebGisDemo/pom.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | Code4Java 7 | com.luxx 8 | 1.0.0 9 | 10 | 11 | 4.0.0 12 | WebGisDemo 13 | jar 14 | 15 | 16 | UTF-8 17 | UTF-8 18 | UTF-8 19 | 2.5.12 20 | 2.2.2 21 | 1.4.2 22 | 7.17.14 23 | 2.18.0 24 | 2.14.0 25 | 3.0.0 26 | 1.18.16 27 | 32.0.0-jre 28 | 3.4.5 29 | 8.0.28 30 | 31 | 32 | 33 | 34 | redshift 35 | https://redshift-maven-repository.s3-website-us-east-1.amazonaws.com/release 36 | 37 | 38 | 39 | 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-starter 44 | ${spring-boot.version} 45 | 46 | 47 | org.springframework.boot 48 | spring-boot-starter-logging 49 | 50 | 51 | 52 | 53 | org.springframework.boot 54 | spring-boot-starter-web 55 | ${spring-boot.version} 56 | 57 | 58 | org.springframework.boot 59 | spring-boot-starter-validation 60 | ${spring-boot.version} 61 | 62 | 63 | org.springframework.boot 64 | spring-boot-starter-log4j2 65 | ${spring-boot.version} 66 | 67 | 68 | 69 | org.apache.logging.log4j 70 | log4j-api 71 | ${log4j2.version} 72 | 73 | 74 | org.apache.logging.log4j 75 | log4j-core 76 | ${log4j2.version} 77 | 78 | 79 | 80 | org.springframework.boot 81 | spring-boot-starter-freemarker 82 | ${spring-boot.version} 83 | 84 | 85 | 86 | 87 | org.mybatis.spring.boot 88 | mybatis-spring-boot-starter 89 | ${mybatis.spring-boot.version} 90 | 91 | 92 | 93 | com.github.pagehelper 94 | pagehelper-spring-boot-starter 95 | ${pagehelper.spring-boot.version} 96 | 97 | 98 | 99 | 100 | com.zaxxer 101 | HikariCP 102 | ${hikaricp.version} 103 | 104 | 105 | 106 | mysql 107 | mysql-connector-java 108 | ${mysql.version} 109 | 110 | 111 | 112 | 113 | com.fasterxml.jackson.core 114 | jackson-databind 115 | ${jackson.version} 116 | 117 | 118 | 119 | 120 | org.elasticsearch 121 | elasticsearch 122 | ${es.version} 123 | 124 | 125 | org.elasticsearch.client 126 | elasticsearch-rest-client 127 | ${es.version} 128 | 129 | 130 | org.elasticsearch.client 131 | elasticsearch-rest-high-level-client 132 | ${es.version} 133 | 134 | 135 | 136 | 137 | com.google.guava 138 | guava 139 | ${guava.version} 140 | 141 | 142 | 143 | 144 | io.springfox 145 | springfox-boot-starter 146 | ${swagger.version} 147 | 148 | 149 | 150 | 151 | org.projectlombok 152 | lombok 153 | ${lombok.version} 154 | 155 | 156 | 157 | 158 | 159 | 160 | org.apache.maven.plugins 161 | maven-compiler-plugin 162 | 3.8.1 163 | 164 | 8 165 | 8 166 | 167 | 168 | 169 | 170 | org.springframework.boot 171 | spring-boot-maven-plugin 172 | ${spring-boot.version} 173 | 174 | true 175 | 176 | 177 | 178 | 179 | repackage 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/java/com/luxx/gis/service/RedshiftIndexService.java: -------------------------------------------------------------------------------- 1 | package com.luxx.gis.service; 2 | 3 | import java.io.IOException; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import com.luxx.gis.client.ElasticSearchClient; 9 | import com.luxx.gis.model.EndpointData; 10 | import com.luxx.gis.util.JsonUtil; 11 | import org.apache.logging.log4j.LogManager; 12 | import org.apache.logging.log4j.Logger; 13 | import org.elasticsearch.action.bulk.*; 14 | import org.elasticsearch.common.xcontent.XContentBuilder; 15 | import org.elasticsearch.common.xcontent.XContentFactory; 16 | import org.elasticsearch.index.query.QueryBuilder; 17 | import org.elasticsearch.index.query.QueryBuilders; 18 | import org.elasticsearch.search.aggregations.AggregationBuilders; 19 | import org.elasticsearch.search.aggregations.BucketOrder; 20 | import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; 21 | import org.springframework.beans.factory.annotation.Autowired; 22 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 23 | import org.springframework.stereotype.Service; 24 | import org.springframework.util.StringUtils; 25 | 26 | @Service 27 | @ConditionalOnProperty(name = "index.es.cluster.address") 28 | public class RedshiftIndexService { 29 | private static Logger log = LogManager.getLogger(RedshiftIndexService.class); 30 | 31 | @Autowired 32 | private ElasticSearchClient elasticSearchClient; 33 | 34 | // Index Name 35 | private static final String Index = "endpoint"; 36 | 37 | private static final String DateFormat = "yyyy-MM-dd HH:mm:ss"; 38 | 39 | private static final String TimeField = "date_time"; 40 | 41 | public void deleteIndex() { 42 | elasticSearchClient.deleteIndex(Index); 43 | } 44 | 45 | public void createIndex() { 46 | elasticSearchClient.createIndex(Index); 47 | } 48 | 49 | public void createIndexMapping() { 50 | XContentBuilder contentBuilder = prepareMappingBuilder(); 51 | elasticSearchClient.createIndexMapping(Index, contentBuilder); 52 | } 53 | 54 | public XContentBuilder prepareMappingBuilder() { 55 | XContentBuilder contentBuilder = null; 56 | try { 57 | contentBuilder = XContentFactory.jsonBuilder(); 58 | contentBuilder.startObject(); 59 | { 60 | contentBuilder.startObject("properties"); 61 | { 62 | contentBuilder.startObject("org_id").field("type", "integer").endObject(); 63 | contentBuilder.startObject("endpoint_id").field("type", "long").endObject(); 64 | contentBuilder.startObject("ds_bytes").field("type", "long").endObject(); 65 | contentBuilder.startObject("ds_max_bps").field("type", "double").endObject(); 66 | contentBuilder.startObject("ds_avg_bps").field("type", "double").endObject(); 67 | contentBuilder.startObject("ds_mwt").field("type", "integer").endObject(); 68 | contentBuilder.startObject("us_bytes").field("type", "long").endObject(); 69 | contentBuilder.startObject("us_max_bps").field("type", "double").endObject(); 70 | contentBuilder.startObject("us_avg_bps").field("type", "double").endObject(); 71 | contentBuilder.startObject("us_mwt").field("type", "integer").endObject(); 72 | contentBuilder.startObject(TimeField).field("type", "date").field("format", DateFormat).endObject(); 73 | } 74 | contentBuilder.endObject(); 75 | } 76 | contentBuilder.endObject(); 77 | } catch (IOException e) { 78 | log.error(e); 79 | } 80 | 81 | return contentBuilder; 82 | } 83 | 84 | public String getIndexDataFromHotspotDataForRedshift(EndpointData data) { 85 | Map map = new HashMap<>(); 86 | if (data != null) { 87 | map.put("org_id", data.getOrg_id()); 88 | map.put("endpoint_id", data.getEndpoint_id()); 89 | map.put("ds_bytes", data.getDs_bytes()); 90 | map.put("ds_max_bps", data.getDs_max_bytes()); 91 | map.put("ds_avg_bps", data.getDs_avg_bytes()); 92 | map.put("ds_mwt", data.getDs_mwt()); 93 | map.put("us_bytes", data.getUs_bytes()); 94 | map.put("us_max_bps", data.getUs_max_bytes()); 95 | map.put("us_avg_bps", data.getUs_avg_bytes()); 96 | map.put("us_mwt", data.getUs_mwt()); 97 | map.put(TimeField, data.getDate_time()); 98 | } 99 | return JsonUtil.objectToJson(map); 100 | } 101 | 102 | // Index data in bulk 103 | public void indexHotSpotDataListForRedshift(List dataList) { 104 | if (dataList != null && dataList.size() > 0) { 105 | BulkProcessor bulkRequest = elasticSearchClient.getBulkRequest(); 106 | for (int i = 0; i < dataList.size(); ++i) { 107 | EndpointData data = dataList.get(i); 108 | String jsonSource = getIndexDataFromHotspotDataForRedshift(data); 109 | if (jsonSource != null) { 110 | bulkRequest.add(elasticSearchClient.getIndexRequest(Index, jsonSource)); 111 | } 112 | } 113 | } 114 | } 115 | 116 | private QueryBuilder getDateRangeQueryBuilder(String startTime, String endTime) { 117 | QueryBuilder rangeBuilder = QueryBuilders.matchAllQuery(); 118 | if (!StringUtils.isEmpty(startTime) && !StringUtils.isEmpty(endTime)) { 119 | rangeBuilder = QueryBuilders.rangeQuery(TimeField).from(startTime).to(endTime).format(DateFormat); 120 | } 121 | return rangeBuilder; 122 | } 123 | 124 | // Get top N endpoint_id based on sum of usage(ds_bytes) from startTime to endTime 125 | public Map getTopNEndpointUsage(String startTime, String endTime, int orgId, int topN) { 126 | Map resultsMap = new HashMap<>(); 127 | 128 | QueryBuilder orgIdQueryBuilder = QueryBuilders.termQuery("org_id", orgId); 129 | QueryBuilder endpointIdFilterBuilder = QueryBuilders.termQuery("endpoint_id", 0); 130 | QueryBuilder rangeBuilder = getDateRangeQueryBuilder(startTime, endTime); 131 | QueryBuilder queryBuilder = QueryBuilders.boolQuery().must(orgIdQueryBuilder).must(rangeBuilder) 132 | .mustNot(endpointIdFilterBuilder); 133 | TermsAggregationBuilder termsBuilder = AggregationBuilders.terms("endpointUsageAgg").field("endpoint_id") 134 | .size(topN); 135 | termsBuilder.subAggregation(AggregationBuilders.sum("sum_usage").field("ds_bytes")); 136 | termsBuilder.order(BucketOrder.aggregation("sum_usage", false)); 137 | 138 | resultsMap = elasticSearchClient.getSumAggSearchOrderResult(Index, queryBuilder, termsBuilder, "endpointUsageAgg", "sum_usage"); 139 | 140 | return resultsMap; 141 | } 142 | 143 | // Get endpoint_id and max_bps based on query from startTime to endTime 144 | public Map getEndpointMaxbps(String startTime, String endTime, int orgId) { 145 | Map resultsMap = new HashMap<>(); 146 | QueryBuilder orgIdQueryBuilder = QueryBuilders.termQuery("org_id", orgId); 147 | QueryBuilder endpointIdFilterBuilder = QueryBuilders.termQuery("endpoint_id", 0); 148 | QueryBuilder rangeBuilder = getDateRangeQueryBuilder(startTime, endTime); 149 | QueryBuilder maxBpsRangeBuilder = QueryBuilders.rangeQuery("ds_max_bps").from(4000000); 150 | QueryBuilder queryBuilder = QueryBuilders.boolQuery().must(orgIdQueryBuilder).must(rangeBuilder) 151 | .mustNot(endpointIdFilterBuilder).must(maxBpsRangeBuilder); 152 | TermsAggregationBuilder termsBuilder = AggregationBuilders.terms("endpointMaxAgg").field("endpoint_id").size(Integer.MAX_VALUE); 153 | termsBuilder.subAggregation(AggregationBuilders.max("max_bps").field("ds_max_bps")); 154 | 155 | resultsMap = elasticSearchClient.getMaxAggSearchOrderResult(Index, queryBuilder, termsBuilder, "endpointMaxAgg", "max_bps"); 156 | return resultsMap; 157 | } 158 | 159 | } 160 | -------------------------------------------------------------------------------- /WebGisDemo/src/main/java/com/luxx/gis/service/PoiIndexService.java: -------------------------------------------------------------------------------- 1 | package com.luxx.gis.service; 2 | 3 | import com.luxx.gis.client.ElasticSearchClient; 4 | import com.luxx.gis.model.PoiData; 5 | import com.luxx.gis.util.JsonUtil; 6 | import org.apache.lucene.document.*; 7 | import org.apache.lucene.search.*; 8 | import org.apache.lucene.search.BooleanClause.Occur; 9 | import org.apache.lucene.spatial.query.SpatialArgs; 10 | import org.apache.lucene.spatial.query.SpatialOperation; 11 | import org.apache.lucene.util.QueryBuilder; 12 | 13 | import org.apache.logging.log4j.LogManager; 14 | import org.apache.logging.log4j.Logger; 15 | import org.elasticsearch.action.bulk.BulkProcessor; 16 | import org.elasticsearch.action.search.SearchRequest; 17 | import org.elasticsearch.action.search.SearchResponse; 18 | import org.elasticsearch.client.RequestOptions; 19 | import org.elasticsearch.common.geo.GeoPoint; 20 | import org.elasticsearch.common.unit.DistanceUnit; 21 | import org.elasticsearch.common.xcontent.XContentBuilder; 22 | import org.elasticsearch.common.xcontent.XContentFactory; 23 | import org.elasticsearch.index.query.GeoBoundingBoxQueryBuilder; 24 | import org.elasticsearch.index.query.GeoDistanceQueryBuilder; 25 | import org.elasticsearch.index.query.QueryBuilders; 26 | import org.elasticsearch.index.query.TermQueryBuilder; 27 | import org.elasticsearch.search.SearchHit; 28 | import org.elasticsearch.search.SearchHits; 29 | import org.elasticsearch.search.builder.SearchSourceBuilder; 30 | import org.springframework.beans.factory.annotation.Autowired; 31 | import org.springframework.stereotype.Service; 32 | 33 | import javax.swing.text.html.HTMLDocument; 34 | import java.io.IOException; 35 | import java.util.ArrayList; 36 | import java.util.List; 37 | 38 | @Service 39 | public class PoiIndexService { 40 | private static Logger log = LogManager.getLogger(PoiIndexService.class); 41 | 42 | // Field Name 43 | private static final String IDFieldName = "id"; 44 | private static final String AddressFieldName = "address"; 45 | private static final String LatFieldName = "lat"; 46 | private static final String LngFieldName = "lng"; 47 | private static final String LocationFieldName = "poiPoint"; 48 | 49 | private static final String IndexName = "geo_location"; 50 | 51 | private final int maxResultCount = 100; 52 | 53 | @Autowired 54 | private ElasticSearchClient elasticSearchClient; 55 | 56 | public void clear() { 57 | elasticSearchClient.deleteIndex(IndexName); 58 | } 59 | 60 | public void createIndex() { 61 | elasticSearchClient.createIndex(IndexName); 62 | } 63 | 64 | public void createIndexMapping() { 65 | XContentBuilder contentBuilder = prepareMappingBuilder(); 66 | elasticSearchClient.createIndexMapping(IndexName, contentBuilder); 67 | } 68 | 69 | public XContentBuilder prepareMappingBuilder() { 70 | XContentBuilder contentBuilder = null; 71 | try { 72 | contentBuilder = XContentFactory.jsonBuilder(); 73 | contentBuilder.startObject(); 74 | { 75 | contentBuilder.startObject("properties"); 76 | { 77 | contentBuilder.startObject(IDFieldName).field("type", "long").endObject(); 78 | contentBuilder.startObject(AddressFieldName).field("type", "keyword").endObject(); 79 | contentBuilder.startObject(LocationFieldName).field("type", "geo_point").endObject(); 80 | } 81 | contentBuilder.endObject(); 82 | } 83 | contentBuilder.endObject(); 84 | } catch (IOException e) { 85 | log.error(e); 86 | } 87 | return contentBuilder; 88 | } 89 | 90 | public boolean indexPoiDataList(List dataList) { 91 | try { 92 | if (dataList != null && dataList.size() > 0) { 93 | BulkProcessor bulkRequest = elasticSearchClient.getBulkRequest(); 94 | for (int i = 0; i < dataList.size(); ++i) { 95 | PoiData data = dataList.get(i); 96 | String jsonSource = JsonUtil.objectToJson(data); 97 | if (jsonSource != null) { 98 | bulkRequest.add(elasticSearchClient.getIndexRequest(IndexName, jsonSource)); 99 | } 100 | } 101 | return true; 102 | } 103 | return false; 104 | } catch (Exception e) { 105 | log.error(e.toString()); 106 | return false; 107 | } 108 | } 109 | 110 | public List searchPoiInRectangle(double minLng, double minLat, double maxLng, double maxLat) { 111 | List results = new ArrayList<>(); 112 | SearchRequest searchRequest = new SearchRequest(IndexName); 113 | SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); 114 | GeoBoundingBoxQueryBuilder geoBoundingBoxQueryBuilder = QueryBuilders.geoBoundingBoxQuery(LocationFieldName) 115 | .setCorners(maxLat, minLng, minLat, maxLng); 116 | sourceBuilder.query(geoBoundingBoxQueryBuilder); 117 | searchRequest.source(sourceBuilder); 118 | try { 119 | SearchResponse searchResponse = elasticSearchClient.getClient().search(searchRequest, RequestOptions.DEFAULT); 120 | SearchHits searchHits = searchResponse.getHits(); 121 | for (SearchHit searchHit : searchHits) { 122 | Long id = (Long) searchHit.getSourceAsMap().get(IDFieldName); 123 | String address = (String) searchHit.getSourceAsMap().get(AddressFieldName); 124 | GeoPoint geoPoint = (GeoPoint) searchHit.getSourceAsMap().get(LocationFieldName); 125 | PoiData poiData = new PoiData(id, address, geoPoint.getLat(), geoPoint.getLon()); 126 | results.add(poiData); 127 | } 128 | } catch (Exception e) { 129 | log.error("Search Poi in rectangle error: " + e.toString()); 130 | } 131 | return results; 132 | } 133 | 134 | public List searchPoiInCircle(double lng, double lat, String distanceKm) { 135 | List results = new ArrayList<>(); 136 | SearchRequest searchRequest = new SearchRequest(IndexName); 137 | SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); 138 | GeoDistanceQueryBuilder geoDistanceQueryBuilder = QueryBuilders.geoDistanceQuery(LocationFieldName) 139 | .distance(distanceKm, DistanceUnit.KILOMETERS) 140 | .point(lat, lng); 141 | sourceBuilder.query(geoDistanceQueryBuilder); 142 | searchRequest.source(sourceBuilder); 143 | try { 144 | SearchResponse searchResponse = elasticSearchClient.getClient().search(searchRequest, RequestOptions.DEFAULT); 145 | SearchHits searchHits = searchResponse.getHits(); 146 | for (SearchHit searchHit : searchHits) { 147 | Long id = (Long) searchHit.getSourceAsMap().get(IDFieldName); 148 | String address = (String) searchHit.getSourceAsMap().get(AddressFieldName); 149 | GeoPoint geoPoint = (GeoPoint) searchHit.getSourceAsMap().get(LocationFieldName); 150 | PoiData poiData = new PoiData(id, address, geoPoint.getLat(), geoPoint.getLon()); 151 | results.add(poiData); 152 | } 153 | } catch (Exception e) { 154 | log.error("Search Poi in circle error: " + e.toString()); 155 | } 156 | 157 | return results; 158 | } 159 | 160 | public List searchPoiInCircleAndAddress(double lng, double lat, String distanceKm, String address) { 161 | List results = new ArrayList<>(); 162 | SearchRequest searchRequest = new SearchRequest(IndexName); 163 | SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); 164 | GeoDistanceQueryBuilder geoDistanceQueryBuilder = QueryBuilders.geoDistanceQuery(LocationFieldName) 165 | .distance(distanceKm, DistanceUnit.KILOMETERS) 166 | .point(lat, lng); 167 | TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(AddressFieldName, address); 168 | sourceBuilder.query(geoDistanceQueryBuilder).query(termQueryBuilder); 169 | searchRequest.source(sourceBuilder); 170 | try { 171 | SearchResponse searchResponse = elasticSearchClient.getClient().search(searchRequest, RequestOptions.DEFAULT); 172 | SearchHits searchHits = searchResponse.getHits(); 173 | for (SearchHit searchHit : searchHits) { 174 | Long id = (Long) searchHit.getSourceAsMap().get(IDFieldName); 175 | String addr = (String) searchHit.getSourceAsMap().get(AddressFieldName); 176 | GeoPoint geoPoint = (GeoPoint) searchHit.getSourceAsMap().get(LocationFieldName); 177 | PoiData poiData = new PoiData(id, addr, geoPoint.getLat(), geoPoint.getLon()); 178 | results.add(poiData); 179 | } 180 | } catch (Exception e) { 181 | log.error("Search Poi in circle and address error: " + e.toString()); 182 | } 183 | 184 | return results; 185 | } 186 | 187 | } 188 | --------------------------------------------------------------------------------