From f6cb0a130fb3bbb7b3d5f6f64f4a7d1a76b8a929 Mon Sep 17 00:00:00 2001 From: Fanyiwen <1225674957@qq.com> Date: Thu, 30 Jun 2022 21:49:17 +0800 Subject: [PATCH] update --- .../logistics/manager/goodManager.java | 25 +- .../java/com/jilk/ros/map/WayPointUtil.java | 1046 ++++++++++ .../com/jilk/ros/model/FootPrintResult.java | 178 ++ .../com/jilk/ros/model/InitPoseResult.java | 274 +++ .../java/com/jilk/ros/model/PoiResult.java | 501 +++++ .../java/com/jilk/ros/nav/Move_Base_Goal.java | 246 +++ .../com/jilk/ros/nav/Move_Base_Status.java | 219 ++ .../java/com/jilk/ros/nav/NavPublich.java | 38 + .../com/jilk/ros/nav/TMove_Base_Goal.java | 402 ++++ .../jilk/ros/net/NetBroadcastReceiver.java | 22 + .../main/java/com/jilk/ros/net/NetUtil.java | 49 + .../src/main/java/com/jilk/ros/net/POI.java | 1846 +++++++++++++++++ src/server/pom.xml | 5 + .../example/testdemo/ServerApplication.java | 18 + .../example/testdemo/TestdemoApplication.java | 42 - .../testdemo/config/SendObjectMessage.java | 61 +- .../testdemo/config/WebSocketConfig.java | 4 +- .../com/example/testdemo/ros/Publisher.java | 57 + .../testdemo/ros/RosListenDelegate.java | 85 + .../testdemo/ros/SubscriptionRequestMsg.java | 118 ++ .../ros/msgs/geometry_msgs/Twist.java | 19 + .../ros/msgs/geometry_msgs/Vector3.java | 21 + .../testdemo/ros/msgs/sensor_msgs/Image.java | 125 ++ .../testdemo/ros/msgs/std_msgs/Header.java | 21 + .../ros/msgs/std_msgs/PrimitiveMsg.java | 12 + .../testdemo/ros/msgs/std_msgs/Time.java | 17 + .../ros/rosbridge/implementation/JSON.java | 2 - .../testdemo/ros/tools/MessageUnpacker.java | 61 + .../testdemo/ros/tools/PeriodicPublisher.java | 178 ++ .../edu/wpi/rail/jrosbridge/JRosbridge.java | 181 ++ .../edu/wpi/rail/jrosbridge/JsonWrapper.java | 106 + .../java/edu/wpi/rail/jrosbridge/Ros.java | 535 +++++ .../java/edu/wpi/rail/jrosbridge/Service.java | 240 +++ .../java/edu/wpi/rail/jrosbridge/Topic.java | 279 +++ .../callback/CallServiceCallback.java | 23 + .../jrosbridge/callback/ServiceCallback.java | 24 + .../jrosbridge/callback/TopicCallback.java | 23 + .../rail/jrosbridge/handler/RosHandler.java | 41 + .../rail/jrosbridge/primitives/Duration.java | 166 ++ .../rail/jrosbridge/primitives/Primitive.java | 313 +++ .../wpi/rail/jrosbridge/primitives/Time.java | 203 ++ .../rail/jrosbridge/primitives/TimeBase.java | 202 ++ .../jrosbridge/services/ServiceRequest.java | 135 ++ .../jrosbridge/services/ServiceResponse.java | 141 ++ .../rail/jrosbridge/services/std/Empty.java | 157 ++ src/server/src/main/res/META-INF/MANIFEST.MF | 26 + src/server/src/main/resources/test.js | 4 +- 47 files changed, 8410 insertions(+), 81 deletions(-) create mode 100644 src/Logistics/app/src/main/java/com/jilk/ros/map/WayPointUtil.java create mode 100644 src/Logistics/app/src/main/java/com/jilk/ros/model/FootPrintResult.java create mode 100644 src/Logistics/app/src/main/java/com/jilk/ros/model/InitPoseResult.java create mode 100644 src/Logistics/app/src/main/java/com/jilk/ros/model/PoiResult.java create mode 100644 src/Logistics/app/src/main/java/com/jilk/ros/nav/Move_Base_Goal.java create mode 100644 src/Logistics/app/src/main/java/com/jilk/ros/nav/Move_Base_Status.java create mode 100644 src/Logistics/app/src/main/java/com/jilk/ros/nav/NavPublich.java create mode 100644 src/Logistics/app/src/main/java/com/jilk/ros/nav/TMove_Base_Goal.java create mode 100644 src/Logistics/app/src/main/java/com/jilk/ros/net/NetBroadcastReceiver.java create mode 100644 src/Logistics/app/src/main/java/com/jilk/ros/net/NetUtil.java create mode 100644 src/Logistics/app/src/main/java/com/jilk/ros/net/POI.java create mode 100644 src/server/src/main/java/com/example/testdemo/ServerApplication.java delete mode 100644 src/server/src/main/java/com/example/testdemo/TestdemoApplication.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/Publisher.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/RosListenDelegate.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/SubscriptionRequestMsg.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/msgs/geometry_msgs/Twist.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/msgs/geometry_msgs/Vector3.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/msgs/sensor_msgs/Image.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/msgs/std_msgs/Header.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/msgs/std_msgs/PrimitiveMsg.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/msgs/std_msgs/Time.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/tools/MessageUnpacker.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/tools/PeriodicPublisher.java create mode 100644 src/server/src/main/java/edu/wpi/rail/jrosbridge/JRosbridge.java create mode 100644 src/server/src/main/java/edu/wpi/rail/jrosbridge/JsonWrapper.java create mode 100644 src/server/src/main/java/edu/wpi/rail/jrosbridge/Ros.java create mode 100644 src/server/src/main/java/edu/wpi/rail/jrosbridge/Service.java create mode 100644 src/server/src/main/java/edu/wpi/rail/jrosbridge/Topic.java create mode 100644 src/server/src/main/java/edu/wpi/rail/jrosbridge/callback/CallServiceCallback.java create mode 100644 src/server/src/main/java/edu/wpi/rail/jrosbridge/callback/ServiceCallback.java create mode 100644 src/server/src/main/java/edu/wpi/rail/jrosbridge/callback/TopicCallback.java create mode 100644 src/server/src/main/java/edu/wpi/rail/jrosbridge/handler/RosHandler.java create mode 100644 src/server/src/main/java/edu/wpi/rail/jrosbridge/primitives/Duration.java create mode 100644 src/server/src/main/java/edu/wpi/rail/jrosbridge/primitives/Primitive.java create mode 100644 src/server/src/main/java/edu/wpi/rail/jrosbridge/primitives/Time.java create mode 100644 src/server/src/main/java/edu/wpi/rail/jrosbridge/primitives/TimeBase.java create mode 100644 src/server/src/main/java/edu/wpi/rail/jrosbridge/services/ServiceRequest.java create mode 100644 src/server/src/main/java/edu/wpi/rail/jrosbridge/services/ServiceResponse.java create mode 100644 src/server/src/main/java/edu/wpi/rail/jrosbridge/services/std/Empty.java create mode 100644 src/server/src/main/res/META-INF/MANIFEST.MF diff --git a/src/Logistics/app/src/main/java/com/example/logistics/manager/goodManager.java b/src/Logistics/app/src/main/java/com/example/logistics/manager/goodManager.java index e5ec254..7f7f8ec 100644 --- a/src/Logistics/app/src/main/java/com/example/logistics/manager/goodManager.java +++ b/src/Logistics/app/src/main/java/com/example/logistics/manager/goodManager.java @@ -20,7 +20,9 @@ public class goodManager { private static final String TAG = "goodDao"; - public int search(String id, String phonenum, Context context){ + public int search(String id, String phonenum, Context context){//搜索快件位置(id,手机号) + + Log.d(TAG, "search"); HashMap map = new HashMap<>(); Connection connection = DBOpenHelper.getConn(); @@ -28,9 +30,11 @@ public class goodManager { int msg = 0; try{ + Log.d(TAG, "select goods"); String sql = "select * from goods where id = ?"; if(connection != null){ + Log.d(TAG, "connection!"); PreparedStatement ps = connection.prepareStatement(sql); if(ps != null){ Log.e(TAG, "id: " + id); @@ -47,13 +51,15 @@ public class goodManager { connection.close(); ps.close(); if(map.size() != 0){ + Log.d(TAG, "map isnot null"); StringBuilder s = new StringBuilder(); for(String key:map.keySet()){ if(key.equals("phonenum")){ String strphone = String.valueOf(map.get(key)); - Log.d("abc", strphone); + Log.d(TAG, strphone); if(phonenum.equals(strphone.substring(7,11))){ msg = 1; //phonenum correct + Log.d(TAG, "phonenum correct"); AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle("快件位置"); builder.setMessage("\n第 "+ map.get("shelfnum")+ " 号货架\n第 " + map.get("floornum")+ " 层"); @@ -61,6 +67,7 @@ public class goodManager { builder.show(); Looper.loop(); }else{ + Log.d(TAG, "phonenum incorrect"); msg = 2; //phonenum incorrect } break; @@ -90,9 +97,11 @@ public class goodManager { Connection connection = DBOpenHelper.getConn(); try{ + Log.d(TAG, "delete"); String sql = "delete from goods where id = ?"; if(connection != null){ + Log.d(TAG, "successCon"); PreparedStatement ps = connection.prepareStatement(sql); if(ps != null){ Log.e(TAG, "pickupcode: " + pickupcode); @@ -121,13 +130,15 @@ public class goodManager { public List> nopick(String phonenum){ Connection connection = DBOpenHelper.getConn(); - + Log.d(TAG, "nopick goods"); List> datalist; datalist = new ArrayList>(); try{ + Log.d(TAG, "select"); String sql = "select * from goods where phonenum = ?"; if(connection != null){ + Log.d(TAG, "successCon"); PreparedStatement ps = connection.prepareStatement(sql); if(ps != null){ Log.e(TAG, "phonenum: " + phonenum); @@ -136,13 +147,18 @@ public class goodManager { int count = rs.getMetaData().getColumnCount(); while(rs.next()){ + + Log.d(TAG, "getResult"); + Map map = new HashMap(); for(int i = 1; i <= count; i++){ String field = rs.getMetaData().getColumnName(i); if(field.equals("id")){ + Log.d(TAG, "id"); map.put(field, rs.getString(field)); } if(field.equals("time")) { + Log.d(TAG, "time"); map.put(field, rs.getString(field)); } } @@ -170,9 +186,11 @@ public class goodManager { int msg = 0; try{ + Log.d(TAG, "pickup"); String sql = "select * from goods where id=?"; if(connection != null){ + Log.d(TAG, "successCon"); PreparedStatement ps = connection.prepareStatement(sql); if(ps != null){ Log.e(TAG, "pickupcode: " + pickupcode); @@ -189,6 +207,7 @@ public class goodManager { connection.close(); ps.close(); if(map.size() != 0){ + Log.d(TAG, "map has value"); StringBuilder s = new StringBuilder(); for(String key:map.keySet()){ if(key.equals("phonenum")){ diff --git a/src/Logistics/app/src/main/java/com/jilk/ros/map/WayPointUtil.java b/src/Logistics/app/src/main/java/com/jilk/ros/map/WayPointUtil.java new file mode 100644 index 0000000..f92d410 --- /dev/null +++ b/src/Logistics/app/src/main/java/com/jilk/ros/map/WayPointUtil.java @@ -0,0 +1,1046 @@ +package com.jilk.ros.map; + +import java.util.List; + +/** + * Created by super_yu on 27/10/2017. + */ + +public class WayPointUtil { + + /** + * goal_timeout : 0 + * name : pose_charge + * header : {"seq":0,"frame_id":"initial_pose","stamp":{"secs":0,"nsecs":0}} + * close_enough : 0 + * failure_mode : LOOP + * pose : {"orientation":{"z":6.72817E-5,"x":0.00212954,"w":0.999965,"y":0.00806749},"position":{"z":-1.11391E-5,"x":0.0140563,"y":-0.00219822}} + */ + + private List waypoints; + + public List getWaypoints() { + return waypoints; + } + + public void setWaypoints(List waypoints) { + this.waypoints = waypoints; + } + + public static class WaypointsBean { + private int goal_timeout; + private String name; + /** + * seq : 0 + * frame_id : initial_pose + * stamp : {"secs":0,"nsecs":0} + */ + + private HeaderBean header; + private double close_enough; + private String failure_mode; + /** + * orientation : {"z":6.72817E-5,"x":0.00212954,"w":0.999965,"y":0.00806749} + * position : {"z":-1.11391E-5,"x":0.0140563,"y":-0.00219822} + */ + + private PoseBean pose; + + public int getGoal_timeout() { + return goal_timeout; + } + + public void setGoal_timeout(int goal_timeout) { + this.goal_timeout = goal_timeout; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public HeaderBean getHeader() { + return header; + } + + public void setHeader(HeaderBean header) { + this.header = header; + } + + public double getClose_enough() { + return close_enough; + } + + public void setClose_enough(double close_enough) { + this.close_enough = close_enough; + } + + public String getFailure_mode() { + return failure_mode; + } + + public void setFailure_mode(String failure_mode) { + this.failure_mode = failure_mode; + } + + public PoseBean getPose() { + return pose; + } + + public void setPose(PoseBean pose) { + this.pose = pose; + } + + public static class HeaderBean { + private int seq; + private String frame_id; + /** + * secs : 0 + * nsecs : 0 + */ + + private StampBean stamp; + + public int getSeq() { + return seq; + } + + public void setSeq(int seq) { + this.seq = seq; + } + + public String getFrame_id() { + return frame_id; + } + + public void setFrame_id(String frame_id) { + this.frame_id = frame_id; + } + + public StampBean getStamp() { + return stamp; + } + + public void setStamp(StampBean stamp) { + this.stamp = stamp; + } + + public static class StampBean { + private int secs; + private int nsecs; + + public int getSecs() { + return secs; + } + + public void setSecs(int secs) { + this.secs = secs; + } + + public int getNsecs() { + return nsecs; + } + + public void setNsecs(int nsecs) { + this.nsecs = nsecs; + } + } + } + + public static class PoseBean { + /** + * z : 6.72817E-5 + * x : 0.00212954 + * w : 0.999965 + * y : 0.00806749 + */ + + private OrientationBean orientation; + /** + * z : -1.11391E-5 + * x : 0.0140563 + * y : -0.00219822 + */ + + private PositionBean position; + + public OrientationBean getOrientation() { + return orientation; + } + + public void setOrientation(OrientationBean orientation) { + this.orientation = orientation; + } + + public PositionBean getPosition() { + return position; + } + + public void setPosition(PositionBean position) { + this.position = position; + } + + public static class OrientationBean { + private double z; + private double x; + private double w; + private double y; + + public double getZ() { + return z; + } + + public void setZ(double z) { + this.z = z; + } + + public double getX() { + return x; + } + + public void setX(double x) { + this.x = x; + } + + public double getW() { + return w; + } + + public void setW(double w) { + this.w = w; + } + + public double getY() { + return y; + } + + public void setY(double y) { + this.y = y; + } + } + + public static class PositionBean { + private double z; + private double x; + private double y; + + public double getZ() { + return z; + } + + public void setZ(double z) { + this.z = z; + } + + public double getX() { + return x; + } + + public void setX(double x) { + this.x = x; + } + + public double getY() { + return y; + } + + public void setY(double y) { + this.y = y; + } + } + } + } + + /** + * { + "waypoints": [ + { + "goal_timeout": 0, + "name": "pose_charge", + "header": { + "seq": 0, + "frame_id": "initial_pose", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0, + "failure_mode": "LOOP", + "pose": { + "orientation": { + "z": 0.0000672817, + "x": 0.00212954, + "w": 0.999965, + "y": 0.00806749 + }, + "position": { + "z": -0.0000111391, + "x": 0.0140563, + "y": -0.00219822 + } + } + }, + { + "goal_timeout": 0, + "name": "map_dockBegin", + "header": { + "seq": 0, + "frame_id": "map", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0, + "failure_mode": "LOOP", + "pose": { + "orientation": { + "z": 0.0000672817, + "x": 0.00212954, + "w": 0.999965, + "y": 0.00806749 + }, + "position": { + "z": -0.0000111391, + "x": -0.335944, + "y": -0.00224531 + } + } + }, + { + "goal_timeout": 0, + "name": "pubsuber_charge_adjust", + "header": { + "seq": 0, + "frame_id": "pubsuber", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0, + "failure_mode": "charge_adjust_done", + "pose": { + "orientation": { + "z": 0, + "x": 0, + "w": 1, + "y": 0 + }, + "position": { + "z": 0, + "x": 0, + "y": 0 + } + } + }, + { + "goal_timeout": 0, + "name": "pubsuber_auto_charge", + "header": { + "seq": 0, + "frame_id": "pubsuber", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0, + "failure_mode": "3", + "pose": { + "orientation": { + "z": 0, + "x": 0, + "w": 1, + "y": 0 + }, + "position": { + "z": 0, + "x": 0, + "y": 0 + } + } + }, + { + "goal_timeout": 0, + "name": "vel_forward", + "header": { + "seq": 0, + "frame_id": "cmd_vel", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0.05000000074505806, + "failure_mode": "NONE", + "pose": { + "orientation": { + "z": 0, + "x": 0, + "w": 1, + "y": 0 + }, + "position": { + "z": 0, + "x": 0, + "y": 0 + } + } + }, + { + "goal_timeout": 0, + "name": "vel_stop", + "header": { + "seq": 0, + "frame_id": "cmd_vel", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0, + "failure_mode": "NONE", + "pose": { + "orientation": { + "z": 0, + "x": 0, + "w": 1, + "y": 0 + }, + "position": { + "z": 0, + "x": 0, + "y": 0 + } + } + }, + { + "goal_timeout": 0, + "name": "vel_backward", + "header": { + "seq": 0, + "frame_id": "cmd_vel", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": -0.05000000074505806, + "failure_mode": "NONE", + "pose": { + "orientation": { + "z": 0, + "x": 0, + "w": 1, + "y": 0 + }, + "position": { + "z": 0, + "x": 0, + "y": 0 + } + } + }, + { + "goal_timeout": 0, + "name": "pub_bumper_on", + "header": { + "seq": 0, + "frame_id": "publisher", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0, + "failure_mode": "NONE", + "pose": { + "orientation": { + "z": 0, + "x": 0, + "w": 1, + "y": 0 + }, + "position": { + "z": 0, + "x": 0, + "y": 0 + } + } + }, + { + "goal_timeout": 0, + "name": "pub_bumper_off", + "header": { + "seq": 0, + "frame_id": "publisher", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0, + "failure_mode": "NONE", + "pose": { + "orientation": { + "z": 0, + "x": 0, + "w": 1, + "y": 0 + }, + "position": { + "z": 0, + "x": 0, + "y": 0 + } + } + }, + { + "goal_timeout": 0, + "name": "pub_estop_on", + "header": { + "seq": 0, + "frame_id": "publisher", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0, + "failure_mode": "NONE", + "pose": { + "orientation": { + "z": 0, + "x": 0, + "w": 1, + "y": 0 + }, + "position": { + "z": 0, + "x": 0, + "y": 0 + } + } + }, + { + "goal_timeout": 0, + "name": "pub_estop_off", + "header": { + "seq": 0, + "frame_id": "publisher", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0, + "failure_mode": "NONE", + "pose": { + "orientation": { + "z": 0, + "x": 0, + "w": 1, + "y": 0 + }, + "position": { + "z": 0, + "x": 0, + "y": 0 + } + } + }, + { + "goal_timeout": 0, + "name": "pub_estop_auto", + "header": { + "seq": 0, + "frame_id": "publisher", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0, + "failure_mode": "NONE", + "pose": { + "orientation": { + "z": 0, + "x": 0, + "w": 1, + "y": 0 + }, + "position": { + "z": 0, + "x": 0, + "y": 0 + } + } + }, + { + "goal_timeout": 0, + "name": "pub_light_r", + "header": { + "seq": 0, + "frame_id": "publisher", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0, + "failure_mode": "NONE", + "pose": { + "orientation": { + "z": 0, + "x": 0, + "w": 1, + "y": 0 + }, + "position": { + "z": 0, + "x": 0, + "y": 0 + } + } + }, + { + "goal_timeout": 0, + "name": "pub_light_g", + "header": { + "seq": 0, + "frame_id": "publisher", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0, + "failure_mode": "NONE", + "pose": { + "orientation": { + "z": 0, + "x": 0, + "w": 1, + "y": 0 + }, + "position": { + "z": 0, + "x": 0, + "y": 0 + } + } + }, + { + "goal_timeout": 0, + "name": "pub_light_b", + "header": { + "seq": 0, + "frame_id": "publisher", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0, + "failure_mode": "NONE", + "pose": { + "orientation": { + "z": 0, + "x": 0, + "w": 1, + "y": 0 + }, + "position": { + "z": 0, + "x": 0, + "y": 0 + } + } + }, + { + "goal_timeout": 0, + "name": "pub_light_y", + "header": { + "seq": 0, + "frame_id": "publisher", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0, + "failure_mode": "NONE", + "pose": { + "orientation": { + "z": 0, + "x": 0, + "w": 1, + "y": 0 + }, + "position": { + "z": 0, + "x": 0, + "y": 0 + } + } + }, + { + "goal_timeout": 0, + "name": "sound_sound_on", + "header": { + "seq": 0, + "frame_id": "sound_play", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0, + "failure_mode": "START", + "pose": { + "orientation": { + "z": 0, + "x": 0, + "w": 1, + "y": 0 + }, + "position": { + "z": 0, + "x": 0, + "y": 0 + } + } + }, + { + "goal_timeout": 0, + "name": "sound_sound_off", + "header": { + "seq": 0, + "frame_id": "sound_play", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0, + "failure_mode": "STOP", + "pose": { + "orientation": { + "z": 0, + "x": 0, + "w": 1, + "y": 0 + }, + "position": { + "z": 0, + "x": 0, + "y": 0 + } + } + }, + { + "goal_timeout": 0, + "name": "sound_sound_play_once", + "header": { + "seq": 0, + "frame_id": "sound_play", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0, + "failure_mode": "ONCE", + "pose": { + "orientation": { + "z": 0, + "x": 0, + "w": 1, + "y": 0 + }, + "position": { + "z": 0, + "x": 0, + "y": 0 + } + } + }, + { + "goal_timeout": 0, + "name": "scanMarker_scan_9", + "header": { + "seq": 0, + "frame_id": "scan_marker", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0.8999999761581421, + "failure_mode": "LOOP", + "pose": { + "orientation": { + "z": 0, + "x": 0, + "w": 1, + "y": 0 + }, + "position": { + "z": 0, + "x": 0, + "y": 0 + } + } + }, + { + "goal_timeout": 0, + "name": "scanMarker_scan_8", + "header": { + "seq": 0, + "frame_id": "scan_marker", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0.800000011920929, + "failure_mode": "LOOP", + "pose": { + "orientation": { + "z": 0, + "x": 0, + "w": 1, + "y": 0 + }, + "position": { + "z": 0, + "x": 0, + "y": 0 + } + } + }, + { + "goal_timeout": 0, + "name": "scanMarker_scan_7", + "header": { + "seq": 0, + "frame_id": "scan_marker", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0.699999988079071, + "failure_mode": "LOOP", + "pose": { + "orientation": { + "z": 0, + "x": 0, + "w": 1, + "y": 0 + }, + "position": { + "z": 0, + "x": 0, + "y": 0 + } + } + }, + { + "goal_timeout": 0, + "name": "scanMarker_scan_6", + "header": { + "seq": 0, + "frame_id": "scan_marker", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0.6000000238418579, + "failure_mode": "LOOP", + "pose": { + "orientation": { + "z": 0, + "x": 0, + "w": 1, + "y": 0 + }, + "position": { + "z": 0, + "x": 0, + "y": 0 + } + } + }, + { + "goal_timeout": 0, + "name": "scanMarker_scan_5", + "header": { + "seq": 0, + "frame_id": "scan_marker", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0.5, + "failure_mode": "LOOP", + "pose": { + "orientation": { + "z": 0, + "x": 0, + "w": 1, + "y": 0 + }, + "position": { + "z": 0, + "x": 0, + "y": 0 + } + } + }, + { + "goal_timeout": 0, + "name": "scanMarker_scan_4", + "header": { + "seq": 0, + "frame_id": "scan_marker", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0.4000000059604645, + "failure_mode": "LOOP", + "pose": { + "orientation": { + "z": 0, + "x": 0, + "w": 1, + "y": 0 + }, + "position": { + "z": 0, + "x": 0, + "y": 0 + } + } + }, + { + "goal_timeout": 6, + "name": "timer_sail", + "header": { + "seq": 0, + "frame_id": "timer", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0, + "failure_mode": "NONE", + "pose": { + "orientation": { + "z": 0, + "x": 0, + "w": 1, + "y": 0 + }, + "position": { + "z": 0, + "x": 0, + "y": 0 + } + } + }, + { + "goal_timeout": 0, + "name": "map_6_A_601", + "header": { + "seq": 0, + "frame_id": "map", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0, + "failure_mode": "LOOP", + "pose": { + "orientation": { + "z": -0.710356, + "x": 0.00568841, + "w": 0.70382, + "y": 0.000206077 + }, + "position": { + "z": 0.0000268415, + "x": -5.43955, + "y": 0.441982 + } + } + }, + { + "goal_timeout": 0, + "name": "scanMarker_6_A_O", + "header": { + "seq": 0, + "frame_id": "scan_marker", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0, + "failure_mode": "LOOP", + "pose": { + "orientation": { + "z": -0.00584617, + "x": 0.00134079, + "w": 0.999976, + "y": -0.00348327 + }, + "position": { + "z": 0.0095544, + "x": -0.00660459, + "y": -0.0187305 + } + } + }, + { + "goal_timeout": 0, + "name": "map_6_A_602", + "header": { + "seq": 0, + "frame_id": "map", + "stamp": { + "secs": 0, + "nsecs": 0 + } + }, + "close_enough": 0, + "failure_mode": "LOOP", + "pose": { + "orientation": { + "z": 0.673475, + "x": 0.00818346, + "w": 0.739164, + "y": 0.00151504 + }, + "position": { + "z": 0.000584151, + "x": -2.65592, + "y": 0.365388 + } + } + } + ] + } + */ +} diff --git a/src/Logistics/app/src/main/java/com/jilk/ros/model/FootPrintResult.java b/src/Logistics/app/src/main/java/com/jilk/ros/model/FootPrintResult.java new file mode 100644 index 0000000..3cf5d54 --- /dev/null +++ b/src/Logistics/app/src/main/java/com/jilk/ros/model/FootPrintResult.java @@ -0,0 +1,178 @@ +package com.jilk.ros.model; + +import java.util.List; + +/** + * Created by super_yu on 2018/1/8. + */ + +public class FootPrintResult { + /** + * header : {"seq":4297,"frame_id":"odom","stamp":{"secs":1515378187,"nsecs":125325857}} + * polygon : {"points":[{"z":0,"x":0.31369608640670776,"y":-0.5355392694473267},{"z":0,"x":0.35115259885787964,"y":-0.016890067607164383},{"z":0,"x":-0.30713292956352234,"y":0.03065088950097561},{"z":0,"x":-0.3445894420146942,"y":-0.4879983365535736}]} + */ + + private HeaderBean header; + private PolygonBean polygon; + + public HeaderBean getHeader() { + return header; + } + + public void setHeader(HeaderBean header) { + this.header = header; + } + + public PolygonBean getPolygon() { + return polygon; + } + + public void setPolygon(PolygonBean polygon) { + this.polygon = polygon; + } + + public static class HeaderBean { + /** + * seq : 4297 + * frame_id : odom + * stamp : {"secs":1515378187,"nsecs":125325857} + */ + + private int seq; + private String frame_id; + private StampBean stamp; + + public int getSeq() { + return seq; + } + + public void setSeq(int seq) { + this.seq = seq; + } + + public String getFrame_id() { + return frame_id; + } + + public void setFrame_id(String frame_id) { + this.frame_id = frame_id; + } + + public StampBean getStamp() { + return stamp; + } + + public void setStamp(StampBean stamp) { + this.stamp = stamp; + } + + public static class StampBean { + /** + * secs : 1515378187 + * nsecs : 125325857 + */ + + private int secs; + private int nsecs; + + public int getSecs() { + return secs; + } + + public void setSecs(int secs) { + this.secs = secs; + } + + public int getNsecs() { + return nsecs; + } + + public void setNsecs(int nsecs) { + this.nsecs = nsecs; + } + } + } + + public static class PolygonBean { + private List points; + + public List getPoints() { + return points; + } + + public void setPoints(List points) { + this.points = points; + } + + public static class PointsBean { + /** + * z : 0 + * x : 0.31369608640670776 + * y : -0.5355392694473267 + */ + + private int z; + private double x; + private double y; + + public int getZ() { + return z; + } + + public void setZ(int z) { + this.z = z; + } + + public double getX() { + return x; + } + + public void setX(double x) { + this.x = x; + } + + public double getY() { + return y; + } + + public void setY(double y) { + this.y = y; + } + } + } + +// { +// "header": { +// "seq": 4297, +// "frame_id": "odom", +// "stamp": { +// "secs": 1515378187, +// "nsecs": 125325857 +// } +// }, +// "polygon": { +// "points": [ +// { +// "z": 0, +// "x": 0.31369608640670776, +// "y": -0.5355392694473267 +// }, +// { +// "z": 0, +// "x": 0.35115259885787964, +// "y": -0.016890067607164383 +// }, +// { +// "z": 0, +// "x": -0.30713292956352234, +// "y": 0.03065088950097561 +// }, +// { +// "z": 0, +// "x": -0.3445894420146942, +// "y": -0.4879983365535736 +// } +// ] +// } +// } +} diff --git a/src/Logistics/app/src/main/java/com/jilk/ros/model/InitPoseResult.java b/src/Logistics/app/src/main/java/com/jilk/ros/model/InitPoseResult.java new file mode 100644 index 0000000..4a37853 --- /dev/null +++ b/src/Logistics/app/src/main/java/com/jilk/ros/model/InitPoseResult.java @@ -0,0 +1,274 @@ +package com.jilk.ros.model; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by super_yu on 2018/2/5. + */ + +public class InitPoseResult { + + /** + * op : publish + * topic : /initialpose + * msg : {"header":{"frame_id":"map"},"pose":{"pose":{"position":{"x":0,"y":0,"z":0},"orientation":{"x":0,"y":0,"z":0,"w":1}},"covariance":[0.25,0,0,0,0,0,0,0.25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.06853891945200942]}} + */ + + private String op = "publish"; + private String topic = "/initialpose"; + private MsgBean msg; + + + public MsgBean getMsg() { + return msg; + } + + public void setMsg(MsgBean msg) { + this.msg = msg; + } + + public static class MsgBean { + /** + * header : {"frame_id":"map"} + * pose : {"pose":{"position":{"x":0,"y":0,"z":0},"orientation":{"x":0,"y":0,"z":0,"w":1}},"covariance":[0.25,0,0,0,0,0,0,0.25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.06853891945200942]} + */ + + private HeaderBean header; + private PoseBeanX pose; + + public HeaderBean getHeader() { + return header; + } + + public void setHeader(HeaderBean header) { + this.header = header; + } + + public PoseBeanX getPose() { + return pose; + } + + public void setPose(PoseBeanX pose) { + this.pose = pose; + } + + public static class HeaderBean { + /** + * frame_id : map + */ + + private String frame_id = "map"; + } + + public static class PoseBeanX { + /** + * pose : {"position":{"x":0,"y":0,"z":0},"orientation":{"x":0,"y":0,"z":0,"w":1}} + * covariance : + * 0.25,0,0,0,0,0,0,0.25, + * 0,0,0,0,0,0,0,0,0,0,0, + * 0,0,0,0,0,0,0,0,0,0,0, + * 0,0,0,0,0,0.06853891945200942 + */ + + private PoseBean pose; + private List covariance; + + public PoseBean getPose() { + return pose; + } + + public void setPose(PoseBean pose) { + this.pose = pose; + } + + public void setCovariance() { + covariance = new ArrayList(); + for (int i = 0; i < 36; i++) { + if (i == 0) { + covariance.add(0.25); + } else if (i == 7) { + covariance.add(0.25); + } else if (i == 35) { + covariance.add(0.06853891945200942); + + } else { + covariance.add((double) 0); + } + } + } + + public static class PoseBean { + /** + * position : {"x":0,"y":0,"z":0} + * orientation : {"x":0,"y":0,"z":0,"w":1} + */ + + private PositionBean position; + private OrientationBean orientation; + + public PositionBean getPosition() { + return position; + } + + public void setPosition(PositionBean position) { + this.position = position; + } + + public OrientationBean getOrientation() { + return orientation; + } + + public void setOrientation(OrientationBean orientation) { + this.orientation = orientation; + } + + public static class PositionBean { + /** + * x : 0 + * y : 0 + * z : 0 + */ + + private double x; + private double y; + private double z; + + public double getX() { + return x; + } + + public void setX(double x) { + this.x = x; + } + + public double getY() { + return y; + } + + public void setY(double y) { + this.y = y; + } + + public double getZ() { + return z; + } + + public void setZ(double z) { + this.z = z; + } + } + + public static class OrientationBean { + /** + * x : 0 + * y : 0 + * z : 0 + * w : 1 + */ + + private double x; + private double y; + private double z; + private double w; + + public double getX() { + return x; + } + + public void setX(double x) { + this.x = x; + } + + public double getY() { + return y; + } + + public void setY(double y) { + this.y = y; + } + + public double getZ() { + return z; + } + + public void setZ(double z) { + this.z = z; + } + + public double getW() { + return w; + } + + public void setW(double w) { + this.w = w; + } + } + } + } + } + + +// { +// "op": "publish", +// "topic": "/initialpose", +// "msg": { +// "header": { +// "frame_id": "map" +// }, +// "pose": { +// "pose": { +// "position": { +// "x": 0, +// "y": 0, +// "z": 0 +// }, +// "orientation": { +// "x": 0, +// "y": 0, +// "z": 0, +// "w": 1 +// } +// }, +// "covariance": [ +// 0.25, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0.25, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0.06853891945200942 +// ] +// } +// } +// } +} diff --git a/src/Logistics/app/src/main/java/com/jilk/ros/model/PoiResult.java b/src/Logistics/app/src/main/java/com/jilk/ros/model/PoiResult.java new file mode 100644 index 0000000..7dbe1f2 --- /dev/null +++ b/src/Logistics/app/src/main/java/com/jilk/ros/model/PoiResult.java @@ -0,0 +1,501 @@ +package com.jilk.ros.model; + +/** + * Created by super_yu on 2018/1/5. + */ + +import java.util.List; + +/** + *对位置移动有数据变化的是 + * orientation z、w + * position x、y + * twist x + * angular z + * Created by super_yu on 2017/9/29. + */ + +public class PoiResult { + + /** + * twist : {"twist":{"angular":{"z":0,"y":0,"x":0},"linear":{"z":0,"y":0,"x":0}},"covariance":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]} + * child_frame_id : base_footprint + * pose : {"covariance":[0.1,0,0,0,0,0,0,0.1,0,0,0,0,0,0,1.7976931348623157E308,0,0,0,0,0,0,1.7976931348623157E308,0,0,0,0,0,0,1.7976931348623157E308,0,0,0,0,0,0,0.2],"pose":{"position":{"z":0,"y":-0.16137039724419636,"x":0.001470031525333453},"orientation":{"w":-0.08271030624895466,"z":-0.9965736326234024,"y":"-0","x":0}}} + * header : {"seq":69712,"stamp":{"secs":1506650141,"nsecs":455670567},"frame_id":"odom"} + */ + + private TwistBeanX twist; + private String child_frame_id; + private PoseBeanX pose; + private HeaderBean header; + + public TwistBeanX getTwist() { + return twist; + } + + public void setTwist(TwistBeanX twist) { + this.twist = twist; + } + + public String getChild_frame_id() { + return child_frame_id; + } + + public void setChild_frame_id(String child_frame_id) { + this.child_frame_id = child_frame_id; + } + + public PoseBeanX getPose() { + return pose; + } + + public void setPose(PoseBeanX pose) { + this.pose = pose; + } + + public HeaderBean getHeader() { + return header; + } + + public void setHeader(HeaderBean header) { + this.header = header; + } + + public static class TwistBeanX { + /** + * twist : {"angular":{"z":0,"y":0,"x":0},"linear":{"z":0,"y":0,"x":0}} + * covariance : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + */ + + private TwistBean twist; + private List covariance; + + public TwistBean getTwist() { + return twist; + } + + public void setTwist(TwistBean twist) { + this.twist = twist; + } + + public List getCovariance() { + return covariance; + } + + public void setCovariance(List covariance) { + this.covariance = covariance; + } + + public static class TwistBean { + /** + * angular : {"z":0,"y":0,"x":0} + * linear : {"z":0,"y":0,"x":0} + */ + + private AngularBean angular; + private LinearBean linear; + + public AngularBean getAngular() { + return angular; + } + + public void setAngular(AngularBean angular) { + this.angular = angular; + } + + public LinearBean getLinear() { + return linear; + } + + public void setLinear(LinearBean linear) { + this.linear = linear; + } + + public static class AngularBean { + /** + * z : 0 + * y : 0 + * x : 0 + */ + + private int z; + private int y; + private int x; + + public int getZ() { + return z; + } + + public void setZ(int z) { + this.z = z; + } + + public int getY() { + return y; + } + + public void setY(int y) { + this.y = y; + } + + public int getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } + } + + public static class LinearBean { + /** + * z : 0 + * y : 0 + * x : 0 + */ + + private int z; + private int y; + private int x; + + public int getZ() { + return z; + } + + public void setZ(int z) { + this.z = z; + } + + public int getY() { + return y; + } + + public void setY(int y) { + this.y = y; + } + + public int getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } + } + } + } + + public static class PoseBeanX { + /** + * covariance : [0.1,0,0,0,0,0,0,0.1,0,0,0,0,0,0,1.7976931348623157E308,0,0,0,0,0,0,1.7976931348623157E308,0,0,0,0,0,0,1.7976931348623157E308,0,0,0,0,0,0,0.2] + * pose : {"position":{"z":0,"y":-0.16137039724419636,"x":0.001470031525333453},"orientation":{"w":-0.08271030624895466,"z":-0.9965736326234024,"y":"-0","x":0}} + */ + + private PoseBean pose; + private List covariance; + + public PoseBean getPose() { + return pose; + } + + public void setPose(PoseBean pose) { + this.pose = pose; + } + + public List getCovariance() { + return covariance; + } + + public void setCovariance(List covariance) { + this.covariance = covariance; + } + + public static class PoseBean { + /** + * position : {"z":0,"y":-0.16137039724419636,"x":0.001470031525333453} + * orientation : {"w":-0.08271030624895466,"z":-0.9965736326234024,"y":"-0","x":0} + */ + + private PositionBean position; + private OrientationBean orientation; + + public PositionBean getPosition() { + return position; + } + + public void setPosition(PositionBean position) { + this.position = position; + } + + public OrientationBean getOrientation() { + return orientation; + } + + public void setOrientation(OrientationBean orientation) { + this.orientation = orientation; + } + + public static class PositionBean { + /** + * z : 0 + * y : -0.16137039724419636 + * x : 0.001470031525333453 + */ + + private int z; + private double y; + private double x; + + public int getZ() { + return z; + } + + public void setZ(int z) { + this.z = z; + } + + public double getY() { + return y; + } + + public void setY(double y) { + this.y = y; + } + + public double getX() { + return x; + } + + public void setX(double x) { + this.x = x; + } + } + + public static class OrientationBean { + /** + * w : -0.08271030624895466 + * z : -0.9965736326234024 + * y : -0 + * x : 0 + */ + + private double w; + private double z; + private String y; + private int x; + + public double getW() { + return w; + } + + public void setW(double w) { + this.w = w; + } + + public double getZ() { + return z; + } + + public void setZ(double z) { + this.z = z; + } + + public String getY() { + return y; + } + + public void setY(String y) { + this.y = y; + } + + public int getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } + } + } + } + + public static class HeaderBean { + /** + * seq : 69712 + * stamp : {"secs":1506650141,"nsecs":455670567} + * frame_id : odom + */ + + private int seq; + private StampBean stamp; + private String frame_id; + + public int getSeq() { + return seq; + } + + public void setSeq(int seq) { + this.seq = seq; + } + + public StampBean getStamp() { + return stamp; + } + + public void setStamp(StampBean stamp) { + this.stamp = stamp; + } + + public String getFrame_id() { + return frame_id; + } + + public void setFrame_id(String frame_id) { + this.frame_id = frame_id; + } + + public static class StampBean { + /** + * secs : 1506650141 + * nsecs : 455670567 + */ + + private int secs; + private int nsecs; + + public int getSecs() { + return secs; + } + + public void setSecs(int secs) { + this.secs = secs; + } + + public int getNsecs() { + return nsecs; + } + + public void setNsecs(int nsecs) { + this.nsecs = nsecs; + } + } + } + +// +// { +// "twist": { +// "twist": { +// "angular": { +// "z": 0, +// "y": 0, +// "x": 0 +// }, +// "linear": { +// "z": 0, +// "y": 0, +// "x": 0 +// } +// }, +// "covariance": [ +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0 +// ] +// }, +// "child_frame_id": "base_footprint", +// "pose": { +// "covariance": [ +// 0.1, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0.1, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 1.7976931348623157E308, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 1.7976931348623157E308, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 1.7976931348623157E308, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0.2 +// ], +// "pose": { +// "position": { +// "z": 0, +// "y": -0.16137039724419636, +// "x": 0.001470031525333453 +// }, +// "orientation": { +// "w": -0.08271030624895466, +// "z": -0.9965736326234024, +// "y": -0, +// "x": 0 +// } +// } +// }, +// "header": { +// "seq": 69712, +// "stamp": { +// "secs": 1506650141, +// "nsecs": 455670567 +// }, +// "frame_id": "odom" +// } +// } +} diff --git a/src/Logistics/app/src/main/java/com/jilk/ros/nav/Move_Base_Goal.java b/src/Logistics/app/src/main/java/com/jilk/ros/nav/Move_Base_Goal.java new file mode 100644 index 0000000..13d6328 --- /dev/null +++ b/src/Logistics/app/src/main/java/com/jilk/ros/nav/Move_Base_Goal.java @@ -0,0 +1,246 @@ +package com.jilk.ros.nav; + +/** + * Created by super_yu on 27/10/2017. + */ + +public class Move_Base_Goal { + /** + * msg : {"target_pose":{"header":{"frame_id":"/map"},"pose":{"w":0.72508,"x":0.00455891,"y":0.0110448,"z":-0.688561}},"base_position":{"header":{"frame_id":"/map"},"pose":{"x":-5.56034,"y":0.543951,"z":2.96803E-4}}} + * op : publish + * topic : /move_base/goal + */ + + private MsgBean msg; + private String op = "publish"; + private String topic = "/move_base/goal"; + + public MsgBean getMsg() { + return msg; + } + + public void setMsg(MsgBean msg) { + this.msg = msg; + } + + public String getOp() { + return op; + } + + public String getTopic() { + return topic; + } + + public static class MsgBean { + /** + * target_pose : {"header":{"frame_id":"/map"},"pose":{"w":0.72508,"x":0.00455891,"y":0.0110448,"z":-0.688561}} + * base_position : {"header":{"frame_id":"/map"},"pose":{"x":-5.56034,"y":0.543951,"z":2.96803E-4}} + */ + + private TargetPoseBean target_pose; + private BasePositionBean base_position; + + public TargetPoseBean getTarget_pose() { + return target_pose; + } + + public void setTarget_pose(TargetPoseBean target_pose) { + this.target_pose = target_pose; + } + + public BasePositionBean getBase_position() { + return base_position; + } + + public void setBase_position(BasePositionBean base_position) { + this.base_position = base_position; + } + + public static class TargetPoseBean { + /** + * header : {"frame_id":"/map"} + * pose : {"w":0.72508,"x":0.00455891,"y":0.0110448,"z":-0.688561} + */ + + private HeaderBean header; + private PoseBean pose; + + public HeaderBean getHeader() { + return header; + } + + public void setHeader(HeaderBean header) { + this.header = header; + } + + public PoseBean getPose() { + return pose; + } + + public void setPose(PoseBean pose) { + this.pose = pose; + } + + public static class HeaderBean { + /** + * frame_id : /map + */ + + private String frame_id = "/map"; + + public String getFrame_id() { + return frame_id; + } + } + + public static class PoseBean { + /** + * w : 0.72508 + * x : 0.00455891 + * y : 0.0110448 + * z : -0.688561 + */ + + private double w; + private double x; + private double y; + private double z; + + public double getW() { + return w; + } + + public void setW(double w) { + this.w = w; + } + + public double getX() { + return x; + } + + public void setX(double x) { + this.x = x; + } + + public double getY() { + return y; + } + + public void setY(double y) { + this.y = y; + } + + public double getZ() { + return z; + } + + public void setZ(double z) { + this.z = z; + } + } + } + + public static class BasePositionBean { + /** + * header : {"frame_id":"/map"} + * pose : {"x":-5.56034,"y":0.543951,"z":2.96803E-4} + */ + + private HeaderBeanX header; + private PoseBeanX pose; + + public HeaderBeanX getHeader() { + return header; + } + + public void setHeader(HeaderBeanX header) { + this.header = header; + } + + public PoseBeanX getPose() { + return pose; + } + + public void setPose(PoseBeanX pose) { + this.pose = pose; + } + + public static class HeaderBeanX { + /** + * frame_id : /map + */ + + private String frame_id = "/map"; + + public String getFrame_id() { + return frame_id; + } + } + + public static class PoseBeanX { + /** + * x : -5.56034 + * y : 0.543951 + * z : 2.96803E-4 + */ + + private double x; + private double y; + private double z; + + public double getX() { + return x; + } + + public void setX(double x) { + this.x = x; + } + + public double getY() { + return y; + } + + public void setY(double y) { + this.y = y; + } + + public double getZ() { + return z; + } + + public void setZ(double z) { + this.z = z; + } + } + } + } + + +// { +// "op": "publish", +// "topic": "/move_base/goal", +// "msg": { +// "target_pose": { +// "header": { +// "frame_id": "/map" +// }, +// "pose": { +// "z": -0.695688, +// "x": 0.000728705, +// "w": 0.71834, +// "y": 0.00213251 +// } +// }, +// "base_position": { +// "header": { +// "frame_id": "/map" +// }, +// "pose": { +// "z": 0.00984454, +// "x": -0.0483838, +// "y": -0.00480753 +// } +// } +// } +// } +} \ No newline at end of file diff --git a/src/Logistics/app/src/main/java/com/jilk/ros/nav/Move_Base_Status.java b/src/Logistics/app/src/main/java/com/jilk/ros/nav/Move_Base_Status.java new file mode 100644 index 0000000..3c3bae4 --- /dev/null +++ b/src/Logistics/app/src/main/java/com/jilk/ros/nav/Move_Base_Status.java @@ -0,0 +1,219 @@ +package com.jilk.ros.nav; + +import java.util.List; + +/** + * Created by super_yu on 30/10/2017. + */ + +public class Move_Base_Status { + /** + * status_list : [{"goal_id":{"id":"map_6_A_603","stamp":{"secs":1509348841,"nsecs":490135242}},"text":"Goal reached.","status":3},{"goal_id":{"id":"map_6_A_601","stamp":{"secs":1509348875,"nsecs":650002258}},"text":"This goal has been accepted by the simple action server","status":1}] + * header : {"seq":13516,"frame_id":"","stamp":{"secs":1509348876,"nsecs":156902566}} + */ + + private HeaderBean header; + private List status_list; + + public HeaderBean getHeader() { + return header; + } + + public void setHeader(HeaderBean header) { + this.header = header; + } + + public List getStatus_list() { + return status_list; + } + + public void setStatus_list(List status_list) { + this.status_list = status_list; + } + + public static class HeaderBean { + /** + * seq : 13516 + * frame_id : + * stamp : {"secs":1509348876,"nsecs":156902566} + */ + + private int seq; + private String frame_id; + private StampBean stamp; + + public int getSeq() { + return seq; + } + + public void setSeq(int seq) { + this.seq = seq; + } + + public String getFrame_id() { + return frame_id; + } + + public void setFrame_id(String frame_id) { + this.frame_id = frame_id; + } + + public StampBean getStamp() { + return stamp; + } + + public void setStamp(StampBean stamp) { + this.stamp = stamp; + } + + public static class StampBean { + /** + * secs : 1509348876 + * nsecs : 156902566 + */ + + private int secs; + private int nsecs; + + public int getSecs() { + return secs; + } + + public void setSecs(int secs) { + this.secs = secs; + } + + public int getNsecs() { + return nsecs; + } + + public void setNsecs(int nsecs) { + this.nsecs = nsecs; + } + } + } + + public static class StatusListBean { + /** + * goal_id : {"id":"map_6_A_603","stamp":{"secs":1509348841,"nsecs":490135242}} + * text : Goal reached. + * status : 3 + */ + + private GoalIdBean goal_id; + private String text; + private int status; + + public GoalIdBean getGoal_id() { + return goal_id; + } + + public void setGoal_id(GoalIdBean goal_id) { + this.goal_id = goal_id; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public static class GoalIdBean { + /** + * id : map_6_A_603 + * stamp : {"secs":1509348841,"nsecs":490135242} + */ + + private String id; + private StampBeanX stamp; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public StampBeanX getStamp() { + return stamp; + } + + public void setStamp(StampBeanX stamp) { + this.stamp = stamp; + } + + public static class StampBeanX { + /** + * secs : 1509348841 + * nsecs : 490135242 + */ + + private int secs; + private int nsecs; + + public int getSecs() { + return secs; + } + + public void setSecs(int secs) { + this.secs = secs; + } + + public int getNsecs() { + return nsecs; + } + + public void setNsecs(int nsecs) { + this.nsecs = nsecs; + } + } + } + } + + +// { +// "status_list": [ +// { +// "goal_id": { +// "id": "map_6_A_603", +// "stamp": { +// "secs": 1509348841, +// "nsecs": 490135242 +// } +// }, +// "text": "Goal reached.", +// "status": 3 +// }, +// { +// "goal_id": { +// "id": "map_6_A_601", +// "stamp": { +// "secs": 1509348875, +// "nsecs": 650002258 +// } +// }, +// "text": "This goal has been accepted by the simple action server", +// "status": 1 +// } +// ], +// "header": { +// "seq": 13516, +// "frame_id": "", +// "stamp": { +// "secs": 1509348876, +// "nsecs": 156902566 +// } +// } +// } +} diff --git a/src/Logistics/app/src/main/java/com/jilk/ros/nav/NavPublich.java b/src/Logistics/app/src/main/java/com/jilk/ros/nav/NavPublich.java new file mode 100644 index 0000000..de5b670 --- /dev/null +++ b/src/Logistics/app/src/main/java/com/jilk/ros/nav/NavPublich.java @@ -0,0 +1,38 @@ +package com.jilk.ros.nav; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 存储导航对象 + * Created by super_yu on 27/10/2017. + */ + +public class NavPublich { + + private List wayPointsNames; + + private HashMap navPublishHashMap; + + public List getWayPointsNames() { + return wayPointsNames; + } + + public void setWayPointsNames(List wayPointsNames) { + this.wayPointsNames = wayPointsNames; + } + + public HashMap getNavPublishHashMap() { + return navPublishHashMap; + } + + public void setNavPublishHashMap(HashMap navPublishHashMap) { + this.navPublishHashMap = navPublishHashMap; + } + + public void clear() { + if (wayPointsNames != null) wayPointsNames.clear(); + if (navPublishHashMap != null) navPublishHashMap.clear(); + } +} diff --git a/src/Logistics/app/src/main/java/com/jilk/ros/nav/TMove_Base_Goal.java b/src/Logistics/app/src/main/java/com/jilk/ros/nav/TMove_Base_Goal.java new file mode 100644 index 0000000..575a794 --- /dev/null +++ b/src/Logistics/app/src/main/java/com/jilk/ros/nav/TMove_Base_Goal.java @@ -0,0 +1,402 @@ +package com.jilk.ros.nav; + +/** + * Created by super_yu on 30/10/2017. + */ + +public class TMove_Base_Goal { + /** + * op : publish + * topic : /move_base/goal + * msg : {"header":{"seq":0,"stamp":{"secs":0,"nsecs":0},"frame_id":"map"},"goal_id":{"stamp":{"secs":0,"nsecs":0},"id":"map_6_A_601"},"goal":{"target_pose":{"header":{"seq":0,"stamp":{"secs":0,"nsecs":0},"frame_id":"map"},"pose":{"position":{"z":2.96803E-4,"x":-5.56034,"y":0.543951},"orientation":{"z":-0.688561,"x":0.00455891,"w":0.72508,"y":0.0110448}}}}} + */ + private String op = "publish"; + private String topic = "/move_base/goal"; + private MsgBean msg; + + public String getOp() { + return op; + } + + public String getTopic() { + return topic; + } + + public MsgBean getMsg() { + return msg; + } + + public void setMsg(MsgBean msg) { + this.msg = msg; + } + + public static class MsgBean { + /** + * header : {"seq":0,"stamp":{"secs":0,"nsecs":0},"frame_id":"map"} + * goal_id : {"stamp":{"secs":0,"nsecs":0},"id":"map_6_A_601"} + * goal : {"target_pose":{"header":{"seq":0,"stamp":{"secs":0,"nsecs":0},"frame_id":"map"},"pose":{"position":{"z":2.96803E-4,"x":-5.56034,"y":0.543951},"orientation":{"z":-0.688561,"x":0.00455891,"w":0.72508,"y":0.0110448}}}} + */ + + private HeaderBean header; + private GoalIdBean goal_id; + private GoalBean goal; + + public HeaderBean getHeader() { + return header; + } + + public void setHeader(HeaderBean header) { + this.header = header; + } + + public GoalIdBean getGoal_id() { + return goal_id; + } + + public void setGoal_id(GoalIdBean goal_id) { + this.goal_id = goal_id; + } + + public GoalBean getGoal() { + return goal; + } + + public void setGoal(GoalBean goal) { + this.goal = goal; + } + + public static class HeaderBean { + /** + * seq : 0 + * stamp : {"secs":0,"nsecs":0} + * frame_id : map + */ + + private int seq = 0; + private StampBean stamp; + private String frame_id = "map"; + + public int getSeq() { + return seq; + } + + public StampBean getStamp() { + return stamp; + } + + public void setStamp(StampBean stamp) { + this.stamp = stamp; + } + + public String getFrame_id() { + return frame_id; + } + + public static class StampBean { + /** + * secs : 0 + * nsecs : 0 + */ + + private int secs = 0; + private int nsecs = 0; + + public int getSecs() { + return secs; + } + + public int getNsecs() { + return nsecs; + } + } + } + + public static class GoalIdBean { + /** + * stamp : {"secs":0,"nsecs":0} + * id : map_6_A_601 + */ + + private StampBeanX stamp; + + private String id; + + public StampBeanX getStamp() { + return stamp; + } + + public void setStamp(StampBeanX stamp) { + this.stamp = stamp; + } + + public void setId(String id) { + this.id = id; + } + + public String getId() { + return id; + } + + public static class StampBeanX { + /** + * secs : 0 + * nsecs : 0 + */ + + private int secs = 0; + private int nsecs = 0; + + public int getSecs() { + return secs; + } + + public int getNsecs() { + return nsecs; + } + } + } + + public static class GoalBean { + /** + * target_pose : {"header":{"seq":0,"stamp":{"secs":0,"nsecs":0},"frame_id":"map"},"pose":{"position":{"z":2.96803E-4,"x":-5.56034,"y":0.543951},"orientation":{"z":-0.688561,"x":0.00455891,"w":0.72508,"y":0.0110448}}} + */ + + private TargetPoseBean target_pose; + + public TargetPoseBean getTarget_pose() { + return target_pose; + } + + public void setTarget_pose(TargetPoseBean target_pose) { + this.target_pose = target_pose; + } + + public static class TargetPoseBean { + /** + * header : {"seq":0,"stamp":{"secs":0,"nsecs":0},"frame_id":"map"} + * pose : {"position":{"z":2.96803E-4,"x":-5.56034,"y":0.543951},"orientation":{"z":-0.688561,"x":0.00455891,"w":0.72508,"y":0.0110448}} + */ + + private HeaderBeanX header; + private PoseBean pose; + + public HeaderBeanX getHeader() { + return header; + } + + public void setHeader(HeaderBeanX header) { + this.header = header; + } + + public PoseBean getPose() { + return pose; + } + + public void setPose(PoseBean pose) { + this.pose = pose; + } + + public static class HeaderBeanX { + /** + * seq : 0 + * stamp : {"secs":0,"nsecs":0} + * frame_id : map + */ + + private int seq = 0; + private StampBeanXX stamp; + private String frame_id = "map"; + + public int getSeq() { + return seq; + } + + public StampBeanXX getStamp() { + return stamp; + } + + public void setStamp(StampBeanXX stamp) { + this.stamp = stamp; + } + + public String getFrame_id() { + return frame_id; + } + + public static class StampBeanXX { + /** + * secs : 0 + * nsecs : 0 + */ + + private int secs = 0; + private int nsecs = 0; + + public int getSecs() { + return secs; + } + + public int getNsecs() { + return nsecs; + } + } + } + + public static class PoseBean { + /** + * position : {"z":2.96803E-4,"x":-5.56034,"y":0.543951} + * orientation : {"z":-0.688561,"x":0.00455891,"w":0.72508,"y":0.0110448} + */ + + private PositionBean position; + private OrientationBean orientation; + + public PositionBean getPosition() { + return position; + } + + public void setPosition(PositionBean position) { + this.position = position; + } + + public OrientationBean getOrientation() { + return orientation; + } + + public void setOrientation(OrientationBean orientation) { + this.orientation = orientation; + } + + public static class PositionBean { + /** + * z : 2.96803E-4 + * x : -5.56034 + * y : 0.543951 + */ + + private double z; + private double x; + private double y; + + public double getZ() { + return z; + } + + public void setZ(double z) { + this.z = z; + } + + public double getX() { + return x; + } + + public void setX(double x) { + this.x = x; + } + + public double getY() { + return y; + } + + public void setY(double y) { + this.y = y; + } + } + + public static class OrientationBean { + /** + * z : -0.688561 + * x : 0.00455891 + * w : 0.72508 + * y : 0.0110448 + */ + + private double z; + private double x; + private double w; + private double y; + + public double getZ() { + return z; + } + + public void setZ(double z) { + this.z = z; + } + + public double getX() { + return x; + } + + public void setX(double x) { + this.x = x; + } + + public double getW() { + return w; + } + + public void setW(double w) { + this.w = w; + } + + public double getY() { + return y; + } + + public void setY(double y) { + this.y = y; + } + } + } + } + } + } + +// { +// "op": "publish", +// "topic": "/move_base/goal", +// "msg": { +// "header": { +// "seq": 0, +// "stamp": { +// "secs": 0, +// "nsecs": 0 +// }, +// "frame_id": "map" +// }, +// "goal_id": { +// "stamp": { +// "secs": 0, +// "nsecs": 0 +// }, +// "id": "map_6_A_601" +// }, +// "goal": { +// "target_pose": { +// "header": { +// "seq": 0, +// "stamp": { +// "secs": 0, +// "nsecs": 0 +// }, +// "frame_id": "map" +// }, +// "pose": { +// "position": { +// "z": 0.000296803, +// "x": -5.56034, +// "y": 0.543951 +// }, +// "orientation": { +// "z": -0.688561, +// "x": 0.00455891, +// "w": 0.72508, +// "y": 0.0110448 +// } +// } +// } +// } +// } +// } +} \ No newline at end of file diff --git a/src/Logistics/app/src/main/java/com/jilk/ros/net/NetBroadcastReceiver.java b/src/Logistics/app/src/main/java/com/jilk/ros/net/NetBroadcastReceiver.java new file mode 100644 index 0000000..49c1bad --- /dev/null +++ b/src/Logistics/app/src/main/java/com/jilk/ros/net/NetBroadcastReceiver.java @@ -0,0 +1,22 @@ +package com.jilk.ros.net; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.net.ConnectivityManager; + + +/** + * Created by Administrator on 2017/5/22 0022. + */ + +public class NetBroadcastReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + // TODO Auto-generated method stub + // 如果相等的话就说明网络状态发生了变化 + if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) { + int netWorkState = NetUtil.getNetWorkState(context); + } + } +} diff --git a/src/Logistics/app/src/main/java/com/jilk/ros/net/NetUtil.java b/src/Logistics/app/src/main/java/com/jilk/ros/net/NetUtil.java new file mode 100644 index 0000000..7878ee7 --- /dev/null +++ b/src/Logistics/app/src/main/java/com/jilk/ros/net/NetUtil.java @@ -0,0 +1,49 @@ +package com.jilk.ros.net; + +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; + +/** + * Created by Administrator on 2017/5/22 0022. + */ + +public class NetUtil { + + /** + * 没有连接网络 + */ + private static final int NETWORK_NONE = -1; + /** + * 移动网络 + */ + private static final int NETWORK_MOBILE = 0; + /** + * 无线网络 + */ + private static final int NETWORK_WIFI = 1; + + public static int getNetWorkState(Context context) { + // 得到连接管理器对象 + ConnectivityManager connectivityManager = (ConnectivityManager) context + .getSystemService(Context.CONNECTIVITY_SERVICE); + + NetworkInfo activeNetworkInfo = connectivityManager + .getActiveNetworkInfo(); + if (activeNetworkInfo != null && activeNetworkInfo.isConnected()) { + + if (activeNetworkInfo.getType() == (ConnectivityManager.TYPE_WIFI)) { + return NETWORK_WIFI; + } else if (activeNetworkInfo.getType() == (ConnectivityManager.TYPE_MOBILE)) { + return NETWORK_MOBILE; + } + } else { + return NETWORK_NONE; + } + return NETWORK_NONE; + } +} + + + + diff --git a/src/Logistics/app/src/main/java/com/jilk/ros/net/POI.java b/src/Logistics/app/src/main/java/com/jilk/ros/net/POI.java new file mode 100644 index 0000000..0c06448 --- /dev/null +++ b/src/Logistics/app/src/main/java/com/jilk/ros/net/POI.java @@ -0,0 +1,1846 @@ +package com.jilk.ros.net; + +import java.util.List; + +/** + * Created by super_yu on 2017/7/13. + */ + +public class POI { + + + /** + * status : 1 + * searchOpt : {"city":"430100","pageSize":"20","pageIndex":"1","ac":"false","keyword":"宠物店","type":"4"} + * data : {"codepoint":0,"code":"1","suggestion":{},"timestamp":"1499941100.95","lqii":{"cache_directive":{"cache_filter":{"flag":"1","expires":"24"},"cache_all":{"flag":"0"}},"query_intent":{"cate_list":"","type":"1000","cate":"06","cate_ext":""},"classify_range":{"district_adcode":"430100","subway_adcode":"430100","nearby_enable":"1","subway_enable":"1","district_enable":"1"},"general_flag":"","specialclassify":"","view_region":"113.029599800,28.194115900,113.123658200,28.181505100","suggestcontent":"","pdheatmap":"","render_name_flag":"1","is_current_city":"2","expand_range_tip":"","suggest_query":{"data":[],"col":"","row":""},"change_query_tip":"","is_tupu_sug":"0","has_recommend":"0","brand_intent":{"t_tag":"","flag":"0","cate":"","name":""},"suggestionview":"1","change_query_type":"","business":"","car_icon_flag":"0","slayer_type":"none","show_pic":"","is_view_city":"1","querytype":"5","self_navigation":"","showaoi":"","utd_sceneid":"1000","distance_info":"","slayer":"1","target_view_city":"","call_taxi":"0","preload_next_page":"1","magic_box":{},"activity":{"new_year":{"flag":"0","tip":""}}},"general_flag":"1","result":"true","keywords":"","message":"Successful.","total":"172","bus_list":[],"is_general_search":"1","bounds":"113.037438;28.182556;113.115820;28.193065","version":"2.0-3.0.7191.1745","busline_count":"0","magicbox_data":{},"interior_count":"0","poi_list":[{"rating":"","tel":"15873110896","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.085508","address":"湖南农业大学农大路东湖小区9栋1号门面","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFF00687","name":"宠物森林宠物店","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/2e1f07ad78ffb766518e2ab25bfe3373","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"宠物森林宠物店","cpdata":"","latitude":"28.186454","discount_flag":"0"},{"rating":"","tel":"","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.109596","address":"榔梨镇新建路22号","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFGHFNA0","name":"欧瑞名门","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430121","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"欧瑞名门","cpdata":"","latitude":"28.183838","discount_flag":"0"},{"rating":"","tel":"0731-86805055;15974202555","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.115820","address":"新建路与梨江路交叉口东南50米","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFGHT7GH","name":"千禧花艺","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430121","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/471be64496d71b9e10aed5ce69103c9b","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"千禧花艺","cpdata":"","latitude":"28.182556","discount_flag":"0"},{"rating":"5","tel":"15675234442","typecode":"061211|060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.045410","address":"长房白沙湾小区a3栋06门店(婚庆公园旁)","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFGBIR3N","name":"灵宠之家","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/563c1dfea3109280d0010c5f","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"061211|060502","disp_name":"灵宠之家","cpdata":"","latitude":"28.193065","discount_flag":"0"},{"rating":"","tel":"0731-82329304;13875869939","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.038326","address":"古曲中路扬帆小区E5栋内","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFFQ7CG9","name":"迦南水族超市","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/37764947dd81c37cd017b6422b632967","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"迦南水族超市","cpdata":"","latitude":"28.189954","discount_flag":"0"},{"rating":"","tel":"0731-88278798;15074947900","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.038223","address":"扬帆市场E10栋1-2号","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFG2UX3F","name":"温鑫水族馆","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/8232b213b2ff6b7b52e8e3fa36a97666","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"温鑫水族馆","cpdata":"","latitude":"28.189884","discount_flag":"0"},{"rating":"3.0","tel":"","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037902","address":"古曲中路与荷花路交叉口西南150米","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFG2UX4P","name":"可丽爱水族(湖南总店)","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/d1f2baab493a8ec2f01f2c329487e6a2","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"可丽爱水族(湖南总店)","cpdata":"","latitude":"28.190558","discount_flag":"0"},{"rating":"","tel":"15802669660","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037923","address":"杨帆小区e4栋11号","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFFQ7E8W","name":"创艺水族(湖南总店)","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/788c5ee41bd2cfcc53d3ff7fa07d564b","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"创艺水族(湖南总店)","cpdata":"","latitude":"28.189849","discount_flag":"0"},{"rating":"","tel":"15084955766;18390868815","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037885","address":"荷花路扬帆小区","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFG2UWYY","name":"湘阳水族","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/bec96cc64c4b0fde273c9a6e395c518a","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"湘阳水族","cpdata":"","latitude":"28.189848","discount_flag":"0"},{"rating":"","tel":"","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037919","address":"金苹果扬帆市场E9栋10号","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFGA45UF","name":"水森林鱼艺创意生活馆","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/97189fa8fb836455e7ded28de1539433","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"水森林鱼艺创意生活馆","cpdata":"","latitude":"28.189610","discount_flag":"0"},{"rating":"","tel":"","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037857","address":"荷花路610号附近","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFH6KQS1","name":"可丽爱水族生活馆(扬帆店)","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/b856f2fddb6e2deb804e4a1cd6fca8d1","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"可丽爱水族生活馆(扬帆店)","cpdata":"","latitude":"28.189846","discount_flag":"0"},{"rating":"3.5","tel":"0731-85148699","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037834","address":"金苹果扬帆大市场E4栋-8号","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFFQ7BSC","name":"闽江水族(扬帆小区西)","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/2709f078b19d94f477265468fb068360","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"闽江水族(扬帆小区西)","cpdata":"","latitude":"28.189847","discount_flag":"0"},{"rating":"5","tel":"13974840573","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037804","address":"古曲中路扬帆小区E-4栋7号门面","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFH6KR5O","name":"方哥金鱼锦鲤批发中心","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/47a9f7f0e6caa0838a69dc77ef793afb","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"方哥金鱼锦鲤批发中心","cpdata":"","latitude":"28.189846","discount_flag":"0"},{"rating":"","tel":"0731-85576062","typecode":"061211","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037806","address":"扬帆小区E9栋8号","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFH86O0U","name":"威顺宠物水族用品批发店","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/b74946382ffc6ecf313f81e2e8522a6a","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"061211","disp_name":"威顺宠物水族用品批发店","cpdata":"","latitude":"28.189609","discount_flag":"0"},{"rating":"","tel":"0731-82562071;13787262098","typecode":"060502|060501","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037641","address":"扬帆小区E4栋6号","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFFQ7E92","name":"利钧花鸟批发专店","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/7dbed3b70bc0332d6f19d3ef37e80d07","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502|060501","disp_name":"利钧花鸟批发专店","cpdata":"","latitude":"28.189937","discount_flag":"0"},{"rating":"","tel":"0731-84420870;13973114985","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037655","address":"金苹果扬帆大市场E4栋-4号","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFGAAZEQ","name":"名仕水族批发(总店)","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/6bcf6364f0086cc694d13d5d5d7017fc","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"名仕水族批发(总店)","cpdata":"","latitude":"28.189842","discount_flag":"0"},{"rating":"","tel":"13973009116","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037578","address":"荷花路610号附近","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFH6KQRH","name":"旺家美花卉水族馆","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/01a7ef414b06cbdac43dbef16d59f7cc","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"旺家美花卉水族馆","cpdata":"","latitude":"28.189843","discount_flag":"0"},{"rating":"","tel":"","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037592","address":"扬帆小区E9栋-5号","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFH6KR4P","name":"阿梅水族批发","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/9bb0da87b7aa80957eadd4c8310d0d56","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"阿梅水族批发","cpdata":"","latitude":"28.189712","discount_flag":"0"},{"rating":"","tel":"13170481820;13170488159","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037574","address":"东屯渡街道扬帆小区E9栋","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFG9YMUY","name":"宋氏水族馆","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/42a6659559e338f553f3d9d822aac298","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"宋氏水族馆","cpdata":"","latitude":"28.189604","discount_flag":"0"},{"rating":"","tel":"18302079703","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037438","address":"扬帆小区e4栋2号","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFG9WXV5","name":"聚友轩水族馆","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/a90f112b20c9dbf3e8627d434232e326","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"聚友轩水族馆","cpdata":"","latitude":"28.189846","discount_flag":"0"}],"classify":[{"checkedvalue":"filter_keywords=宠物市场","category":[{"alias":"","multiselect":"","name":"全部分类","value":"category=0601|061000|061001|0603|0606|0607|0605|060800|0613","display":""},{"alias":"","multiselect":"","name":"超市","value":"filter_keywords=超市","display":""},{"category":[{"alias":"","name":"全部","value":"category=060101|060103"},{"alias":"","name":"购物中心","value":"filter_keywords=购物中心"},{"alias":"","name":"免税品店","value":"category=060103"}],"alias":"","multiselect":"","name":"综合商场","display":""},{"category":[{"alias":"","name":"全部","value":"category=061000|061001"},{"alias":"","name":"特色商业街","value":"category=061000"},{"alias":"","name":"步行街","value":"filter_keywords=步行街"}],"alias":"","multiselect":"","name":"商业街","display":""},{"category":[{"alias":"","name":"全部","value":"filter_keywords=家电卖场"},{"alias":"","name":"家电电子卖场","value":"category=060300"},{"alias":"","name":"综合家电商场","value":"filter_keywords=综合家电"},{"alias":"","name":"国美","value":"category=060302"},{"alias":"","name":"大中","value":"filter_keywords=大中电器"},{"alias":"","name":"苏宁","value":"category=060304"},{"alias":"","name":"手机销售","value":"filter_keywords=手机销售"},{"alias":"","name":"数码电子","value":"filter_keywords=数码电子"}],"alias":"","multiselect":"","name":"家电","display":""},{"category":[{"alias":"","name":"全部","value":"filter_keywords=家具建材"},{"alias":"","name":"家具建材市场","value":"category=060601"},{"alias":"","name":"家具城","value":"filter_keywords=家具城"},{"alias":"","name":"建材五金市场","value":"filter_keywords=建材五金市场"},{"alias":"","name":"厨卫市场","value":"category=060604"},{"alias":"","name":"布艺市场","value":"category=060605"},{"alias":"","name":"灯具瓷器市场","value":"category=060606"}],"alias":"","multiselect":"","name":"家具建材","display":""},{"category":[{"alias":"","name":"全部","value":"filter_keywords=综合市场"},{"alias":"","name":"小商品市场","value":"filter_keywords=小商品批发市场"},{"alias":"","name":"旧货市场","value":"category=060702"},{"alias":"","name":"农副产品市场","value":"filter_keywords=农产品批发市场"},{"alias":"","name":"果品市场","value":"filter_keywords=果品批发市场"},{"alias":"","name":"蔬菜市场","value":"filter_keywords=蔬菜市场"},{"alias":"","name":"水产海鲜市场","value":"filter_keywords=水产海鲜市场"}],"alias":"","multiselect":"","name":"综合市场","display":""},{"alias":"","multiselect":"","name":"文化用品店","value":"filter_keywords=文化办公用品","display":""},{"category":[{"alias":"","name":"全部","value":"category=060500|060501|060502"},{"alias":"","name":"花鸟鱼虫市场","value":"filter_keywords=花鸟市场"},{"alias":"","name":"花卉市场","value":"filter_keywords=花卉市场"},{"alias":"","name":"宠物市场","value":"filter_keywords=宠物市场"}],"alias":"","multiselect":"","name":"花鸟市场","display":""},{"category":[{"alias":"","name":"全部","value":"category=061301|061302"},{"alias":"","name":"拍卖行","value":"category=061301"},{"alias":"","name":"典当行","value":"category=061302"}],"alias":"","multiselect":"","name":"买卖场所","display":""}],"name":"全部分类","ctype":"category","flag":2},{"checkedvalue":"sort_rule=0;reserved_keywords=true","category":[{"name":"推荐排序","value":"sort_rule=0;reserved_keywords=true"},{"name":"距离优先","value":"sort_rule=1;reserved_keywords=true"},{"name":"好评优先","value":"sort_rule=5;sort_fields=rating:d;reserved_keywords=true"},{"name":"低价优先","value":"sort_rule=5;sort_fields=averagecost:a0;reserved_keywords=true"},{"name":"高价优先","value":"sort_rule=5;sort_fields=averagecost:d;reserved_keywords=true"}],"name":"排序","ctype":"filter"}],"busline_list":[]} + * SPQ : true + * isSPQ : false + * classify : {"classify_type":{"checkedvalue":"filter_keywords=宠物市场","category":[{"alias":"","multiselect":"","name":"全部分类","value":"category=0601|061000|061001|0603|0606|0607|0605|060800|0613","display":""},{"alias":"","multiselect":"","name":"超市","value":"filter_keywords=超市","display":""},{"category":[{"alias":"","name":"全部","value":"category=060101|060103"},{"alias":"","name":"购物中心","value":"filter_keywords=购物中心"},{"alias":"","name":"免税品店","value":"category=060103"}],"alias":"","multiselect":"","name":"综合商场","display":""},{"category":[{"alias":"","name":"全部","value":"category=061000|061001"},{"alias":"","name":"特色商业街","value":"category=061000"},{"alias":"","name":"步行街","value":"filter_keywords=步行街"}],"alias":"","multiselect":"","name":"商业街","display":""},{"category":[{"alias":"","name":"全部","value":"filter_keywords=家电卖场"},{"alias":"","name":"家电电子卖场","value":"category=060300"},{"alias":"","name":"综合家电商场","value":"filter_keywords=综合家电"},{"alias":"","name":"国美","value":"category=060302"},{"alias":"","name":"大中","value":"filter_keywords=大中电器"},{"alias":"","name":"苏宁","value":"category=060304"},{"alias":"","name":"手机销售","value":"filter_keywords=手机销售"},{"alias":"","name":"数码电子","value":"filter_keywords=数码电子"}],"alias":"","multiselect":"","name":"家电","display":""},{"category":[{"alias":"","name":"全部","value":"filter_keywords=家具建材"},{"alias":"","name":"家具建材市场","value":"category=060601"},{"alias":"","name":"家具城","value":"filter_keywords=家具城"},{"alias":"","name":"建材五金市场","value":"filter_keywords=建材五金市场"},{"alias":"","name":"厨卫市场","value":"category=060604"},{"alias":"","name":"布艺市场","value":"category=060605"},{"alias":"","name":"灯具瓷器市场","value":"category=060606"}],"alias":"","multiselect":"","name":"家具建材","display":""},{"category":[{"alias":"","name":"全部","value":"filter_keywords=综合市场"},{"alias":"","name":"小商品市场","value":"filter_keywords=小商品批发市场"},{"alias":"","name":"旧货市场","value":"category=060702"},{"alias":"","name":"农副产品市场","value":"filter_keywords=农产品批发市场"},{"alias":"","name":"果品市场","value":"filter_keywords=果品批发市场"},{"alias":"","name":"蔬菜市场","value":"filter_keywords=蔬菜市场"},{"alias":"","name":"水产海鲜市场","value":"filter_keywords=水产海鲜市场"}],"alias":"","multiselect":"","name":"综合市场","display":""},{"alias":"","multiselect":"","name":"文化用品店","value":"filter_keywords=文化办公用品","display":""},{"category":[{"alias":"","name":"全部","value":"category=060500|060501|060502"},{"alias":"","name":"花鸟鱼虫市场","value":"filter_keywords=花鸟市场"},{"alias":"","name":"花卉市场","value":"filter_keywords=花卉市场"},{"alias":"","name":"宠物市场","value":"filter_keywords=宠物市场"}],"alias":"","multiselect":"","name":"花鸟市场","display":""},{"category":[{"alias":"","name":"全部","value":"category=061301|061302"},{"alias":"","name":"拍卖行","value":"category=061301"},{"alias":"","name":"典当行","value":"category=061302"}],"alias":"","multiselect":"","name":"买卖场所","display":""}],"name":"全部分类","ctype":"category","flag":2},"classify_sort":{"checkedvalue":"sort_rule=0;reserved_keywords=true","category":[{"name":"推荐排序","value":"sort_rule=0;reserved_keywords=true"},{"name":"距离优先","value":"sort_rule=1;reserved_keywords=true"},{"name":"好评优先","value":"sort_rule=5;sort_fields=rating:d;reserved_keywords=true"},{"name":"低价优先","value":"sort_rule=5;sort_fields=averagecost:a0;reserved_keywords=true"},{"name":"高价优先","value":"sort_rule=5;sort_fields=averagecost:d;reserved_keywords=true"}],"name":"排序","ctype":"filter"},"count":2} + * bizAreaData : {"citycode":"0731","adcode":"430100","name":"长沙市","center":"112.982279,28.19409","level":"city","districts":[{"citycode":"0731","adcode":"430102","name":"芙蓉区","center":"112.988094,28.193106","level":"district","districts":[{"citycode":"0731","adcode":"430102","name":"德政园","center":"113.022609,28.186145","level":"biz_area","areacode":"19749","districts":[]},{"citycode":"0731","adcode":"430102","name":"定王台","center":"112.985227,28.190025","level":"biz_area","areacode":"19750","districts":[]},{"citycode":"0731","adcode":"430102","name":"黄兴路","center":"112.976687,28.190437","level":"biz_area","areacode":"19751","districts":[]},{"citycode":"0731","adcode":"430102","name":"韭菜园","center":"112.988766,28.194756","level":"biz_area","areacode":"19752","districts":[]},{"citycode":"0731","adcode":"430102","name":"马王堆","center":"113.028870,28.195465","level":"biz_area","areacode":"19753","districts":[]},{"citycode":"0731","adcode":"430102","name":"五里牌","center":"113.011699,28.198328","level":"biz_area","areacode":"19754","districts":[]},{"citycode":"0731","adcode":"430102","name":"湘湖","center":"113.012682,28.205252","level":"biz_area","areacode":"19755","districts":[]},{"citycode":"0731","adcode":"430102","name":"袁家岭","center":"112.997033,28.194455","level":"biz_area","areacode":"19756","districts":[]},{"citycode":"0731","adcode":"430102","name":"八一路","center":"113.000355,28.197485","level":"biz_area","areacode":"19757","districts":[]},{"citycode":"0731","adcode":"430102","name":"朝阳路","center":"113.007038,28.189212","level":"biz_area","areacode":"19758","districts":[]},{"citycode":"0731","adcode":"430102","name":"东屯渡","center":"113.038626,28.194082","level":"biz_area","areacode":"19759","districts":[]},{"citycode":"0731","adcode":"430102","name":"芙蓉广场","center":"112.995054,28.197940","level":"biz_area","areacode":"19760","districts":[]},{"citycode":"0731","adcode":"430102","name":"芙蓉中路","center":"112.986125,28.187681","level":"biz_area","areacode":"19761","districts":[]},{"citycode":"0731","adcode":"430102","name":"荷花路","center":"113.032740,28.191378","level":"biz_area","areacode":"19762","districts":[]},{"citycode":"0731","adcode":"430102","name":"荷花园","center":"113.021219,28.191605","level":"biz_area","areacode":"19763","districts":[]},{"citycode":"0731","adcode":"430102","name":"火星","center":"113.023431,28.202349","level":"biz_area","areacode":"19764","districts":[]},{"citycode":"0731","adcode":"430102","name":"凌霄路","center":"113.029080,28.202090","level":"biz_area","areacode":"19765","districts":[]},{"citycode":"0731","adcode":"430102","name":"浏正街","center":"112.984803,28.191896","level":"biz_area","areacode":"19766","districts":[]},{"citycode":"0731","adcode":"430102","name":"三湘大市场","center":"113.016648,28.202302","level":"biz_area","areacode":"19768","districts":[]},{"citycode":"0731","adcode":"430102","name":"万家丽","center":"113.030236,28.185394","level":"biz_area","areacode":"19770","districts":[]},{"citycode":"0731","adcode":"430102","name":"文艺路","center":"112.994009,28.191407","level":"biz_area","areacode":"19771","districts":[]},{"citycode":"0731","adcode":"430102","name":"五一大道","center":"112.988446,28.194898","level":"biz_area","areacode":"19772","districts":[]},{"citycode":"0731","adcode":"430102","name":"燕山街","center":"113.000486,28.196539","level":"biz_area","areacode":"19773","districts":[]},{"citycode":"0731","adcode":"430102","name":"远大路","center":"113.027617,28.198384","level":"biz_area","areacode":"19774","districts":[]},{"citycode":"0731","adcode":"430102","name":"中山路","center":"112.979051,28.199921","level":"biz_area","areacode":"19775","districts":[]},{"citycode":"0731","adcode":"430102","name":"车站中路","center":"113.010938,28.193068","level":"biz_area","areacode":"19776","districts":[]},{"citycode":"0731","adcode":"430102","name":"芙蓉区政府","center":"113.003653,28.194434","level":"biz_area","areacode":"19785","districts":[]},{"citycode":"0731","adcode":"430102","name":"解放东路","center":"113.005201,28.190678","level":"biz_area","areacode":"19792","districts":[]},{"citycode":"0731","adcode":"430102","name":"解放西路","center":"112.979381,28.191326","level":"biz_area","areacode":"19813","districts":[]},{"citycode":"0731","adcode":"430102","name":"都正街","center":"112.981833,28.187702","level":"biz_area","areacode":"19814","districts":[]},{"citycode":"0731","adcode":"430102","name":"火车站","center":"113.011203,28.193686","level":"biz_area","areacode":"19830","districts":[]},{"citycode":"0731","adcode":"430102","name":"车站北路","center":"113.009321,28.207354","level":"biz_area","areacode":"19845","districts":[]}]},{"citycode":"0731","adcode":"430103","name":"天心区","center":"112.97307,28.192375","level":"district","districts":[{"citycode":"0731","adcode":"430103","name":"韶山南路","center":"113.000079,28.135185","level":"biz_area","areacode":"19782","districts":[]},{"citycode":"0731","adcode":"430103","name":"城南路","center":"112.983886,28.182259","level":"biz_area","areacode":"19787","districts":[]},{"citycode":"0731","adcode":"430103","name":"劳动西路","center":"112.983972,28.173499","level":"biz_area","areacode":"19797","districts":[]},{"citycode":"0731","adcode":"430103","name":"黄土岭","center":"112.985897,28.161960","level":"biz_area","areacode":"19808","districts":[]},{"citycode":"0731","adcode":"430103","name":"友谊路","center":"112.997239,28.125006","level":"biz_area","areacode":"19809","districts":[]},{"citycode":"0731","adcode":"430103","name":"裕南街","center":"112.972993,28.172404","level":"biz_area","areacode":"19810","districts":[]},{"citycode":"0731","adcode":"430103","name":"芙蓉南路","center":"112.986581,28.132236","level":"biz_area","areacode":"19811","districts":[]},{"citycode":"0731","adcode":"430103","name":"赤岭路","center":"112.979397,28.153046","level":"biz_area","areacode":"19812","districts":[]},{"citycode":"0731","adcode":"430103","name":"芙蓉南路","center":"112.987141,28.124923","level":"biz_area","areacode":"19816","districts":[]},{"citycode":"0731","adcode":"430103","name":"白沙路","center":"112.982195,28.182379","level":"biz_area","areacode":"19818","districts":[]},{"citycode":"0731","adcode":"430103","name":"碧湘街","center":"112.972105,28.182679","level":"biz_area","areacode":"19819","districts":[]},{"citycode":"0731","adcode":"430103","name":"金盆岭","center":"112.977234,28.151578","level":"biz_area","areacode":"19822","districts":[]},{"citycode":"0731","adcode":"430103","name":"南湖路","center":"112.977905,28.165537","level":"biz_area","areacode":"19825","districts":[]},{"citycode":"0731","adcode":"430103","name":"南门口","center":"112.975929,28.183259","level":"biz_area","areacode":"19827","districts":[]},{"citycode":"0731","adcode":"430103","name":"坡子街","center":"112.973189,28.190238","level":"biz_area","areacode":"19828","districts":[]},{"citycode":"0731","adcode":"430103","name":"青园","center":"112.994944,28.128891","level":"biz_area","areacode":"19829","districts":[]},{"citycode":"0731","adcode":"430103","name":"书院路","center":"112.971563,28.175927","level":"biz_area","areacode":"19832","districts":[]},{"citycode":"0731","adcode":"430103","name":"书院南路","center":"112.972190,28.150083","level":"biz_area","areacode":"19833","districts":[]},{"citycode":"0731","adcode":"430103","name":"天心阁","center":"112.981184,28.184664","level":"biz_area","areacode":"19835","districts":[]},{"citycode":"0731","adcode":"430103","name":"西牌楼","center":"112.972712,28.193602","level":"biz_area","areacode":"19837","districts":[]},{"citycode":"0731","adcode":"430103","name":"新开铺","center":"112.970512,28.133102","level":"biz_area","areacode":"19838","districts":[]},{"citycode":"0731","adcode":"430103","name":"铁道学院","center":"112.992682,28.140356","level":"biz_area","areacode":"19839","districts":[]},{"citycode":"0731","adcode":"430103","name":"西湖","center":"112.967188,28.187826","level":"biz_area","areacode":"19879","districts":[]}]},{"citycode":"0731","adcode":"430104","name":"岳麓区","center":"112.911591,28.213044","level":"district","districts":[{"citycode":"0731","adcode":"430104","name":"观沙岭","center":"112.950525,28.235600","level":"biz_area","areacode":"19861","districts":[]},{"citycode":"0731","adcode":"430104","name":"湖南商学院","center":"112.918042,28.219331","level":"biz_area","areacode":"19862","districts":[]},{"citycode":"0731","adcode":"430104","name":"麓谷","center":"112.889410,28.214029","level":"biz_area","areacode":"19863","districts":[]},{"citycode":"0731","adcode":"430104","name":"汽车西站","center":"112.910711,28.209866","level":"biz_area","areacode":"19864","districts":[]},{"citycode":"0731","adcode":"430104","name":"桐梓坡","center":"112.930153,28.218539","level":"biz_area","areacode":"19865","districts":[]},{"citycode":"0731","adcode":"430104","name":"望月湖","center":"112.955265,28.204105","level":"biz_area","areacode":"19866","districts":[]},{"citycode":"0731","adcode":"430104","name":"咸嘉湖","center":"112.930929,28.212604","level":"biz_area","areacode":"19867","districts":[]},{"citycode":"0731","adcode":"430104","name":"岳麓山","center":"112.943829,28.178123","level":"biz_area","areacode":"19868","districts":[]},{"citycode":"0731","adcode":"430104","name":"玉兰路","center":"112.910965,28.214257","level":"biz_area","areacode":"19869","districts":[]},{"citycode":"0731","adcode":"430104","name":"白沙液街","center":"112.952884,28.201147","level":"biz_area","areacode":"19870","districts":[]},{"citycode":"0731","adcode":"430104","name":"枫林一路","center":"112.946030,28.198881","level":"biz_area","areacode":"19871","districts":[]},{"citycode":"0731","adcode":"430104","name":"湖南大学","center":"112.945213,28.177733","level":"biz_area","areacode":"19872","districts":[]},{"citycode":"0731","adcode":"430104","name":"湖南师范大学","center":"112.948495,28.187094","level":"biz_area","areacode":"19873","districts":[]},{"citycode":"0731","adcode":"430104","name":"雷锋大道","center":"112.899515,28.237511","level":"biz_area","areacode":"19874","districts":[]},{"citycode":"0731","adcode":"430104","name":"麓山路","center":"112.949074,28.189117","level":"biz_area","areacode":"19875","districts":[]},{"citycode":"0731","adcode":"430104","name":"桐梓坡路","center":"112.934137,28.218532","level":"biz_area","areacode":"19876","districts":[]},{"citycode":"0731","adcode":"430104","name":"望城坡","center":"112.912119,28.213111","level":"biz_area","areacode":"19877","districts":[]},{"citycode":"0731","adcode":"430104","name":"望岳","center":"112.922311,28.221183","level":"biz_area","areacode":"19878","districts":[]},{"citycode":"0731","adcode":"430104","name":"咸嘉新村","center":"112.927504,28.220168","level":"biz_area","areacode":"19880","districts":[]},{"citycode":"0731","adcode":"430104","name":"新民路","center":"112.953168,28.192306","level":"biz_area","areacode":"19881","districts":[]},{"citycode":"0731","adcode":"430104","name":"银盆岭","center":"112.953686,28.222394","level":"biz_area","areacode":"19882","districts":[]},{"citycode":"0731","adcode":"430104","name":"中南大学","center":"112.933330,28.163911","level":"biz_area","areacode":"19883","districts":[]}]},{"citycode":"0731","adcode":"430105","name":"开福区","center":"112.985525,28.201336","level":"district","districts":[{"citycode":"0731","adcode":"430105","name":"五一广场","center":"112.976276,28.195472","level":"biz_area","areacode":"19840","districts":[]},{"citycode":"0731","adcode":"430105","name":"四方坪","center":"113.010379,28.235254","level":"biz_area","areacode":"19841","districts":[]},{"citycode":"0731","adcode":"430105","name":"伍家岭","center":"112.989085,28.229513","level":"biz_area","areacode":"19842","districts":[]},{"citycode":"0731","adcode":"430105","name":"湘雅医院","center":"112.970288,28.208441","level":"biz_area","areacode":"19843","districts":[]},{"citycode":"0731","adcode":"430105","name":"营盘路","center":"112.980982,28.204196","level":"biz_area","areacode":"19844","districts":[]},{"citycode":"0731","adcode":"430105","name":"芙蓉北路","center":"112.984343,28.253526","level":"biz_area","areacode":"19846","districts":[]},{"citycode":"0731","adcode":"430105","name":"北正街","center":"112.976591,28.206011","level":"biz_area","areacode":"19847","districts":[]},{"citycode":"0731","adcode":"430105","name":"蔡锷北路","center":"112.981659,28.206246","level":"biz_area","areacode":"19848","districts":[]},{"citycode":"0731","adcode":"430105","name":"德雅路","center":"113.004718,28.222866","level":"biz_area","areacode":"19849","districts":[]},{"citycode":"0731","adcode":"430105","name":"东风路","center":"112.992763,28.217975","level":"biz_area","areacode":"19850","districts":[]},{"citycode":"0731","adcode":"430105","name":"华夏路","center":"112.982770,28.224978","level":"biz_area","areacode":"19851","districts":[]},{"citycode":"0731","adcode":"430105","name":"开福寺","center":"112.980862,28.223230","level":"biz_area","areacode":"19852","districts":[]},{"citycode":"0731","adcode":"430105","name":"科大佳园","center":"113.003668,28.236008","level":"biz_area","areacode":"19853","districts":[]},{"citycode":"0731","adcode":"430105","name":"麻园岭","center":"112.984825,28.215030","level":"biz_area","areacode":"19854","districts":[]},{"citycode":"0731","adcode":"430105","name":"清水塘","center":"112.988751,28.200502","level":"biz_area","areacode":"19855","districts":[]},{"citycode":"0731","adcode":"430105","name":"三一大道","center":"113.005297,28.231043","level":"biz_area","areacode":"19856","districts":[]},{"citycode":"0731","adcode":"430105","name":"通泰街","center":"112.974645,28.206132","level":"biz_area","areacode":"19857","districts":[]},{"citycode":"0731","adcode":"430105","name":"湘江中路","center":"112.972143,28.203561","level":"biz_area","areacode":"19858","districts":[]},{"citycode":"0731","adcode":"430105","name":"湘雅路","center":"112.979935,28.213924","level":"biz_area","areacode":"19859","districts":[]},{"citycode":"0731","adcode":"430105","name":"新河","center":"112.982264,28.227548","level":"biz_area","areacode":"19860","districts":[]}]},{"citycode":"0731","adcode":"430111","name":"雨花区","center":"113.016337,28.109937","level":"district","districts":[{"citycode":"0731","adcode":"430111","name":"人民中路","center":"113.001047,28.185355","level":"biz_area","areacode":"19767","districts":[]},{"citycode":"0731","adcode":"430111","name":"曙光路","center":"113.001969,28.179694","level":"biz_area","areacode":"19769","districts":[]},{"citycode":"0731","adcode":"430111","name":"窑岭","center":"112.998484,28.185167","level":"biz_area","areacode":"19777","districts":[]},{"citycode":"0731","adcode":"430111","name":"茶园坡","center":"113.008657,28.159707","level":"biz_area","areacode":"19778","districts":[]},{"citycode":"0731","adcode":"430111","name":"东塘","center":"112.994720,28.168757","level":"biz_area","areacode":"19779","districts":[]},{"citycode":"0731","adcode":"430111","name":"高桥","center":"113.022508,28.172998","level":"biz_area","areacode":"19780","districts":[]},{"citycode":"0731","adcode":"430111","name":"砂子塘","center":"112.997399,28.161249","level":"biz_area","areacode":"19781","districts":[]},{"citycode":"0731","adcode":"430111","name":"雨花亭","center":"112.997573,28.150595","level":"biz_area","areacode":"19783","districts":[]},{"citycode":"0731","adcode":"430111","name":"左家塘","center":"113.003294,28.176401","level":"biz_area","areacode":"19784","districts":[]},{"citycode":"0731","adcode":"430111","name":"小林子冲","center":"112.988135,28.177010","level":"biz_area","areacode":"19786","districts":[]},{"citycode":"0731","adcode":"430111","name":"阿弥岭","center":"113.006469,28.172421","level":"biz_area","areacode":"19788","districts":[]},{"citycode":"0731","adcode":"430111","name":"圭塘","center":"113.033391,28.139720","level":"biz_area","areacode":"19794","districts":[]},{"citycode":"0731","adcode":"430111","name":"红花坡","center":"113.005448,28.165878","level":"biz_area","areacode":"19795","districts":[]},{"citycode":"0731","adcode":"430111","name":"井湾子","center":"113.009767,28.124386","level":"biz_area","areacode":"19796","districts":[]},{"citycode":"0731","adcode":"430111","name":"劳动中路","center":"113.002097,28.163422","level":"biz_area","areacode":"19798","districts":[]},{"citycode":"0731","adcode":"430111","name":"曲塘","center":"113.032987,28.148308","level":"biz_area","areacode":"19799","districts":[]},{"citycode":"0731","adcode":"430111","name":"韶山中路","center":"112.994247,28.158138","level":"biz_area","areacode":"19800","districts":[]},{"citycode":"0731","adcode":"430111","name":"树木岭","center":"113.022365,28.150991","level":"biz_area","areacode":"19801","districts":[]},{"citycode":"0731","adcode":"430111","name":"王家冲","center":"113.001659,28.152828","level":"biz_area","areacode":"19802","districts":[]},{"citycode":"0731","adcode":"430111","name":"香樟路","center":"113.012409,28.136391","level":"biz_area","areacode":"19803","districts":[]},{"citycode":"0731","adcode":"430111","name":"雨花区政府","center":"113.018871,28.146627","level":"biz_area","areacode":"19804","districts":[]},{"citycode":"0731","adcode":"430111","name":"植物园","center":"113.019004,28.103487","level":"biz_area","areacode":"19805","districts":[]},{"citycode":"0731","adcode":"430111","name":"梓园路","center":"112.991337,28.178514","level":"biz_area","areacode":"19806","districts":[]},{"citycode":"0731","adcode":"430111","name":"侯家塘","center":"112.985710,28.173230","level":"biz_area","areacode":"19807","districts":[]}]},{"citycode":"0731","adcode":"430112","name":"望城区","center":"112.819549,28.347458","level":"district","districts":[]},{"citycode":"0731","adcode":"430121","name":"长沙县","center":"113.080098,28.237888","level":"district","districts":[]},{"citycode":"0731","adcode":"430124","name":"宁乡县","center":"112.553182,28.253928","level":"district","districts":[]},{"citycode":"0731","adcode":"430181","name":"浏阳市","center":"113.633301,28.141112","level":"district","districts":[]}],"checkedvalue":"query_type=TQUERY"} + * classifyFlag : true + */ + + private String status; + /** + * city : 430100 + * pageSize : 20 + * pageIndex : 1 + * ac : false + * keyword : 宠物店 + * type : 4 + */ + + private SearchOptBean searchOpt; + /** + * codepoint : 0 + * code : 1 + * suggestion : {} + * timestamp : 1499941100.95 + * lqii : {"cache_directive":{"cache_filter":{"flag":"1","expires":"24"},"cache_all":{"flag":"0"}},"query_intent":{"cate_list":"","type":"1000","cate":"06","cate_ext":""},"classify_range":{"district_adcode":"430100","subway_adcode":"430100","nearby_enable":"1","subway_enable":"1","district_enable":"1"},"general_flag":"","specialclassify":"","view_region":"113.029599800,28.194115900,113.123658200,28.181505100","suggestcontent":"","pdheatmap":"","render_name_flag":"1","is_current_city":"2","expand_range_tip":"","suggest_query":{"data":[],"col":"","row":""},"change_query_tip":"","is_tupu_sug":"0","has_recommend":"0","brand_intent":{"t_tag":"","flag":"0","cate":"","name":""},"suggestionview":"1","change_query_type":"","business":"","car_icon_flag":"0","slayer_type":"none","show_pic":"","is_view_city":"1","querytype":"5","self_navigation":"","showaoi":"","utd_sceneid":"1000","distance_info":"","slayer":"1","target_view_city":"","call_taxi":"0","preload_next_page":"1","magic_box":{},"activity":{"new_year":{"flag":"0","tip":""}}} + * general_flag : 1 + * result : true + * keywords : + * message : Successful. + * total : 172 + * bus_list : [] + * is_general_search : 1 + * bounds : 113.037438;28.182556;113.115820;28.193065 + * version : 2.0-3.0.7191.1745 + * busline_count : 0 + * magicbox_data : {} + * interior_count : 0 + * poi_list : [{"rating":"","tel":"15873110896","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.085508","address":"湖南农业大学农大路东湖小区9栋1号门面","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFF00687","name":"宠物森林宠物店","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/2e1f07ad78ffb766518e2ab25bfe3373","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"宠物森林宠物店","cpdata":"","latitude":"28.186454","discount_flag":"0"},{"rating":"","tel":"","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.109596","address":"榔梨镇新建路22号","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFGHFNA0","name":"欧瑞名门","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430121","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"欧瑞名门","cpdata":"","latitude":"28.183838","discount_flag":"0"},{"rating":"","tel":"0731-86805055;15974202555","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.115820","address":"新建路与梨江路交叉口东南50米","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFGHT7GH","name":"千禧花艺","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430121","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/471be64496d71b9e10aed5ce69103c9b","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"千禧花艺","cpdata":"","latitude":"28.182556","discount_flag":"0"},{"rating":"5","tel":"15675234442","typecode":"061211|060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.045410","address":"长房白沙湾小区a3栋06门店(婚庆公园旁)","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFGBIR3N","name":"灵宠之家","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/563c1dfea3109280d0010c5f","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"061211|060502","disp_name":"灵宠之家","cpdata":"","latitude":"28.193065","discount_flag":"0"},{"rating":"","tel":"0731-82329304;13875869939","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.038326","address":"古曲中路扬帆小区E5栋内","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFFQ7CG9","name":"迦南水族超市","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/37764947dd81c37cd017b6422b632967","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"迦南水族超市","cpdata":"","latitude":"28.189954","discount_flag":"0"},{"rating":"","tel":"0731-88278798;15074947900","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.038223","address":"扬帆市场E10栋1-2号","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFG2UX3F","name":"温鑫水族馆","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/8232b213b2ff6b7b52e8e3fa36a97666","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"温鑫水族馆","cpdata":"","latitude":"28.189884","discount_flag":"0"},{"rating":"3.0","tel":"","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037902","address":"古曲中路与荷花路交叉口西南150米","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFG2UX4P","name":"可丽爱水族(湖南总店)","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/d1f2baab493a8ec2f01f2c329487e6a2","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"可丽爱水族(湖南总店)","cpdata":"","latitude":"28.190558","discount_flag":"0"},{"rating":"","tel":"15802669660","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037923","address":"杨帆小区e4栋11号","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFFQ7E8W","name":"创艺水族(湖南总店)","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/788c5ee41bd2cfcc53d3ff7fa07d564b","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"创艺水族(湖南总店)","cpdata":"","latitude":"28.189849","discount_flag":"0"},{"rating":"","tel":"15084955766;18390868815","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037885","address":"荷花路扬帆小区","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFG2UWYY","name":"湘阳水族","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/bec96cc64c4b0fde273c9a6e395c518a","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"湘阳水族","cpdata":"","latitude":"28.189848","discount_flag":"0"},{"rating":"","tel":"","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037919","address":"金苹果扬帆市场E9栋10号","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFGA45UF","name":"水森林鱼艺创意生活馆","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/97189fa8fb836455e7ded28de1539433","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"水森林鱼艺创意生活馆","cpdata":"","latitude":"28.189610","discount_flag":"0"},{"rating":"","tel":"","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037857","address":"荷花路610号附近","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFH6KQS1","name":"可丽爱水族生活馆(扬帆店)","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/b856f2fddb6e2deb804e4a1cd6fca8d1","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"可丽爱水族生活馆(扬帆店)","cpdata":"","latitude":"28.189846","discount_flag":"0"},{"rating":"3.5","tel":"0731-85148699","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037834","address":"金苹果扬帆大市场E4栋-8号","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFFQ7BSC","name":"闽江水族(扬帆小区西)","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/2709f078b19d94f477265468fb068360","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"闽江水族(扬帆小区西)","cpdata":"","latitude":"28.189847","discount_flag":"0"},{"rating":"5","tel":"13974840573","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037804","address":"古曲中路扬帆小区E-4栋7号门面","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFH6KR5O","name":"方哥金鱼锦鲤批发中心","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/47a9f7f0e6caa0838a69dc77ef793afb","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"方哥金鱼锦鲤批发中心","cpdata":"","latitude":"28.189846","discount_flag":"0"},{"rating":"","tel":"0731-85576062","typecode":"061211","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037806","address":"扬帆小区E9栋8号","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFH86O0U","name":"威顺宠物水族用品批发店","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/b74946382ffc6ecf313f81e2e8522a6a","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"061211","disp_name":"威顺宠物水族用品批发店","cpdata":"","latitude":"28.189609","discount_flag":"0"},{"rating":"","tel":"0731-82562071;13787262098","typecode":"060502|060501","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037641","address":"扬帆小区E4栋6号","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFFQ7E92","name":"利钧花鸟批发专店","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/7dbed3b70bc0332d6f19d3ef37e80d07","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502|060501","disp_name":"利钧花鸟批发专店","cpdata":"","latitude":"28.189937","discount_flag":"0"},{"rating":"","tel":"0731-84420870;13973114985","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037655","address":"金苹果扬帆大市场E4栋-4号","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFGAAZEQ","name":"名仕水族批发(总店)","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/6bcf6364f0086cc694d13d5d5d7017fc","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"名仕水族批发(总店)","cpdata":"","latitude":"28.189842","discount_flag":"0"},{"rating":"","tel":"13973009116","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037578","address":"荷花路610号附近","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFH6KQRH","name":"旺家美花卉水族馆","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/01a7ef414b06cbdac43dbef16d59f7cc","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"旺家美花卉水族馆","cpdata":"","latitude":"28.189843","discount_flag":"0"},{"rating":"","tel":"","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037592","address":"扬帆小区E9栋-5号","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFH6KR4P","name":"阿梅水族批发","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/9bb0da87b7aa80957eadd4c8310d0d56","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"阿梅水族批发","cpdata":"","latitude":"28.189712","discount_flag":"0"},{"rating":"","tel":"13170481820;13170488159","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037574","address":"东屯渡街道扬帆小区E9栋","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFG9YMUY","name":"宋氏水族馆","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/42a6659559e338f553f3d9d822aac298","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"宋氏水族馆","cpdata":"","latitude":"28.189604","discount_flag":"0"},{"rating":"","tel":"18302079703","typecode":"060502","areacode":"0731","cityname":"长沙市","display_brand":"","shape_region":"","longitude":"113.037438","address":"扬帆小区e4栋2号","cinemazuo_flag":"0","diner_flag":"0","id":"B0FFG9WXV5","name":"聚友轩水族馆","group_flag":"0","distance":"0","entrances":[],"recommend_flag":"0","exits":[],"adcode":"430102","domain_list":[{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/a90f112b20c9dbf3e8627d434232e326","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}],"newtype":"060502","disp_name":"聚友轩水族馆","cpdata":"","latitude":"28.189846","discount_flag":"0"}] + * classify : [{"checkedvalue":"filter_keywords=宠物市场","category":[{"alias":"","multiselect":"","name":"全部分类","value":"category=0601|061000|061001|0603|0606|0607|0605|060800|0613","display":""},{"alias":"","multiselect":"","name":"超市","value":"filter_keywords=超市","display":""},{"category":[{"alias":"","name":"全部","value":"category=060101|060103"},{"alias":"","name":"购物中心","value":"filter_keywords=购物中心"},{"alias":"","name":"免税品店","value":"category=060103"}],"alias":"","multiselect":"","name":"综合商场","display":""},{"category":[{"alias":"","name":"全部","value":"category=061000|061001"},{"alias":"","name":"特色商业街","value":"category=061000"},{"alias":"","name":"步行街","value":"filter_keywords=步行街"}],"alias":"","multiselect":"","name":"商业街","display":""},{"category":[{"alias":"","name":"全部","value":"filter_keywords=家电卖场"},{"alias":"","name":"家电电子卖场","value":"category=060300"},{"alias":"","name":"综合家电商场","value":"filter_keywords=综合家电"},{"alias":"","name":"国美","value":"category=060302"},{"alias":"","name":"大中","value":"filter_keywords=大中电器"},{"alias":"","name":"苏宁","value":"category=060304"},{"alias":"","name":"手机销售","value":"filter_keywords=手机销售"},{"alias":"","name":"数码电子","value":"filter_keywords=数码电子"}],"alias":"","multiselect":"","name":"家电","display":""},{"category":[{"alias":"","name":"全部","value":"filter_keywords=家具建材"},{"alias":"","name":"家具建材市场","value":"category=060601"},{"alias":"","name":"家具城","value":"filter_keywords=家具城"},{"alias":"","name":"建材五金市场","value":"filter_keywords=建材五金市场"},{"alias":"","name":"厨卫市场","value":"category=060604"},{"alias":"","name":"布艺市场","value":"category=060605"},{"alias":"","name":"灯具瓷器市场","value":"category=060606"}],"alias":"","multiselect":"","name":"家具建材","display":""},{"category":[{"alias":"","name":"全部","value":"filter_keywords=综合市场"},{"alias":"","name":"小商品市场","value":"filter_keywords=小商品批发市场"},{"alias":"","name":"旧货市场","value":"category=060702"},{"alias":"","name":"农副产品市场","value":"filter_keywords=农产品批发市场"},{"alias":"","name":"果品市场","value":"filter_keywords=果品批发市场"},{"alias":"","name":"蔬菜市场","value":"filter_keywords=蔬菜市场"},{"alias":"","name":"水产海鲜市场","value":"filter_keywords=水产海鲜市场"}],"alias":"","multiselect":"","name":"综合市场","display":""},{"alias":"","multiselect":"","name":"文化用品店","value":"filter_keywords=文化办公用品","display":""},{"category":[{"alias":"","name":"全部","value":"category=060500|060501|060502"},{"alias":"","name":"花鸟鱼虫市场","value":"filter_keywords=花鸟市场"},{"alias":"","name":"花卉市场","value":"filter_keywords=花卉市场"},{"alias":"","name":"宠物市场","value":"filter_keywords=宠物市场"}],"alias":"","multiselect":"","name":"花鸟市场","display":""},{"category":[{"alias":"","name":"全部","value":"category=061301|061302"},{"alias":"","name":"拍卖行","value":"category=061301"},{"alias":"","name":"典当行","value":"category=061302"}],"alias":"","multiselect":"","name":"买卖场所","display":""}],"name":"全部分类","ctype":"category","flag":2},{"checkedvalue":"sort_rule=0;reserved_keywords=true","category":[{"name":"推荐排序","value":"sort_rule=0;reserved_keywords=true"},{"name":"距离优先","value":"sort_rule=1;reserved_keywords=true"},{"name":"好评优先","value":"sort_rule=5;sort_fields=rating:d;reserved_keywords=true"},{"name":"低价优先","value":"sort_rule=5;sort_fields=averagecost:a0;reserved_keywords=true"},{"name":"高价优先","value":"sort_rule=5;sort_fields=averagecost:d;reserved_keywords=true"}],"name":"排序","ctype":"filter"}] + * busline_list : [] + */ + + private DataBean data; + private boolean SPQ; + private boolean isSPQ; + /** + * classify_type : {"checkedvalue":"filter_keywords=宠物市场","category":[{"alias":"","multiselect":"","name":"全部分类","value":"category=0601|061000|061001|0603|0606|0607|0605|060800|0613","display":""},{"alias":"","multiselect":"","name":"超市","value":"filter_keywords=超市","display":""},{"category":[{"alias":"","name":"全部","value":"category=060101|060103"},{"alias":"","name":"购物中心","value":"filter_keywords=购物中心"},{"alias":"","name":"免税品店","value":"category=060103"}],"alias":"","multiselect":"","name":"综合商场","display":""},{"category":[{"alias":"","name":"全部","value":"category=061000|061001"},{"alias":"","name":"特色商业街","value":"category=061000"},{"alias":"","name":"步行街","value":"filter_keywords=步行街"}],"alias":"","multiselect":"","name":"商业街","display":""},{"category":[{"alias":"","name":"全部","value":"filter_keywords=家电卖场"},{"alias":"","name":"家电电子卖场","value":"category=060300"},{"alias":"","name":"综合家电商场","value":"filter_keywords=综合家电"},{"alias":"","name":"国美","value":"category=060302"},{"alias":"","name":"大中","value":"filter_keywords=大中电器"},{"alias":"","name":"苏宁","value":"category=060304"},{"alias":"","name":"手机销售","value":"filter_keywords=手机销售"},{"alias":"","name":"数码电子","value":"filter_keywords=数码电子"}],"alias":"","multiselect":"","name":"家电","display":""},{"category":[{"alias":"","name":"全部","value":"filter_keywords=家具建材"},{"alias":"","name":"家具建材市场","value":"category=060601"},{"alias":"","name":"家具城","value":"filter_keywords=家具城"},{"alias":"","name":"建材五金市场","value":"filter_keywords=建材五金市场"},{"alias":"","name":"厨卫市场","value":"category=060604"},{"alias":"","name":"布艺市场","value":"category=060605"},{"alias":"","name":"灯具瓷器市场","value":"category=060606"}],"alias":"","multiselect":"","name":"家具建材","display":""},{"category":[{"alias":"","name":"全部","value":"filter_keywords=综合市场"},{"alias":"","name":"小商品市场","value":"filter_keywords=小商品批发市场"},{"alias":"","name":"旧货市场","value":"category=060702"},{"alias":"","name":"农副产品市场","value":"filter_keywords=农产品批发市场"},{"alias":"","name":"果品市场","value":"filter_keywords=果品批发市场"},{"alias":"","name":"蔬菜市场","value":"filter_keywords=蔬菜市场"},{"alias":"","name":"水产海鲜市场","value":"filter_keywords=水产海鲜市场"}],"alias":"","multiselect":"","name":"综合市场","display":""},{"alias":"","multiselect":"","name":"文化用品店","value":"filter_keywords=文化办公用品","display":""},{"category":[{"alias":"","name":"全部","value":"category=060500|060501|060502"},{"alias":"","name":"花鸟鱼虫市场","value":"filter_keywords=花鸟市场"},{"alias":"","name":"花卉市场","value":"filter_keywords=花卉市场"},{"alias":"","name":"宠物市场","value":"filter_keywords=宠物市场"}],"alias":"","multiselect":"","name":"花鸟市场","display":""},{"category":[{"alias":"","name":"全部","value":"category=061301|061302"},{"alias":"","name":"拍卖行","value":"category=061301"},{"alias":"","name":"典当行","value":"category=061302"}],"alias":"","multiselect":"","name":"买卖场所","display":""}],"name":"全部分类","ctype":"category","flag":2} + * classify_sort : {"checkedvalue":"sort_rule=0;reserved_keywords=true","category":[{"name":"推荐排序","value":"sort_rule=0;reserved_keywords=true"},{"name":"距离优先","value":"sort_rule=1;reserved_keywords=true"},{"name":"好评优先","value":"sort_rule=5;sort_fields=rating:d;reserved_keywords=true"},{"name":"低价优先","value":"sort_rule=5;sort_fields=averagecost:a0;reserved_keywords=true"},{"name":"高价优先","value":"sort_rule=5;sort_fields=averagecost:d;reserved_keywords=true"}],"name":"排序","ctype":"filter"} + * count : 2 + */ + + private ClassifyBean classify; + /** + * citycode : 0731 + * adcode : 430100 + * name : 长沙市 + * center : 112.982279,28.19409 + * level : city + * districts : [{"citycode":"0731","adcode":"430102","name":"芙蓉区","center":"112.988094,28.193106","level":"district","districts":[{"citycode":"0731","adcode":"430102","name":"德政园","center":"113.022609,28.186145","level":"biz_area","areacode":"19749","districts":[]},{"citycode":"0731","adcode":"430102","name":"定王台","center":"112.985227,28.190025","level":"biz_area","areacode":"19750","districts":[]},{"citycode":"0731","adcode":"430102","name":"黄兴路","center":"112.976687,28.190437","level":"biz_area","areacode":"19751","districts":[]},{"citycode":"0731","adcode":"430102","name":"韭菜园","center":"112.988766,28.194756","level":"biz_area","areacode":"19752","districts":[]},{"citycode":"0731","adcode":"430102","name":"马王堆","center":"113.028870,28.195465","level":"biz_area","areacode":"19753","districts":[]},{"citycode":"0731","adcode":"430102","name":"五里牌","center":"113.011699,28.198328","level":"biz_area","areacode":"19754","districts":[]},{"citycode":"0731","adcode":"430102","name":"湘湖","center":"113.012682,28.205252","level":"biz_area","areacode":"19755","districts":[]},{"citycode":"0731","adcode":"430102","name":"袁家岭","center":"112.997033,28.194455","level":"biz_area","areacode":"19756","districts":[]},{"citycode":"0731","adcode":"430102","name":"八一路","center":"113.000355,28.197485","level":"biz_area","areacode":"19757","districts":[]},{"citycode":"0731","adcode":"430102","name":"朝阳路","center":"113.007038,28.189212","level":"biz_area","areacode":"19758","districts":[]},{"citycode":"0731","adcode":"430102","name":"东屯渡","center":"113.038626,28.194082","level":"biz_area","areacode":"19759","districts":[]},{"citycode":"0731","adcode":"430102","name":"芙蓉广场","center":"112.995054,28.197940","level":"biz_area","areacode":"19760","districts":[]},{"citycode":"0731","adcode":"430102","name":"芙蓉中路","center":"112.986125,28.187681","level":"biz_area","areacode":"19761","districts":[]},{"citycode":"0731","adcode":"430102","name":"荷花路","center":"113.032740,28.191378","level":"biz_area","areacode":"19762","districts":[]},{"citycode":"0731","adcode":"430102","name":"荷花园","center":"113.021219,28.191605","level":"biz_area","areacode":"19763","districts":[]},{"citycode":"0731","adcode":"430102","name":"火星","center":"113.023431,28.202349","level":"biz_area","areacode":"19764","districts":[]},{"citycode":"0731","adcode":"430102","name":"凌霄路","center":"113.029080,28.202090","level":"biz_area","areacode":"19765","districts":[]},{"citycode":"0731","adcode":"430102","name":"浏正街","center":"112.984803,28.191896","level":"biz_area","areacode":"19766","districts":[]},{"citycode":"0731","adcode":"430102","name":"三湘大市场","center":"113.016648,28.202302","level":"biz_area","areacode":"19768","districts":[]},{"citycode":"0731","adcode":"430102","name":"万家丽","center":"113.030236,28.185394","level":"biz_area","areacode":"19770","districts":[]},{"citycode":"0731","adcode":"430102","name":"文艺路","center":"112.994009,28.191407","level":"biz_area","areacode":"19771","districts":[]},{"citycode":"0731","adcode":"430102","name":"五一大道","center":"112.988446,28.194898","level":"biz_area","areacode":"19772","districts":[]},{"citycode":"0731","adcode":"430102","name":"燕山街","center":"113.000486,28.196539","level":"biz_area","areacode":"19773","districts":[]},{"citycode":"0731","adcode":"430102","name":"远大路","center":"113.027617,28.198384","level":"biz_area","areacode":"19774","districts":[]},{"citycode":"0731","adcode":"430102","name":"中山路","center":"112.979051,28.199921","level":"biz_area","areacode":"19775","districts":[]},{"citycode":"0731","adcode":"430102","name":"车站中路","center":"113.010938,28.193068","level":"biz_area","areacode":"19776","districts":[]},{"citycode":"0731","adcode":"430102","name":"芙蓉区政府","center":"113.003653,28.194434","level":"biz_area","areacode":"19785","districts":[]},{"citycode":"0731","adcode":"430102","name":"解放东路","center":"113.005201,28.190678","level":"biz_area","areacode":"19792","districts":[]},{"citycode":"0731","adcode":"430102","name":"解放西路","center":"112.979381,28.191326","level":"biz_area","areacode":"19813","districts":[]},{"citycode":"0731","adcode":"430102","name":"都正街","center":"112.981833,28.187702","level":"biz_area","areacode":"19814","districts":[]},{"citycode":"0731","adcode":"430102","name":"火车站","center":"113.011203,28.193686","level":"biz_area","areacode":"19830","districts":[]},{"citycode":"0731","adcode":"430102","name":"车站北路","center":"113.009321,28.207354","level":"biz_area","areacode":"19845","districts":[]}]},{"citycode":"0731","adcode":"430103","name":"天心区","center":"112.97307,28.192375","level":"district","districts":[{"citycode":"0731","adcode":"430103","name":"韶山南路","center":"113.000079,28.135185","level":"biz_area","areacode":"19782","districts":[]},{"citycode":"0731","adcode":"430103","name":"城南路","center":"112.983886,28.182259","level":"biz_area","areacode":"19787","districts":[]},{"citycode":"0731","adcode":"430103","name":"劳动西路","center":"112.983972,28.173499","level":"biz_area","areacode":"19797","districts":[]},{"citycode":"0731","adcode":"430103","name":"黄土岭","center":"112.985897,28.161960","level":"biz_area","areacode":"19808","districts":[]},{"citycode":"0731","adcode":"430103","name":"友谊路","center":"112.997239,28.125006","level":"biz_area","areacode":"19809","districts":[]},{"citycode":"0731","adcode":"430103","name":"裕南街","center":"112.972993,28.172404","level":"biz_area","areacode":"19810","districts":[]},{"citycode":"0731","adcode":"430103","name":"芙蓉南路","center":"112.986581,28.132236","level":"biz_area","areacode":"19811","districts":[]},{"citycode":"0731","adcode":"430103","name":"赤岭路","center":"112.979397,28.153046","level":"biz_area","areacode":"19812","districts":[]},{"citycode":"0731","adcode":"430103","name":"芙蓉南路","center":"112.987141,28.124923","level":"biz_area","areacode":"19816","districts":[]},{"citycode":"0731","adcode":"430103","name":"白沙路","center":"112.982195,28.182379","level":"biz_area","areacode":"19818","districts":[]},{"citycode":"0731","adcode":"430103","name":"碧湘街","center":"112.972105,28.182679","level":"biz_area","areacode":"19819","districts":[]},{"citycode":"0731","adcode":"430103","name":"金盆岭","center":"112.977234,28.151578","level":"biz_area","areacode":"19822","districts":[]},{"citycode":"0731","adcode":"430103","name":"南湖路","center":"112.977905,28.165537","level":"biz_area","areacode":"19825","districts":[]},{"citycode":"0731","adcode":"430103","name":"南门口","center":"112.975929,28.183259","level":"biz_area","areacode":"19827","districts":[]},{"citycode":"0731","adcode":"430103","name":"坡子街","center":"112.973189,28.190238","level":"biz_area","areacode":"19828","districts":[]},{"citycode":"0731","adcode":"430103","name":"青园","center":"112.994944,28.128891","level":"biz_area","areacode":"19829","districts":[]},{"citycode":"0731","adcode":"430103","name":"书院路","center":"112.971563,28.175927","level":"biz_area","areacode":"19832","districts":[]},{"citycode":"0731","adcode":"430103","name":"书院南路","center":"112.972190,28.150083","level":"biz_area","areacode":"19833","districts":[]},{"citycode":"0731","adcode":"430103","name":"天心阁","center":"112.981184,28.184664","level":"biz_area","areacode":"19835","districts":[]},{"citycode":"0731","adcode":"430103","name":"西牌楼","center":"112.972712,28.193602","level":"biz_area","areacode":"19837","districts":[]},{"citycode":"0731","adcode":"430103","name":"新开铺","center":"112.970512,28.133102","level":"biz_area","areacode":"19838","districts":[]},{"citycode":"0731","adcode":"430103","name":"铁道学院","center":"112.992682,28.140356","level":"biz_area","areacode":"19839","districts":[]},{"citycode":"0731","adcode":"430103","name":"西湖","center":"112.967188,28.187826","level":"biz_area","areacode":"19879","districts":[]}]},{"citycode":"0731","adcode":"430104","name":"岳麓区","center":"112.911591,28.213044","level":"district","districts":[{"citycode":"0731","adcode":"430104","name":"观沙岭","center":"112.950525,28.235600","level":"biz_area","areacode":"19861","districts":[]},{"citycode":"0731","adcode":"430104","name":"湖南商学院","center":"112.918042,28.219331","level":"biz_area","areacode":"19862","districts":[]},{"citycode":"0731","adcode":"430104","name":"麓谷","center":"112.889410,28.214029","level":"biz_area","areacode":"19863","districts":[]},{"citycode":"0731","adcode":"430104","name":"汽车西站","center":"112.910711,28.209866","level":"biz_area","areacode":"19864","districts":[]},{"citycode":"0731","adcode":"430104","name":"桐梓坡","center":"112.930153,28.218539","level":"biz_area","areacode":"19865","districts":[]},{"citycode":"0731","adcode":"430104","name":"望月湖","center":"112.955265,28.204105","level":"biz_area","areacode":"19866","districts":[]},{"citycode":"0731","adcode":"430104","name":"咸嘉湖","center":"112.930929,28.212604","level":"biz_area","areacode":"19867","districts":[]},{"citycode":"0731","adcode":"430104","name":"岳麓山","center":"112.943829,28.178123","level":"biz_area","areacode":"19868","districts":[]},{"citycode":"0731","adcode":"430104","name":"玉兰路","center":"112.910965,28.214257","level":"biz_area","areacode":"19869","districts":[]},{"citycode":"0731","adcode":"430104","name":"白沙液街","center":"112.952884,28.201147","level":"biz_area","areacode":"19870","districts":[]},{"citycode":"0731","adcode":"430104","name":"枫林一路","center":"112.946030,28.198881","level":"biz_area","areacode":"19871","districts":[]},{"citycode":"0731","adcode":"430104","name":"湖南大学","center":"112.945213,28.177733","level":"biz_area","areacode":"19872","districts":[]},{"citycode":"0731","adcode":"430104","name":"湖南师范大学","center":"112.948495,28.187094","level":"biz_area","areacode":"19873","districts":[]},{"citycode":"0731","adcode":"430104","name":"雷锋大道","center":"112.899515,28.237511","level":"biz_area","areacode":"19874","districts":[]},{"citycode":"0731","adcode":"430104","name":"麓山路","center":"112.949074,28.189117","level":"biz_area","areacode":"19875","districts":[]},{"citycode":"0731","adcode":"430104","name":"桐梓坡路","center":"112.934137,28.218532","level":"biz_area","areacode":"19876","districts":[]},{"citycode":"0731","adcode":"430104","name":"望城坡","center":"112.912119,28.213111","level":"biz_area","areacode":"19877","districts":[]},{"citycode":"0731","adcode":"430104","name":"望岳","center":"112.922311,28.221183","level":"biz_area","areacode":"19878","districts":[]},{"citycode":"0731","adcode":"430104","name":"咸嘉新村","center":"112.927504,28.220168","level":"biz_area","areacode":"19880","districts":[]},{"citycode":"0731","adcode":"430104","name":"新民路","center":"112.953168,28.192306","level":"biz_area","areacode":"19881","districts":[]},{"citycode":"0731","adcode":"430104","name":"银盆岭","center":"112.953686,28.222394","level":"biz_area","areacode":"19882","districts":[]},{"citycode":"0731","adcode":"430104","name":"中南大学","center":"112.933330,28.163911","level":"biz_area","areacode":"19883","districts":[]}]},{"citycode":"0731","adcode":"430105","name":"开福区","center":"112.985525,28.201336","level":"district","districts":[{"citycode":"0731","adcode":"430105","name":"五一广场","center":"112.976276,28.195472","level":"biz_area","areacode":"19840","districts":[]},{"citycode":"0731","adcode":"430105","name":"四方坪","center":"113.010379,28.235254","level":"biz_area","areacode":"19841","districts":[]},{"citycode":"0731","adcode":"430105","name":"伍家岭","center":"112.989085,28.229513","level":"biz_area","areacode":"19842","districts":[]},{"citycode":"0731","adcode":"430105","name":"湘雅医院","center":"112.970288,28.208441","level":"biz_area","areacode":"19843","districts":[]},{"citycode":"0731","adcode":"430105","name":"营盘路","center":"112.980982,28.204196","level":"biz_area","areacode":"19844","districts":[]},{"citycode":"0731","adcode":"430105","name":"芙蓉北路","center":"112.984343,28.253526","level":"biz_area","areacode":"19846","districts":[]},{"citycode":"0731","adcode":"430105","name":"北正街","center":"112.976591,28.206011","level":"biz_area","areacode":"19847","districts":[]},{"citycode":"0731","adcode":"430105","name":"蔡锷北路","center":"112.981659,28.206246","level":"biz_area","areacode":"19848","districts":[]},{"citycode":"0731","adcode":"430105","name":"德雅路","center":"113.004718,28.222866","level":"biz_area","areacode":"19849","districts":[]},{"citycode":"0731","adcode":"430105","name":"东风路","center":"112.992763,28.217975","level":"biz_area","areacode":"19850","districts":[]},{"citycode":"0731","adcode":"430105","name":"华夏路","center":"112.982770,28.224978","level":"biz_area","areacode":"19851","districts":[]},{"citycode":"0731","adcode":"430105","name":"开福寺","center":"112.980862,28.223230","level":"biz_area","areacode":"19852","districts":[]},{"citycode":"0731","adcode":"430105","name":"科大佳园","center":"113.003668,28.236008","level":"biz_area","areacode":"19853","districts":[]},{"citycode":"0731","adcode":"430105","name":"麻园岭","center":"112.984825,28.215030","level":"biz_area","areacode":"19854","districts":[]},{"citycode":"0731","adcode":"430105","name":"清水塘","center":"112.988751,28.200502","level":"biz_area","areacode":"19855","districts":[]},{"citycode":"0731","adcode":"430105","name":"三一大道","center":"113.005297,28.231043","level":"biz_area","areacode":"19856","districts":[]},{"citycode":"0731","adcode":"430105","name":"通泰街","center":"112.974645,28.206132","level":"biz_area","areacode":"19857","districts":[]},{"citycode":"0731","adcode":"430105","name":"湘江中路","center":"112.972143,28.203561","level":"biz_area","areacode":"19858","districts":[]},{"citycode":"0731","adcode":"430105","name":"湘雅路","center":"112.979935,28.213924","level":"biz_area","areacode":"19859","districts":[]},{"citycode":"0731","adcode":"430105","name":"新河","center":"112.982264,28.227548","level":"biz_area","areacode":"19860","districts":[]}]},{"citycode":"0731","adcode":"430111","name":"雨花区","center":"113.016337,28.109937","level":"district","districts":[{"citycode":"0731","adcode":"430111","name":"人民中路","center":"113.001047,28.185355","level":"biz_area","areacode":"19767","districts":[]},{"citycode":"0731","adcode":"430111","name":"曙光路","center":"113.001969,28.179694","level":"biz_area","areacode":"19769","districts":[]},{"citycode":"0731","adcode":"430111","name":"窑岭","center":"112.998484,28.185167","level":"biz_area","areacode":"19777","districts":[]},{"citycode":"0731","adcode":"430111","name":"茶园坡","center":"113.008657,28.159707","level":"biz_area","areacode":"19778","districts":[]},{"citycode":"0731","adcode":"430111","name":"东塘","center":"112.994720,28.168757","level":"biz_area","areacode":"19779","districts":[]},{"citycode":"0731","adcode":"430111","name":"高桥","center":"113.022508,28.172998","level":"biz_area","areacode":"19780","districts":[]},{"citycode":"0731","adcode":"430111","name":"砂子塘","center":"112.997399,28.161249","level":"biz_area","areacode":"19781","districts":[]},{"citycode":"0731","adcode":"430111","name":"雨花亭","center":"112.997573,28.150595","level":"biz_area","areacode":"19783","districts":[]},{"citycode":"0731","adcode":"430111","name":"左家塘","center":"113.003294,28.176401","level":"biz_area","areacode":"19784","districts":[]},{"citycode":"0731","adcode":"430111","name":"小林子冲","center":"112.988135,28.177010","level":"biz_area","areacode":"19786","districts":[]},{"citycode":"0731","adcode":"430111","name":"阿弥岭","center":"113.006469,28.172421","level":"biz_area","areacode":"19788","districts":[]},{"citycode":"0731","adcode":"430111","name":"圭塘","center":"113.033391,28.139720","level":"biz_area","areacode":"19794","districts":[]},{"citycode":"0731","adcode":"430111","name":"红花坡","center":"113.005448,28.165878","level":"biz_area","areacode":"19795","districts":[]},{"citycode":"0731","adcode":"430111","name":"井湾子","center":"113.009767,28.124386","level":"biz_area","areacode":"19796","districts":[]},{"citycode":"0731","adcode":"430111","name":"劳动中路","center":"113.002097,28.163422","level":"biz_area","areacode":"19798","districts":[]},{"citycode":"0731","adcode":"430111","name":"曲塘","center":"113.032987,28.148308","level":"biz_area","areacode":"19799","districts":[]},{"citycode":"0731","adcode":"430111","name":"韶山中路","center":"112.994247,28.158138","level":"biz_area","areacode":"19800","districts":[]},{"citycode":"0731","adcode":"430111","name":"树木岭","center":"113.022365,28.150991","level":"biz_area","areacode":"19801","districts":[]},{"citycode":"0731","adcode":"430111","name":"王家冲","center":"113.001659,28.152828","level":"biz_area","areacode":"19802","districts":[]},{"citycode":"0731","adcode":"430111","name":"香樟路","center":"113.012409,28.136391","level":"biz_area","areacode":"19803","districts":[]},{"citycode":"0731","adcode":"430111","name":"雨花区政府","center":"113.018871,28.146627","level":"biz_area","areacode":"19804","districts":[]},{"citycode":"0731","adcode":"430111","name":"植物园","center":"113.019004,28.103487","level":"biz_area","areacode":"19805","districts":[]},{"citycode":"0731","adcode":"430111","name":"梓园路","center":"112.991337,28.178514","level":"biz_area","areacode":"19806","districts":[]},{"citycode":"0731","adcode":"430111","name":"侯家塘","center":"112.985710,28.173230","level":"biz_area","areacode":"19807","districts":[]}]},{"citycode":"0731","adcode":"430112","name":"望城区","center":"112.819549,28.347458","level":"district","districts":[]},{"citycode":"0731","adcode":"430121","name":"长沙县","center":"113.080098,28.237888","level":"district","districts":[]},{"citycode":"0731","adcode":"430124","name":"宁乡县","center":"112.553182,28.253928","level":"district","districts":[]},{"citycode":"0731","adcode":"430181","name":"浏阳市","center":"113.633301,28.141112","level":"district","districts":[]}] + * checkedvalue : query_type=TQUERY + */ + + private BizAreaDataBean bizAreaData; + private boolean classifyFlag; + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public SearchOptBean getSearchOpt() { + return searchOpt; + } + + public void setSearchOpt(SearchOptBean searchOpt) { + this.searchOpt = searchOpt; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public boolean isSPQ() { + return SPQ; + } + + public void setSPQ(boolean SPQ) { + this.SPQ = SPQ; + } + + public boolean isIsSPQ() { + return isSPQ; + } + + public void setIsSPQ(boolean isSPQ) { + this.isSPQ = isSPQ; + } + + public ClassifyBean getClassify() { + return classify; + } + + public void setClassify(ClassifyBean classify) { + this.classify = classify; + } + + public BizAreaDataBean getBizAreaData() { + return bizAreaData; + } + + public void setBizAreaData(BizAreaDataBean bizAreaData) { + this.bizAreaData = bizAreaData; + } + + public boolean isClassifyFlag() { + return classifyFlag; + } + + public void setClassifyFlag(boolean classifyFlag) { + this.classifyFlag = classifyFlag; + } + + public static class SearchOptBean { + private String city; + private String pageSize; + private String pageIndex; + private String ac; + private String keyword; + private String type; + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getPageSize() { + return pageSize; + } + + public void setPageSize(String pageSize) { + this.pageSize = pageSize; + } + + public String getPageIndex() { + return pageIndex; + } + + public void setPageIndex(String pageIndex) { + this.pageIndex = pageIndex; + } + + public String getAc() { + return ac; + } + + public void setAc(String ac) { + this.ac = ac; + } + + public String getKeyword() { + return keyword; + } + + public void setKeyword(String keyword) { + this.keyword = keyword; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + } + + public static class DataBean { + private int codepoint; + private String code; + private String timestamp; + /** + * cache_directive : {"cache_filter":{"flag":"1","expires":"24"},"cache_all":{"flag":"0"}} + * query_intent : {"cate_list":"","type":"1000","cate":"06","cate_ext":""} + * classify_range : {"district_adcode":"430100","subway_adcode":"430100","nearby_enable":"1","subway_enable":"1","district_enable":"1"} + * general_flag : + * specialclassify : + * view_region : 113.029599800,28.194115900,113.123658200,28.181505100 + * suggestcontent : + * pdheatmap : + * render_name_flag : 1 + * is_current_city : 2 + * expand_range_tip : + * suggest_query : {"data":[],"col":"","row":""} + * change_query_tip : + * is_tupu_sug : 0 + * has_recommend : 0 + * brand_intent : {"t_tag":"","flag":"0","cate":"","name":""} + * suggestionview : 1 + * change_query_type : + * business : + * car_icon_flag : 0 + * slayer_type : none + * show_pic : + * is_view_city : 1 + * querytype : 5 + * self_navigation : + * showaoi : + * utd_sceneid : 1000 + * distance_info : + * slayer : 1 + * target_view_city : + * call_taxi : 0 + * preload_next_page : 1 + * magic_box : {} + * activity : {"new_year":{"flag":"0","tip":""}} + */ + + private LqiiBean lqii; + private String general_flag; + private String result; + private String keywords; + private String message; + private String total; + private String is_general_search; + private String bounds; + private String version; + private String busline_count; + private MagicboxDataBean magicbox_data; + private String interior_count; + private List bus_list; + /** + * rating : + * tel : 15873110896 + * typecode : 060502 + * areacode : 0731 + * cityname : 长沙市 + * display_brand : + * shape_region : + * longitude : 113.085508 + * address : 湖南农业大学农大路东湖小区9栋1号门面 + * cinemazuo_flag : 0 + * diner_flag : 0 + * id : B0FFF00687 + * name : 宠物森林宠物店 + * group_flag : 0 + * distance : 0 + * entrances : [] + * recommend_flag : 0 + * exits : [] + * adcode : 430102 + * domain_list : [{"type":"html","id":"1015","name":"poiclosed"},{"type":"img","id":"1003","name":"icon"},{"type":"html","id":"1011","name":"traffic"},{"type":"text","id":"1014","name":"roadaoi"},{"type":"button","id":"1012","name":"ext_btn"},{"type":"webimg","id":"1009","value":"http://store.is.autonavi.com/showpic/2e1f07ad78ffb766518e2ab25bfe3373","name":"pic_info"},{"type":"img","id":"1008","name":"overbooked"},{"type":"img","id":"1007","name":"moreservice"},{"type":"html","id":"1006","name":"tag"},{"type":"text","id":"1005","name":"parent_info"},{"type":"array","name":"parent_other_rel","id":"1004"},{"type":"text","id":"1010","name":"business_area"},{"type":"html","id":"1002","name":"deepinfo"},{"type":"html","id":"1001","name":"price"},{"type":"text","id":"1013","name":"aoi"}] + * newtype : 060502 + * disp_name : 宠物森林宠物店 + * cpdata : + * latitude : 28.186454 + * discount_flag : 0 + */ + + private List poi_list; + /** + * checkedvalue : filter_keywords=宠物市场 + * category : [{"alias":"","multiselect":"","name":"全部分类","value":"category=0601|061000|061001|0603|0606|0607|0605|060800|0613","display":""},{"alias":"","multiselect":"","name":"超市","value":"filter_keywords=超市","display":""},{"category":[{"alias":"","name":"全部","value":"category=060101|060103"},{"alias":"","name":"购物中心","value":"filter_keywords=购物中心"},{"alias":"","name":"免税品店","value":"category=060103"}],"alias":"","multiselect":"","name":"综合商场","display":""},{"category":[{"alias":"","name":"全部","value":"category=061000|061001"},{"alias":"","name":"特色商业街","value":"category=061000"},{"alias":"","name":"步行街","value":"filter_keywords=步行街"}],"alias":"","multiselect":"","name":"商业街","display":""},{"category":[{"alias":"","name":"全部","value":"filter_keywords=家电卖场"},{"alias":"","name":"家电电子卖场","value":"category=060300"},{"alias":"","name":"综合家电商场","value":"filter_keywords=综合家电"},{"alias":"","name":"国美","value":"category=060302"},{"alias":"","name":"大中","value":"filter_keywords=大中电器"},{"alias":"","name":"苏宁","value":"category=060304"},{"alias":"","name":"手机销售","value":"filter_keywords=手机销售"},{"alias":"","name":"数码电子","value":"filter_keywords=数码电子"}],"alias":"","multiselect":"","name":"家电","display":""},{"category":[{"alias":"","name":"全部","value":"filter_keywords=家具建材"},{"alias":"","name":"家具建材市场","value":"category=060601"},{"alias":"","name":"家具城","value":"filter_keywords=家具城"},{"alias":"","name":"建材五金市场","value":"filter_keywords=建材五金市场"},{"alias":"","name":"厨卫市场","value":"category=060604"},{"alias":"","name":"布艺市场","value":"category=060605"},{"alias":"","name":"灯具瓷器市场","value":"category=060606"}],"alias":"","multiselect":"","name":"家具建材","display":""},{"category":[{"alias":"","name":"全部","value":"filter_keywords=综合市场"},{"alias":"","name":"小商品市场","value":"filter_keywords=小商品批发市场"},{"alias":"","name":"旧货市场","value":"category=060702"},{"alias":"","name":"农副产品市场","value":"filter_keywords=农产品批发市场"},{"alias":"","name":"果品市场","value":"filter_keywords=果品批发市场"},{"alias":"","name":"蔬菜市场","value":"filter_keywords=蔬菜市场"},{"alias":"","name":"水产海鲜市场","value":"filter_keywords=水产海鲜市场"}],"alias":"","multiselect":"","name":"综合市场","display":""},{"alias":"","multiselect":"","name":"文化用品店","value":"filter_keywords=文化办公用品","display":""},{"category":[{"alias":"","name":"全部","value":"category=060500|060501|060502"},{"alias":"","name":"花鸟鱼虫市场","value":"filter_keywords=花鸟市场"},{"alias":"","name":"花卉市场","value":"filter_keywords=花卉市场"},{"alias":"","name":"宠物市场","value":"filter_keywords=宠物市场"}],"alias":"","multiselect":"","name":"花鸟市场","display":""},{"category":[{"alias":"","name":"全部","value":"category=061301|061302"},{"alias":"","name":"拍卖行","value":"category=061301"},{"alias":"","name":"典当行","value":"category=061302"}],"alias":"","multiselect":"","name":"买卖场所","display":""}] + * name : 全部分类 + * ctype : category + * flag : 2 + */ + + private List classify; + private List busline_list; + + public int getCodepoint() { + return codepoint; + } + + public void setCodepoint(int codepoint) { + this.codepoint = codepoint; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getTimestamp() { + return timestamp; + } + + public void setTimestamp(String timestamp) { + this.timestamp = timestamp; + } + + public LqiiBean getLqii() { + return lqii; + } + + public void setLqii(LqiiBean lqii) { + this.lqii = lqii; + } + + public String getGeneral_flag() { + return general_flag; + } + + public void setGeneral_flag(String general_flag) { + this.general_flag = general_flag; + } + + public String getResult() { + return result; + } + + public void setResult(String result) { + this.result = result; + } + + public String getKeywords() { + return keywords; + } + + public void setKeywords(String keywords) { + this.keywords = keywords; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getTotal() { + return total; + } + + public void setTotal(String total) { + this.total = total; + } + + public String getIs_general_search() { + return is_general_search; + } + + public void setIs_general_search(String is_general_search) { + this.is_general_search = is_general_search; + } + + public String getBounds() { + return bounds; + } + + public void setBounds(String bounds) { + this.bounds = bounds; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getBusline_count() { + return busline_count; + } + + public void setBusline_count(String busline_count) { + this.busline_count = busline_count; + } + + public MagicboxDataBean getMagicbox_data() { + return magicbox_data; + } + + public void setMagicbox_data(MagicboxDataBean magicbox_data) { + this.magicbox_data = magicbox_data; + } + + public String getInterior_count() { + return interior_count; + } + + public void setInterior_count(String interior_count) { + this.interior_count = interior_count; + } + + public List getBus_list() { + return bus_list; + } + + public void setBus_list(List bus_list) { + this.bus_list = bus_list; + } + + public List getPoi_list() { + return poi_list; + } + + public void setPoi_list(List poi_list) { + this.poi_list = poi_list; + } + + public List getClassify() { + return classify; + } + + public void setClassify(List classify) { + this.classify = classify; + } + + public List getBusline_list() { + return busline_list; + } + + public void setBusline_list(List busline_list) { + this.busline_list = busline_list; + } + + public static class LqiiBean { + /** + * cache_filter : {"flag":"1","expires":"24"} + * cache_all : {"flag":"0"} + */ + + private CacheDirectiveBean cache_directive; + /** + * cate_list : + * type : 1000 + * cate : 06 + * cate_ext : + */ + + private QueryIntentBean query_intent; + /** + * district_adcode : 430100 + * subway_adcode : 430100 + * nearby_enable : 1 + * subway_enable : 1 + * district_enable : 1 + */ + + private ClassifyRangeBean classify_range; + private String general_flag; + private String specialclassify; + private String view_region; + private String suggestcontent; + private String pdheatmap; + private String render_name_flag; + private String is_current_city; + private String expand_range_tip; + /** + * data : [] + * col : + * row : + */ + + private SuggestQueryBean suggest_query; + private String change_query_tip; + private String is_tupu_sug; + private String has_recommend; + /** + * t_tag : + * flag : 0 + * cate : + * name : + */ + + private BrandIntentBean brand_intent; + private String suggestionview; + private String change_query_type; + private String business; + private String car_icon_flag; + private String slayer_type; + private String show_pic; + private String is_view_city; + private String querytype; + private String self_navigation; + private String showaoi; + private String utd_sceneid; + private String distance_info; + private String slayer; + private String target_view_city; + private String call_taxi; + private String preload_next_page; + private MagicBoxBean magic_box; + /** + * new_year : {"flag":"0","tip":""} + */ + + private ActivityBean activity; + + public CacheDirectiveBean getCache_directive() { + return cache_directive; + } + + public void setCache_directive(CacheDirectiveBean cache_directive) { + this.cache_directive = cache_directive; + } + + public QueryIntentBean getQuery_intent() { + return query_intent; + } + + public void setQuery_intent(QueryIntentBean query_intent) { + this.query_intent = query_intent; + } + + public ClassifyRangeBean getClassify_range() { + return classify_range; + } + + public void setClassify_range(ClassifyRangeBean classify_range) { + this.classify_range = classify_range; + } + + public String getGeneral_flag() { + return general_flag; + } + + public void setGeneral_flag(String general_flag) { + this.general_flag = general_flag; + } + + public String getSpecialclassify() { + return specialclassify; + } + + public void setSpecialclassify(String specialclassify) { + this.specialclassify = specialclassify; + } + + public String getView_region() { + return view_region; + } + + public void setView_region(String view_region) { + this.view_region = view_region; + } + + public String getSuggestcontent() { + return suggestcontent; + } + + public void setSuggestcontent(String suggestcontent) { + this.suggestcontent = suggestcontent; + } + + public String getPdheatmap() { + return pdheatmap; + } + + public void setPdheatmap(String pdheatmap) { + this.pdheatmap = pdheatmap; + } + + public String getRender_name_flag() { + return render_name_flag; + } + + public void setRender_name_flag(String render_name_flag) { + this.render_name_flag = render_name_flag; + } + + public String getIs_current_city() { + return is_current_city; + } + + public void setIs_current_city(String is_current_city) { + this.is_current_city = is_current_city; + } + + public String getExpand_range_tip() { + return expand_range_tip; + } + + public void setExpand_range_tip(String expand_range_tip) { + this.expand_range_tip = expand_range_tip; + } + + public SuggestQueryBean getSuggest_query() { + return suggest_query; + } + + public void setSuggest_query(SuggestQueryBean suggest_query) { + this.suggest_query = suggest_query; + } + + public String getChange_query_tip() { + return change_query_tip; + } + + public void setChange_query_tip(String change_query_tip) { + this.change_query_tip = change_query_tip; + } + + public String getIs_tupu_sug() { + return is_tupu_sug; + } + + public void setIs_tupu_sug(String is_tupu_sug) { + this.is_tupu_sug = is_tupu_sug; + } + + public String getHas_recommend() { + return has_recommend; + } + + public void setHas_recommend(String has_recommend) { + this.has_recommend = has_recommend; + } + + public BrandIntentBean getBrand_intent() { + return brand_intent; + } + + public void setBrand_intent(BrandIntentBean brand_intent) { + this.brand_intent = brand_intent; + } + + public String getSuggestionview() { + return suggestionview; + } + + public void setSuggestionview(String suggestionview) { + this.suggestionview = suggestionview; + } + + public String getChange_query_type() { + return change_query_type; + } + + public void setChange_query_type(String change_query_type) { + this.change_query_type = change_query_type; + } + + public String getBusiness() { + return business; + } + + public void setBusiness(String business) { + this.business = business; + } + + public String getCar_icon_flag() { + return car_icon_flag; + } + + public void setCar_icon_flag(String car_icon_flag) { + this.car_icon_flag = car_icon_flag; + } + + public String getSlayer_type() { + return slayer_type; + } + + public void setSlayer_type(String slayer_type) { + this.slayer_type = slayer_type; + } + + public String getShow_pic() { + return show_pic; + } + + public void setShow_pic(String show_pic) { + this.show_pic = show_pic; + } + + public String getIs_view_city() { + return is_view_city; + } + + public void setIs_view_city(String is_view_city) { + this.is_view_city = is_view_city; + } + + public String getQuerytype() { + return querytype; + } + + public void setQuerytype(String querytype) { + this.querytype = querytype; + } + + public String getSelf_navigation() { + return self_navigation; + } + + public void setSelf_navigation(String self_navigation) { + this.self_navigation = self_navigation; + } + + public String getShowaoi() { + return showaoi; + } + + public void setShowaoi(String showaoi) { + this.showaoi = showaoi; + } + + public String getUtd_sceneid() { + return utd_sceneid; + } + + public void setUtd_sceneid(String utd_sceneid) { + this.utd_sceneid = utd_sceneid; + } + + public String getDistance_info() { + return distance_info; + } + + public void setDistance_info(String distance_info) { + this.distance_info = distance_info; + } + + public String getSlayer() { + return slayer; + } + + public void setSlayer(String slayer) { + this.slayer = slayer; + } + + public String getTarget_view_city() { + return target_view_city; + } + + public void setTarget_view_city(String target_view_city) { + this.target_view_city = target_view_city; + } + + public String getCall_taxi() { + return call_taxi; + } + + public void setCall_taxi(String call_taxi) { + this.call_taxi = call_taxi; + } + + public String getPreload_next_page() { + return preload_next_page; + } + + public void setPreload_next_page(String preload_next_page) { + this.preload_next_page = preload_next_page; + } + + public MagicBoxBean getMagic_box() { + return magic_box; + } + + public void setMagic_box(MagicBoxBean magic_box) { + this.magic_box = magic_box; + } + + public ActivityBean getActivity() { + return activity; + } + + public void setActivity(ActivityBean activity) { + this.activity = activity; + } + + public static class CacheDirectiveBean { + /** + * flag : 1 + * expires : 24 + */ + + private CacheFilterBean cache_filter; + /** + * flag : 0 + */ + + private CacheAllBean cache_all; + + public CacheFilterBean getCache_filter() { + return cache_filter; + } + + public void setCache_filter(CacheFilterBean cache_filter) { + this.cache_filter = cache_filter; + } + + public CacheAllBean getCache_all() { + return cache_all; + } + + public void setCache_all(CacheAllBean cache_all) { + this.cache_all = cache_all; + } + + public static class CacheFilterBean { + private String flag; + private String expires; + + public String getFlag() { + return flag; + } + + public void setFlag(String flag) { + this.flag = flag; + } + + public String getExpires() { + return expires; + } + + public void setExpires(String expires) { + this.expires = expires; + } + } + + public static class CacheAllBean { + private String flag; + + public String getFlag() { + return flag; + } + + public void setFlag(String flag) { + this.flag = flag; + } + } + } + + public static class QueryIntentBean { + private String cate_list; + private String type; + private String cate; + private String cate_ext; + + public String getCate_list() { + return cate_list; + } + + public void setCate_list(String cate_list) { + this.cate_list = cate_list; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getCate() { + return cate; + } + + public void setCate(String cate) { + this.cate = cate; + } + + public String getCate_ext() { + return cate_ext; + } + + public void setCate_ext(String cate_ext) { + this.cate_ext = cate_ext; + } + } + + public static class ClassifyRangeBean { + private String district_adcode; + private String subway_adcode; + private String nearby_enable; + private String subway_enable; + private String district_enable; + + public String getDistrict_adcode() { + return district_adcode; + } + + public void setDistrict_adcode(String district_adcode) { + this.district_adcode = district_adcode; + } + + public String getSubway_adcode() { + return subway_adcode; + } + + public void setSubway_adcode(String subway_adcode) { + this.subway_adcode = subway_adcode; + } + + public String getNearby_enable() { + return nearby_enable; + } + + public void setNearby_enable(String nearby_enable) { + this.nearby_enable = nearby_enable; + } + + public String getSubway_enable() { + return subway_enable; + } + + public void setSubway_enable(String subway_enable) { + this.subway_enable = subway_enable; + } + + public String getDistrict_enable() { + return district_enable; + } + + public void setDistrict_enable(String district_enable) { + this.district_enable = district_enable; + } + } + + public static class SuggestQueryBean { + private String col; + private String row; + private List data; + + public String getCol() { + return col; + } + + public void setCol(String col) { + this.col = col; + } + + public String getRow() { + return row; + } + + public void setRow(String row) { + this.row = row; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + } + + public static class BrandIntentBean { + private String t_tag; + private String flag; + private String cate; + private String name; + + public String getT_tag() { + return t_tag; + } + + public void setT_tag(String t_tag) { + this.t_tag = t_tag; + } + + public String getFlag() { + return flag; + } + + public void setFlag(String flag) { + this.flag = flag; + } + + public String getCate() { + return cate; + } + + public void setCate(String cate) { + this.cate = cate; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } + + public static class MagicBoxBean { + } + + public static class ActivityBean { + /** + * flag : 0 + * tip : + */ + + private NewYearBean new_year; + + public NewYearBean getNew_year() { + return new_year; + } + + public void setNew_year(NewYearBean new_year) { + this.new_year = new_year; + } + + public static class NewYearBean { + private String flag; + private String tip; + + public String getFlag() { + return flag; + } + + public void setFlag(String flag) { + this.flag = flag; + } + + public String getTip() { + return tip; + } + + public void setTip(String tip) { + this.tip = tip; + } + } + } + } + + public static class MagicboxDataBean { + } + + public static class PoiListBean { + private String rating; + private String tel; + private String typecode; + private String areacode; + private String cityname; + private String display_brand; + private String shape_region; + private String longitude; + private String address; + private String cinemazuo_flag; + private String diner_flag; + private String id; + private String name; + private String group_flag; + private String distance; + private String recommend_flag; + private String adcode; + private String newtype; + private String disp_name; + private String cpdata; + private String latitude; + private String discount_flag; + private List entrances; + private List exits; + /** + * type : html + * id : 1015 + * name : poiclosed + */ + + private List domain_list; + + public String getRating() { + return rating; + } + + public void setRating(String rating) { + this.rating = rating; + } + + public String getTel() { + return tel; + } + + public void setTel(String tel) { + this.tel = tel; + } + + public String getTypecode() { + return typecode; + } + + public void setTypecode(String typecode) { + this.typecode = typecode; + } + + public String getAreacode() { + return areacode; + } + + public void setAreacode(String areacode) { + this.areacode = areacode; + } + + public String getCityname() { + return cityname; + } + + public void setCityname(String cityname) { + this.cityname = cityname; + } + + public String getDisplay_brand() { + return display_brand; + } + + public void setDisplay_brand(String display_brand) { + this.display_brand = display_brand; + } + + public String getShape_region() { + return shape_region; + } + + public void setShape_region(String shape_region) { + this.shape_region = shape_region; + } + + public String getLongitude() { + return longitude; + } + + public void setLongitude(String longitude) { + this.longitude = longitude; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getCinemazuo_flag() { + return cinemazuo_flag; + } + + public void setCinemazuo_flag(String cinemazuo_flag) { + this.cinemazuo_flag = cinemazuo_flag; + } + + public String getDiner_flag() { + return diner_flag; + } + + public void setDiner_flag(String diner_flag) { + this.diner_flag = diner_flag; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getGroup_flag() { + return group_flag; + } + + public void setGroup_flag(String group_flag) { + this.group_flag = group_flag; + } + + public String getDistance() { + return distance; + } + + public void setDistance(String distance) { + this.distance = distance; + } + + public String getRecommend_flag() { + return recommend_flag; + } + + public void setRecommend_flag(String recommend_flag) { + this.recommend_flag = recommend_flag; + } + + public String getAdcode() { + return adcode; + } + + public void setAdcode(String adcode) { + this.adcode = adcode; + } + + public String getNewtype() { + return newtype; + } + + public void setNewtype(String newtype) { + this.newtype = newtype; + } + + public String getDisp_name() { + return disp_name; + } + + public void setDisp_name(String disp_name) { + this.disp_name = disp_name; + } + + public String getCpdata() { + return cpdata; + } + + public void setCpdata(String cpdata) { + this.cpdata = cpdata; + } + + public String getLatitude() { + return latitude; + } + + public void setLatitude(String latitude) { + this.latitude = latitude; + } + + public String getDiscount_flag() { + return discount_flag; + } + + public void setDiscount_flag(String discount_flag) { + this.discount_flag = discount_flag; + } + + public List getEntrances() { + return entrances; + } + + public void setEntrances(List entrances) { + this.entrances = entrances; + } + + public List getExits() { + return exits; + } + + public void setExits(List exits) { + this.exits = exits; + } + + public List getDomain_list() { + return domain_list; + } + + public void setDomain_list(List domain_list) { + this.domain_list = domain_list; + } + + public static class DomainListBean { + private String type; + private String id; + private String name; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } + } + + public static class ClassifyBean { + private String checkedvalue; + private String name; + private String ctype; + private int flag; + /** + * alias : + * multiselect : + * name : 全部分类 + * value : category=0601|061000|061001|0603|0606|0607|0605|060800|0613 + * display : + */ + + private List category; + + public String getCheckedvalue() { + return checkedvalue; + } + + public void setCheckedvalue(String checkedvalue) { + this.checkedvalue = checkedvalue; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCtype() { + return ctype; + } + + public void setCtype(String ctype) { + this.ctype = ctype; + } + + public int getFlag() { + return flag; + } + + public void setFlag(int flag) { + this.flag = flag; + } + + public List getCategory() { + return category; + } + + public void setCategory(List category) { + this.category = category; + } + + public static class CategoryBean { + private String alias; + private String multiselect; + private String name; + private String value; + private String display; + + public String getAlias() { + return alias; + } + + public void setAlias(String alias) { + this.alias = alias; + } + + public String getMultiselect() { + return multiselect; + } + + public void setMultiselect(String multiselect) { + this.multiselect = multiselect; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getDisplay() { + return display; + } + + public void setDisplay(String display) { + this.display = display; + } + } + } + } + + public static class ClassifyBean { + /** + * checkedvalue : filter_keywords=宠物市场 + * category : [{"alias":"","multiselect":"","name":"全部分类","value":"category=0601|061000|061001|0603|0606|0607|0605|060800|0613","display":""},{"alias":"","multiselect":"","name":"超市","value":"filter_keywords=超市","display":""},{"category":[{"alias":"","name":"全部","value":"category=060101|060103"},{"alias":"","name":"购物中心","value":"filter_keywords=购物中心"},{"alias":"","name":"免税品店","value":"category=060103"}],"alias":"","multiselect":"","name":"综合商场","display":""},{"category":[{"alias":"","name":"全部","value":"category=061000|061001"},{"alias":"","name":"特色商业街","value":"category=061000"},{"alias":"","name":"步行街","value":"filter_keywords=步行街"}],"alias":"","multiselect":"","name":"商业街","display":""},{"category":[{"alias":"","name":"全部","value":"filter_keywords=家电卖场"},{"alias":"","name":"家电电子卖场","value":"category=060300"},{"alias":"","name":"综合家电商场","value":"filter_keywords=综合家电"},{"alias":"","name":"国美","value":"category=060302"},{"alias":"","name":"大中","value":"filter_keywords=大中电器"},{"alias":"","name":"苏宁","value":"category=060304"},{"alias":"","name":"手机销售","value":"filter_keywords=手机销售"},{"alias":"","name":"数码电子","value":"filter_keywords=数码电子"}],"alias":"","multiselect":"","name":"家电","display":""},{"category":[{"alias":"","name":"全部","value":"filter_keywords=家具建材"},{"alias":"","name":"家具建材市场","value":"category=060601"},{"alias":"","name":"家具城","value":"filter_keywords=家具城"},{"alias":"","name":"建材五金市场","value":"filter_keywords=建材五金市场"},{"alias":"","name":"厨卫市场","value":"category=060604"},{"alias":"","name":"布艺市场","value":"category=060605"},{"alias":"","name":"灯具瓷器市场","value":"category=060606"}],"alias":"","multiselect":"","name":"家具建材","display":""},{"category":[{"alias":"","name":"全部","value":"filter_keywords=综合市场"},{"alias":"","name":"小商品市场","value":"filter_keywords=小商品批发市场"},{"alias":"","name":"旧货市场","value":"category=060702"},{"alias":"","name":"农副产品市场","value":"filter_keywords=农产品批发市场"},{"alias":"","name":"果品市场","value":"filter_keywords=果品批发市场"},{"alias":"","name":"蔬菜市场","value":"filter_keywords=蔬菜市场"},{"alias":"","name":"水产海鲜市场","value":"filter_keywords=水产海鲜市场"}],"alias":"","multiselect":"","name":"综合市场","display":""},{"alias":"","multiselect":"","name":"文化用品店","value":"filter_keywords=文化办公用品","display":""},{"category":[{"alias":"","name":"全部","value":"category=060500|060501|060502"},{"alias":"","name":"花鸟鱼虫市场","value":"filter_keywords=花鸟市场"},{"alias":"","name":"花卉市场","value":"filter_keywords=花卉市场"},{"alias":"","name":"宠物市场","value":"filter_keywords=宠物市场"}],"alias":"","multiselect":"","name":"花鸟市场","display":""},{"category":[{"alias":"","name":"全部","value":"category=061301|061302"},{"alias":"","name":"拍卖行","value":"category=061301"},{"alias":"","name":"典当行","value":"category=061302"}],"alias":"","multiselect":"","name":"买卖场所","display":""}] + * name : 全部分类 + * ctype : category + * flag : 2 + */ + + private ClassifyTypeBean classify_type; + /** + * checkedvalue : sort_rule=0;reserved_keywords=true + * category : [{"name":"推荐排序","value":"sort_rule=0;reserved_keywords=true"},{"name":"距离优先","value":"sort_rule=1;reserved_keywords=true"},{"name":"好评优先","value":"sort_rule=5;sort_fields=rating:d;reserved_keywords=true"},{"name":"低价优先","value":"sort_rule=5;sort_fields=averagecost:a0;reserved_keywords=true"},{"name":"高价优先","value":"sort_rule=5;sort_fields=averagecost:d;reserved_keywords=true"}] + * name : 排序 + * ctype : filter + */ + + private ClassifySortBean classify_sort; + private int count; + + public ClassifyTypeBean getClassify_type() { + return classify_type; + } + + public void setClassify_type(ClassifyTypeBean classify_type) { + this.classify_type = classify_type; + } + + public ClassifySortBean getClassify_sort() { + return classify_sort; + } + + public void setClassify_sort(ClassifySortBean classify_sort) { + this.classify_sort = classify_sort; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + public static class ClassifyTypeBean { + private String checkedvalue; + private String name; + private String ctype; + private int flag; + /** + * alias : + * multiselect : + * name : 全部分类 + * value : category=0601|061000|061001|0603|0606|0607|0605|060800|0613 + * display : + */ + + private List category; + + public String getCheckedvalue() { + return checkedvalue; + } + + public void setCheckedvalue(String checkedvalue) { + this.checkedvalue = checkedvalue; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCtype() { + return ctype; + } + + public void setCtype(String ctype) { + this.ctype = ctype; + } + + public int getFlag() { + return flag; + } + + public void setFlag(int flag) { + this.flag = flag; + } + + public List getCategory() { + return category; + } + + public void setCategory(List category) { + this.category = category; + } + + public static class CategoryBean { + private String alias; + private String multiselect; + private String name; + private String value; + private String display; + + public String getAlias() { + return alias; + } + + public void setAlias(String alias) { + this.alias = alias; + } + + public String getMultiselect() { + return multiselect; + } + + public void setMultiselect(String multiselect) { + this.multiselect = multiselect; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getDisplay() { + return display; + } + + public void setDisplay(String display) { + this.display = display; + } + } + } + + public static class ClassifySortBean { + private String checkedvalue; + private String name; + private String ctype; + /** + * name : 推荐排序 + * value : sort_rule=0;reserved_keywords=true + */ + + private List category; + + public String getCheckedvalue() { + return checkedvalue; + } + + public void setCheckedvalue(String checkedvalue) { + this.checkedvalue = checkedvalue; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCtype() { + return ctype; + } + + public void setCtype(String ctype) { + this.ctype = ctype; + } + + public List getCategory() { + return category; + } + + public void setCategory(List category) { + this.category = category; + } + + public static class CategoryBean { + private String name; + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + } + } + + public static class BizAreaDataBean { + private String citycode; + private String adcode; + private String name; + private String center; + private String level; + private String checkedvalue; + /** + * citycode : 0731 + * adcode : 430102 + * name : 芙蓉区 + * center : 112.988094,28.193106 + * level : district + * districts : [{"citycode":"0731","adcode":"430102","name":"德政园","center":"113.022609,28.186145","level":"biz_area","areacode":"19749","districts":[]},{"citycode":"0731","adcode":"430102","name":"定王台","center":"112.985227,28.190025","level":"biz_area","areacode":"19750","districts":[]},{"citycode":"0731","adcode":"430102","name":"黄兴路","center":"112.976687,28.190437","level":"biz_area","areacode":"19751","districts":[]},{"citycode":"0731","adcode":"430102","name":"韭菜园","center":"112.988766,28.194756","level":"biz_area","areacode":"19752","districts":[]},{"citycode":"0731","adcode":"430102","name":"马王堆","center":"113.028870,28.195465","level":"biz_area","areacode":"19753","districts":[]},{"citycode":"0731","adcode":"430102","name":"五里牌","center":"113.011699,28.198328","level":"biz_area","areacode":"19754","districts":[]},{"citycode":"0731","adcode":"430102","name":"湘湖","center":"113.012682,28.205252","level":"biz_area","areacode":"19755","districts":[]},{"citycode":"0731","adcode":"430102","name":"袁家岭","center":"112.997033,28.194455","level":"biz_area","areacode":"19756","districts":[]},{"citycode":"0731","adcode":"430102","name":"八一路","center":"113.000355,28.197485","level":"biz_area","areacode":"19757","districts":[]},{"citycode":"0731","adcode":"430102","name":"朝阳路","center":"113.007038,28.189212","level":"biz_area","areacode":"19758","districts":[]},{"citycode":"0731","adcode":"430102","name":"东屯渡","center":"113.038626,28.194082","level":"biz_area","areacode":"19759","districts":[]},{"citycode":"0731","adcode":"430102","name":"芙蓉广场","center":"112.995054,28.197940","level":"biz_area","areacode":"19760","districts":[]},{"citycode":"0731","adcode":"430102","name":"芙蓉中路","center":"112.986125,28.187681","level":"biz_area","areacode":"19761","districts":[]},{"citycode":"0731","adcode":"430102","name":"荷花路","center":"113.032740,28.191378","level":"biz_area","areacode":"19762","districts":[]},{"citycode":"0731","adcode":"430102","name":"荷花园","center":"113.021219,28.191605","level":"biz_area","areacode":"19763","districts":[]},{"citycode":"0731","adcode":"430102","name":"火星","center":"113.023431,28.202349","level":"biz_area","areacode":"19764","districts":[]},{"citycode":"0731","adcode":"430102","name":"凌霄路","center":"113.029080,28.202090","level":"biz_area","areacode":"19765","districts":[]},{"citycode":"0731","adcode":"430102","name":"浏正街","center":"112.984803,28.191896","level":"biz_area","areacode":"19766","districts":[]},{"citycode":"0731","adcode":"430102","name":"三湘大市场","center":"113.016648,28.202302","level":"biz_area","areacode":"19768","districts":[]},{"citycode":"0731","adcode":"430102","name":"万家丽","center":"113.030236,28.185394","level":"biz_area","areacode":"19770","districts":[]},{"citycode":"0731","adcode":"430102","name":"文艺路","center":"112.994009,28.191407","level":"biz_area","areacode":"19771","districts":[]},{"citycode":"0731","adcode":"430102","name":"五一大道","center":"112.988446,28.194898","level":"biz_area","areacode":"19772","districts":[]},{"citycode":"0731","adcode":"430102","name":"燕山街","center":"113.000486,28.196539","level":"biz_area","areacode":"19773","districts":[]},{"citycode":"0731","adcode":"430102","name":"远大路","center":"113.027617,28.198384","level":"biz_area","areacode":"19774","districts":[]},{"citycode":"0731","adcode":"430102","name":"中山路","center":"112.979051,28.199921","level":"biz_area","areacode":"19775","districts":[]},{"citycode":"0731","adcode":"430102","name":"车站中路","center":"113.010938,28.193068","level":"biz_area","areacode":"19776","districts":[]},{"citycode":"0731","adcode":"430102","name":"芙蓉区政府","center":"113.003653,28.194434","level":"biz_area","areacode":"19785","districts":[]},{"citycode":"0731","adcode":"430102","name":"解放东路","center":"113.005201,28.190678","level":"biz_area","areacode":"19792","districts":[]},{"citycode":"0731","adcode":"430102","name":"解放西路","center":"112.979381,28.191326","level":"biz_area","areacode":"19813","districts":[]},{"citycode":"0731","adcode":"430102","name":"都正街","center":"112.981833,28.187702","level":"biz_area","areacode":"19814","districts":[]},{"citycode":"0731","adcode":"430102","name":"火车站","center":"113.011203,28.193686","level":"biz_area","areacode":"19830","districts":[]},{"citycode":"0731","adcode":"430102","name":"车站北路","center":"113.009321,28.207354","level":"biz_area","areacode":"19845","districts":[]}] + */ + + private List districts; + + public String getCitycode() { + return citycode; + } + + public void setCitycode(String citycode) { + this.citycode = citycode; + } + + public String getAdcode() { + return adcode; + } + + public void setAdcode(String adcode) { + this.adcode = adcode; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCenter() { + return center; + } + + public void setCenter(String center) { + this.center = center; + } + + public String getLevel() { + return level; + } + + public void setLevel(String level) { + this.level = level; + } + + public String getCheckedvalue() { + return checkedvalue; + } + + public void setCheckedvalue(String checkedvalue) { + this.checkedvalue = checkedvalue; + } + + public List getDistricts() { + return districts; + } + + public void setDistricts(List districts) { + this.districts = districts; + } + + public static class DistrictsBean { + private String citycode; + private String adcode; + private String name; + private String center; + private String level; + /** + * citycode : 0731 + * adcode : 430102 + * name : 德政园 + * center : 113.022609,28.186145 + * level : biz_area + * areacode : 19749 + * districts : [] + */ + + private List districts; + + public String getCitycode() { + return citycode; + } + + public void setCitycode(String citycode) { + this.citycode = citycode; + } + + public String getAdcode() { + return adcode; + } + + public void setAdcode(String adcode) { + this.adcode = adcode; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCenter() { + return center; + } + + public void setCenter(String center) { + this.center = center; + } + + public String getLevel() { + return level; + } + + public void setLevel(String level) { + this.level = level; + } + + public List getDistricts() { + return districts; + } + + public void setDistricts(List districts) { + this.districts = districts; + } + + public static class DistrictsBea { + private String citycode; + private String adcode; + private String name; + private String center; + private String level; + private String areacode; + private List districts; + + public String getCitycode() { + return citycode; + } + + public void setCitycode(String citycode) { + this.citycode = citycode; + } + + public String getAdcode() { + return adcode; + } + + public void setAdcode(String adcode) { + this.adcode = adcode; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCenter() { + return center; + } + + public void setCenter(String center) { + this.center = center; + } + + public String getLevel() { + return level; + } + + public void setLevel(String level) { + this.level = level; + } + + public String getAreacode() { + return areacode; + } + + public void setAreacode(String areacode) { + this.areacode = areacode; + } + + public List getDistricts() { + return districts; + } + + public void setDistricts(List districts) { + this.districts = districts; + } + } + } + } +} diff --git a/src/server/pom.xml b/src/server/pom.xml index ab4f8f1..7a65126 100644 --- a/src/server/pom.xml +++ b/src/server/pom.xml @@ -17,6 +17,11 @@ 1.8 + + org.glassfish + javax.json + 1.0.4 + org.springframework.boot spring-boot-starter-websocket diff --git a/src/server/src/main/java/com/example/testdemo/ServerApplication.java b/src/server/src/main/java/com/example/testdemo/ServerApplication.java new file mode 100644 index 0000000..a9c32f1 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ServerApplication.java @@ -0,0 +1,18 @@ +package com.example.testdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + + +@SpringBootApplication +public class ServerApplication { + + public static void main(String[] args) { + + SpringApplication.run(ServerApplication.class, args); + } + + +} + + diff --git a/src/server/src/main/java/com/example/testdemo/TestdemoApplication.java b/src/server/src/main/java/com/example/testdemo/TestdemoApplication.java deleted file mode 100644 index 5b0706c..0000000 --- a/src/server/src/main/java/com/example/testdemo/TestdemoApplication.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.example.testdemo; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; -import com.sun.javafx.webkit.EventLoopImpl; -import org.openqa.selenium.*; -import org.openqa.selenium.chrome.ChromeDriver; -import org.openqa.selenium.chrome.ChromeOptions; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.scheduling.annotation.EnableScheduling; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.sql.Driver; -import java.util.Arrays; -import java.util.List; -import java.util.Random; -import java.util.concurrent.ConcurrentLinkedQueue; - - -@SpringBootApplication -public class TestdemoApplication { - - public static void main(String[] args) { - - SpringApplication.run(TestdemoApplication.class, args); - } - - -} - - diff --git a/src/server/src/main/java/com/example/testdemo/config/SendObjectMessage.java b/src/server/src/main/java/com/example/testdemo/config/SendObjectMessage.java index 1b84ae8..158c364 100644 --- a/src/server/src/main/java/com/example/testdemo/config/SendObjectMessage.java +++ b/src/server/src/main/java/com/example/testdemo/config/SendObjectMessage.java @@ -23,28 +23,25 @@ import java.io.IOException; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.atomic.AtomicInteger; -/** - * @Description : 群发消息 //描述 - */ + @Slf4j @ServerEndpoint("/result") @Component public class SendObjectMessage { - /** 记录当前在线连接数 */ + private static String TAG = "SendObjectMessage"; private static AtomicInteger onlineCount = new AtomicInteger(0); private static ConcurrentLinkedQueue socket = new ConcurrentLinkedQueue(); - /** - * 与某个客户端的连接会话,需要通过它来给客户端发送数据 - */ + + private Session session; private SendObjectMessage mObject = null; - /** - * 连接建立成功调用的方法 - */ + @OnOpen public void onOpen(Session session) { + + log.info(TAG, "open"); this.session = session; socket.add(this); onlineCount.incrementAndGet(); // 在线数加1 @@ -59,31 +56,31 @@ public class SendObjectMessage { log.info("有新连接加入,当前在线人数为:{}", onlineCount.get()); } - /** - * 连接关闭调用的方法 - */ @OnClose public void onClose(Session session) { + + log.info(TAG, "onclose"); socket.remove(this); // 在线数减1 onlineCount.decrementAndGet(); log.info("用户退出,当前在线人数为:{}", onlineCount.get()); } - /** - * 收到客户端消息后调用的方法 - * - * @param message - * 客户端发送过来的消息 - */ + @OnMessage public void onMessage(String message, Session session) throws IOException { + + log.info(TAG, "onMessage"); if (message != null && !message.isEmpty()) { + + log.info(TAG, "message has value"); //socket.peek().sendMessage(message); JSONObject js = JSONObject.parseObject(message); String op = js.getString("op"); if(op.equals("connect")){ + + log.info(TAG, "connect"); JSONObject content = js.getJSONObject("content"); String user = content.getString("user"); //JSONArray note = content.getJSONArray("note"); @@ -98,20 +95,26 @@ public class SendObjectMessage { String con = js.getString("content"); if(con.equals("yes")){ try { + + log.info(TAG, "testSelenium1"); testSelenium1(); + } catch (Exception e) { + e.printStackTrace(); + } System.out.println("robot"); }else if(con.equals("no")){ System.out.println("no"); } }else if(op.equals("finish")){ - System.out.println("fin"); + log.info(TAG, "finish"); mObject.onClose(mObject.session); socket.poll(); if(socket.peek() != null){ + log.info(TAG, "has no ths first node"); mObject = socket.peek(); mObject.sendMessage("confirm"); }else{ @@ -128,22 +131,20 @@ public class SendObjectMessage { error.printStackTrace(); } - /** - * 服务端发送消息给客户端 - */ + public void sendMessage(String message) throws IOException { //如果开启@Async异步需要加锁,否则就会报错 + + log.info(TAG, "sendMessage"); synchronized (session){ this.session.getBasicRemote().sendText(message); } } - /** - * 自定义群发 - */ public static void testSelenium1() throws Exception { // 使用HtmlUnitDriver 是不需要 安装 浏览器 和 驱动支持\ + System.setProperty("webdriver.chrome.driver", "D:\\chromedriver.exe"); ChromeOptions chromeOptions = new ChromeOptions(); chromeOptions.setHeadless(true); @@ -158,19 +159,21 @@ public class SendObjectMessage { } - private static String readJsFile(String url) throws Exception { + private static String readJsFile(String url) throws Exception {//读取js文件 + + log.info(TAG, "readjsfile"); StringBuffer script = new StringBuffer(); File file = new File(url); FileReader filereader = new FileReader(file); - BufferedReader bufferedReader = new BufferedReader(filereader); + BufferedReader bufferedReader = new BufferedReader(filereader);//读取js文件 String tempString = null; while ((tempString = bufferedReader.readLine()) != null) { script.append(tempString).append("\n"); } bufferedReader.close(); filereader.close(); - return script.toString(); + return script.toString();//返回读取的文件流 } } diff --git a/src/server/src/main/java/com/example/testdemo/config/WebSocketConfig.java b/src/server/src/main/java/com/example/testdemo/config/WebSocketConfig.java index dc62fa8..b21c88e 100644 --- a/src/server/src/main/java/com/example/testdemo/config/WebSocketConfig.java +++ b/src/server/src/main/java/com/example/testdemo/config/WebSocketConfig.java @@ -4,9 +4,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; -/** - * @Description : websocket配置 //描述 - */ + @Configuration public class WebSocketConfig { diff --git a/src/server/src/main/java/com/example/testdemo/ros/Publisher.java b/src/server/src/main/java/com/example/testdemo/ros/Publisher.java new file mode 100644 index 0000000..775ccbc --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/Publisher.java @@ -0,0 +1,57 @@ +package com.example.testdemo.ros; + + +public class Publisher { + + protected String topic; + protected String msgType; + protected int rosBridge; + + + public Publisher(String topic, String msgType, int rosBridge){ + this.topic = topic; + this.msgType = msgType; + this.rosBridge = rosBridge; + + //this.rosBridge.advertise(this.topic, this.msgType); + + } + + + public Publisher(String topic, String msgType, int rosBridge, boolean advertiseNow){ + this.topic = topic; + this.msgType = msgType; + this.rosBridge = rosBridge; + + if(advertiseNow) { + //this.rosBridge.advertise(this.topic, this.msgType); + } + + } + + + + public String getTopic() { + return topic; + } + + + /** + * Returns the ROS message type of the topic to which this object publishes. + * @return the ROS message type of the topic to which this object publishes. + */ + public String getMsgType() { + return msgType; + } + + + /** + * Returns the {@link ros.RosBridge} object that manages the connection to the ROS Bridge server. + * @return the {@link ros.RosBridge} object that manages the connection to the ROS Bridge server. + */ + + + /** + * Unadvertises that you are publishing to the topic. + */ +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/RosListenDelegate.java b/src/server/src/main/java/com/example/testdemo/ros/RosListenDelegate.java new file mode 100644 index 0000000..2fd06fe --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/RosListenDelegate.java @@ -0,0 +1,85 @@ +package com.example.testdemo.ros; + +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +/** + * This is a delegate interface for handling ros topic subscriptions. The {@link #receive(JsonNode, String)} + * is called every time the topic with which this delegate is associated has a new message published. + * The JSON data, given as a {@link JsonNode}, has four top-level fields:

+ * op: what kind of operation it was; should always be "publish"

+ * topic: to which topic the message was published

+ * type: the ROS message type of the topic

+ * msg: the provided ros message in JSON format. This the primary field you will work with.

+ * There are generally two ways you can parse the message into a more usable Java object. The first involves manually + * iterating through the JSON fields of the msg. For example, + * for a geometry_msgs/Twist message, you can get out the linear x value as follows:

+ * double x = data.get("msg").get("linear").get("x").asDouble();

+ * (If an element is na array, JSON methods exist for handling it such as {@link JsonNode#get(int)} + * and {@link JsonNode#size()}). The the other way is to let the Jackson library unpack + * it into a JavaBean. The {@link ros.tools.MessageUnpacker} class further streamlines this process. See its documentation + * for more information. + * @author James MacGlashan. + */ +public interface RosListenDelegate { + + /** + * Receives a new published message to a subscribed topic. The JSON data, given as a {@link JsonNode}, has four top-level fields:

+ * op: what kind of operation it was; should always be "publish"

+ * topic: to which topic the message was published

+ * type: the ROS message type of the topic

+ * msg: the provided ros message in JSON format. This the primary field you will work with.

+ * This method also receives the full string representation of the received JSON message from ROSBridge. + * @param data the {@link JsonNode} containing the JSON data received. + * @param stringRep the string representation of the JSON object. + */ + void receive(JsonNode data, String stringRep); + + + /** + * A class for easy conversion to the legacy java_rosbridge {@link #receive(JsonNode, String)} + * message format that presented the JSON data + * in a {@link Map} from {@link String} to {@link Object} instances + * in which the values were ether primitives, {@link Map} objects themselves, or {@link java.util.List} + * objects. + */ + public static class LegacyFormat{ + + /** + * A method for easy conversion to the legacy java_rosbridge {@link #receive(JsonNode, String)} + * message format that presented the JSON data + * in a {@link Map} from {@link String} to {@link Object} instances + * in which the values were ether primitives, {@link Map} objects themselves, or {@link java.util.List} + * objects. + * @param jsonString the source JSON string message that was received + * @return a {@link Map} data structure of the JSON data. + */ + public static Map legacyFormat(String jsonString){ + + JsonFactory jsonFactory = new JsonFactory(); + Map messageData = new HashMap(); + try { + ObjectMapper objectMapper = new ObjectMapper(jsonFactory); + TypeReference> listTypeRef = + new TypeReference>() {}; + messageData = objectMapper.readValue(jsonString, listTypeRef); + } catch (JsonParseException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + return messageData; + } + } + + + +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/SubscriptionRequestMsg.java b/src/server/src/main/java/com/example/testdemo/ros/SubscriptionRequestMsg.java new file mode 100644 index 0000000..a0739fe --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/SubscriptionRequestMsg.java @@ -0,0 +1,118 @@ +package com.example.testdemo.ros; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.util.HashMap; +import java.util.Map; + +/** + * A Subscription request builder. Supports all Rosbridge protocol fields for + * a subscription request except png compression. Requires a topic to be set, + * with the rest of the optional values set with setter methods that return + * the this object so that you can chain settters on a single line. Use + * the static {@link #generate(String)} to start the sequence. If a value is set + * to null, it will be removed from the message. + *

+ * When everything is set, the JSON message can be retrieved with the {@link #generateJsonString()} + * @author James MacGlashan. + */ +public class SubscriptionRequestMsg { + + protected Map keyValues = new HashMap(7); + + public static SubscriptionRequestMsg generate(String topic){ + return new SubscriptionRequestMsg(topic); + } + + public SubscriptionRequestMsg(String topic){ + if(topic == null){ + throw new RuntimeException("ROS topic cannot be null in subscription request."); + } + keyValues.put("op", "subscribe"); + keyValues.put("topic", topic); + } + + public SubscriptionRequestMsg setTopic(String topic){ + this.setKeyValue("topic", topic); + return this; + } + + public SubscriptionRequestMsg setType(String type){ + this.setKeyValue("type", type); + return this; + } + + public SubscriptionRequestMsg setThrottleRate(Integer throttleRate){ + this.setKeyValue("throttle_rate", throttleRate); + return this; + } + + public SubscriptionRequestMsg setQueueLength(Integer queueLength){ + this.setKeyValue("queue_length", queueLength); + return this; + } + + public SubscriptionRequestMsg setFragmentSize(Integer fragmentSize){ + this.setKeyValue("fragment_size", fragmentSize); + return this; + } + + + public SubscriptionRequestMsg setId(String id){ + this.setKeyValue("id", id); + return this; + } + + public String getTopic(){ + return (String)this.keyValues.get("topic"); + } + + public String getType(){ + return (String)this.keyValues.get("type"); + } + + public Integer getThrottleRate(){ + return (Integer)this.keyValues.get("throttle_rate"); + } + + public Integer getQueueLength(){ + return (Integer)this.keyValues.get("queue_length"); + } + + public Integer getFragmentSize(){ + return (Integer)this.keyValues.get("fragment_size"); + } + + + public String getId(){ + return (String)this.keyValues.get("id"); + } + + /** + * Generates the JSON string for this subscription request. + * @return the JSON string for this subscription request. + */ + public String generateJsonString(){ + ObjectMapper mapper = new ObjectMapper(); + String jsonString = null; + try { + jsonString = mapper.writeValueAsString(this.keyValues); + } catch(JsonProcessingException e) { + e.printStackTrace(); + } + + return jsonString; + } + + + protected void setKeyValue(String key, Object value){ + if(value == null){ + this.keyValues.remove(key); + } + else{ + this.keyValues.put(key, value); + } + } + +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/msgs/geometry_msgs/Twist.java b/src/server/src/main/java/com/example/testdemo/ros/msgs/geometry_msgs/Twist.java new file mode 100644 index 0000000..9b138e4 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/msgs/geometry_msgs/Twist.java @@ -0,0 +1,19 @@ +package com.example.testdemo.ros.msgs.geometry_msgs; + +/** + * A Java Bean for the Vector3 ROS geometry_msgs/Twist message type. This can be used both for publishing Twist messages to + * {@link ros.RosBridge} and unpacking Twist messages received from {@link ros.RosBridge} (see the {@link ros.tools.MessageUnpacker} + * documentation for how to easily unpack a ROS Bridge message into a Java object). + * @author James MacGlashan. + */ +public class Twist { + public Vector3 linear = new Vector3(); + public Vector3 angular = new Vector3(); + + public Twist(){} + + public Twist(Vector3 linear, Vector3 angular) { + this.linear = linear; + this.angular = angular; + } +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/msgs/geometry_msgs/Vector3.java b/src/server/src/main/java/com/example/testdemo/ros/msgs/geometry_msgs/Vector3.java new file mode 100644 index 0000000..13b3aa3 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/msgs/geometry_msgs/Vector3.java @@ -0,0 +1,21 @@ +package com.example.testdemo.ros.msgs.geometry_msgs; + +/** + * A Java Bean for the Vector3 ROS geometry_msgs/Vector3 message type. This can be used both for publishing Vector3 messages to + * {@link ros.RosBridge} and unpacking Vector3 messages received from {@link ros.RosBridge} (see the {@link ros.tools.MessageUnpacker} + * documentation for how to easily unpack a ROS Bridge message into a Java object). + * @author James MacGlashan. + */ +public class Vector3 { + public double x; + public double y; + public double z; + + public Vector3(){} + + public Vector3(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/msgs/sensor_msgs/Image.java b/src/server/src/main/java/com/example/testdemo/ros/msgs/sensor_msgs/Image.java new file mode 100644 index 0000000..35f60b8 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/msgs/sensor_msgs/Image.java @@ -0,0 +1,125 @@ +package com.example.testdemo.ros.msgs.sensor_msgs; + +import com.example.testdemo.ros.message.Header; + +import java.awt.image.BufferedImage; + +/** + * Implementation of ROS sensor_msgs/Image.msg: + * http://docs.ros.org/api/sensor_msgs/html/msg/Image.html. + * This class can also decode the ROS Image into a Java Buffered Image for images that are encoded in either + * bgr8, rgb8, or mono8, by using the {@link #toBufferedImage()} method. + * @author James MacGlashan. + */ +public class Image { + + public Header header; + public int height; + public int width; + public String encoding; + public int is_bigendian; + public int step; + public byte[] data; + + public Image() { + } + + public Image(Header header, int height, int width, String encoding, int is_bigendian, int step, byte[] data) { + this.header = header; + this.height = height; + this.width = width; + this.encoding = encoding; + this.is_bigendian = is_bigendian; + this.step = step; + this.data = data; + } + + /** + * Constructs a {@link BufferedImage} from this ROS Image, provided the encoding is either rgb8, bgr8, or mono8. + * If it is not one of those encodings, then a runtime exception will be thrown. + * @return a {@link BufferedImage} representation of this image. + */ + public BufferedImage toBufferedImage(){ + + if(this.encoding.equals("bgr8") || this.encoding.equals("rgb8")){ + return this.toBufferedImageFromRGB8(); + } + else if(this.encoding.equals("mono8")){ + return this.toBufferedImageFromMono8(); + } + + + throw new RuntimeException("ROS Image does not currently decode " + this.encoding + ". See Java doc for support types."); + } + + + /** + * Constructs a {@link BufferedImage} from this ROS Image assuming the encoding is mono8 + * @return a {@link BufferedImage} representation of this image. + */ + protected BufferedImage toBufferedImageFromMono8(){ + int w = this.width; + int h = this.height; + + BufferedImage i = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); + for (int y = 0; y < h; ++y) { + for(int x = 0; x < w; ++x) { + + //row major + int index = (y * w) + x; + // combine to RGB format + int anded = data[index++] & 0xFF; + int rgb = anded | + (anded << 8) | + (anded << 16) | + 0xFF000000; + + i.setRGB(x, y, rgb); + } + } + + return i; + } + + + /** + * Constructs a {@link BufferedImage} representation from this ROS Image assuming the encoding is either rgb8 or bgr8. + * @return a {@link BufferedImage} representation of this image. + */ + protected BufferedImage toBufferedImageFromRGB8(){ + + int w = this.width; + int h = this.height; + + BufferedImage i = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); + for (int y = 0; y < h; ++y) { + for (int x = 0; x < w; ++x) { + + //row major, consecutive channels + int index = (y * w * 3) + (x * 3); + // combine to RGB format + int rgb; + if(this.encoding.equals("bgr8")){ + rgb = ((data[index++] & 0xFF)) | + ((data[index++] & 0xFF) << 8) | + ((data[index++] & 0xFF) << 16) | + 0xFF000000; + } + else if(this.encoding.equals("rgb8")){ + rgb = ((data[index++] & 0xFF) << 16) | + ((data[index++] & 0xFF) << 8) | + ((data[index++] & 0xFF)) | + 0xFF000000; + } + else{ + throw new RuntimeException("ROS Image toBufferedImageFromRGB8 does not decode " + this.encoding); + } + i.setRGB(x, y, rgb); + } + } + + return i; + + } + +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/msgs/std_msgs/Header.java b/src/server/src/main/java/com/example/testdemo/ros/msgs/std_msgs/Header.java new file mode 100644 index 0000000..a3eb410 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/msgs/std_msgs/Header.java @@ -0,0 +1,21 @@ +package com.example.testdemo.ros.msgs.std_msgs; + +/** + * @author James MacGlashan. + */ +public class Header { + + public int seq; + public Time stamp; + public String frame_id; + + public Header() { + } + + public Header(int seq, Time stamp, String frame_id) { + this.seq = seq; + this.stamp = stamp; + this.frame_id = frame_id; + } + +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/msgs/std_msgs/PrimitiveMsg.java b/src/server/src/main/java/com/example/testdemo/ros/msgs/std_msgs/PrimitiveMsg.java new file mode 100644 index 0000000..0bc0deb --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/msgs/std_msgs/PrimitiveMsg.java @@ -0,0 +1,12 @@ +package com.example.testdemo.ros.msgs.std_msgs; + +/** + * A generic specified Java Bean for capturing many of the primitive data-type messages used by ROS in the std_msgs + * package. The class has a single public data member called "data" that belongs to the specified primitive type. + * @author James MacGlashan. + */ +public class PrimitiveMsg { + public T data; + public PrimitiveMsg(){} + public PrimitiveMsg(T data){this.data = data;} +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/msgs/std_msgs/Time.java b/src/server/src/main/java/com/example/testdemo/ros/msgs/std_msgs/Time.java new file mode 100644 index 0000000..28526ac --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/msgs/std_msgs/Time.java @@ -0,0 +1,17 @@ +package com.example.testdemo.ros.msgs.std_msgs; + +/** + * @author James MacGlashan. + */ +public class Time { + public int secs; + public int nsecs; + + public Time() { + } + + public Time(int secs, int nsecs) { + this.secs = secs; + this.nsecs = nsecs; + } +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/implementation/JSON.java b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/implementation/JSON.java index 67a3d0b..6e4b231 100644 --- a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/implementation/JSON.java +++ b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/implementation/JSON.java @@ -24,8 +24,6 @@ import com.alibaba.fastjson.JSONObject; import com.example.testdemo.ros.message.Message; import com.example.testdemo.ros.rosbridge.indication.Indication; import com.example.testdemo.ros.rosbridge.operation.Wrapper; -import jdk.nashorn.internal.parser.JSONParser; - import java.io.StringReader; import java.lang.reflect.Array; diff --git a/src/server/src/main/java/com/example/testdemo/ros/tools/MessageUnpacker.java b/src/server/src/main/java/com/example/testdemo/ros/tools/MessageUnpacker.java new file mode 100644 index 0000000..31b3cbb --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/tools/MessageUnpacker.java @@ -0,0 +1,61 @@ +package com.example.testdemo.ros.tools; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * This is a helper class that may be used for taking a JSON message returned from Ros bridge, and unpacking + * the actual ros message inside it into a Java bean object. (A Java bean is a Java object that has a default + * constructor and getter and has either public data members or getter and setter methods for the data members + * using standard Java naming conventions.) + *

+ * To use this class, type the generic to the Java Bean class to which the message will be unpacked and provide + * the constructor the class of it as well. For example:

+ * MessageUnpacker<Twist> unpacker = new MessageUnpacker<Twist>(Twist.class);. Then provide the + * {@link #unpackRosMessage(JsonNode)} method the {@link JsonNode} + * provided to a {@link ros.RosListenDelegate} to unpack the "msg" field into the Java Bean. This will also work + * with Java Beans with generics. For example, you can do + * MessageUnpacker<PrimitiveMsg<String>> unpacker = new MessageUnpacker<PrimitiveMsg<String>>(PrimitiveMsg.class);. + * + * @author James MacGlashan. + */ +public class MessageUnpacker { + protected ObjectMapper mapper = new ObjectMapper(); + protected Class javaClass; + + /** + * Constructor. + * @param javaClass a {@link Class} specifying the class of the Java bean into which + * a ros message will be unpacked. + */ + public MessageUnpacker(Class javaClass) { + this.javaClass = javaClass; + } + + /** + * Unpacks a ros message into the appropriate Java bean from the JSON message returned by + * ros bridge. Note that the Ros bridge JSON message contains header information and the actual + * ROS message is stored in the 'msg' field in the JSON message. Therefore, this method should be provided the + * {@link JsonNode} that is given to a {@link ros.RosListenDelegate} + * {@link ros.RosListenDelegate#receive(JsonNode, String)} method. + * If the provided {@link JsonNode} argument of this method + * does not have a "msg" field, then it will attempt to unpack from the whole JSON node. + * @param rosBridgeMessage the {@link JsonNode} from RosBridge. + * @return the unpacked Java Bean of the ROS message. + */ + @SuppressWarnings("unchecked") + public T unpackRosMessage(JsonNode rosBridgeMessage){ + JsonNode rosMsgNode = rosBridgeMessage.get("msg"); + if(rosMsgNode == null){ + rosMsgNode = rosBridgeMessage; + } + T rosMsg = null; + try { + rosMsg = (T)mapper.treeToValue(rosMsgNode, javaClass); + } catch(JsonProcessingException e) { + e.printStackTrace(); + } + return rosMsg; + } +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/tools/PeriodicPublisher.java b/src/server/src/main/java/com/example/testdemo/ros/tools/PeriodicPublisher.java new file mode 100644 index 0000000..7d7dec2 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/tools/PeriodicPublisher.java @@ -0,0 +1,178 @@ +package com.example.testdemo.ros.tools; + +import com.example.testdemo.ros.Publisher; + +import java.util.Timer; +import java.util.TimerTask; + +/** + * This class is a tool for causing a ROS message to be periodically published at a given rate. To start periodic publishing + * use the {@link #beginPublishing(int)} or {@link #beginPublishing(Object, int)} methods. Note that subsequent calls + * to these method will automatically cancel the previous periodic publishing and start again at the newly specified rate. + * To cancel periodic publishing, use the {@link #cancelPublishing()} method. You can also change the message that is + * being published without stopping or restarting the publishing by using the {@link #setMsg(Object)} method. + * @author James MacGlashan. + */ +public class PeriodicPublisher { + + + /** + * The {@link Publisher} to which publish calls are made + */ + protected Publisher pub; + + /** + * The ROS message that will be periodically published + */ + protected volatile Object msg = null; + + /** + * The period at which this object is publishing; -1 if it is not currently publishing. + */ + protected int period = -1; + + /** + * The timer task that calls the publish. Null if this object is not periodically publishing. + */ + protected PublisherTimerTask timerTask; + + /** + * Initializes with a {@link Publisher} for this action using the specified topic, message type, and {@link RosBridge} connection. + * @param topic the ros topic to which messages will be published + * @param msgType the ros message type of th target topic + * @param rosBridge the {@link RosBridge} connection to use. + */ + + + /** + * Initializes with a {@link Publisher} for this action using the specified topic, message type, and {@link RosBridge} connection. + * @param topic the ros topic to which messages will be published + * @param msgType the ros message type of th target topic + * @param rosBridge the {@link RosBridge} connection to use. + * @param msg the ROS message to periodically publish when publishing begins + */ + + + /** + * Initializes with a {@link Publisher} for publishing action messages to ROS. + * @param pub the {@link Publisher} to which to publish + */ + public PeriodicPublisher(Publisher pub){ + this.pub = pub; + } + + /** + * Initializes with a {@link Publisher} for publishing action messages to ROS. + * @param pub the {@link Publisher} to which to publish + * @param msg the ROS message to periodically publish when publishing begins + */ + public PeriodicPublisher(Publisher pub, Object msg) { + this.pub = pub; + this.msg = msg; + } + + public Publisher getPub() { + return pub; + } + + public void setPub(Publisher pub) { + this.pub = pub; + } + + /** + * Returns the ROS message that is being or will be periodically published. + * @return the ROS message that is being or will be periodically published. + */ + public Object getMsg() { + return msg; + } + + /** + * Sets the ROS message that will be periodically published. Note that if the provided message is null and this + * object is already periodically publishing, a runtime error will be thrown. + * @param msg the ROS message that will be published. + */ + public void setMsg(Object msg) { + if(msg == null && this.timerTask != null){ + System.out.println("PeriodicPublisher is not setting message because new message is null and publisher is currently publishing."); + } + this.msg = msg; + } + + /** + * The delay in milliseconds between subsequent periodic publishes. Returns -1 if this object is not currently periodically publishing. + * @return The delay in milliseconds between subsequent publishes. Returns -1 if this object is not currently periodically publishing. + */ + public int getPublishingPeriod(){ + return this.period; + } + + /** + * Stops this object from periodically publishing, or does nothing if it is not currently periodically publishing. + */ + public void cancelPublishing(){ + if(this.timerTask != null) { + this.timerTask.cancel(); + this.timerTask = null; + this.period = -1; + } + } + + /** + * Indicates whether this object is currently periodically publishing. + * @return true if this object is periodically publishing; false if it is not. + */ + public boolean isPublishing(){ + return this.timerTask != null; + } + + + /** + * Causes this object to begin periodically publishing at the specified rate. If this object is + * already publishing then the previous publishing rate is canceled and started at the new rate. + * If the current message to + * publish is not set, then a runtime exception will be thrown. The message can be set either with the + * {@link #setMsg(Object)} method or by using the alternative {@link #beginPublishing(Object, int)} + * method that takes the message to publish. + * @param period the time in milliseconds between publishes + */ + public void beginPublishing(int period){ + if(this.msg == null){ + throw new RuntimeException("Cannot begin publishing because the message to publish is unset. " + + "Use the setMsg method or beginPublishing(Object msg, int period)"); + } + if(this.timerTask != null){ + this.timerTask.cancel(); + } + this.timerTask = new PublisherTimerTask(); + Timer timer = new Timer(); + timer.schedule(this.timerTask, 0, period); + } + + + /** + * Causes this object to begin periodically publishing the specified message at the specified rate. + * If this object is already publishing then the previous publishing rate is canceled and started at the new rate. + * Note that if the provided message is null then a runtime exception will be thrown. + * @param msg the ROS message to publish + * @param period the time in milliseconds between publishes + */ + public void beginPublishing(Object msg, int period){ + this.msg = msg; + this.beginPublishing(period); + } + + + /** + * The class that is called by Java's {@link Timer} and invokes the actual + * publish call. + */ + protected class PublisherTimerTask extends TimerTask{ + + @Override + public void run() { + //pub.publish(msg); + } + } + +} diff --git a/src/server/src/main/java/edu/wpi/rail/jrosbridge/JRosbridge.java b/src/server/src/main/java/edu/wpi/rail/jrosbridge/JRosbridge.java new file mode 100644 index 0000000..d049c90 --- /dev/null +++ b/src/server/src/main/java/edu/wpi/rail/jrosbridge/JRosbridge.java @@ -0,0 +1,181 @@ +package edu.wpi.rail.jrosbridge; + +/** + * The JRosbridge class contains constant definitions used in the rosbridge + * protocol itself (e.g., op code types). + * + * @author Russell Toris - russell.toris@gmail.com + * @version April 1, 2014 + */ +public class JRosbridge { + + /** + * The args field for the rosbridge protocol. + */ + public static final String FIELD_ARGS = "args"; + + /** + * The client field for the rosbridge protocol. + */ + public static final String FIELD_CLIENT = "client"; + + /** + * The compression field for the rosbridge protocol. + */ + public static final String FIELD_COMPRESSION = "compression"; + + /** + * The data field for the rosbridge protocol. + */ + public static final String FIELD_DATA = "data"; + + /** + * The destination field for the rosbridge protocol. + */ + public static final String FIELD_DESTINATION = "dest"; + + /** + * The end time field for the rosbridge protocol. + */ + public static final String FIELD_END_TIME = "end"; + + /** + * The ID field for the rosbridge protocol. + */ + public static final String FIELD_ID = "id"; + + /** + * The user level field for the rosbridge protocol. + */ + public static final String FIELD_LEVEL = "level"; + + /** + * The MAC field for the rosbridge protocol. + */ + public static final String FIELD_MAC = "mac"; + + /** + * The message data field for the rosbridge protocol. + */ + public static final String FIELD_MESSAGE = "msg"; + + /** + * The op code field for the rosbridge protocol. + */ + public static final String FIELD_OP = "op"; + + /** + * The random field for the rosbridge protocol. + */ + public static final String FIELD_RAND = "rand"; + + /** + * The result field for the rosbridge protocol. + */ + public static final String FIELD_RESULT = "result"; + + /** + * The service field for the rosbridge protocol. + */ + public static final String FIELD_SERVICE = "service"; + + /** + * The throttle rate field for the rosbridge protocol. + */ + public static final String FIELD_THROTTLE_RATE = "throttle_rate"; + + /** + * The time field for the rosbridge protocol. + */ + public static final String FIELD_TIME = "t"; + + /** + * The topic field for the rosbridge protocol. + */ + public static final String FIELD_TOPIC = "topic"; + + /** + * The message/service type field for the rosbridge protocol. + */ + public static final String FIELD_TYPE = "type"; + + /** + * The values field for the rosbridge protocol. + */ + public static final String FIELD_VALUES = "values"; + + /** + * The advertise op code for the rosbridge protocol. + */ + public static final String OP_CODE_ADVERTISE = "advertise"; + + /** + * The advertise service op code for the rosbridge protocol. + */ + public static final String OP_CODE_ADVERTISE_SERVICE = "advertise_service"; + + /** + * The unadvertise service op code for the rosbridge protocol. + */ + public static final String OP_CODE_UNADVERTISE_SERVICE = "unadvertise_service"; + + /** + * The authenticate op code for the rosbridge protocol. + */ + public static final String OP_CODE_AUTH = "auth"; + + /** + * The call service op code for the rosbridge protocol. + */ + public static final String OP_CODE_CALL_SERVICE = "call_service"; + + /** + * The png compression op code for the rosbridge protocol. + */ + public static final String OP_CODE_PNG = "png"; + + /** + * The publish op code for the rosbridge protocol. + */ + public static final String OP_CODE_PUBLISH = "publish"; + + /** + * The service response op code for the rosbridge protocol. + */ + public static final String OP_CODE_SERVICE_RESPONSE = "service_response"; + + /** + * The subscribe op code for the rosbridge protocol. + */ + public static final String OP_CODE_SUBSCRIBE = "subscribe"; + + /** + * The unadvertise op code for the rosbridge protocol. + */ + public static final String OP_CODE_UNADVERTISE = "unadvertise"; + + /** + * The unsubscribe op code for the rosbridge protocol. + */ + public static final String OP_CODE_UNSUBSCRIBE = "unsubscribe"; + + /** + * The types of websocket protocols supported by jrosbridge and rosbridge. + * + * @author Russell Toris - russell.toris@gmail.com + * @version April 1, 2014 + */ + public enum WebSocketType { + ws, wss + } + + /** + * The types of compression supported by jrosbridge and rosbridge. + * + * @author Russell Toris - russell.toris@gmail.com + * @version April 1, 2014 + */ + public enum CompressionType { + png, none + } +} diff --git a/src/server/src/main/java/edu/wpi/rail/jrosbridge/JsonWrapper.java b/src/server/src/main/java/edu/wpi/rail/jrosbridge/JsonWrapper.java new file mode 100644 index 0000000..62d1cf6 --- /dev/null +++ b/src/server/src/main/java/edu/wpi/rail/jrosbridge/JsonWrapper.java @@ -0,0 +1,106 @@ +package edu.wpi.rail.jrosbridge; + +import java.io.StringReader; + +import javax.json.Json; +import javax.json.JsonObject; + +/** + * JsonWrapper objects are used as a wrapper around JSON objects. That is, they + * are a reusable convince for messages and services. This objects are immutable + * and declared abstract as they should not be used directly. + * + * @author Russell Toris - russell.toris@gmail.com + * @version April 1, 2014 + */ +public abstract class JsonWrapper { + + /** + * The String representation of an empty message in JSON. + */ + public static final String EMPTY_JSON = "{}"; + + private final JsonObject jsonObject; + private final String jsonString; + + /** + * Create a new, empty JSON object. + */ + public JsonWrapper() { + this(JsonWrapper.EMPTY_JSON); + } + + /** + * Create a JSON object based on the given String representation of a JSON + * object. + * + * @param json + * The JSON String to parse. + */ + public JsonWrapper(String jsonString) { + // parse and pass it to the JSON constructor + this(Json.createReader(new StringReader(jsonString)).readObject()); + } + + /** + * Create a Message based on the given JSON object. + * + * @param jsonObject + * The JSON object containing the message data. + */ + public JsonWrapper(JsonObject jsonObject) { + this.jsonObject = jsonObject; + // only need to do this once + this.jsonString = this.jsonObject.toString(); + } + + /** + * Get the JSON object. + * + * @return The JSON object. + */ + public JsonObject toJsonObject() { + return this.jsonObject; + } + + /** + * Get the String representation of this JSON object in JSON format. + * + * @return The String representation of this JSON object in JSON format. + */ + @Override + public String toString() { + return this.jsonString; + } + + /** + * Create a clone of this JSON object. + */ + public abstract JsonWrapper clone(); + + /** + * Return the hash code of this JSON object, which is the hash code of the + * JSON string. + * + * @return The hash code of the message. + */ + @Override + public int hashCode() { + return this.jsonString.hashCode(); + } + + /** + * Test if the given Object is equal to this JsonWrapper. Two JsonWrappers + * are equal if and only if their JSON strings match. + * + * @param o + * The Object to test equality with. + * @return If the given Object is equal to this JsonWrapper. + */ + @Override + public boolean equals(Object o) { + return o == this + || (o instanceof JsonWrapper && this.jsonString.equals(o + .toString())); + } +} diff --git a/src/server/src/main/java/edu/wpi/rail/jrosbridge/Ros.java b/src/server/src/main/java/edu/wpi/rail/jrosbridge/Ros.java new file mode 100644 index 0000000..d55176e --- /dev/null +++ b/src/server/src/main/java/edu/wpi/rail/jrosbridge/Ros.java @@ -0,0 +1,535 @@ +package edu.wpi.rail.jrosbridge; + +import java.awt.image.Raster; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.StringReader; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.HashMap; + +import javax.imageio.ImageIO; +import javax.json.Json; +import javax.json.JsonObject; +import javax.json.stream.JsonParsingException; +import javax.websocket.ClientEndpoint; +import javax.websocket.ContainerProvider; +import javax.websocket.DeploymentException; +import javax.websocket.OnClose; +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; + +import com.example.testdemo.ros.message.Message; +import edu.wpi.rail.jrosbridge.callback.CallServiceCallback; +import edu.wpi.rail.jrosbridge.services.ServiceRequest; + +import edu.wpi.rail.jrosbridge.callback.ServiceCallback; +import edu.wpi.rail.jrosbridge.callback.TopicCallback; +import edu.wpi.rail.jrosbridge.handler.RosHandler; +import edu.wpi.rail.jrosbridge.services.ServiceResponse; +import org.springframework.util.Base64Utils; + +@ClientEndpoint +public class Ros { + + /** + * The default hostname used if none is provided. + */ + public static final String DEFAULT_HOSTNAME = "localhost"; + + /** + * The default port used if none is provided. + */ + public static final int DEFAULT_PORT = 9090; + + private final String hostname; + private final int port; + private final JRosbridge.WebSocketType protocol; + + // active session (stored upon connection) + private Session session; + + // used throughout the library to create unique IDs for requests. + private long idCounter; + + // keeps track of callback functions for a given topic + private final HashMap> topicCallbacks; + + // keeps track of callback functions for a given service request + private final HashMap serviceCallbacks; + + // keeps track of callback functions for a given advertised service + private final HashMap callServiceCallbacks; + + // keeps track of handlers for this connection + private final ArrayList handlers; + + /** + * Create a connection to ROS with the default hostname and port. A call to + * connect must be made to establish a connection. + */ + public Ros() { + this(Ros.DEFAULT_HOSTNAME); + } + + /** + * Create a connection to ROS with the given hostname and default port. A + * call to connect must be made to establish a connection. By default, + * WebSockets is used (as opposed to WSS). + * + * @param hostname + * The hostname to connect to. + */ + public Ros(String hostname) { + this(hostname, Ros.DEFAULT_PORT); + } + + /** + * Create a connection to ROS with the given hostname and port. A call to + * connect must be made to establish a connection. By default, WebSockets is + * used (as opposed to WSS). + * + * @param hostname + * The hostname to connect to. + * @param port + * The port to connect to. + */ + public Ros(String hostname, int port) { + this(hostname, port, JRosbridge.WebSocketType.ws); + } + + /** + * Create a connection to ROS with the given hostname and port. A call to + * connect must be made to establish a connection. + * + * @param hostname + * The hostname to connect to. + * @param port + * The port to connect to. + * @param protocol + * The WebSocket protocol to use. + */ + public Ros(String hostname, int port, JRosbridge.WebSocketType protocol) { + this.hostname = hostname; + this.port = port; + this.protocol = protocol; + this.session = null; + this.idCounter = 0; + this.topicCallbacks = new HashMap>(); + this.serviceCallbacks = new HashMap(); + this.callServiceCallbacks = new HashMap(); + this.handlers = new ArrayList(); + } + + /** + * Get the hostname associated with this connection. + * + * @return The hostname associated with this connection. + */ + public String getHostname() { + return this.hostname; + } + + /** + * Get the port associated with this connection. + * + * @return The port associated with this connection. + */ + public int getPort() { + return this.port; + } + + /** + * Get the type of WebSocket protocol being used. + * + * @return The type of WebSocket protocol being used. + */ + public JRosbridge.WebSocketType getProtocol() { + return this.protocol; + } + + /** + * Get the full URL this client is connecting to. + * + * @return + */ + public String getURL() { + return this.protocol.toString() + "://" + this.hostname + ":" + + this.port; + } + + /** + * Get the next unique ID number for this connection. + * + * @return The next unique ID number for this connection. + */ + public long nextId() { + return this.idCounter++; + } + + /** + * Add a handler to this connection. This handler is called when the + * associated events occur. + * + * @param handler + * The handler to add. + */ + public void addRosHandler(RosHandler handler) { + this.handlers.add(handler); + } + + /** + * Attempt to establish a connection to rosbridge. Errors are printed to the + * error output stream. + * + * @return Returns true if the connection was established successfully and + * false otherwise. + */ + public boolean connect() { + try { + // create a WebSocket connection here + URI uri = new URI(this.getURL()); + ContainerProvider.getWebSocketContainer() + .connectToServer(this, uri); + return true; + } catch (DeploymentException | URISyntaxException | IOException e) { + // failed connection, return false + System.err.println("[ERROR]: Could not create WebSocket: " + + e.getMessage()); + return false; + } + } + + /** + * Disconnect the connection to rosbridge. Errors are printed to the error + * output stream. + * + * @return Returns true if the disconnection was successful and false + * otherwise. + */ + public boolean disconnect() { + if (this.isConnected()) { + try { + this.session.close(); + return true; + } catch (IOException e) { + System.err.println("[ERROR]: Could not disconnect: " + + e.getMessage()); + } + } + // could not disconnect cleanly + return false; + } + + /** + * Check if there is a connection to rosbridge. + * + * @return If there is a connection to rosbridge. + */ + public boolean isConnected() { + return this.session != null && this.session.isOpen(); + } + + /** + * This function is called once a successful connection is made. + * + * @param session + * The session associated with the connection. + */ + @OnOpen + public void onOpen(Session session) { + // store the session + this.session = session; + + // call the handlers + for (RosHandler handler : this.handlers) { + handler.handleConnection(session); + } + } + + /** + * This function is called once a successful disconnection is made. + * + * @param session + * The session associated with the disconnection. + */ + @OnClose + public void onClose(Session session) { + // remove the session + this.session = null; + + // call the handlers + for (RosHandler handler : this.handlers) { + handler.handleDisconnection(session); + } + } + + /** + * This function is called if an error occurs. + * + * @param session + * The session for the error. + * @param session + * The session for the error. + */ + @OnError + public void onError(Session session, Throwable t) { + // call the handlers + for (RosHandler handler : this.handlers) { + handler.handleError(session, t); + } + } + + /** + * This method is called once an entire message has been read in by the + * connection from rosbridge. It will parse the incoming JSON and attempt to + * handle the request appropriately. + * + * @param message + * The incoming JSON message from rosbridge. + */ + @OnMessage + public void onMessage(String message) { + try { + // parse the JSON + JsonObject jsonObject = Json + .createReader(new StringReader(message)).readObject(); + + // check for compression + String op = jsonObject.getString(JRosbridge.FIELD_OP); + if (op.equals(JRosbridge.OP_CODE_PNG)) { + String data = jsonObject.getString(JRosbridge.FIELD_DATA); + // decompress the PNG data + byte[] bytes = Base64Utils.decode(data.getBytes()); + Raster imageData = ImageIO + .read(new ByteArrayInputStream(bytes)).getRaster(); + + // read the RGB data + int[] rawData = null; + rawData = imageData.getPixels(0, 0, imageData.getWidth(), + imageData.getHeight(), rawData); + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < rawData.length; i++) { + buffer.append(Character.toString((char) rawData[i])); + } + + // reparse the JSON + JsonObject newJsonObject = Json.createReader( + new StringReader(buffer.toString())).readObject(); + handleMessage(newJsonObject); + } else { + handleMessage(jsonObject); + } + } catch (NullPointerException | IOException | JsonParsingException e) { + // only occurs if there was an error with the JSON + System.err.println("[WARN]: Invalid incoming rosbridge protocol: " + + message); + } + } + + /** + * Handle the incoming rosbridge message by calling the appropriate + * callbacks. + * + * @param jsonObject + * The JSON object from the incoming rosbridge message. + */ + private void handleMessage(JsonObject jsonObject) { + // check for the correct fields + String op = jsonObject.getString(JRosbridge.FIELD_OP); + if (op.equals(JRosbridge.OP_CODE_PUBLISH)) { + // check for the topic name + String topic = jsonObject.getString(JRosbridge.FIELD_TOPIC); + + // call each callback with the message + ArrayList callbacks = topicCallbacks.get(topic); + if (callbacks != null) { + Message msg = new Message() { + @Override + public void print() { + super.print(); + } + }; + for (TopicCallback cb : callbacks) { + cb.handleMessage(msg); + } + } + } else if (op.equals(JRosbridge.OP_CODE_SERVICE_RESPONSE)) { + // check for the request ID + String id = jsonObject.getString(JRosbridge.FIELD_ID); + + // call the callback for the request + ServiceCallback cb = serviceCallbacks.get(id); + if (cb != null) { + // check if a success code was given + boolean success = jsonObject + .containsKey(JRosbridge.FIELD_RESULT) ? jsonObject + .getBoolean(JRosbridge.FIELD_RESULT) : true; + // get the response + JsonObject values = jsonObject + .getJsonObject(JRosbridge.FIELD_VALUES); + ServiceResponse response = new ServiceResponse(values, success); + cb.handleServiceResponse(response); + } + } else if (op.equals(JRosbridge.OP_CODE_CALL_SERVICE)) { + // check for the request ID + String id = jsonObject.getString("id"); + String service = jsonObject.getString("service"); + + // call the callback for the request + CallServiceCallback cb = callServiceCallbacks.get(service); + if (cb != null) { + // get the response + JsonObject args = jsonObject + .getJsonObject(JRosbridge.FIELD_ARGS); + ServiceRequest request = new ServiceRequest(args); + request.setId(id); + cb.handleServiceCall(request); + } + } else { + System.err.println("[WARN]: Unrecognized op code: " + + jsonObject.toString()); + } + + } + + /** + * Send the given JSON object to rosbridge. + * + * @param jsonObject + * The JSON object to send to rosbridge. + * @return If the sending of the message was successful. + */ + public boolean send(JsonObject jsonObject) { + // check the connection + if (this.isConnected()) { + try { + // send it as text + this.session.getBasicRemote().sendText(jsonObject.toString()); + return true; + } catch (IOException e) { + System.err.println("[ERROR]: Could not send message: " + + e.getMessage()); + } + } + // message send failed + return false; + } + + /** + * Sends an authorization request to the server. + * + * @param mac + * The MAC (hash) string given by the trusted source. + * @param client + * The IP of the client. + * @param dest + * The IP of the destination. + * @param rand + * The random string given by the trusted source. + * @param t + * The time of the authorization request. + * @param level + * The user level as a string given by the client. + * @param end + * The end time of the client's session. + */ + public void authenticate(String mac, String client, String dest, + String rand, int t, String level, int end) { + // build and send the rosbridge call + JsonObject call = Json.createObjectBuilder() + .add(JRosbridge.FIELD_OP, JRosbridge.OP_CODE_AUTH) + .add(JRosbridge.FIELD_MAC, mac) + .add(JRosbridge.FIELD_CLIENT, client) + .add(JRosbridge.FIELD_DESTINATION, dest) + .add(JRosbridge.FIELD_RAND, rand).add(JRosbridge.FIELD_TIME, t) + .add(JRosbridge.FIELD_LEVEL, level) + .add(JRosbridge.FIELD_END_TIME, end).build(); + this.send(call); + } + + /** + * Register a callback for a given topic. + * + * @param topic + * The topic to register this callback with. + * @param cb + * The callback that will be called when messages come in for the + * associated topic. + */ + public void registerTopicCallback(String topic, TopicCallback cb) { + // check if any callbacks exist yet + if (!this.topicCallbacks.containsKey(topic)) { + this.topicCallbacks.put(topic, new ArrayList()); + } + + // add the callback + this.topicCallbacks.get(topic).add(cb); + } + + /** + * Deregister a callback for a given topic. + * + * @param topic + * The topic associated with the callback. + * @param cb + * The callback to remove. + */ + public void deregisterTopicCallback(String topic, TopicCallback cb) { + // check if any exist for this topic + if (this.topicCallbacks.containsKey(topic)) { + // remove the callback if it exists + ArrayList callbacks = this.topicCallbacks.get(topic); + if (callbacks.contains(cb)) { + callbacks.remove(cb); + } + + // remove the list if it is empty + if (callbacks.size() == 0) { + this.topicCallbacks.remove(topic); + } + } + } + + /** + * Register a callback for a given outgoing service call. + * + * @param serviceCallId + * The unique ID of the service call. + * @param cb + * The callback that will be called when a service response comes + * back for the associated request. + */ + public void registerServiceCallback(String serviceCallId, ServiceCallback cb) { + // add the callback + this.serviceCallbacks.put(serviceCallId, cb); + } + + /** + * Register a callback for a given incoming service request. + * + * @param serviceName + * The unique name of the service call. + * @param cb + * The callback that will be called when a service request comes + * in for the associated request. + */ + public void registerCallServiceCallback(String serviceName, CallServiceCallback cb) { + // add the callback + this.callServiceCallbacks.put(serviceName, cb); + } + + /** + * Deregister a callback for a given incoming service request. + * + * @param serviceName + * The unique name of the service call. + */ + public void deregisterCallServiceCallback(String serviceName) { + // remove the callback + callServiceCallbacks.remove(serviceName); + } +} diff --git a/src/server/src/main/java/edu/wpi/rail/jrosbridge/Service.java b/src/server/src/main/java/edu/wpi/rail/jrosbridge/Service.java new file mode 100644 index 0000000..406272a --- /dev/null +++ b/src/server/src/main/java/edu/wpi/rail/jrosbridge/Service.java @@ -0,0 +1,240 @@ +package edu.wpi.rail.jrosbridge; + +import javax.json.Json; +import javax.json.JsonObject; + +import edu.wpi.rail.jrosbridge.callback.ServiceCallback; +import edu.wpi.rail.jrosbridge.callback.CallServiceCallback; +import edu.wpi.rail.jrosbridge.services.ServiceRequest; +import edu.wpi.rail.jrosbridge.services.ServiceResponse; + +/** + * The Service object is responsible for calling or advertising a service in ROS. + * + * @author Russell Toris - russell.toris@gmail.com + * @version November 26, 2014 + */ +public class Service { + + private final Ros ros; + private final String name; + private final String type; + private boolean isAdvertised; + + /** + * Create a ROS service with the given information. + * + * @param ros + * A handle to the ROS connection. + * @param name + * The name of the service (e.g., "/add_two_ints"). + * @param type + * The service type (e.g., "rospy_tutorials/AddTwoInts"). + */ + public Service(Ros ros, String name, String type) { + this.ros = ros; + this.name = name; + this.type = type; + this.isAdvertised = false; + } + + /** + * Get the ROS connection handle for this service. + * + * @return The ROS connection handle for this service. + */ + public Ros getRos() { + return this.ros; + } + + /** + * Get the name of this service. + * + * @return The name of this service. + */ + public String getName() { + return this.name; + } + + /** + * Return the service type of this service. + * + * @return The service type of this service. + */ + public String getType() { + return this.type; + } + + /** + * Check if the current service is advertising to ROS. + * + * @return If the current service is advertising to ROS. + */ + public boolean isAdvertised() { + return this.isAdvertised; + } + + /** + * Call this service. The callback function will be called with the + * associated service response. + * + * @param request + * The service request to send. + * @param cb + * The callback used when the associated response comes back. + */ + public void callService(ServiceRequest request, ServiceCallback cb) { + // construct the unique ID + String callServceId = "call_service:" + this.name + ":" + + this.ros.nextId(); + + // register the callback function + this.ros.registerServiceCallback(callServceId, cb); + + // build and send the rosbridge call + JsonObject call = Json.createObjectBuilder() + .add(JRosbridge.FIELD_OP, JRosbridge.OP_CODE_CALL_SERVICE) + .add(JRosbridge.FIELD_ID, callServceId) + .add(JRosbridge.FIELD_TYPE, this.type) + .add(JRosbridge.FIELD_SERVICE, this.name) + .add(JRosbridge.FIELD_ARGS, request.toJsonObject()).build(); + this.ros.send(call); + } + + /** + * Send a service response. + * + * @param response + * The service response to send. + * @param id + * The ID of the response (matching that of the service call). + */ + public void sendResponse(ServiceResponse response, String id) { + // build and send the rosbridge call + JsonObject call = Json.createObjectBuilder() + .add(JRosbridge.FIELD_OP, JRosbridge.OP_CODE_SERVICE_RESPONSE) + .add(JRosbridge.FIELD_ID, id) + .add(JRosbridge.FIELD_SERVICE, this.name) + .add(JRosbridge.FIELD_VALUES, response.toJsonObject()) + .add(JRosbridge.FIELD_RESULT, response.getResult()).build(); + this.ros.send(call); + } + + /** + * Registers as service advertiser. + */ + public void advertiseService(CallServiceCallback cb) { + // register the callback + this.ros.registerCallServiceCallback(this.name, cb); + + // build and send the rosbridge call + JsonObject call = Json.createObjectBuilder() + .add(JRosbridge.FIELD_OP, JRosbridge.OP_CODE_ADVERTISE_SERVICE) + .add(JRosbridge.FIELD_TYPE, this.type) + .add(JRosbridge.FIELD_SERVICE, this.name).build(); + this.ros.send(call); + + // set the flag indicating we are registered + this.isAdvertised = true; + } + + /** + * Unregisters as service advertiser. + */ + public void unadvertiseService() { + this.ros.deregisterCallServiceCallback(this.name); + + // build and send the rosbridge call + JsonObject call = Json.createObjectBuilder() + .add(JRosbridge.FIELD_OP, JRosbridge.OP_CODE_UNADVERTISE_SERVICE) + .add(JRosbridge.FIELD_SERVICE, this.name).build(); + this.ros.send(call); + + // set the flag indicating we are registered + this.isAdvertised = false; + } + + /** + * Call the service and wait for a response. This is a blocking call and + * will only return once rosbridge returns the service response. For an + * asynchronous version of this call, see the + * {@link #callService(ServiceRequest request, ServiceCallback cb) + * callService} method. + * + * @param request + * The service request to send. + * @return The corresponding service response from ROS. + */ + public synchronized ServiceResponse callServiceAndWait( + ServiceRequest request) { + + // private inner class to use as a callback + BlockingCallback cb = new BlockingCallback(this); + // use the asynchronous version and block on the result + this.callService(request, cb); + + // wait for a response + while (cb.getResponse() == null) { + try { + this.wait(); + } catch (InterruptedException e) { + // continue on + } + } + + return cb.getResponse(); + } + + /** + * A private {@link ServiceCallback + * ServiceCallback} used to block and wait for a response from rosbridge. + * + * @author Russell Toris - russell.toris@gmail.com + * @version April 1, 2014 + */ + private class BlockingCallback implements ServiceCallback { + + private ServiceResponse response; + private Service service; + + /** + * Create a new callback function which will notify the given + * {@link Service Service} once a response + * has been received. + * + * @param service + * The {@link Service Service} + * to notify once a response has been received. + */ + public BlockingCallback(Service service) { + this.response = null; + this.service = service; + } + + /** + * Store the response internally and notify the corresponding + * {@link Service Service}. + * + * @param response + * The incoming service response from ROS. + */ + @Override + public void handleServiceResponse(ServiceResponse response) { + this.response = response; + synchronized (this.service) { + this.service.notifyAll(); + } + } + + /** + * Get the response stored in this callback, if one exists. Otherwise, + * null is returned. + * + * @return The resulting service response from ROS, or null if one does + * not exist yet. + */ + public ServiceResponse getResponse() { + return this.response; + } + } +} diff --git a/src/server/src/main/java/edu/wpi/rail/jrosbridge/Topic.java b/src/server/src/main/java/edu/wpi/rail/jrosbridge/Topic.java new file mode 100644 index 0000000..dcaacf6 --- /dev/null +++ b/src/server/src/main/java/edu/wpi/rail/jrosbridge/Topic.java @@ -0,0 +1,279 @@ +package edu.wpi.rail.jrosbridge; + +import java.util.ArrayList; + +import javax.json.Json; +import javax.json.JsonObject; + +import com.example.testdemo.ros.message.Message; +import edu.wpi.rail.jrosbridge.callback.TopicCallback; + +/** + * The Topic object is responsible for publishing and/or subscribing to a topic + * in ROS. + * + * @author Russell Toris - russell.toris@gmail.com + * @version April 1, 2014 + */ +public class Topic { + + private final Ros ros; + private final String name; + private final String type; + private boolean isAdvertised; + private boolean isSubscribed; + private final JRosbridge.CompressionType compression; + private final int throttleRate; + + // used to keep track of this object's callbacks + private final ArrayList callbacks; + + // used to keep track of the subscription IDs + private final ArrayList ids; + + /** + * Create a ROS topic with the given information. No compression or + * throttling is used. + * + * @param ros + * A handle to the ROS connection. + * @param name + * The name of the topic (e.g., "/cmd_vel"). + * @param type + * The message type (e.g., "std_msgs/String"). + */ + public Topic(Ros ros, String name, String type) { + this(ros, name, type, JRosbridge.CompressionType.none, 0); + } + + /** + * Create a ROS topic with the given information. No throttling is used. + * + * @param ros + * A handle to the ROS connection. + * @param name + * The name of the topic (e.g., "/cmd_vel"). + * @param type + * The message type (e.g., "std_msgs/String"). + * @param compression + * The type of compression used for this topic. + */ + public Topic(Ros ros, String name, String type, + JRosbridge.CompressionType compression) { + this(ros, name, type, compression, 0); + } + + /** + * Create a ROS topic with the given information. No compression is used. + * + * @param ros + * A handle to the ROS connection. + * @param name + * The name of the topic (e.g., "/cmd_vel"). + * @param type + * The message type (e.g., "std_msgs/String"). + * @param throttleRate + * The throttle rate to use for this topic. + */ + public Topic(Ros ros, String name, String type, int throttleRate) { + this(ros, name, type, JRosbridge.CompressionType.none, throttleRate); + } + + /** + * Create a ROS topic with the given information. + * + * @param ros + * A handle to the ROS connection. + * @param name + * The name of the topic (e.g., "/cmd_vel"). + * @param type + * The message type (e.g., "std_msgs/String"). + * @param compression + * The type of compression used for this topic. + * @param throttleRate + * The throttle rate to use for this topic. + */ + public Topic(Ros ros, String name, String type, + JRosbridge.CompressionType compression, int throttleRate) { + this.ros = ros; + this.name = name; + this.type = type; + this.isAdvertised = false; + this.isSubscribed = false; + this.compression = compression; + this.throttleRate = throttleRate; + this.callbacks = new ArrayList(); + this.ids = new ArrayList(); + } + + /** + * Get the ROS connection handle for this topic. + * + * @return The ROS connection handle for this topic. + */ + public Ros getRos() { + return this.ros; + } + + /** + * Get the name of this topic. + * + * @return The name of this topic. + */ + public String getName() { + return this.name; + } + + /** + * Return the message type of this topic. + * + * @return The message type of this topic. + */ + public String getType() { + return this.type; + } + + /** + * Check if the current topic is advertising to ROS. + * + * @return If the current topic is advertising to ROS. + */ + public boolean isAdvertised() { + return this.isAdvertised; + } + + /** + * Check if the current topic is subscribed to ROS. + * + * @return If the current topic is subscribed to ROS. + */ + public boolean isSubscribed() { + return this.isSubscribed; + } + + /** + * Get the compression type for this topic. + * + * @return The compression type for this topic. + */ + public JRosbridge.CompressionType getCompression() { + return this.compression; + } + + /** + * Get the throttle rate for this topic. + * + * @return The throttle rate for this topic. + */ + public int getThrottleRate() { + return this.throttleRate; + } + + /** + * Subscribe to this topic. A callback function is required and will be + * called with any incoming message for this topic. + * + * @param cb + * The callback that will be called when incoming messages are + * received. + */ + public void subscribe(TopicCallback cb) { + // register the callback function + this.ros.registerTopicCallback(this.name, cb); + // internal reference used during unsubscribe + this.callbacks.add(cb); + + String subscribeId = "subscribe:" + this.name + ":" + this.ros.nextId(); + this.ids.add(subscribeId); + + // build and send the rosbridge call + JsonObject call = Json.createObjectBuilder() + .add(JRosbridge.FIELD_OP, JRosbridge.OP_CODE_SUBSCRIBE) + .add(JRosbridge.FIELD_ID, subscribeId) + .add(JRosbridge.FIELD_TYPE, this.type) + .add(JRosbridge.FIELD_TOPIC, this.name) + .add(JRosbridge.FIELD_COMPRESSION, this.compression.toString()) + .add(JRosbridge.FIELD_THROTTLE_RATE, this.throttleRate).build(); + this.ros.send(call); + + // set the flag indicating we have subscribed + this.isSubscribed = true; + } + + /** + * Unregisters as a subscriber for the topic. Unsubscribing will remove all + * the associated subscribe callbacks. + */ + public void unsubscribe() { + // remove this object's associated callbacks. + for (TopicCallback cb : this.callbacks) { + this.ros.deregisterTopicCallback(this.name, cb); + } + this.callbacks.clear(); + + // build and send the rosbridge calls + for (String id : this.ids) { + JsonObject call = Json.createObjectBuilder() + .add(JRosbridge.FIELD_OP, JRosbridge.OP_CODE_UNSUBSCRIBE) + .add(JRosbridge.FIELD_ID, id) + .add(JRosbridge.FIELD_TOPIC, this.name).build(); + this.ros.send(call); + } + + // set the flag indicating we are not longer subscribed + this.isSubscribed = false; + } + + /** + * Registers as a publisher for the topic. This call will be automatically + * called by publish if you do not explicitly call it. + */ + public void advertise() { + // build and send the rosbridge call + String advertiseId = "advertise:" + this.name + ":" + this.ros.nextId(); + JsonObject call = Json.createObjectBuilder() + .add(JRosbridge.FIELD_OP, JRosbridge.OP_CODE_ADVERTISE) + .add(JRosbridge.FIELD_ID, advertiseId) + .add(JRosbridge.FIELD_TYPE, this.type) + .add(JRosbridge.FIELD_TOPIC, this.name).build(); + this.ros.send(call); + + // set the flag indicating we are registered + this.isAdvertised = true; + } + + /** + * Unregister as a publisher for the topic. + */ + public void unadvertise() { + // build and send the rosbridge call + String unadvertiseId = "unadvertise:" + this.name + ":" + + this.ros.nextId(); + JsonObject call = Json.createObjectBuilder() + .add(JRosbridge.FIELD_OP, JRosbridge.OP_CODE_UNADVERTISE) + .add(JRosbridge.FIELD_ID, unadvertiseId) + .add(JRosbridge.FIELD_TOPIC, this.name).build(); + this.ros.send(call); + + // set the flag indicating we are no longer registered + this.isAdvertised = false; + } + + /** + * Publish the given message to ROS on this topic. If the topic is not + * advertised, it will be advertised first. + * + * @param message + * The message to publish. + */ + public void publish(Message message) { + // check if we have advertised yet. + if (!this.isAdvertised()) { + this.advertise(); + } + + // build and send the rosbridge call + String publishId = "publish:" + this.name + ":" + this.ros.nextId(); + //JsonObject call = Json.createObjectBuilder() + } +} diff --git a/src/server/src/main/java/edu/wpi/rail/jrosbridge/callback/CallServiceCallback.java b/src/server/src/main/java/edu/wpi/rail/jrosbridge/callback/CallServiceCallback.java new file mode 100644 index 0000000..0bad06e --- /dev/null +++ b/src/server/src/main/java/edu/wpi/rail/jrosbridge/callback/CallServiceCallback.java @@ -0,0 +1,23 @@ +package edu.wpi.rail.jrosbridge.callback; + +import edu.wpi.rail.jrosbridge.services.ServiceRequest; + +/** + * The CallServiceCallback interface defines a single method which will be called + * when an incoming service request is received for an associated service request. + * + * @author Russell Toris - russell.toris@gmail.com + * @version November 26, 2014 + */ +public interface CallServiceCallback { + + /** + * This function is called when an incoming service request is received for + * a given service request. No ROS type checking is done on the internal + * data. + * + * @param request + * The service request that was received. + */ + public void handleServiceCall(ServiceRequest request); +} diff --git a/src/server/src/main/java/edu/wpi/rail/jrosbridge/callback/ServiceCallback.java b/src/server/src/main/java/edu/wpi/rail/jrosbridge/callback/ServiceCallback.java new file mode 100644 index 0000000..e53571b --- /dev/null +++ b/src/server/src/main/java/edu/wpi/rail/jrosbridge/callback/ServiceCallback.java @@ -0,0 +1,24 @@ +package edu.wpi.rail.jrosbridge.callback; + +import edu.wpi.rail.jrosbridge.services.ServiceResponse; + +/** + * The ServiceCallback interface defines a single method which will be called + * when an incoming service response is received for an associated service + * request. + * + * @author Russell Toris - russell.toris@gmail.com + * @version April 1, 2014 + */ +public interface ServiceCallback { + + /** + * This function is called when an incoming service response is received for + * a given service request. No ROS type checking is done on the internal + * data. A flag indicating if the call was successful is given. + * + * @param response + * The service response that was received. + */ + public void handleServiceResponse(ServiceResponse response); +} diff --git a/src/server/src/main/java/edu/wpi/rail/jrosbridge/callback/TopicCallback.java b/src/server/src/main/java/edu/wpi/rail/jrosbridge/callback/TopicCallback.java new file mode 100644 index 0000000..e3492d1 --- /dev/null +++ b/src/server/src/main/java/edu/wpi/rail/jrosbridge/callback/TopicCallback.java @@ -0,0 +1,23 @@ +package edu.wpi.rail.jrosbridge.callback; + + +import com.example.testdemo.ros.message.Message; + +/** + * The TopicCallback interface defines a single method which will be called when + * an incoming message is received for an associated topic. + * + * @author Russell Toris - russell.toris@gmail.com + * @version April 1, 2014 + */ +public interface TopicCallback { + + /** + * This function is called when an incoming message is received for a given + * topic. No ROS type checking is done on the internal message data. + * + * @param message + * The message that was received. + */ + public void handleMessage(Message message); +} diff --git a/src/server/src/main/java/edu/wpi/rail/jrosbridge/handler/RosHandler.java b/src/server/src/main/java/edu/wpi/rail/jrosbridge/handler/RosHandler.java new file mode 100644 index 0000000..7cc68d3 --- /dev/null +++ b/src/server/src/main/java/edu/wpi/rail/jrosbridge/handler/RosHandler.java @@ -0,0 +1,41 @@ +package edu.wpi.rail.jrosbridge.handler; + +import javax.websocket.Session; + +/** + * The RosHandler interface defines the methods that will be called during + * certain events in the Ros connection object. + * + * @author Russell Toris - russell.toris@gmail.com + * @version April 1, 2014 + */ +public interface RosHandler { + + /** + * Handle the connection event. This occurs during a successful connection + * to rosbridge. + * + * @param session + * The session associated with the connection. + */ + public void handleConnection(Session session); + + /** + * Handle the disconnection event. This occurs during a successful + * disconnection from rosbridge. + * + * @param session + * The session associated with the disconnection. + */ + public void handleDisconnection(Session session); + + /** + * Handle the error event. + * + * @param session + * The session associated with the error. + * @param t + * The error. + */ + public void handleError(Session session, Throwable t); +} diff --git a/src/server/src/main/java/edu/wpi/rail/jrosbridge/primitives/Duration.java b/src/server/src/main/java/edu/wpi/rail/jrosbridge/primitives/Duration.java new file mode 100644 index 0000000..07304ee --- /dev/null +++ b/src/server/src/main/java/edu/wpi/rail/jrosbridge/primitives/Duration.java @@ -0,0 +1,166 @@ +package edu.wpi.rail.jrosbridge.primitives; + +import java.io.StringReader; + +import javax.json.Json; +import javax.json.JsonObject; + +/** + * The ROS duration primitive. + * + * @author Russell Toris - russell.toris@gmail.com + * @version April 1, 2014 + */ +public class Duration extends TimeBase { + + /** + * The primitive type. + */ + public static final String TYPE = "duration"; + + /** + * Create a new Duration with a default of 0. + */ + public Duration() { + super(Duration.TYPE); + } + + /** + * Create a new Duration with the given seconds and nanoseconds values. + * + * @param secs + * The seconds value of this duration. + * @param nsecs + * The nanoseconds value of this duration. + */ + public Duration(int secs, int nsecs) { + super(secs, nsecs, Duration.TYPE); + } + + /** + * Create a new Duration with the given duration in seconds (and partial + * seconds). + * + * @param sec + * The duration in seconds. + */ + public Duration(double sec) { + super(sec, Duration.TYPE); + } + + /** + * Create a new Duration with the given duration in nanoseconds. + * + * @param sec + * The duration in nanoseconds. + */ + public Duration(long nano) { + super(nano, Duration.TYPE); + } + + /** + * Add the given Duration to this Duration and return a new Duration with + * that value. + * + * @param d + * The Duration to add. + * @return A new Duration with the new value. + */ + @Override + public Duration add(Duration d) { + return new Duration(this.toSec() + d.toSec()); + } + + /** + * Subtract the given Duration from this Duration and return a new Duration + * with that value. + * + * @param d + * The Duration to subtract. + * @return A new Duration with the new value. + */ + @Override + public Duration subtract(Duration d) { + return new Duration(this.toSec() - d.toSec()); + } + + /** + * Attempt to sleep for the duration specified in this object. + * + * @return If the sleep was successful. + */ + public boolean sleep() { + try { + Thread.sleep( + (this.secs * TimeBase.SECS_TO_MILLI) + + ((long) ((double) this.nsecs / (double) TimeBase.MILLI_TO_NSECS)), + this.nsecs % (int) TimeBase.MILLI_TO_NSECS); + return true; + } catch (InterruptedException e) { + return false; + } + } + + /** + * Create a clone of this Duration. + */ + @Override + public Duration clone() { + return new Duration(this.secs, this.nsecs); + } + + /** + * Create a new Duration message based on the given seconds. + * + * @param sec + * The duration in seconds. + * + * @return The new Duration primitive. + */ + public static Duration fromSec(double sec) { + return new Duration(sec); + } + + /** + * Create a new Duration message based on the given nanoseconds. + * + * @param nano + * The duration in nanoseconds. + * + * @return The new Duration primitive. + */ + public static Duration fromNano(long nano) { + return new Duration(nano); + } + + /** + * Create a new Duration based on the given JSON string. Any missing values + * will be set to their defaults. + * + * @param jsonString + * The JSON string to parse. + * @return A Duration message based on the given JSON string. + */ + public static Duration fromJsonString(String jsonString) { + // convert to a JSON object + return Duration.fromJsonObject(Json.createReader( + new StringReader(jsonString)).readObject()); + } + + /** + * Create a new Duration based on the given JSON object. Any missing values + * will be set to their defaults. + * + * @param jsonObject + * The JSON object to parse. + * @return A Duration message based on the given JSON object. + */ + public static Duration fromJsonObject(JsonObject jsonObject) { + // check the fields + int secs = jsonObject.containsKey(Duration.FIELD_SECS) ? jsonObject + .getInt(Duration.FIELD_SECS) : 0; + int nsecs = jsonObject.containsKey(Duration.FIELD_NSECS) ? jsonObject + .getInt(Duration.FIELD_NSECS) : 0; + return new Duration(secs, nsecs); + } +} diff --git a/src/server/src/main/java/edu/wpi/rail/jrosbridge/primitives/Primitive.java b/src/server/src/main/java/edu/wpi/rail/jrosbridge/primitives/Primitive.java new file mode 100644 index 0000000..564a813 --- /dev/null +++ b/src/server/src/main/java/edu/wpi/rail/jrosbridge/primitives/Primitive.java @@ -0,0 +1,313 @@ +package edu.wpi.rail.jrosbridge.primitives; + +import java.io.StringReader; +import java.math.BigInteger; + +import javax.json.Json; +import javax.json.JsonObject; + +import edu.wpi.rail.jrosbridge.JsonWrapper; + +/** + * Primitive objects are used as a wrapper for non-native ROS primitives. These + * primitives act as wrappers around JSON objects. + * + * This class also contains static functions for dealing with ROS' unsigned + * numbers. + * + * @author Russell Toris - russell.toris@gmail.com + * @version April 1, 2014 + */ +public abstract class Primitive extends JsonWrapper { + + /** + * The String representation of an empty primitive in JSON. + */ + public static final String EMPTY_MESSAGE = JsonWrapper.EMPTY_JSON; + + private String primitiveType; + + /** + * Create a Primitive based on the given String representation of a JSON + * object. + * + * @param jsonString + * The JSON String to parse. + * @param primitiveType + * The type of the primitive (e.g., "geometry_msgs/Twist"). + */ + public Primitive(String jsonString, String primitiveType) { + // parse and pass it to the JSON constructor + this(Json.createReader(new StringReader(jsonString)).readObject(), + primitiveType); + } + + /** + * Create a Primitive based on the given JSON object. + * + * @param jsonObject + * The JSON object containing the primitive data. + * @param primitiveType + * The type of the primitive (e.g., "time"). + */ + public Primitive(JsonObject jsonObject, String primitiveType) { + // setup the JSON information + super(jsonObject); + // set the type + this.primitiveType = primitiveType; + } + + /** + * Get the type of the primitive. + * + * @return The type of the primitive. + */ + public String getPrimitiveType() { + return this.primitiveType; + } + + /** + * Set the type of the primitive. + * + * @param primitiveType + * The type of the primitive (e.g., "time"). + */ + public void setPrimitiveType(String primitiveType) { + this.primitiveType = primitiveType; + } + + /** + * Convert the given value to an unsigned 8-bit unsigned integer. This + * ignores the high 8-bits of the short. + * + * @param value + * The value to convert. + * @return The value encoded as an 8-bit unsigned integer. + */ + public static byte toUInt8(short value) { + // zero out the high 8-bits + short tmp = (short) ((value >> 8) << 8); + return (byte) (value - tmp); + } + + /** + * Convert the given values to unsigned 8-bit unsigned integers. This + * ignores the high 8-bits of the input. + * + * @param values + * The values to convert. + * @return The values encoded as an 8-bit unsigned integer. + */ + public static byte[] toUInt8(short[] values) { + byte[] tmp = new byte[values.length]; + for (int i = 0; i < tmp.length; i++) { + tmp[i] = Primitive.toUInt8(values[i]); + } + return tmp; + } + + /** + * Convert the given value in unsigned 8-bit representation into its actual + * value. That is, all return values of this function will be positive. + * + * @param value + * The unsigned 8-bit value to convert. + * @return The value of the given 8-bit unsigned value. + */ + public static short fromUInt8(byte value) { + return (short) (value & (short) 0xFF); + } + + /** + * Convert the given values in unsigned 8-bit representation into their + * actual values. That is, all return values of this function will be + * positive. + * + * @param values + * The unsigned 8-bit values to convert. + * @return The values of the given 8-bit unsigned values. + */ + public static short[] fromUInt8(byte[] values) { + short[] tmp = new short[values.length]; + for (int i = 0; i < tmp.length; i++) { + tmp[i] = Primitive.fromUInt8(values[i]); + } + return tmp; + } + + /** + * Convert the given value to an unsigned 16-bit unsigned integer. This + * ignores the high 16-bits of the input. + * + * @param value + * The value to convert. + * @return The value encoded as an 16-bit unsigned integer. + */ + public static short toUInt16(int value) { + // zero out the high 16-bits + int tmp = (int) ((value >> 16) << 16); + return (short) (value - tmp); + } + + /** + * Convert the given values to unsigned 16-bit unsigned integers. This + * ignores the high 16-bits of the input. + * + * @param values + * The values to convert. + * @return The values encoded as an 16-bit unsigned integer. + */ + public static short[] toUInt16(int[] values) { + short[] tmp = new short[values.length]; + for (int i = 0; i < tmp.length; i++) { + tmp[i] = Primitive.toUInt16(values[i]); + } + return tmp; + } + + /** + * Convert the given value in unsigned 16-bit representation into its actual + * value. That is, all return values of this function will be positive. + * + * @param value + * The unsigned 16-bit value to convert. + * @return The value of the given 16-bit unsigned value. + */ + public static int fromUInt16(short value) { + return (int) (value & 0xFFFF); + } + + /** + * Convert the given values in unsigned 16-bit representation into their + * actual values. That is, all return values of this function will be + * positive. + * + * @param values + * The unsigned 16-bit values to convert. + * @return The values of the given 16-bit unsigned values. + */ + public static int[] fromUInt16(short[] values) { + int[] tmp = new int[values.length]; + for (int i = 0; i < tmp.length; i++) { + tmp[i] = Primitive.fromUInt16(values[i]); + } + return tmp; + } + + /** + * Convert the given value to an unsigned 32-bit unsigned integer. This + * ignores the high 32-bits of the input. + * + * @param value + * The value to convert. + * @return The value encoded as an 32-bit unsigned integer. + */ + public static int toUInt32(long value) { + // zero out the high 32-bits + long tmp = (long) ((value >> 32) << 32); + return (int) (value - tmp); + } + + /** + * Convert the given values to unsigned 32-bit unsigned integers. This + * ignores the high 32-bits of the input. + * + * @param values + * The values to convert. + * @return The values encoded as an 32-bit unsigned integer. + */ + public static int[] toUInt32(long[] values) { + int[] tmp = new int[values.length]; + for (int i = 0; i < tmp.length; i++) { + tmp[i] = Primitive.toUInt32(values[i]); + } + return tmp; + } + + /** + * Convert the given value in unsigned 32-bit representation into its actual + * value. That is, all return values of this function will be positive. + * + * @param value + * The unsigned 32-bit value to convert. + * @return The value of the given 32-bit unsigned value. + */ + public static long fromUInt32(int value) { + return (long) (value & 0xFFFFFFFFL); + } + + /** + * Convert the given values in unsigned 32-bit representation into their + * actual values. That is, all return values of this function will be + * positive. + * + * @param values + * The unsigned 32-bit values to convert. + * @return The values of the given 64-bit unsigned values. + */ + public static long[] fromUInt32(int[] values) { + long[] tmp = new long[values.length]; + for (int i = 0; i < tmp.length; i++) { + tmp[i] = Primitive.fromUInt32(values[i]); + } + return tmp; + } + + /** + * Convert the given value to an unsigned 64-bit unsigned integer. This + * ignores the high 64-bits of the input. + * + * @param value + * The value to convert. + * @return The value encoded as an 64-bit unsigned integer. + */ + public static long toUInt64(BigInteger value) { + return value.longValue(); + } + + /** + * Convert the given values to unsigned 64-bit unsigned integers. This + * ignores the high 64-bits of the input. + * + * @param values + * The values to convert. + * @return The values encoded as an 64-bit unsigned integer. + */ + public static long[] toUInt64(BigInteger[] values) { + long[] tmp = new long[values.length]; + for (int i = 0; i < tmp.length; i++) { + tmp[i] = Primitive.toUInt64(values[i]); + } + return tmp; + } + + /** + * Convert the given value in unsigned 64-bit representation into its actual + * value. That is, all return values of this function will be positive. + * + * @param value + * The unsigned 64-bit value to convert. + * @return The value of the given 64-bit unsigned value. + */ + public static BigInteger fromUInt64(long value) { + return BigInteger.valueOf(value).and( + BigInteger.ONE.shiftLeft(64).subtract(BigInteger.ONE)); + } + + /** + * Convert the given values in unsigned 64-bit representation into their + * actual values. That is, all return values of this function will be + * positive. + * + * @param values + * The unsigned 64-bit values to convert. + * @return The values of the given 64-bit unsigned values. + */ + public static BigInteger[] fromUInt64(long[] values) { + BigInteger[] tmp = new BigInteger[values.length]; + for (int i = 0; i < tmp.length; i++) { + tmp[i] = Primitive.fromUInt64(values[i]); + } + return tmp; + } +} diff --git a/src/server/src/main/java/edu/wpi/rail/jrosbridge/primitives/Time.java b/src/server/src/main/java/edu/wpi/rail/jrosbridge/primitives/Time.java new file mode 100644 index 0000000..bef7460 --- /dev/null +++ b/src/server/src/main/java/edu/wpi/rail/jrosbridge/primitives/Time.java @@ -0,0 +1,203 @@ +package edu.wpi.rail.jrosbridge.primitives; + +import java.io.StringReader; +import java.util.Calendar; +import java.util.Date; + +import javax.json.Json; +import javax.json.JsonObject; + +/** + * The ROS time primitive. + * + * @author Russell Toris - russell.toris@gmail.com + * @version April 1, 2014 + */ +public class Time extends TimeBase