Commit 05849f9cc847eb8a396e41d5f54b1bb6e101d872

Authored by 娄高锋
2 parents f77f9827 d75e3052

Merge branch 'minhang' of 192.168.168.201:panzhaov5/bsth_control into

minhang
Showing 44 changed files with 6458 additions and 6457 deletions
src/main/java/com/bsth/controller/schedule/BController.java
1 -package com.bsth.controller.schedule;  
2 -  
3 -import com.bsth.common.ResponseCode;  
4 -import com.bsth.service.schedule.BService;  
5 -import com.bsth.service.schedule.ScheduleException;  
6 -import com.google.common.base.Splitter;  
7 -import org.springframework.beans.factory.annotation.Autowired;  
8 -import org.springframework.data.domain.PageRequest;  
9 -import org.springframework.data.domain.Sort;  
10 -import org.springframework.web.bind.annotation.*;  
11 -  
12 -import java.io.Serializable;  
13 -import java.util.ArrayList;  
14 -import java.util.HashMap;  
15 -import java.util.List;  
16 -import java.util.Map;  
17 -  
18 -/**  
19 - * 基础控制器。  
20 - */  
21 -public class BController<T, ID extends Serializable> {  
22 - @Autowired  
23 - protected BService<T, ID> bService;  
24 -  
25 - // CRUD 操作  
26 - // Create操作  
27 - @RequestMapping(method = RequestMethod.POST)  
28 - public Map<String, Object> save(@RequestBody T t) {  
29 - T t_saved = bService.save(t);  
30 - Map<String, Object> rtn = new HashMap<>();  
31 - rtn.put("status", ResponseCode.SUCCESS);  
32 - rtn.put("data", t_saved);  
33 - return rtn;  
34 - }  
35 - // Update操作  
36 - @RequestMapping(value="/{id}", method = RequestMethod.POST)  
37 - public Map<String, Object> update(@RequestBody T t) {  
38 - return save(t);  
39 - }  
40 - // Research操作  
41 - @RequestMapping(value = "/{id}", method = RequestMethod.GET)  
42 - public Map<String, Object> findById(@PathVariable("id") ID id) {  
43 - T t = bService.findById(id);  
44 - Map<String, Object> rtn = new HashMap<>();  
45 - rtn.put("status", ResponseCode.SUCCESS);  
46 - rtn.put("data", t);  
47 - return rtn;  
48 - }  
49 - @RequestMapping(value = "/all", method = RequestMethod.GET)  
50 - public Map<String, Object> list(@RequestParam Map<String, Object> param) {  
51 - List<T> tList = bService.list(param);  
52 - Map<String, Object> rtn = new HashMap<>();  
53 - rtn.put("status", ResponseCode.SUCCESS);  
54 - rtn.put("data", tList);  
55 - return rtn;  
56 - }  
57 - @RequestMapping(method = RequestMethod.GET)  
58 - public Map<String, Object> list(  
59 - @RequestParam Map<String, Object> map,  
60 - @RequestParam(defaultValue = "0") int page,  
61 - @RequestParam(defaultValue = "10") int size,  
62 - @RequestParam(defaultValue = "id") String order,  
63 - @RequestParam(defaultValue = "DESC") String direction) {  
64 - // 允许多个字段排序,order可以写单个字段,也可以写多个字段  
65 - // 多个字段格式:{col1},{col2},{col3},....,{coln}  
66 - List<String> order_columns = Splitter.on(",").trimResults().splitToList(order);  
67 - // 多字段排序:DESC,ASC...  
68 - List<String> order_dirs = Splitter.on(",").trimResults().splitToList(direction);  
69 -  
70 - Map<String, Object> rtn = new HashMap<>();  
71 -  
72 - if (order_dirs.size() == 1) { // 所有字段采用一种排序  
73 - rtn.put("status", ResponseCode.SUCCESS);  
74 - if (order_dirs.get(0).equals("ASC")) {  
75 - rtn.put("data", bService.list(map, new PageRequest(page, size, new Sort(Sort.Direction.ASC, order_columns))));  
76 - } else {  
77 - rtn.put("data", bService.list(map, new PageRequest(page, size, new Sort(Sort.Direction.DESC, order_columns))));  
78 - }  
79 - } else if (order_columns.size() == order_dirs.size()) {  
80 - List<Sort.Order> orderList = new ArrayList<>();  
81 - for (int i = 0; i < order_columns.size(); i++) {  
82 - if (null != order_dirs.get(i) && order_dirs.get(i).equals("ASC")) {  
83 - orderList.add(new Sort.Order(Sort.Direction.ASC, order_columns.get(i)));  
84 - } else {  
85 - orderList.add(new Sort.Order(Sort.Direction.DESC, order_columns.get(i)));  
86 - }  
87 - }  
88 - rtn.put("status", ResponseCode.SUCCESS);  
89 - rtn.put("data", bService.list(map, new PageRequest(page, size, new Sort(orderList))));  
90 - } else {  
91 - throw new RuntimeException("多字段排序参数格式问题,排序顺序和字段数不一致");  
92 - }  
93 -  
94 - return rtn;  
95 -  
96 - }  
97 -  
98 - // Delete操作  
99 - @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)  
100 - public Map<String, Object> delete(@PathVariable("id") ID id) {  
101 - Map<String, Object> rtn = new HashMap<>();  
102 - try {  
103 - bService.delete(id);  
104 - rtn.put("status", ResponseCode.SUCCESS);  
105 - } catch (ScheduleException exp) {  
106 - rtn.put("status", ResponseCode.ERROR);  
107 - rtn.put("msg", exp.getMessage());  
108 - }  
109 -  
110 - return rtn;  
111 - }  
112 -  
113 -} 1 +package com.bsth.controller.schedule;
  2 +
  3 +import com.bsth.common.ResponseCode;
  4 +import com.bsth.service.schedule.BService;
  5 +import com.bsth.service.schedule.ScheduleException;
  6 +import com.google.common.base.Splitter;
  7 +import org.springframework.beans.factory.annotation.Autowired;
  8 +import org.springframework.data.domain.PageRequest;
  9 +import org.springframework.data.domain.Sort;
  10 +import org.springframework.web.bind.annotation.*;
  11 +
  12 +import java.io.Serializable;
  13 +import java.util.ArrayList;
  14 +import java.util.HashMap;
  15 +import java.util.List;
  16 +import java.util.Map;
  17 +
  18 +/**
  19 + * 基础控制器。
  20 + */
  21 +public class BController<T, ID extends Serializable> {
  22 + @Autowired
  23 + protected BService<T, ID> bService;
  24 +
  25 + // CRUD 操作
  26 + // Create操作
  27 + @RequestMapping(method = RequestMethod.POST)
  28 + public Map<String, Object> save(@RequestBody T t) {
  29 + T t_saved = bService.save(t);
  30 + Map<String, Object> rtn = new HashMap<>();
  31 + rtn.put("status", ResponseCode.SUCCESS);
  32 + rtn.put("data", t_saved);
  33 + return rtn;
  34 + }
  35 + // Update操作
  36 + @RequestMapping(value="/{id}", method = RequestMethod.POST)
  37 + public Map<String, Object> update(@RequestBody T t) {
  38 + return save(t);
  39 + }
  40 + // Research操作
  41 + @RequestMapping(value = "/{id}", method = RequestMethod.GET)
  42 + public Map<String, Object> findById(@PathVariable("id") ID id) {
  43 + T t = bService.findById(id);
  44 + Map<String, Object> rtn = new HashMap<>();
  45 + rtn.put("status", ResponseCode.SUCCESS);
  46 + rtn.put("data", t);
  47 + return rtn;
  48 + }
  49 + @RequestMapping(value = "/all", method = RequestMethod.GET)
  50 + public Map<String, Object> list(@RequestParam Map<String, Object> param) {
  51 + List<T> tList = bService.list(param);
  52 + Map<String, Object> rtn = new HashMap<>();
  53 + rtn.put("status", ResponseCode.SUCCESS);
  54 + rtn.put("data", tList);
  55 + return rtn;
  56 + }
  57 + @RequestMapping(method = RequestMethod.GET)
  58 + public Map<String, Object> list(
  59 + @RequestParam Map<String, Object> map,
  60 + @RequestParam(defaultValue = "0") int page,
  61 + @RequestParam(defaultValue = "10") int size,
  62 + @RequestParam(defaultValue = "id") String order,
  63 + @RequestParam(defaultValue = "DESC") String direction) {
  64 + // 允许多个字段排序,order可以写单个字段,也可以写多个字段
  65 + // 多个字段格式:{col1},{col2},{col3},....,{coln}
  66 + List<String> order_columns = Splitter.on(",").trimResults().splitToList(order);
  67 + // 多字段排序:DESC,ASC...
  68 + List<String> order_dirs = Splitter.on(",").trimResults().splitToList(direction);
  69 +
  70 + Map<String, Object> rtn = new HashMap<>();
  71 +
  72 + if (order_dirs.size() == 1) { // 所有字段采用一种排序
  73 + rtn.put("status", ResponseCode.SUCCESS);
  74 + if (order_dirs.get(0).equals("ASC")) {
  75 + rtn.put("data", bService.list(map, new PageRequest(page, size, new Sort(Sort.Direction.ASC, order_columns))));
  76 + } else {
  77 + rtn.put("data", bService.list(map, new PageRequest(page, size, new Sort(Sort.Direction.DESC, order_columns))));
  78 + }
  79 + } else if (order_columns.size() == order_dirs.size()) {
  80 + List<Sort.Order> orderList = new ArrayList<>();
  81 + for (int i = 0; i < order_columns.size(); i++) {
  82 + if (null != order_dirs.get(i) && order_dirs.get(i).equals("ASC")) {
  83 + orderList.add(new Sort.Order(Sort.Direction.ASC, order_columns.get(i)));
  84 + } else {
  85 + orderList.add(new Sort.Order(Sort.Direction.DESC, order_columns.get(i)));
  86 + }
  87 + }
  88 + rtn.put("status", ResponseCode.SUCCESS);
  89 + rtn.put("data", bService.list(map, new PageRequest(page, size, new Sort(orderList))));
  90 + } else {
  91 + throw new RuntimeException("多字段排序参数格式问题,排序顺序和字段数不一致");
  92 + }
  93 +
  94 + return rtn;
  95 +
  96 + }
  97 +
  98 + // Delete操作
  99 + @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
  100 + public Map<String, Object> delete(@PathVariable("id") ID id) {
  101 + Map<String, Object> rtn = new HashMap<>();
  102 + try {
  103 + bService.delete(id);
  104 + rtn.put("status", ResponseCode.SUCCESS);
  105 + } catch (ScheduleException exp) {
  106 + rtn.put("status", ResponseCode.ERROR);
  107 + rtn.put("msg", exp.getMessage());
  108 + }
  109 +
  110 + return rtn;
  111 + }
  112 +
  113 +}
src/main/java/com/bsth/controller/schedule/basicinfo/CarsController.java
1 -package com.bsth.controller.schedule.basicinfo;  
2 -  
3 -import com.bsth.common.ResponseCode;  
4 -import com.bsth.controller.schedule.BController;  
5 -import com.bsth.entity.Cars;  
6 -import com.bsth.service.schedule.CarsService;  
7 -import com.bsth.service.schedule.ScheduleException;  
8 -import org.springframework.beans.factory.annotation.Autowired;  
9 -import org.springframework.web.bind.annotation.RequestMapping;  
10 -import org.springframework.web.bind.annotation.RequestMethod;  
11 -import org.springframework.web.bind.annotation.RequestParam;  
12 -import org.springframework.web.bind.annotation.RestController;  
13 -  
14 -import java.util.HashMap;  
15 -import java.util.Map;  
16 -  
17 -/**  
18 - * 车辆基础信息controller  
19 - */  
20 -@RestController(value = "carsController_sc")  
21 -@RequestMapping("cars_sc")  
22 -public class CarsController extends BController<Cars, Integer> {  
23 - @Autowired  
24 - private CarsService carsService;  
25 -  
26 - @RequestMapping(value = "/validate_zbh", method = RequestMethod.GET)  
27 - public Map<String, Object> validate_zbh(@RequestParam Map<String, Object> param) {  
28 - Map<String, Object> rtn = new HashMap<>();  
29 - try {  
30 - // 自编号验证  
31 - Cars cars = new Cars(  
32 - param.get("id_eq"),  
33 - param.get("insideCode_eq"),  
34 - null,  
35 - null,  
36 - null);  
37 - carsService.validate_nbbh(cars);  
38 - rtn.put("status", ResponseCode.SUCCESS);  
39 - } catch (ScheduleException exp) {  
40 - rtn.put("status", ResponseCode.ERROR);  
41 - rtn.put("msg", exp.getMessage());  
42 - }  
43 - return rtn;  
44 - }  
45 -  
46 - @RequestMapping(value = "/validate_clbh", method = RequestMethod.GET)  
47 - public Map<String, Object> validate_clbh(@RequestParam Map<String, Object> param) {  
48 - Map<String, Object> rtn = new HashMap<>();  
49 - try {  
50 - // 车辆编号验证  
51 - Cars cars = new Cars(  
52 - param.get("id_eq"),  
53 - null,  
54 - param.get("carCode_eq"),  
55 - null,  
56 - null);  
57 - carsService.validate_clbh(cars);  
58 - rtn.put("status", ResponseCode.SUCCESS);  
59 - } catch (ScheduleException exp) {  
60 - rtn.put("status", ResponseCode.ERROR);  
61 - rtn.put("msg", exp.getMessage());  
62 - }  
63 - return rtn;  
64 - }  
65 -  
66 - @RequestMapping(value = "/validate_cph", method = RequestMethod.GET)  
67 - public Map<String, Object> validate_cph(@RequestParam Map<String, Object> param) {  
68 - Map<String, Object> rtn = new HashMap<>();  
69 - try {  
70 - // 车牌号验证  
71 - Cars cars = new Cars(  
72 - param.get("id_eq"),  
73 - null,  
74 - null,  
75 - param.get("carPlate_eq"),  
76 - null);  
77 - carsService.validate_cph(cars);  
78 - rtn.put("status", ResponseCode.SUCCESS);  
79 - } catch (ScheduleException exp) {  
80 - rtn.put("status", ResponseCode.ERROR);  
81 - rtn.put("msg", exp.getMessage());  
82 - }  
83 - return rtn;  
84 - }  
85 -  
86 - @RequestMapping(value = "/validate_sbbh", method = RequestMethod.GET)  
87 - public Map<String, Object> validate_sbbh(@RequestParam Map<String, Object> param) {  
88 - Map<String, Object> rtn = new HashMap<>();  
89 - try {  
90 - // 设备编号验证  
91 - Cars cars = new Cars(  
92 - param.get("id_eq"),  
93 - null,  
94 - null,  
95 - null,  
96 - param.get("equipmentCode_eq")  
97 - );  
98 - carsService.validate_sbbh(cars);  
99 - rtn.put("status", ResponseCode.SUCCESS);  
100 - } catch (ScheduleException exp) {  
101 - rtn.put("status", ResponseCode.ERROR);  
102 - rtn.put("msg", exp.getMessage());  
103 - }  
104 - return rtn;  
105 - }  
106 -} 1 +package com.bsth.controller.schedule.basicinfo;
  2 +
  3 +import com.bsth.common.ResponseCode;
  4 +import com.bsth.controller.schedule.BController;
  5 +import com.bsth.entity.Cars;
  6 +import com.bsth.service.schedule.CarsService;
  7 +import com.bsth.service.schedule.ScheduleException;
  8 +import org.springframework.beans.factory.annotation.Autowired;
  9 +import org.springframework.web.bind.annotation.RequestMapping;
  10 +import org.springframework.web.bind.annotation.RequestMethod;
  11 +import org.springframework.web.bind.annotation.RequestParam;
  12 +import org.springframework.web.bind.annotation.RestController;
  13 +
  14 +import java.util.HashMap;
  15 +import java.util.Map;
  16 +
  17 +/**
  18 + * 车辆基础信息controller
  19 + */
  20 +@RestController(value = "carsController_sc")
  21 +@RequestMapping("cars_sc")
  22 +public class CarsController extends BController<Cars, Integer> {
  23 + @Autowired
  24 + private CarsService carsService;
  25 +
  26 + @RequestMapping(value = "/validate_zbh", method = RequestMethod.GET)
  27 + public Map<String, Object> validate_zbh(@RequestParam Map<String, Object> param) {
  28 + Map<String, Object> rtn = new HashMap<>();
  29 + try {
  30 + // 自编号验证
  31 + Cars cars = new Cars(
  32 + param.get("id_eq"),
  33 + param.get("insideCode_eq"),
  34 + null,
  35 + null,
  36 + null);
  37 + carsService.validate_nbbh(cars);
  38 + rtn.put("status", ResponseCode.SUCCESS);
  39 + } catch (ScheduleException exp) {
  40 + rtn.put("status", ResponseCode.ERROR);
  41 + rtn.put("msg", exp.getMessage());
  42 + }
  43 + return rtn;
  44 + }
  45 +
  46 + @RequestMapping(value = "/validate_clbh", method = RequestMethod.GET)
  47 + public Map<String, Object> validate_clbh(@RequestParam Map<String, Object> param) {
  48 + Map<String, Object> rtn = new HashMap<>();
  49 + try {
  50 + // 车辆编号验证
  51 + Cars cars = new Cars(
  52 + param.get("id_eq"),
  53 + null,
  54 + param.get("carCode_eq"),
  55 + null,
  56 + null);
  57 + carsService.validate_clbh(cars);
  58 + rtn.put("status", ResponseCode.SUCCESS);
  59 + } catch (ScheduleException exp) {
  60 + rtn.put("status", ResponseCode.ERROR);
  61 + rtn.put("msg", exp.getMessage());
  62 + }
  63 + return rtn;
  64 + }
  65 +
  66 + @RequestMapping(value = "/validate_cph", method = RequestMethod.GET)
  67 + public Map<String, Object> validate_cph(@RequestParam Map<String, Object> param) {
  68 + Map<String, Object> rtn = new HashMap<>();
  69 + try {
  70 + // 车牌号验证
  71 + Cars cars = new Cars(
  72 + param.get("id_eq"),
  73 + null,
  74 + null,
  75 + param.get("carPlate_eq"),
  76 + null);
  77 + carsService.validate_cph(cars);
  78 + rtn.put("status", ResponseCode.SUCCESS);
  79 + } catch (ScheduleException exp) {
  80 + rtn.put("status", ResponseCode.ERROR);
  81 + rtn.put("msg", exp.getMessage());
  82 + }
  83 + return rtn;
  84 + }
  85 +
  86 + @RequestMapping(value = "/validate_sbbh", method = RequestMethod.GET)
  87 + public Map<String, Object> validate_sbbh(@RequestParam Map<String, Object> param) {
  88 + Map<String, Object> rtn = new HashMap<>();
  89 + try {
  90 + // 设备编号验证
  91 + Cars cars = new Cars(
  92 + param.get("id_eq"),
  93 + null,
  94 + null,
  95 + null,
  96 + param.get("equipmentCode_eq")
  97 + );
  98 + carsService.validate_sbbh(cars);
  99 + rtn.put("status", ResponseCode.SUCCESS);
  100 + } catch (ScheduleException exp) {
  101 + rtn.put("status", ResponseCode.ERROR);
  102 + rtn.put("msg", exp.getMessage());
  103 + }
  104 + return rtn;
  105 + }
  106 +}
src/main/java/com/bsth/service/forms/impl/FormsServiceImpl.java
@@ -525,7 +525,8 @@ public class FormsServiceImpl implements FormsService { @@ -525,7 +525,8 @@ public class FormsServiceImpl implements FormsService {
525 tu.setRq(rq); 525 tu.setRq(rq);
526 tu.setGs(arg0.getString("gs_name").toString()); 526 tu.setGs(arg0.getString("gs_name").toString());
527 tu.setZhgs(arg0.getString("fgs_name").toString()); 527 tu.setZhgs(arg0.getString("fgs_name").toString());
528 - tu.setXl(arg0.getString("xlgs")); 528 + //tu.setXl(arg0.getString("xlgs"));这个是根据公司判断线路有几条
  529 + tu.setXl(arg0.getString("sxl"));
529 tu.setXlmc(arg0.getString("sxl")); 530 tu.setXlmc(arg0.getString("sxl"));
530 tu.setCchjh(arg0.getString("jcl").toString()); 531 tu.setCchjh(arg0.getString("jcl").toString());
531 tu.setCchsj(arg0.getString("scl").toString()); 532 tu.setCchsj(arg0.getString("scl").toString());
src/main/java/com/bsth/service/realcontrol/dto/SectionRouteCoords.java
1 -package com.bsth.service.realcontrol.dto;  
2 -  
3 -/**  
4 - * 线调地图 路段路由DTO  
5 - * Created by panzhao on 2016/12/1.  
6 - */  
7 -public class SectionRouteCoords {  
8 -  
9 - private int id;  
10 -  
11 - private String lineCode;  
12 -  
13 - private String sectionCode;  
14 -  
15 - private String sectionrouteCode;  
16 -  
17 - private int directions;  
18 -  
19 - private String sectionName;  
20 -  
21 - private String gsectionVector;  
22 -  
23 - private Float sectionDistance;  
24 -  
25 - private Float sectionTime;  
26 -  
27 - public int getId() {  
28 - return id;  
29 - }  
30 -  
31 - public void setId(int id) {  
32 - this.id = id;  
33 - }  
34 -  
35 - public String getLineCode() {  
36 - return lineCode;  
37 - }  
38 -  
39 - public void setLineCode(String lineCode) {  
40 - this.lineCode = lineCode;  
41 - }  
42 -  
43 - public String getSectionCode() {  
44 - return sectionCode;  
45 - }  
46 -  
47 - public void setSectionCode(String sectionCode) {  
48 - this.sectionCode = sectionCode;  
49 - }  
50 -  
51 - public String getSectionrouteCode() {  
52 - return sectionrouteCode;  
53 - }  
54 -  
55 - public void setSectionrouteCode(String sectionrouteCode) {  
56 - this.sectionrouteCode = sectionrouteCode;  
57 - }  
58 -  
59 - public int getDirections() {  
60 - return directions;  
61 - }  
62 -  
63 - public void setDirections(int directions) {  
64 - this.directions = directions;  
65 - }  
66 -  
67 - public String getSectionName() {  
68 - return sectionName;  
69 - }  
70 -  
71 - public void setSectionName(String sectionName) {  
72 - this.sectionName = sectionName;  
73 - }  
74 -  
75 - public String getGsectionVector() {  
76 - return gsectionVector;  
77 - }  
78 -  
79 - public void setGsectionVector(String gsectionVector) {  
80 - this.gsectionVector = gsectionVector;  
81 - }  
82 -  
83 - public Float getSectionDistance() {  
84 - return sectionDistance;  
85 - }  
86 -  
87 - public void setSectionDistance(Float sectionDistance) {  
88 - this.sectionDistance = sectionDistance;  
89 - }  
90 -  
91 - public Float getSectionTime() {  
92 - return sectionTime;  
93 - }  
94 -  
95 - public void setSectionTime(Float sectionTime) {  
96 - this.sectionTime = sectionTime;  
97 - }  
98 -} 1 +package com.bsth.service.realcontrol.dto;
  2 +
  3 +/**
  4 + * 线调地图 路段路由DTO
  5 + * Created by panzhao on 2016/12/1.
  6 + */
  7 +public class SectionRouteCoords {
  8 +
  9 + private int id;
  10 +
  11 + private String lineCode;
  12 +
  13 + private String sectionCode;
  14 +
  15 + private String sectionrouteCode;
  16 +
  17 + private int directions;
  18 +
  19 + private String sectionName;
  20 +
  21 + private String gsectionVector;
  22 +
  23 + private Float sectionDistance;
  24 +
  25 + private Float sectionTime;
  26 +
  27 + public int getId() {
  28 + return id;
  29 + }
  30 +
  31 + public void setId(int id) {
  32 + this.id = id;
  33 + }
  34 +
  35 + public String getLineCode() {
  36 + return lineCode;
  37 + }
  38 +
  39 + public void setLineCode(String lineCode) {
  40 + this.lineCode = lineCode;
  41 + }
  42 +
  43 + public String getSectionCode() {
  44 + return sectionCode;
  45 + }
  46 +
  47 + public void setSectionCode(String sectionCode) {
  48 + this.sectionCode = sectionCode;
  49 + }
  50 +
  51 + public String getSectionrouteCode() {
  52 + return sectionrouteCode;
  53 + }
  54 +
  55 + public void setSectionrouteCode(String sectionrouteCode) {
  56 + this.sectionrouteCode = sectionrouteCode;
  57 + }
  58 +
  59 + public int getDirections() {
  60 + return directions;
  61 + }
  62 +
  63 + public void setDirections(int directions) {
  64 + this.directions = directions;
  65 + }
  66 +
  67 + public String getSectionName() {
  68 + return sectionName;
  69 + }
  70 +
  71 + public void setSectionName(String sectionName) {
  72 + this.sectionName = sectionName;
  73 + }
  74 +
  75 + public String getGsectionVector() {
  76 + return gsectionVector;
  77 + }
  78 +
  79 + public void setGsectionVector(String gsectionVector) {
  80 + this.gsectionVector = gsectionVector;
  81 + }
  82 +
  83 + public Float getSectionDistance() {
  84 + return sectionDistance;
  85 + }
  86 +
  87 + public void setSectionDistance(Float sectionDistance) {
  88 + this.sectionDistance = sectionDistance;
  89 + }
  90 +
  91 + public Float getSectionTime() {
  92 + return sectionTime;
  93 + }
  94 +
  95 + public void setSectionTime(Float sectionTime) {
  96 + this.sectionTime = sectionTime;
  97 + }
  98 +}
src/main/java/com/bsth/service/schedule/BService.java
1 -package com.bsth.service.schedule;  
2 -  
3 -import org.springframework.data.domain.Page;  
4 -import org.springframework.data.domain.Pageable;  
5 -  
6 -import java.io.Serializable;  
7 -import java.util.List;  
8 -import java.util.Map;  
9 -  
10 -/**  
11 - * 基础service接口。  
12 - */  
13 -public interface BService<T, ID extends Serializable> {  
14 - // CRUD 操作  
15 - // Create,Update操作  
16 - T save(T t);  
17 - <S extends T> List<S> bulkSave(List<S> entities); // 批量保存(TODO:待测试)  
18 - // Research操作  
19 - T findById(ID id);  
20 - List<T> findAll();  
21 - Page<T> list(Map<String, Object> param, Pageable pageable);  
22 - List<T> list(Map<String, Object> param);  
23 - // Delete操作  
24 - void delete(ID id) throws ScheduleException;  
25 -} 1 +package com.bsth.service.schedule;
  2 +
  3 +import org.springframework.data.domain.Page;
  4 +import org.springframework.data.domain.Pageable;
  5 +
  6 +import java.io.Serializable;
  7 +import java.util.List;
  8 +import java.util.Map;
  9 +
  10 +/**
  11 + * 基础service接口。
  12 + */
  13 +public interface BService<T, ID extends Serializable> {
  14 + // CRUD 操作
  15 + // Create,Update操作
  16 + T save(T t);
  17 + <S extends T> List<S> bulkSave(List<S> entities); // 批量保存(TODO:待测试)
  18 + // Research操作
  19 + T findById(ID id);
  20 + List<T> findAll();
  21 + Page<T> list(Map<String, Object> param, Pageable pageable);
  22 + List<T> list(Map<String, Object> param);
  23 + // Delete操作
  24 + void delete(ID id) throws ScheduleException;
  25 +}
src/main/java/com/bsth/service/schedule/CarsService.java
1 -package com.bsth.service.schedule;  
2 -  
3 -import com.bsth.entity.Cars;  
4 -  
5 -/**  
6 - * Created by xu on 16/12/8.  
7 - */  
8 -public interface CarsService extends BService<Cars, Integer> {  
9 - public void validate_nbbh(Cars cars) throws ScheduleException;  
10 - public void validate_clbh(Cars cars) throws ScheduleException;  
11 - public void validate_cph(Cars cars) throws ScheduleException;  
12 - public void validate_sbbh(Cars cars) throws ScheduleException;  
13 -} 1 +package com.bsth.service.schedule;
  2 +
  3 +import com.bsth.entity.Cars;
  4 +
  5 +/**
  6 + * Created by xu on 16/12/8.
  7 + */
  8 +public interface CarsService extends BService<Cars, Integer> {
  9 + public void validate_nbbh(Cars cars) throws ScheduleException;
  10 + public void validate_clbh(Cars cars) throws ScheduleException;
  11 + public void validate_cph(Cars cars) throws ScheduleException;
  12 + public void validate_sbbh(Cars cars) throws ScheduleException;
  13 +}
src/main/java/com/bsth/service/schedule/ScheduleException.java
1 -package com.bsth.service.schedule;  
2 -  
3 -/**  
4 - * Created by xu on 16/12/5.  
5 - */  
6 -public class ScheduleException extends Exception {  
7 - public ScheduleException(String message) {  
8 - super("计划调度业务错误==>>" + message);  
9 - }  
10 -} 1 +package com.bsth.service.schedule;
  2 +
  3 +/**
  4 + * Created by xu on 16/12/5.
  5 + */
  6 +public class ScheduleException extends Exception {
  7 + public ScheduleException(String message) {
  8 + super("计划调度业务错误==>>" + message);
  9 + }
  10 +}
src/main/java/com/bsth/service/schedule/impl/BServiceImpl.java
1 -package com.bsth.service.schedule.impl;  
2 -  
3 -import com.bsth.entity.search.CustomerSpecs;  
4 -import com.bsth.repository.BaseRepository;  
5 -import com.bsth.service.schedule.BService;  
6 -import com.bsth.service.schedule.ScheduleException;  
7 -import org.slf4j.Logger;  
8 -import org.slf4j.LoggerFactory;  
9 -import org.springframework.beans.factory.annotation.Autowired;  
10 -import org.springframework.beans.factory.annotation.Value;  
11 -import org.springframework.data.domain.Page;  
12 -import org.springframework.data.domain.Pageable;  
13 -import org.springframework.data.jpa.domain.Specification;  
14 -  
15 -import javax.persistence.EntityManager;  
16 -import java.io.Serializable;  
17 -import java.util.ArrayList;  
18 -import java.util.List;  
19 -import java.util.Map;  
20 -  
21 -/**  
22 - * 基础BService实现。  
23 - */  
24 -public class BServiceImpl<T, ID extends Serializable> implements BService<T, ID> {  
25 - @Autowired  
26 - private BaseRepository<T, ID> baseRepository;  
27 - @Autowired  
28 - private EntityManager entityManager;  
29 - @Value("${hibernate.jdbc.batch_size}")  
30 - private int batchSize;  
31 -  
32 - /** 日志记录器 */  
33 - protected Logger logger = LoggerFactory.getLogger(this.getClass());  
34 -  
35 - // CRUD 操作  
36 - // Create,Update操作  
37 - @Override  
38 - public T save(T t) {  
39 - if (logger.isDebugEnabled()) {  
40 - logger.debug("save...");  
41 - }  
42 - return baseRepository.save(t);  
43 - }  
44 - @Override  
45 - public <S extends T> List<S> bulkSave(List<S> entities) {  
46 - if (logger.isDebugEnabled()) {  
47 - logger.debug("bulkSave...");  
48 - }  
49 -  
50 - // 不使用内部批量保存,自己实现批量保存  
51 - final List<S> savedEntities = new ArrayList<>(entities.size());  
52 - int i = 0;  
53 - for (S t : entities) {  
54 - entityManager.persist(t);  
55 - savedEntities.add(t);  
56 - i++;  
57 - if (i % batchSize == 0) {  
58 - entityManager.flush();  
59 - entityManager.clear();  
60 - }  
61 - }  
62 - return savedEntities;  
63 - }  
64 -  
65 - // Research操作  
66 - @Override  
67 - public T findById(ID id) {  
68 - if (logger.isDebugEnabled()) {  
69 - logger.debug("findById...");  
70 - }  
71 -  
72 - return baseRepository.findOne(id);  
73 - }  
74 - @Override  
75 - public List<T> findAll() {  
76 - if (logger.isDebugEnabled()) {  
77 - logger.debug("findAll...");  
78 - }  
79 -  
80 - return (List<T>) baseRepository.findAll();  
81 - }  
82 - @Override  
83 - public Page<T> list(Map<String, Object> param, Pageable pageable) {  
84 - if (logger.isDebugEnabled()) {  
85 - logger.debug("list(...,pageable)...");  
86 - }  
87 -  
88 - // 自定义查询参数  
89 - Specification<T> specification = new CustomerSpecs<>(param);  
90 - return baseRepository.findAll(specification, pageable);  
91 - }  
92 - @Override  
93 - public List<T> list(Map<String, Object> param) {  
94 - if (logger.isDebugEnabled()) {  
95 - logger.debug("list...");  
96 - }  
97 -  
98 - // 自定义查询参数  
99 - Specification<T> specification = new CustomerSpecs<>(param);  
100 - return baseRepository.findAll(specification);  
101 - }  
102 - // Delete操作  
103 - @Override  
104 - public void delete(ID id) throws ScheduleException {  
105 - if (logger.isDebugEnabled()) {  
106 - logger.debug("delete...");  
107 - }  
108 -  
109 - baseRepository.delete(id);  
110 - }  
111 -} 1 +package com.bsth.service.schedule.impl;
  2 +
  3 +import com.bsth.entity.search.CustomerSpecs;
  4 +import com.bsth.repository.BaseRepository;
  5 +import com.bsth.service.schedule.BService;
  6 +import com.bsth.service.schedule.ScheduleException;
  7 +import org.slf4j.Logger;
  8 +import org.slf4j.LoggerFactory;
  9 +import org.springframework.beans.factory.annotation.Autowired;
  10 +import org.springframework.beans.factory.annotation.Value;
  11 +import org.springframework.data.domain.Page;
  12 +import org.springframework.data.domain.Pageable;
  13 +import org.springframework.data.jpa.domain.Specification;
  14 +
  15 +import javax.persistence.EntityManager;
  16 +import java.io.Serializable;
  17 +import java.util.ArrayList;
  18 +import java.util.List;
  19 +import java.util.Map;
  20 +
  21 +/**
  22 + * 基础BService实现。
  23 + */
  24 +public class BServiceImpl<T, ID extends Serializable> implements BService<T, ID> {
  25 + @Autowired
  26 + private BaseRepository<T, ID> baseRepository;
  27 + @Autowired
  28 + private EntityManager entityManager;
  29 + @Value("${hibernate.jdbc.batch_size}")
  30 + private int batchSize;
  31 +
  32 + /** 日志记录器 */
  33 + protected Logger logger = LoggerFactory.getLogger(this.getClass());
  34 +
  35 + // CRUD 操作
  36 + // Create,Update操作
  37 + @Override
  38 + public T save(T t) {
  39 + if (logger.isDebugEnabled()) {
  40 + logger.debug("save...");
  41 + }
  42 + return baseRepository.save(t);
  43 + }
  44 + @Override
  45 + public <S extends T> List<S> bulkSave(List<S> entities) {
  46 + if (logger.isDebugEnabled()) {
  47 + logger.debug("bulkSave...");
  48 + }
  49 +
  50 + // 不使用内部批量保存,自己实现批量保存
  51 + final List<S> savedEntities = new ArrayList<>(entities.size());
  52 + int i = 0;
  53 + for (S t : entities) {
  54 + entityManager.persist(t);
  55 + savedEntities.add(t);
  56 + i++;
  57 + if (i % batchSize == 0) {
  58 + entityManager.flush();
  59 + entityManager.clear();
  60 + }
  61 + }
  62 + return savedEntities;
  63 + }
  64 +
  65 + // Research操作
  66 + @Override
  67 + public T findById(ID id) {
  68 + if (logger.isDebugEnabled()) {
  69 + logger.debug("findById...");
  70 + }
  71 +
  72 + return baseRepository.findOne(id);
  73 + }
  74 + @Override
  75 + public List<T> findAll() {
  76 + if (logger.isDebugEnabled()) {
  77 + logger.debug("findAll...");
  78 + }
  79 +
  80 + return (List<T>) baseRepository.findAll();
  81 + }
  82 + @Override
  83 + public Page<T> list(Map<String, Object> param, Pageable pageable) {
  84 + if (logger.isDebugEnabled()) {
  85 + logger.debug("list(...,pageable)...");
  86 + }
  87 +
  88 + // 自定义查询参数
  89 + Specification<T> specification = new CustomerSpecs<>(param);
  90 + return baseRepository.findAll(specification, pageable);
  91 + }
  92 + @Override
  93 + public List<T> list(Map<String, Object> param) {
  94 + if (logger.isDebugEnabled()) {
  95 + logger.debug("list...");
  96 + }
  97 +
  98 + // 自定义查询参数
  99 + Specification<T> specification = new CustomerSpecs<>(param);
  100 + return baseRepository.findAll(specification);
  101 + }
  102 + // Delete操作
  103 + @Override
  104 + public void delete(ID id) throws ScheduleException {
  105 + if (logger.isDebugEnabled()) {
  106 + logger.debug("delete...");
  107 + }
  108 +
  109 + baseRepository.delete(id);
  110 + }
  111 +}
src/main/java/com/bsth/service/schedule/impl/CarsServiceImpl.java
1 -package com.bsth.service.schedule.impl;  
2 -  
3 -import com.bsth.entity.Cars;  
4 -import com.bsth.service.schedule.CarsService;  
5 -import com.bsth.service.schedule.ScheduleException;  
6 -import org.springframework.stereotype.Service;  
7 -import org.springframework.transaction.annotation.Transactional;  
8 -import org.springframework.util.CollectionUtils;  
9 -  
10 -import java.util.HashMap;  
11 -import java.util.Map;  
12 -  
13 -/**  
14 - * Created by xu on 16/12/8.  
15 - */  
16 -@Service(value = "carsServiceImpl_sc")  
17 -public class CarsServiceImpl extends BServiceImpl<Cars, Integer> implements CarsService {  
18 -  
19 - @Override  
20 - @Transactional  
21 - public void validate_nbbh(Cars cars) throws ScheduleException {  
22 - // 查询条件  
23 - Map<String, Object> param = new HashMap<>();  
24 - if (cars.getId() != null) {  
25 - param.put("id_ne", cars.getId());  
26 - }  
27 - param.put("insideCode_eq", cars.getInsideCode());  
28 - if (!CollectionUtils.isEmpty(list(param))) {  
29 - throw new ScheduleException("车辆内部编号/自编号重复");  
30 - }  
31 - }  
32 -  
33 - @Override  
34 - @Transactional  
35 - public void validate_clbh(Cars cars) throws ScheduleException {  
36 - // 查询条件  
37 - Map<String, Object> param = new HashMap<>();  
38 - if (cars.getId() != null) {  
39 - param.put("id_ne", cars.getId());  
40 - }  
41 - param.put("carCode_eq", cars.getCarCode());  
42 - if (!CollectionUtils.isEmpty(list(param))) {  
43 - throw new ScheduleException("车辆编号重复");  
44 - }  
45 - }  
46 -  
47 - @Override  
48 - @Transactional  
49 - public void validate_cph(Cars cars) throws ScheduleException {  
50 - // 查询条件  
51 - Map<String, Object> param = new HashMap<>();  
52 - if (cars.getId() != null) {  
53 - param.put("id_ne", cars.getId());  
54 - }  
55 - param.put("carPlate_eq", cars.getCarPlate());  
56 - if (!CollectionUtils.isEmpty(list(param))) {  
57 - throw new ScheduleException("车牌号重复");  
58 - }  
59 - }  
60 -  
61 - @Override  
62 - @Transactional  
63 - public void validate_sbbh(Cars cars) throws ScheduleException {  
64 - // 查询条件  
65 - Map<String, Object> param = new HashMap<>();  
66 - if (cars.getId() != null) {  
67 - param.put("id_ne", cars.getId());  
68 - }  
69 - param.put("equipmentCode_eq", cars.getEquipmentCode());  
70 - if (!CollectionUtils.isEmpty(list(param))) {  
71 - throw new ScheduleException("设备编号重复");  
72 - }  
73 - }  
74 -} 1 +package com.bsth.service.schedule.impl;
  2 +
  3 +import com.bsth.entity.Cars;
  4 +import com.bsth.service.schedule.CarsService;
  5 +import com.bsth.service.schedule.ScheduleException;
  6 +import org.springframework.stereotype.Service;
  7 +import org.springframework.transaction.annotation.Transactional;
  8 +import org.springframework.util.CollectionUtils;
  9 +
  10 +import java.util.HashMap;
  11 +import java.util.Map;
  12 +
  13 +/**
  14 + * Created by xu on 16/12/8.
  15 + */
  16 +@Service(value = "carsServiceImpl_sc")
  17 +public class CarsServiceImpl extends BServiceImpl<Cars, Integer> implements CarsService {
  18 +
  19 + @Override
  20 + @Transactional
  21 + public void validate_nbbh(Cars cars) throws ScheduleException {
  22 + // 查询条件
  23 + Map<String, Object> param = new HashMap<>();
  24 + if (cars.getId() != null) {
  25 + param.put("id_ne", cars.getId());
  26 + }
  27 + param.put("insideCode_eq", cars.getInsideCode());
  28 + if (!CollectionUtils.isEmpty(list(param))) {
  29 + throw new ScheduleException("车辆内部编号/自编号重复");
  30 + }
  31 + }
  32 +
  33 + @Override
  34 + @Transactional
  35 + public void validate_clbh(Cars cars) throws ScheduleException {
  36 + // 查询条件
  37 + Map<String, Object> param = new HashMap<>();
  38 + if (cars.getId() != null) {
  39 + param.put("id_ne", cars.getId());
  40 + }
  41 + param.put("carCode_eq", cars.getCarCode());
  42 + if (!CollectionUtils.isEmpty(list(param))) {
  43 + throw new ScheduleException("车辆编号重复");
  44 + }
  45 + }
  46 +
  47 + @Override
  48 + @Transactional
  49 + public void validate_cph(Cars cars) throws ScheduleException {
  50 + // 查询条件
  51 + Map<String, Object> param = new HashMap<>();
  52 + if (cars.getId() != null) {
  53 + param.put("id_ne", cars.getId());
  54 + }
  55 + param.put("carPlate_eq", cars.getCarPlate());
  56 + if (!CollectionUtils.isEmpty(list(param))) {
  57 + throw new ScheduleException("车牌号重复");
  58 + }
  59 + }
  60 +
  61 + @Override
  62 + @Transactional
  63 + public void validate_sbbh(Cars cars) throws ScheduleException {
  64 + // 查询条件
  65 + Map<String, Object> param = new HashMap<>();
  66 + if (cars.getId() != null) {
  67 + param.put("id_ne", cars.getId());
  68 + }
  69 + param.put("equipmentCode_eq", cars.getEquipmentCode());
  70 + if (!CollectionUtils.isEmpty(list(param))) {
  71 + throw new ScheduleException("设备编号重复");
  72 + }
  73 + }
  74 +}
src/main/resources/static/pages/forms/statement/daily.html
@@ -98,7 +98,6 @@ @@ -98,7 +98,6 @@
98 for(var code in result){ 98 for(var code in result){
99 data.push({id: code, text: result[code]}); 99 data.push({id: code, text: result[code]});
100 } 100 }
101 - console.log(data);  
102 initPinYinSelect2('#line',data,''); 101 initPinYinSelect2('#line',data,'');
103 102
104 }) 103 })
@@ -106,9 +105,10 @@ @@ -106,9 +105,10 @@
106 var date; 105 var date;
107 $("#query").on("click",function(){ 106 $("#query").on("click",function(){
108 line = $("#line").val(); 107 line = $("#line").val();
  108 + var lineName=$("#select2-line-container").html();
109 date = $("#date").val(); 109 date = $("#date").val();
110 $get('/realSchedule/dailyInfo',{line:line,date:date,type:'query'},function(result){ 110 $get('/realSchedule/dailyInfo',{line:line,date:date,type:'query'},function(result){
111 - $("#form_line").text(line); 111 + $("#form_line").text(lineName);
112 $("#form_date").text(date); 112 $("#form_date").text(date);
113 var total_zgl = 0,total_ksgl = 0,total_yh = 0,total_bcs = 0; 113 var total_zgl = 0,total_ksgl = 0,total_yh = 0,total_bcs = 0;
114 $.each(result, function(i, obj) { 114 $.each(result, function(i, obj) {
src/main/resources/static/pages/scheduleApp/module/basicInfo/busInfoManage/service.js
1 -// 车辆信息service  
2 -angular.module('ScheduleApp').factory('BusInfoManageService_g', ['$resource', function($resource) {  
3 - return {  
4 - rest: $resource(  
5 - '/cars_sc/:id',  
6 - {order: 'carCode', direction: 'ASC', id: '@id_route'},  
7 - {  
8 - list: {  
9 - method: 'GET',  
10 - params: {  
11 - page: 0  
12 - },  
13 - transformResponse: function(rs) {  
14 - var dst = angular.fromJson(rs);  
15 - if (dst.status == 'SUCCESS') {  
16 - return dst.data;  
17 - } else {  
18 - return dst; // 业务错误留给控制器处理  
19 - }  
20 - }  
21 - },  
22 - get: {  
23 - method: 'GET',  
24 - transformResponse: function(rs) {  
25 - var dst = angular.fromJson(rs);  
26 - if (dst.status == 'SUCCESS') {  
27 - return dst.data;  
28 - } else {  
29 - return dst;  
30 - }  
31 - }  
32 - },  
33 - save: {  
34 - method: 'POST'  
35 - }  
36 - }  
37 - ),  
38 - import: $resource(  
39 - '/cars/importfile',  
40 - {},  
41 - {  
42 - do: {  
43 - method: 'POST',  
44 - headers: {  
45 - 'Content-Type': 'application/x-www-form-urlencoded'  
46 - },  
47 - transformRequest: function(obj) {  
48 - var str = [];  
49 - for (var p in obj) {  
50 - str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));  
51 - }  
52 - return str.join("&");  
53 - }  
54 - }  
55 - }  
56 - ),  
57 - validate: $resource(  
58 - '/cars/validate/:type',  
59 - {},  
60 - {  
61 - insideCode: {  
62 - method: 'GET'  
63 - }  
64 - }  
65 - ),  
66 - dataTools: $resource(  
67 - '/cars/:type',  
68 - {},  
69 - {  
70 - dataExport: {  
71 - method: 'GET',  
72 - responseType: "arraybuffer",  
73 - params: {  
74 - type: "dataExport"  
75 - },  
76 - transformResponse: function(data, headers){  
77 - return {data : data};  
78 - }  
79 - }  
80 - }  
81 - )  
82 - }; 1 +// 车辆信息service
  2 +angular.module('ScheduleApp').factory('BusInfoManageService_g', ['$resource', function($resource) {
  3 + return {
  4 + rest: $resource(
  5 + '/cars_sc/:id',
  6 + {order: 'carCode', direction: 'ASC', id: '@id_route'},
  7 + {
  8 + list: {
  9 + method: 'GET',
  10 + params: {
  11 + page: 0
  12 + },
  13 + transformResponse: function(rs) {
  14 + var dst = angular.fromJson(rs);
  15 + if (dst.status == 'SUCCESS') {
  16 + return dst.data;
  17 + } else {
  18 + return dst; // 业务错误留给控制器处理
  19 + }
  20 + }
  21 + },
  22 + get: {
  23 + method: 'GET',
  24 + transformResponse: function(rs) {
  25 + var dst = angular.fromJson(rs);
  26 + if (dst.status == 'SUCCESS') {
  27 + return dst.data;
  28 + } else {
  29 + return dst;
  30 + }
  31 + }
  32 + },
  33 + save: {
  34 + method: 'POST'
  35 + }
  36 + }
  37 + ),
  38 + import: $resource(
  39 + '/cars/importfile',
  40 + {},
  41 + {
  42 + do: {
  43 + method: 'POST',
  44 + headers: {
  45 + 'Content-Type': 'application/x-www-form-urlencoded'
  46 + },
  47 + transformRequest: function(obj) {
  48 + var str = [];
  49 + for (var p in obj) {
  50 + str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
  51 + }
  52 + return str.join("&");
  53 + }
  54 + }
  55 + }
  56 + ),
  57 + validate: $resource(
  58 + '/cars/validate/:type',
  59 + {},
  60 + {
  61 + insideCode: {
  62 + method: 'GET'
  63 + }
  64 + }
  65 + ),
  66 + dataTools: $resource(
  67 + '/cars/:type',
  68 + {},
  69 + {
  70 + dataExport: {
  71 + method: 'GET',
  72 + responseType: "arraybuffer",
  73 + params: {
  74 + type: "dataExport"
  75 + },
  76 + transformResponse: function(data, headers){
  77 + return {data : data};
  78 + }
  79 + }
  80 + }
  81 + )
  82 + };
83 }]); 83 }]);
84 \ No newline at end of file 84 \ No newline at end of file
src/main/resources/static/pages/scheduleApp/module/basicInfo/deviceInfoManage/service.js
1 -// 车辆设备信息service  
2 -angular.module('ScheduleApp').factory('DeviceInfoManageService_g', ['$resource', function($resource) {  
3 - return $resource(  
4 - '/cde/:id',  
5 - {order: 'xl,isCancel,cl,qyrq', direction: 'ASC,ASC,ASC,DESC', id: '@id_route'},  
6 - {  
7 - list: {  
8 - method: 'GET',  
9 - params: {  
10 - page: 0  
11 - }  
12 - },  
13 - get: {  
14 - method: 'GET'  
15 - },  
16 - save: {  
17 - method: 'POST'  
18 - },  
19 - delete: {  
20 - method: 'DELETE'  
21 - }  
22 - }  
23 - ); 1 +// 车辆设备信息service
  2 +angular.module('ScheduleApp').factory('DeviceInfoManageService_g', ['$resource', function($resource) {
  3 + return $resource(
  4 + '/cde/:id',
  5 + {order: 'xl,isCancel,cl,qyrq', direction: 'ASC,ASC,ASC,DESC', id: '@id_route'},
  6 + {
  7 + list: {
  8 + method: 'GET',
  9 + params: {
  10 + page: 0
  11 + }
  12 + },
  13 + get: {
  14 + method: 'GET'
  15 + },
  16 + save: {
  17 + method: 'POST'
  18 + },
  19 + delete: {
  20 + method: 'DELETE'
  21 + }
  22 + }
  23 + );
24 }]); 24 }]);
25 \ No newline at end of file 25 \ No newline at end of file
src/main/resources/static/pages/scheduleApp/module/basicInfo/employeeInfoManage/service.js
1 -// 人员信息service  
2 -angular.module('ScheduleApp').factory('EmployeeInfoManageService_g', ['$resource', function($resource) {  
3 - return {  
4 - rest : $resource(  
5 - '/personnel/:id',  
6 - {order: 'jobCode', direction: 'ASC', id: '@id_route'},  
7 - {  
8 - list: {  
9 - method: 'GET',  
10 - params: {  
11 - page: 0  
12 - }  
13 - },  
14 - get: {  
15 - method: 'GET'  
16 - },  
17 - save: {  
18 - method: 'POST'  
19 - }  
20 - }  
21 - ),  
22 - validate: $resource(  
23 - '/personnel/validate/:type',  
24 - {},  
25 - {  
26 - jobCode: {  
27 - method: 'GET'  
28 - }  
29 - }  
30 - ),  
31 - dataTools: $resource(  
32 - '/personnel/:type',  
33 - {},  
34 - {  
35 - dataExport: {  
36 - method: 'GET',  
37 - responseType: "arraybuffer",  
38 - params: {  
39 - type: "dataExport"  
40 - },  
41 - transformResponse: function(data, headers){  
42 - return {data : data};  
43 - }  
44 - }  
45 - }  
46 - )  
47 - };  
48 -}]); 1 +// 人员信息service
  2 +angular.module('ScheduleApp').factory('EmployeeInfoManageService_g', ['$resource', function($resource) {
  3 + return {
  4 + rest : $resource(
  5 + '/personnel/:id',
  6 + {order: 'jobCode', direction: 'ASC', id: '@id_route'},
  7 + {
  8 + list: {
  9 + method: 'GET',
  10 + params: {
  11 + page: 0
  12 + }
  13 + },
  14 + get: {
  15 + method: 'GET'
  16 + },
  17 + save: {
  18 + method: 'POST'
  19 + }
  20 + }
  21 + ),
  22 + validate: $resource(
  23 + '/personnel/validate/:type',
  24 + {},
  25 + {
  26 + jobCode: {
  27 + method: 'GET'
  28 + }
  29 + }
  30 + ),
  31 + dataTools: $resource(
  32 + '/personnel/:type',
  33 + {},
  34 + {
  35 + dataExport: {
  36 + method: 'GET',
  37 + responseType: "arraybuffer",
  38 + params: {
  39 + type: "dataExport"
  40 + },
  41 + transformResponse: function(data, headers){
  42 + return {data : data};
  43 + }
  44 + }
  45 + }
  46 + )
  47 + };
  48 +}]);
src/main/resources/static/pages/scheduleApp/module/common/directives/select/mySelect.js
1 -/**  
2 - * mySelect指令,封装uiselect指令,封装内部数据获取,只支持单选  
3 - * cm(必须):绑定外部对象,因为关联的字段不只一个,单独使用ngModel不够  
4 - * cmoptions(必须):描述绑定的逻辑配置对象,格式如下:  
5 - *  
6 - * // TODO:  
7 - */  
8 -angular.module('ScheduleApp').directive('mySelect', [  
9 - function() {  
10 - return {  
11 - restrict: 'E',  
12 - template: '<div>bioxuxuan</div>',  
13 - require: 'ngModel',  
14 - compile: function(tElem, tAttrs) {  
15 - return {  
16 - pre: function(scope, element, attr) {  
17 -  
18 - },  
19 - post: function(scope, element, attr, ngModelCtr) {  
20 - // model -> view  
21 - ngModelCtr.$formatters.push(function(modelValue) {  
22 - // 监控model的变化  
23 - if (typeof modelValue != "undefined") {  
24 - console.log(modelValue);  
25 -  
26 - return modelValue;  
27 - }  
28 - });  
29 -  
30 - ngModelCtr.$render = function() {  
31 - if (typeof scope.ctrl.say != "undefined") {  
32 - element.find('div').css('color', 'red');  
33 - }  
34 - };  
35 -  
36 - ngModelCtr.$setViewValue("init value");  
37 -  
38 -  
39 - }  
40 - }  
41 - }  
42 - }  
43 - } 1 +/**
  2 + * mySelect指令,封装uiselect指令,封装内部数据获取,只支持单选
  3 + * cm(必须):绑定外部对象,因为关联的字段不只一个,单独使用ngModel不够
  4 + * cmoptions(必须):描述绑定的逻辑配置对象,格式如下:
  5 + *
  6 + * // TODO:
  7 + */
  8 +angular.module('ScheduleApp').directive('mySelect', [
  9 + function() {
  10 + return {
  11 + restrict: 'E',
  12 + template: '<div>bioxuxuan</div>',
  13 + require: 'ngModel',
  14 + compile: function(tElem, tAttrs) {
  15 + return {
  16 + pre: function(scope, element, attr) {
  17 +
  18 + },
  19 + post: function(scope, element, attr, ngModelCtr) {
  20 + // model -> view
  21 + ngModelCtr.$formatters.push(function(modelValue) {
  22 + // 监控model的变化
  23 + if (typeof modelValue != "undefined") {
  24 + console.log(modelValue);
  25 +
  26 + return modelValue;
  27 + }
  28 + });
  29 +
  30 + ngModelCtr.$render = function() {
  31 + if (typeof scope.ctrl.say != "undefined") {
  32 + element.find('div').css('color', 'red');
  33 + }
  34 + };
  35 +
  36 + ngModelCtr.$setViewValue("init value");
  37 +
  38 +
  39 + }
  40 + }
  41 + }
  42 + }
  43 + }
44 ]); 44 ]);
45 \ No newline at end of file 45 \ No newline at end of file
src/main/resources/static/pages/scheduleApp/module/common/directives/select/mySelectTemplate.html
1 -<div class="input-group" name="指令compile阶段设定1"  
2 - ng-model="$saSelectCtrl.$$internalmodel">  
3 - <ui-select ng-model="$saSelectCtrl.$$internal_select_value" on-select="$saSelectCtrl.$$internal_select_fn($item)"  
4 - theme="bootstrap" >  
5 - <ui-select-match placeholder="指令compile阶段设定">指令compile阶段设定2</ui-select-match>  
6 - <ui-select-choices repeat="指令compile阶段设定3"  
7 - refresh="$saSelectCtrl.$$internal_refresh_fn($select.search)"  
8 - refresh-delay="10">  
9 -  
10 - 指令compile阶段设定777  
11 -  
12 - </ui-select-choices>  
13 - </ui-select>  
14 - <span class="input-group-btn">  
15 - <button type="button" ng-click="$saSelectCtrl.$$internal_remove_fn()" class="btn btn-default">  
16 - <span class="glyphicon glyphicon-trash"></span>  
17 - </button>  
18 - </span> 1 +<div class="input-group" name="指令compile阶段设定1"
  2 + ng-model="$saSelectCtrl.$$internalmodel">
  3 + <ui-select ng-model="$saSelectCtrl.$$internal_select_value" on-select="$saSelectCtrl.$$internal_select_fn($item)"
  4 + theme="bootstrap" >
  5 + <ui-select-match placeholder="指令compile阶段设定">指令compile阶段设定2</ui-select-match>
  6 + <ui-select-choices repeat="指令compile阶段设定3"
  7 + refresh="$saSelectCtrl.$$internal_refresh_fn($select.search)"
  8 + refresh-delay="10">
  9 +
  10 + 指令compile阶段设定777
  11 +
  12 + </ui-select-choices>
  13 + </ui-select>
  14 + <span class="input-group-btn">
  15 + <button type="button" ng-click="$saSelectCtrl.$$internal_remove_fn()" class="btn btn-default">
  16 + <span class="glyphicon glyphicon-trash"></span>
  17 + </button>
  18 + </span>
19 </div> 19 </div>
20 \ No newline at end of file 20 \ No newline at end of file
src/main/resources/static/pages/scheduleApp/module/common/dts1/validation/remoteValidation3.js
1 -/**  
2 - * remoteValidationt3 远程验证指令(监控依赖的model变化)  
3 - * 属性如下:  
4 - * remotevtype(必须):验证类型(在service中有对应映射),如rvtype="xl"  
5 - * remotemodel(必须):关联的model  
6 - * remotemodelcol(必须):关联的model属性  
7 - */  
8 -angular.module('ScheduleApp').directive(  
9 - 'remoteValidation3',  
10 - [  
11 - '$$SearchInfoService_g',  
12 - '$q',  
13 - function($$SearchInfoService_g, $q) {  
14 - return {  
15 - restrict: 'A', // 属性  
16 - require: '^ngModel', // 依赖所属指令的ngModel  
17 - compile: function(tElem, tAttrs) {  
18 - var remotevtype_attr = tAttrs['remotevtype'];  
19 - var remotemodel_attr = tAttrs['remotemodel'];  
20 - var remotemodelcol_attr = tAttrs['remotemodelcol'];  
21 - if (!remotevtype_attr) {  
22 - throw new Error("remotevtype属性必须填写");  
23 - }  
24 - if (!remotemodel_attr) {  
25 - throw new Error("remotemodel属性必须填写");  
26 - }  
27 - if (!remotemodelcol_attr) {  
28 - throw new Error("remotemodelcol属性必须填写");  
29 - }  
30 -  
31 - return {  
32 - pre: function(scope, element, attr) {  
33 -  
34 - },  
35 -  
36 - post: function(scope, element, attr, ngModelCtrl) {  
37 - ngModelCtrl.$asyncValidators.remote =  
38 - function(modelValue, viewValue) {  
39 - var deferred = $q.defer();  
40 -  
41 - // 远端验证service  
42 - var param = JSON.parse(attr['remotemodel']);  
43 - console.log(param);  
44 - param[remotemodelcol_attr] = modelValue;  
45 - $$SearchInfoService_g.validate[remotevtype_attr].remote.do(  
46 - param,  
47 - function(result) {  
48 - if (result.status == "SUCCESS") {  
49 - deferred.resolve();  
50 - } else {  
51 - scope.$remote_msg = result.msg;  
52 - deferred.reject();  
53 - }  
54 - },  
55 - function(result) {  
56 - deferred.reject();  
57 - }  
58 - );  
59 -  
60 - return deferred.promise;  
61 - };  
62 - }  
63 - };  
64 - }  
65 - }  
66 - }  
67 - ] 1 +/**
  2 + * remoteValidationt3 远程验证指令(监控依赖的model变化)
  3 + * 属性如下:
  4 + * remotevtype(必须):验证类型(在service中有对应映射),如rvtype="xl"
  5 + * remotemodel(必须):关联的model
  6 + * remotemodelcol(必须):关联的model属性
  7 + */
  8 +angular.module('ScheduleApp').directive(
  9 + 'remoteValidation3',
  10 + [
  11 + '$$SearchInfoService_g',
  12 + '$q',
  13 + function($$SearchInfoService_g, $q) {
  14 + return {
  15 + restrict: 'A', // 属性
  16 + require: '^ngModel', // 依赖所属指令的ngModel
  17 + compile: function(tElem, tAttrs) {
  18 + var remotevtype_attr = tAttrs['remotevtype'];
  19 + var remotemodel_attr = tAttrs['remotemodel'];
  20 + var remotemodelcol_attr = tAttrs['remotemodelcol'];
  21 + if (!remotevtype_attr) {
  22 + throw new Error("remotevtype属性必须填写");
  23 + }
  24 + if (!remotemodel_attr) {
  25 + throw new Error("remotemodel属性必须填写");
  26 + }
  27 + if (!remotemodelcol_attr) {
  28 + throw new Error("remotemodelcol属性必须填写");
  29 + }
  30 +
  31 + return {
  32 + pre: function(scope, element, attr) {
  33 +
  34 + },
  35 +
  36 + post: function(scope, element, attr, ngModelCtrl) {
  37 + ngModelCtrl.$asyncValidators.remote =
  38 + function(modelValue, viewValue) {
  39 + var deferred = $q.defer();
  40 +
  41 + // 远端验证service
  42 + var param = JSON.parse(attr['remotemodel']);
  43 + console.log(param);
  44 + param[remotemodelcol_attr] = modelValue;
  45 + $$SearchInfoService_g.validate[remotevtype_attr].remote.do(
  46 + param,
  47 + function(result) {
  48 + if (result.status == "SUCCESS") {
  49 + deferred.resolve();
  50 + } else {
  51 + scope.$remote_msg = result.msg;
  52 + deferred.reject();
  53 + }
  54 + },
  55 + function(result) {
  56 + deferred.reject();
  57 + }
  58 + );
  59 +
  60 + return deferred.promise;
  61 + };
  62 + }
  63 + };
  64 + }
  65 + }
  66 + }
  67 + ]
68 ); 68 );
69 \ No newline at end of file 69 \ No newline at end of file
src/main/resources/static/pages/scheduleApp/module/common/dts2/ttinfotable/mySelect.js
1 -/**  
2 - * mySelect指令,封装uiselect指令,封装内部数据获取,只支持单选  
3 - * cm(必须):绑定外部对象,因为关联的字段不只一个,单独使用ngModel不够  
4 - * cmoptions(必须):描述绑定的逻辑配置对象,格式如下:  
5 - *  
6 - * // TODO:  
7 - */  
8 -angular.module('ScheduleApp').directive('mySelect', [  
9 - function() {  
10 - return {  
11 - restrict: 'E',  
12 - template: '<div>bioxuxuan</div>',  
13 - require: 'ngModel',  
14 - compile: function(tElem, tAttrs) {  
15 - return {  
16 - pre: function(scope, element, attr) {  
17 -  
18 - },  
19 - post: function(scope, element, attr, ngModelCtr) {  
20 - // model -> view  
21 - ngModelCtr.$formatters.push(function(modelValue) {  
22 - // 监控model的变化  
23 - if (typeof modelValue != "undefined") {  
24 - console.log(modelValue);  
25 -  
26 - return modelValue;  
27 - }  
28 - });  
29 -  
30 - ngModelCtr.$render = function() {  
31 - if (typeof scope.ctrl.say != "undefined") {  
32 - element.find('div').css('color', 'red');  
33 - }  
34 - };  
35 -  
36 - ngModelCtr.$setViewValue("init value");  
37 -  
38 -  
39 - }  
40 - }  
41 - }  
42 - }  
43 - } 1 +/**
  2 + * mySelect指令,封装uiselect指令,封装内部数据获取,只支持单选
  3 + * cm(必须):绑定外部对象,因为关联的字段不只一个,单独使用ngModel不够
  4 + * cmoptions(必须):描述绑定的逻辑配置对象,格式如下:
  5 + *
  6 + * // TODO:
  7 + */
  8 +angular.module('ScheduleApp').directive('mySelect', [
  9 + function() {
  10 + return {
  11 + restrict: 'E',
  12 + template: '<div>bioxuxuan</div>',
  13 + require: 'ngModel',
  14 + compile: function(tElem, tAttrs) {
  15 + return {
  16 + pre: function(scope, element, attr) {
  17 +
  18 + },
  19 + post: function(scope, element, attr, ngModelCtr) {
  20 + // model -> view
  21 + ngModelCtr.$formatters.push(function(modelValue) {
  22 + // 监控model的变化
  23 + if (typeof modelValue != "undefined") {
  24 + console.log(modelValue);
  25 +
  26 + return modelValue;
  27 + }
  28 + });
  29 +
  30 + ngModelCtr.$render = function() {
  31 + if (typeof scope.ctrl.say != "undefined") {
  32 + element.find('div').css('color', 'red');
  33 + }
  34 + };
  35 +
  36 + ngModelCtr.$setViewValue("init value");
  37 +
  38 +
  39 + }
  40 + }
  41 + }
  42 + }
  43 + }
44 ]); 44 ]);
45 \ No newline at end of file 45 \ No newline at end of file
src/main/resources/static/pages/scheduleApp/module/common/dts2/ttinfotable/mySelectTemplate.html
1 -<div class="input-group" name="指令compile阶段设定1"  
2 - ng-model="$saSelectCtrl.$$internalmodel">  
3 - <ui-select ng-model="$saSelectCtrl.$$internal_select_value" on-select="$saSelectCtrl.$$internal_select_fn($item)"  
4 - theme="bootstrap" >  
5 - <ui-select-match placeholder="指令compile阶段设定">指令compile阶段设定2</ui-select-match>  
6 - <ui-select-choices repeat="指令compile阶段设定3"  
7 - refresh="$saSelectCtrl.$$internal_refresh_fn($select.search)"  
8 - refresh-delay="10">  
9 -  
10 - 指令compile阶段设定777  
11 -  
12 - </ui-select-choices>  
13 - </ui-select>  
14 - <span class="input-group-btn">  
15 - <button type="button" ng-click="$saSelectCtrl.$$internal_remove_fn()" class="btn btn-default">  
16 - <span class="glyphicon glyphicon-trash"></span>  
17 - </button>  
18 - </span> 1 +<div class="input-group" name="指令compile阶段设定1"
  2 + ng-model="$saSelectCtrl.$$internalmodel">
  3 + <ui-select ng-model="$saSelectCtrl.$$internal_select_value" on-select="$saSelectCtrl.$$internal_select_fn($item)"
  4 + theme="bootstrap" >
  5 + <ui-select-match placeholder="指令compile阶段设定">指令compile阶段设定2</ui-select-match>
  6 + <ui-select-choices repeat="指令compile阶段设定3"
  7 + refresh="$saSelectCtrl.$$internal_refresh_fn($select.search)"
  8 + refresh-delay="10">
  9 +
  10 + 指令compile阶段设定777
  11 +
  12 + </ui-select-choices>
  13 + </ui-select>
  14 + <span class="input-group-btn">
  15 + <button type="button" ng-click="$saSelectCtrl.$$internal_remove_fn()" class="btn btn-default">
  16 + <span class="glyphicon glyphicon-trash"></span>
  17 + </button>
  18 + </span>
19 </div> 19 </div>
20 \ No newline at end of file 20 \ No newline at end of file
src/main/resources/static/pages/scheduleApp/module/common/prj-common-globalservice-legacy.js
1 -// 项目通用的全局service服务,供不同的controller使用,自定义指令不使用  
2 -  
3 -// 文件下载服务  
4 -angular.module('ScheduleApp').factory('FileDownload_g', function() {  
5 - return {  
6 - downloadFile: function (data, mimeType, fileName) {  
7 - var success = false;  
8 - var blob = new Blob([data], { type: mimeType });  
9 - try {  
10 - if (navigator.msSaveBlob)  
11 - navigator.msSaveBlob(blob, fileName);  
12 - else {  
13 - // Try using other saveBlob implementations, if available  
14 - var saveBlob = navigator.webkitSaveBlob || navigator.mozSaveBlob || navigator.saveBlob;  
15 - if (saveBlob === undefined) throw "Not supported";  
16 - saveBlob(blob, fileName);  
17 - }  
18 - success = true;  
19 - } catch (ex) {  
20 - console.log("saveBlob method failed with the following exception:");  
21 - console.log(ex);  
22 - }  
23 -  
24 - if (!success) {  
25 - // Get the blob url creator  
26 - var urlCreator = window.URL || window.webkitURL || window.mozURL || window.msURL;  
27 - if (urlCreator) {  
28 - // Try to use a download link  
29 - var link = document.createElement('a');  
30 - if ('download' in link) {  
31 - // Try to simulate a click  
32 - try {  
33 - // Prepare a blob URL  
34 - var url = urlCreator.createObjectURL(blob);  
35 - link.setAttribute('href', url);  
36 -  
37 - // Set the download attribute (Supported in Chrome 14+ / Firefox 20+)  
38 - link.setAttribute("download", fileName);  
39 -  
40 - // Simulate clicking the download link  
41 - var event = document.createEvent('MouseEvents');  
42 - event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);  
43 - link.dispatchEvent(event);  
44 - success = true;  
45 -  
46 - } catch (ex) {  
47 - console.log("Download link method with simulated click failed with the following exception:");  
48 - console.log(ex);  
49 - }  
50 - }  
51 -  
52 - if (!success) {  
53 - // Fallback to window.location method  
54 - try {  
55 - // Prepare a blob URL  
56 - // Use application/octet-stream when using window.location to force download  
57 - var url = urlCreator.createObjectURL(blob);  
58 - window.location = url;  
59 - console.log("Download link method with window.location succeeded");  
60 - success = true;  
61 - } catch (ex) {  
62 - console.log("Download link method with window.location failed with the following exception:");  
63 - console.log(ex);  
64 - }  
65 - }  
66 - }  
67 - }  
68 -  
69 - if (!success) {  
70 - // Fallback to window.open method  
71 - console.log("No methods worked for saving the arraybuffer, using last resort window.open");  
72 - window.open("", '_blank', '');  
73 - }  
74 - }  
75 - };  
76 -});  
77 -  
78 -  
79 -/**  
80 - * saSelect2指令,根据属性值,动态载入数据,然后支持拼音搜索,点击右边的按钮清除选择并重新载入数据。  
81 - * 1、compile阶段使用的属性如下:  
82 - * required:用于和表单验证连接,指定成required="true"才有效。  
83 - * 2、link阶段使用的属性如下  
84 - * model:关联的模型对象  
85 - * name:表单验证时需要的名字  
86 - * type:关联的那种数据值(xl/cl/ry)-> 对应线路信息/车辆信息/人员信息,后面有的继续加  
87 - * modelcolname1:关联的模型字段名字1(一般应该是编码字段)  
88 - * modelcolname2:关联的模型字段名字2(一般应该是名字字段)  
89 - * datacolname1;内部数据对应的字段名字1(与模型字段1对应)  
90 - * datacolname2:内部数据对应的字段名字2(与模型字段2对应)  
91 - * showcolname:下拉框显示的内部数据字段名(注意:不是模型数据字段名),TODO:以后考虑放动态表达式,并在compile阶段使用  
92 - * placeholder:select placeholder字符串描述  
93 - *  
94 - * $$pyFilter,内部的filter指令,结合简拼音进行拼音过滤。  
95 - * $$SearchInfoService_g,内部使用的数据服务  
96 - */  
97 -// saSelect2指令使用的内部信service  
98 -angular.module('ScheduleApp').factory('$$SearchInfoService_g', ['$resource', function($resource) {  
99 - return {  
100 - xl: $resource(  
101 - '/line/:type',  
102 - {order: 'name', direction: 'ASC'},  
103 - {  
104 - list: {  
105 - method: 'GET',  
106 - isArray: true  
107 - }  
108 - }  
109 - ),  
110 - xlinfo: $resource(  
111 - '/lineInformation/:type',  
112 - {order: 'line.name', direction: 'ASC'},  
113 - {  
114 - list: {  
115 - method: 'GET',  
116 - isArray: true  
117 - }  
118 - }  
119 - ),  
120 - zd: $resource(  
121 - '/stationroute/stations',  
122 - {order: 'stationCode', direction: 'ASC'},  
123 - {  
124 - list: {  
125 - method: 'GET',  
126 - isArray: true  
127 - }  
128 - }  
129 - ),  
130 - tcc: $resource(  
131 - '/carpark/:type',  
132 - {order: 'parkCode', direction: 'ASC'},  
133 - {  
134 - list: {  
135 - method: 'GET',  
136 - isArray: true  
137 - }  
138 - }  
139 - ),  
140 - ry: $resource(  
141 - '/personnel/:type',  
142 - {order: 'personnelName', direction: 'ASC'},  
143 - {  
144 - list: {  
145 - method: 'GET',  
146 - isArray: true  
147 - }  
148 - }  
149 - ),  
150 - cl: $resource(  
151 - '/cars/:type',  
152 - {order: "insideCode", direction: 'ASC'},  
153 - {  
154 - list: {  
155 - method: 'GET',  
156 - isArray: true  
157 - }  
158 - }  
159 - ),  
160 - ttInfo: $resource(  
161 - '/tic/:type',  
162 - {order: "name", direction: 'ASC'},  
163 - {  
164 - list: {  
165 - method: 'GET',  
166 - isArray: true  
167 - }  
168 - }  
169 - ),  
170 - lpInfo: $resource(  
171 - '/gic/ttlpnames',  
172 - {order: "lpName", direction: 'ASC'},  
173 - {  
174 - list: {  
175 - method: 'GET',  
176 - isArray: true  
177 - }  
178 - }  
179 - ),  
180 - lpInfo2: $resource(  
181 - '/gic/:type',  
182 - {order: "lpName", direction: 'ASC'},  
183 - {  
184 - list: {  
185 - method: 'GET',  
186 - isArray: true  
187 - }  
188 - }  
189 - ),  
190 - cci: $resource(  
191 - '/cci/cars',  
192 - {},  
193 - {  
194 - list: {  
195 - method: 'GET',  
196 - isArray: true  
197 - }  
198 - }  
199 -  
200 - ),  
201 - cci2: $resource(  
202 - '/cci/:type',  
203 - {},  
204 - {  
205 - list: {  
206 - method: 'GET',  
207 - isArray: true  
208 - }  
209 - }  
210 - ),  
211 - cci3: $resource(  
212 - '/cci/cars2',  
213 - {},  
214 - {  
215 - list: {  
216 - method: 'GET',  
217 - isArray: true  
218 - }  
219 - }  
220 -  
221 - ),  
222 - eci: $resource(  
223 - '/eci/jsy',  
224 - {},  
225 - {  
226 - list: {  
227 - method: 'GET',  
228 - isArray: true  
229 - }  
230 - }  
231 - ),  
232 - eci2: $resource(  
233 - '/eci/spy',  
234 - {},  
235 - {  
236 - list: {  
237 - method: 'GET',  
238 - isArray: true  
239 - }  
240 - }  
241 - ),  
242 - eci3: $resource(  
243 - '/eci/:type',  
244 - {},  
245 - {  
246 - list: {  
247 - method: 'GET',  
248 - isArray: true  
249 - }  
250 - }  
251 - ),  
252 -  
253 -  
254 - validate: { // remoteValidation指令用到的resource  
255 - gbv1: { // 路牌序号验证  
256 - template: {'xl.id_eq': -1, 'lpNo_eq': 'ddd'},  
257 - remote: $resource(  
258 - '/gic/validate1',  
259 - {},  
260 - {  
261 - do: {  
262 - method: 'GET'  
263 - }  
264 - }  
265 - )  
266 - },  
267 - gbv2: { // 路牌名称验证  
268 - template: {'xl.id_eq': -1, 'lpName_eq': 'ddd'},  
269 - remote: $resource(  
270 - '/gic/validate2',  
271 - {},  
272 - {  
273 - do: {  
274 - method: 'GET'  
275 - }  
276 - }  
277 - )  
278 - },  
279 -  
280 - cars_zbh: { // 自编号验证  
281 - template: {'insideCode_eq': '-1'}, // 查询参数模版  
282 - remote: $resource( // $resource封装对象  
283 - '/cars_sc/validate_zbh',  
284 - {},  
285 - {  
286 - do: {  
287 - method: 'GET'  
288 - }  
289 - }  
290 - )  
291 - },  
292 -  
293 - cars_sbbh: { // 验证设备编号  
294 - template: {'equipmentCode_eq': '-1'}, // 查询参数模版  
295 - remote: $resource( // $resource封装对象  
296 - '/cars_sc/validate_sbbh',  
297 - {},  
298 - {  
299 - do: {  
300 - method: 'GET'  
301 - }  
302 - }  
303 - )  
304 - },  
305 -  
306 - cars_clbh: { // 车辆编号验证  
307 - template: {'carCode_eq': '-1'}, // 查询参数模版  
308 - remote: $resource( // $resource封装对象  
309 - '/cars_sc/validate_clbh',  
310 - {},  
311 - {  
312 - do: {  
313 - method: 'GET'  
314 - }  
315 - }  
316 - )  
317 - },  
318 -  
319 - cars_cph: { // 车牌号验证  
320 - template: {'carPlate_eq': '-1'}, // 查询参数模版  
321 - remote: $resource( // $resource封装对象  
322 - '/cars_sc/validate_cph',  
323 - {},  
324 - {  
325 - do: {  
326 - method: 'GET'  
327 - }  
328 - }  
329 - )  
330 - },  
331 -  
332 -  
333 - cde1: { // 车辆设备启用日期验证  
334 - template: {'qyrq': 0, 'xl': 1, 'cl': 1}, // 日期毫秒  
335 - remote: $resource( // $resource封装对象  
336 - '/cde//validate/qyrq',  
337 - {},  
338 - {  
339 - do: {  
340 - method: 'GET'  
341 - }  
342 - }  
343 - )  
344 - },  
345 - ttc1: { // 时刻表名字验证  
346 - template: {'xl.id_eq': -1, 'name_eq': 'ddd'},  
347 - remote: $resource( // $resource封装对象  
348 - '/tic/validate/equale',  
349 - {},  
350 - {  
351 - do: {  
352 - method: 'GET'  
353 - }  
354 - }  
355 - )  
356 - },  
357 - sheet: { // 时刻表sheet工作区验证  
358 - template: {'filename': '', 'sheetname': '', 'lineid': -1, 'linename': ''},  
359 - remote: $resource( // $resource封装对象  
360 - '/tidc/validate/sheet',  
361 - {},  
362 - {  
363 - do: {  
364 - method: 'POST',  
365 - headers: {  
366 - 'Content-Type': 'application/x-www-form-urlencoded'  
367 - },  
368 - transformRequest: function(obj) {  
369 - var str = [];  
370 - for (var p in obj) {  
371 - str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));  
372 - }  
373 - return str.join("&");  
374 - }  
375 - }  
376 - }  
377 - )  
378 - },  
379 - sheetli: { // 时刻表线路标准验证  
380 - template: {'lineinfoid': -1},  
381 - remote: $resource( // $resource封装对象  
382 - '/tidc/validate/lineinfo',  
383 - {},  
384 - {  
385 - do: {  
386 - method: 'GET'  
387 - }  
388 - }  
389 - )  
390 - }  
391 - }  
392 -  
393 - //validate: $resource(  
394 - // '/cars/validate/:type',  
395 - // {},  
396 - // {  
397 - // insideCode: {  
398 - // method: 'GET'  
399 - // }  
400 - // }  
401 - //)  
402 -  
403 -  
404 -  
405 - }  
406 -}]);  
407 -  
408 -  
409 - 1 +// 项目通用的全局service服务,供不同的controller使用,自定义指令不使用
  2 +
  3 +// 文件下载服务
  4 +angular.module('ScheduleApp').factory('FileDownload_g', function() {
  5 + return {
  6 + downloadFile: function (data, mimeType, fileName) {
  7 + var success = false;
  8 + var blob = new Blob([data], { type: mimeType });
  9 + try {
  10 + if (navigator.msSaveBlob)
  11 + navigator.msSaveBlob(blob, fileName);
  12 + else {
  13 + // Try using other saveBlob implementations, if available
  14 + var saveBlob = navigator.webkitSaveBlob || navigator.mozSaveBlob || navigator.saveBlob;
  15 + if (saveBlob === undefined) throw "Not supported";
  16 + saveBlob(blob, fileName);
  17 + }
  18 + success = true;
  19 + } catch (ex) {
  20 + console.log("saveBlob method failed with the following exception:");
  21 + console.log(ex);
  22 + }
  23 +
  24 + if (!success) {
  25 + // Get the blob url creator
  26 + var urlCreator = window.URL || window.webkitURL || window.mozURL || window.msURL;
  27 + if (urlCreator) {
  28 + // Try to use a download link
  29 + var link = document.createElement('a');
  30 + if ('download' in link) {
  31 + // Try to simulate a click
  32 + try {
  33 + // Prepare a blob URL
  34 + var url = urlCreator.createObjectURL(blob);
  35 + link.setAttribute('href', url);
  36 +
  37 + // Set the download attribute (Supported in Chrome 14+ / Firefox 20+)
  38 + link.setAttribute("download", fileName);
  39 +
  40 + // Simulate clicking the download link
  41 + var event = document.createEvent('MouseEvents');
  42 + event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
  43 + link.dispatchEvent(event);
  44 + success = true;
  45 +
  46 + } catch (ex) {
  47 + console.log("Download link method with simulated click failed with the following exception:");
  48 + console.log(ex);
  49 + }
  50 + }
  51 +
  52 + if (!success) {
  53 + // Fallback to window.location method
  54 + try {
  55 + // Prepare a blob URL
  56 + // Use application/octet-stream when using window.location to force download
  57 + var url = urlCreator.createObjectURL(blob);
  58 + window.location = url;
  59 + console.log("Download link method with window.location succeeded");
  60 + success = true;
  61 + } catch (ex) {
  62 + console.log("Download link method with window.location failed with the following exception:");
  63 + console.log(ex);
  64 + }
  65 + }
  66 + }
  67 + }
  68 +
  69 + if (!success) {
  70 + // Fallback to window.open method
  71 + console.log("No methods worked for saving the arraybuffer, using last resort window.open");
  72 + window.open("", '_blank', '');
  73 + }
  74 + }
  75 + };
  76 +});
  77 +
  78 +
  79 +/**
  80 + * saSelect2指令,根据属性值,动态载入数据,然后支持拼音搜索,点击右边的按钮清除选择并重新载入数据。
  81 + * 1、compile阶段使用的属性如下:
  82 + * required:用于和表单验证连接,指定成required="true"才有效。
  83 + * 2、link阶段使用的属性如下
  84 + * model:关联的模型对象
  85 + * name:表单验证时需要的名字
  86 + * type:关联的那种数据值(xl/cl/ry)-> 对应线路信息/车辆信息/人员信息,后面有的继续加
  87 + * modelcolname1:关联的模型字段名字1(一般应该是编码字段)
  88 + * modelcolname2:关联的模型字段名字2(一般应该是名字字段)
  89 + * datacolname1;内部数据对应的字段名字1(与模型字段1对应)
  90 + * datacolname2:内部数据对应的字段名字2(与模型字段2对应)
  91 + * showcolname:下拉框显示的内部数据字段名(注意:不是模型数据字段名),TODO:以后考虑放动态表达式,并在compile阶段使用
  92 + * placeholder:select placeholder字符串描述
  93 + *
  94 + * $$pyFilter,内部的filter指令,结合简拼音进行拼音过滤。
  95 + * $$SearchInfoService_g,内部使用的数据服务
  96 + */
  97 +// saSelect2指令使用的内部信service
  98 +angular.module('ScheduleApp').factory('$$SearchInfoService_g', ['$resource', function($resource) {
  99 + return {
  100 + xl: $resource(
  101 + '/line/:type',
  102 + {order: 'name', direction: 'ASC'},
  103 + {
  104 + list: {
  105 + method: 'GET',
  106 + isArray: true
  107 + }
  108 + }
  109 + ),
  110 + xlinfo: $resource(
  111 + '/lineInformation/:type',
  112 + {order: 'line.name', direction: 'ASC'},
  113 + {
  114 + list: {
  115 + method: 'GET',
  116 + isArray: true
  117 + }
  118 + }
  119 + ),
  120 + zd: $resource(
  121 + '/stationroute/stations',
  122 + {order: 'stationCode', direction: 'ASC'},
  123 + {
  124 + list: {
  125 + method: 'GET',
  126 + isArray: true
  127 + }
  128 + }
  129 + ),
  130 + tcc: $resource(
  131 + '/carpark/:type',
  132 + {order: 'parkCode', direction: 'ASC'},
  133 + {
  134 + list: {
  135 + method: 'GET',
  136 + isArray: true
  137 + }
  138 + }
  139 + ),
  140 + ry: $resource(
  141 + '/personnel/:type',
  142 + {order: 'personnelName', direction: 'ASC'},
  143 + {
  144 + list: {
  145 + method: 'GET',
  146 + isArray: true
  147 + }
  148 + }
  149 + ),
  150 + cl: $resource(
  151 + '/cars/:type',
  152 + {order: "insideCode", direction: 'ASC'},
  153 + {
  154 + list: {
  155 + method: 'GET',
  156 + isArray: true
  157 + }
  158 + }
  159 + ),
  160 + ttInfo: $resource(
  161 + '/tic/:type',
  162 + {order: "name", direction: 'ASC'},
  163 + {
  164 + list: {
  165 + method: 'GET',
  166 + isArray: true
  167 + }
  168 + }
  169 + ),
  170 + lpInfo: $resource(
  171 + '/gic/ttlpnames',
  172 + {order: "lpName", direction: 'ASC'},
  173 + {
  174 + list: {
  175 + method: 'GET',
  176 + isArray: true
  177 + }
  178 + }
  179 + ),
  180 + lpInfo2: $resource(
  181 + '/gic/:type',
  182 + {order: "lpName", direction: 'ASC'},
  183 + {
  184 + list: {
  185 + method: 'GET',
  186 + isArray: true
  187 + }
  188 + }
  189 + ),
  190 + cci: $resource(
  191 + '/cci/cars',
  192 + {},
  193 + {
  194 + list: {
  195 + method: 'GET',
  196 + isArray: true
  197 + }
  198 + }
  199 +
  200 + ),
  201 + cci2: $resource(
  202 + '/cci/:type',
  203 + {},
  204 + {
  205 + list: {
  206 + method: 'GET',
  207 + isArray: true
  208 + }
  209 + }
  210 + ),
  211 + cci3: $resource(
  212 + '/cci/cars2',
  213 + {},
  214 + {
  215 + list: {
  216 + method: 'GET',
  217 + isArray: true
  218 + }
  219 + }
  220 +
  221 + ),
  222 + eci: $resource(
  223 + '/eci/jsy',
  224 + {},
  225 + {
  226 + list: {
  227 + method: 'GET',
  228 + isArray: true
  229 + }
  230 + }
  231 + ),
  232 + eci2: $resource(
  233 + '/eci/spy',
  234 + {},
  235 + {
  236 + list: {
  237 + method: 'GET',
  238 + isArray: true
  239 + }
  240 + }
  241 + ),
  242 + eci3: $resource(
  243 + '/eci/:type',
  244 + {},
  245 + {
  246 + list: {
  247 + method: 'GET',
  248 + isArray: true
  249 + }
  250 + }
  251 + ),
  252 +
  253 +
  254 + validate: { // remoteValidation指令用到的resource
  255 + gbv1: { // 路牌序号验证
  256 + template: {'xl.id_eq': -1, 'lpNo_eq': 'ddd'},
  257 + remote: $resource(
  258 + '/gic/validate1',
  259 + {},
  260 + {
  261 + do: {
  262 + method: 'GET'
  263 + }
  264 + }
  265 + )
  266 + },
  267 + gbv2: { // 路牌名称验证
  268 + template: {'xl.id_eq': -1, 'lpName_eq': 'ddd'},
  269 + remote: $resource(
  270 + '/gic/validate2',
  271 + {},
  272 + {
  273 + do: {
  274 + method: 'GET'
  275 + }
  276 + }
  277 + )
  278 + },
  279 +
  280 + cars_zbh: { // 自编号验证
  281 + template: {'insideCode_eq': '-1'}, // 查询参数模版
  282 + remote: $resource( // $resource封装对象
  283 + '/cars_sc/validate_zbh',
  284 + {},
  285 + {
  286 + do: {
  287 + method: 'GET'
  288 + }
  289 + }
  290 + )
  291 + },
  292 +
  293 + cars_sbbh: { // 验证设备编号
  294 + template: {'equipmentCode_eq': '-1'}, // 查询参数模版
  295 + remote: $resource( // $resource封装对象
  296 + '/cars_sc/validate_sbbh',
  297 + {},
  298 + {
  299 + do: {
  300 + method: 'GET'
  301 + }
  302 + }
  303 + )
  304 + },
  305 +
  306 + cars_clbh: { // 车辆编号验证
  307 + template: {'carCode_eq': '-1'}, // 查询参数模版
  308 + remote: $resource( // $resource封装对象
  309 + '/cars_sc/validate_clbh',
  310 + {},
  311 + {
  312 + do: {
  313 + method: 'GET'
  314 + }
  315 + }
  316 + )
  317 + },
  318 +
  319 + cars_cph: { // 车牌号验证
  320 + template: {'carPlate_eq': '-1'}, // 查询参数模版
  321 + remote: $resource( // $resource封装对象
  322 + '/cars_sc/validate_cph',
  323 + {},
  324 + {
  325 + do: {
  326 + method: 'GET'
  327 + }
  328 + }
  329 + )
  330 + },
  331 +
  332 +
  333 + cde1: { // 车辆设备启用日期验证
  334 + template: {'qyrq': 0, 'xl': 1, 'cl': 1}, // 日期毫秒
  335 + remote: $resource( // $resource封装对象
  336 + '/cde//validate/qyrq',
  337 + {},
  338 + {
  339 + do: {
  340 + method: 'GET'
  341 + }
  342 + }
  343 + )
  344 + },
  345 + ttc1: { // 时刻表名字验证
  346 + template: {'xl.id_eq': -1, 'name_eq': 'ddd'},
  347 + remote: $resource( // $resource封装对象
  348 + '/tic/validate/equale',
  349 + {},
  350 + {
  351 + do: {
  352 + method: 'GET'
  353 + }
  354 + }
  355 + )
  356 + },
  357 + sheet: { // 时刻表sheet工作区验证
  358 + template: {'filename': '', 'sheetname': '', 'lineid': -1, 'linename': ''},
  359 + remote: $resource( // $resource封装对象
  360 + '/tidc/validate/sheet',
  361 + {},
  362 + {
  363 + do: {
  364 + method: 'POST',
  365 + headers: {
  366 + 'Content-Type': 'application/x-www-form-urlencoded'
  367 + },
  368 + transformRequest: function(obj) {
  369 + var str = [];
  370 + for (var p in obj) {
  371 + str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
  372 + }
  373 + return str.join("&");
  374 + }
  375 + }
  376 + }
  377 + )
  378 + },
  379 + sheetli: { // 时刻表线路标准验证
  380 + template: {'lineinfoid': -1},
  381 + remote: $resource( // $resource封装对象
  382 + '/tidc/validate/lineinfo',
  383 + {},
  384 + {
  385 + do: {
  386 + method: 'GET'
  387 + }
  388 + }
  389 + )
  390 + }
  391 + }
  392 +
  393 + //validate: $resource(
  394 + // '/cars/validate/:type',
  395 + // {},
  396 + // {
  397 + // insideCode: {
  398 + // method: 'GET'
  399 + // }
  400 + // }
  401 + //)
  402 +
  403 +
  404 +
  405 + }
  406 +}]);
  407 +
  408 +
  409 +
src/main/resources/static/pages/scheduleApp/module/common/prj-common-globalservice.js
1 -//所有模块service配置  
2 -// 车辆信息service  
3 -angular.module('ScheduleApp').factory('BusInfoManageService_g', ['$resource', function($resource) {  
4 - return {  
5 - rest: $resource(  
6 - '/cars_sc/:id',  
7 - {order: 'carCode', direction: 'ASC', id: '@id_route'},  
8 - {  
9 - list: {  
10 - method: 'GET',  
11 - params: {  
12 - page: 0  
13 - },  
14 - transformResponse: function(rs) {  
15 - var dst = angular.fromJson(rs);  
16 - if (dst.status == 'SUCCESS') {  
17 - return dst.data;  
18 - } else {  
19 - return dst; // 业务错误留给控制器处理  
20 - }  
21 - }  
22 - },  
23 - get: {  
24 - method: 'GET',  
25 - transformResponse: function(rs) {  
26 - var dst = angular.fromJson(rs);  
27 - if (dst.status == 'SUCCESS') {  
28 - return dst.data;  
29 - } else {  
30 - return dst;  
31 - }  
32 - }  
33 - },  
34 - save: {  
35 - method: 'POST'  
36 - }  
37 - }  
38 - ),  
39 - import: $resource(  
40 - '/cars/importfile',  
41 - {},  
42 - {  
43 - do: {  
44 - method: 'POST',  
45 - headers: {  
46 - 'Content-Type': 'application/x-www-form-urlencoded'  
47 - },  
48 - transformRequest: function(obj) {  
49 - var str = [];  
50 - for (var p in obj) {  
51 - str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));  
52 - }  
53 - return str.join("&");  
54 - }  
55 - }  
56 - }  
57 - ),  
58 - validate: $resource(  
59 - '/cars/validate/:type',  
60 - {},  
61 - {  
62 - insideCode: {  
63 - method: 'GET'  
64 - }  
65 - }  
66 - ),  
67 - dataTools: $resource(  
68 - '/cars/:type',  
69 - {},  
70 - {  
71 - dataExport: {  
72 - method: 'GET',  
73 - responseType: "arraybuffer",  
74 - params: {  
75 - type: "dataExport"  
76 - },  
77 - transformResponse: function(data, headers){  
78 - return {data : data};  
79 - }  
80 - }  
81 - }  
82 - )  
83 - };  
84 -}]);  
85 -// 车辆设备信息service  
86 -angular.module('ScheduleApp').factory('DeviceInfoManageService_g', ['$resource', function($resource) {  
87 - return $resource(  
88 - '/cde/:id',  
89 - {order: 'xl,isCancel,cl,qyrq', direction: 'ASC,ASC,ASC,DESC', id: '@id_route'},  
90 - {  
91 - list: {  
92 - method: 'GET',  
93 - params: {  
94 - page: 0  
95 - }  
96 - },  
97 - get: {  
98 - method: 'GET'  
99 - },  
100 - save: {  
101 - method: 'POST'  
102 - },  
103 - delete: {  
104 - method: 'DELETE'  
105 - }  
106 - }  
107 - );  
108 -}]);  
109 -// 人员信息service  
110 -angular.module('ScheduleApp').factory('EmployeeInfoManageService_g', ['$resource', function($resource) {  
111 - return {  
112 - rest : $resource(  
113 - '/personnel/:id',  
114 - {order: 'jobCode', direction: 'ASC', id: '@id_route'},  
115 - {  
116 - list: {  
117 - method: 'GET',  
118 - params: {  
119 - page: 0  
120 - }  
121 - },  
122 - get: {  
123 - method: 'GET'  
124 - },  
125 - save: {  
126 - method: 'POST'  
127 - }  
128 - }  
129 - ),  
130 - validate: $resource(  
131 - '/personnel/validate/:type',  
132 - {},  
133 - {  
134 - jobCode: {  
135 - method: 'GET'  
136 - }  
137 - }  
138 - ),  
139 - dataTools: $resource(  
140 - '/personnel/:type',  
141 - {},  
142 - {  
143 - dataExport: {  
144 - method: 'GET',  
145 - responseType: "arraybuffer",  
146 - params: {  
147 - type: "dataExport"  
148 - },  
149 - transformResponse: function(data, headers){  
150 - return {data : data};  
151 - }  
152 - }  
153 - }  
154 - )  
155 - };  
156 -}]);  
157 -  
158 -// 车辆配置service  
159 -angular.module('ScheduleApp').factory('BusConfigService_g', ['$resource', function($resource) {  
160 - return {  
161 - rest : $resource(  
162 - '/cci/:id',  
163 - {order: 'xl.id,cl.insideCode,isCancel', direction: 'ASC', id: '@id_route'},  
164 - {  
165 - list: {  
166 - method: 'GET',  
167 - params: {  
168 - page: 0  
169 - }  
170 - },  
171 - get: {  
172 - method: 'GET'  
173 - },  
174 - save: {  
175 - method: 'POST'  
176 - }  
177 - }  
178 - )  
179 - };  
180 -}]);  
181 -// 线路运营统计service  
182 -angular.module('ScheduleApp').factory('BusLineInfoStatService_g', ['$resource', function($resource) {  
183 - return $resource(  
184 - '/bic/:id',  
185 - {order: 'createDate', direction: 'DESC', id: '@id_route'}, // TODO:以后需要根据属性对象的属性查询  
186 - {  
187 - list: {  
188 - method: 'GET',  
189 - params: {  
190 - page: 0  
191 - }  
192 - }  
193 - }  
194 - );  
195 -}]);  
196 -  
197 -// 人员配置service  
198 -angular.module('ScheduleApp').factory('EmployeeConfigService_g', ['$resource', function($resource) {  
199 - return {  
200 - rest : $resource(  
201 - '/eci/:id',  
202 - {order: 'xl.id,isCancel,dbbmFormula', direction: 'ASC', id: '@id_route'},  
203 - {  
204 - list: {  
205 - method: 'GET',  
206 - params: {  
207 - page: 0  
208 - }  
209 - },  
210 - get: {  
211 - method: 'GET'  
212 - },  
213 - save: {  
214 - method: 'POST'  
215 - },  
216 - delete: {  
217 - method: 'DELETE'  
218 - }  
219 - }  
220 - ),  
221 - validate: $resource( // TODO:  
222 - '/personnel/validate/:type',  
223 - {},  
224 - {  
225 - jobCode: {  
226 - method: 'GET'  
227 - }  
228 - }  
229 - )  
230 - };  
231 -}]);  
232 -// 路牌管理service  
233 -angular.module('ScheduleApp').factory('GuideboardManageService_g', ['$resource', function($resource) {  
234 - return {  
235 - rest: $resource(  
236 - '/gic/:id',  
237 - {order: 'xl,isCancel', direction: 'DESC,ASC', id: '@id_route'},  
238 - {  
239 - list: {  
240 - method: 'GET',  
241 - params: {  
242 - page: 0  
243 - },  
244 - transformResponse: function(rs) {  
245 - var dst = angular.fromJson(rs);  
246 - if (dst.status == 'SUCCESS') {  
247 - return dst.data;  
248 - } else {  
249 - return dst;  
250 - }  
251 - }  
252 - },  
253 - get: {  
254 - method: 'GET',  
255 - transformResponse: function(rs) {  
256 - var dst = angular.fromJson(rs);  
257 - if (dst.status == 'SUCCESS') {  
258 - return dst.data;  
259 - } else {  
260 - return dst;  
261 - }  
262 - }  
263 - },  
264 - save: {  
265 - method: 'POST'  
266 - }  
267 - // 内部还有默认的方法delete  
268 - }  
269 - )  
270 - };  
271 -}]);  
272 -// 套跑管理service  
273 -angular.module('ScheduleApp').factory('rerunManageService_g', ['$resource', function($resource) {  
274 - return {  
275 - rest: $resource(  
276 - 'rms/:id',  
277 - {order: 'rerunXl.id,isCancel', direction: 'ASC', id: '@id_route'},  
278 - {  
279 - list: {  
280 - method: 'GET',  
281 - params: {  
282 - page: 0  
283 - }  
284 - },  
285 - get: {  
286 - method: 'GET'  
287 - },  
288 - save: {  
289 - method: 'POST'  
290 - },  
291 - delete: {  
292 - method: 'DELETE'  
293 - }  
294 - }  
295 - )  
296 - };  
297 -}]);  
298 -// 排班计划管理service  
299 -angular.module('ScheduleApp').factory('SchedulePlanManageService_g', ['$resource', function($resource) {  
300 - return {  
301 - rest : $resource(  
302 - '/spc/:id',  
303 - {order: 'xl.id,createDate', direction: 'DESC,DESC', id: '@id_route'},  
304 - {  
305 - list: {  
306 - method: 'GET',  
307 - params: {  
308 - page: 0  
309 - }  
310 - },  
311 - get: {  
312 - method: 'GET'  
313 - },  
314 - save: {  
315 - method: 'POST'  
316 - },  
317 - delete: {  
318 - method: 'DELETE'  
319 - }  
320 - }  
321 - ),  
322 - tommorw: $resource(  
323 - '/spc/tommorw',  
324 - {},  
325 - {  
326 - list: {  
327 - method: 'GET'  
328 - }  
329 - }  
330 - )  
331 - };  
332 -}]);  
333 -  
334 -// 排班计划明细管理service  
335 -angular.module('ScheduleApp').factory('SchedulePlanInfoManageService_g', ['$resource', function($resource) {  
336 - return {  
337 - rest : $resource(  
338 - '/spic/:id',  
339 - {order: 'scheduleDate,lp,fcno', direction: 'ASC,ASC,ASC', id: '@id_route'},  
340 - {  
341 - list: {  
342 - method: 'GET',  
343 - params: {  
344 - page: 0  
345 - }  
346 - },  
347 - get: {  
348 - method: 'GET'  
349 - },  
350 - save: {  
351 - method: 'POST'  
352 - }  
353 - }  
354 - ),  
355 - groupinfo : $resource(  
356 - '/spic/groupinfos/:xlid/:sdate',  
357 - {},  
358 - {  
359 - list: {  
360 - method: 'GET',  
361 - isArray: true  
362 - }  
363 - }  
364 - ),  
365 - updateGroupInfo : $resource(  
366 - '/spic/groupinfos/update',  
367 - {},  
368 - {  
369 - update: {  
370 - method: 'POST'  
371 - }  
372 - }  
373 - )  
374 - };  
375 -}]);  
376 -// 排班管理service  
377 -angular.module('ScheduleApp').factory('ScheduleRuleManageService_g', ['$resource', function($resource) {  
378 - return {  
379 - rest: $resource(  
380 - '/sr1fc/:id',  
381 - {order: 'createDate', direction: 'DESC', id: '@id_route'},  
382 - {  
383 - list: {  
384 - method: 'GET',  
385 - params: {  
386 - page: 0  
387 - }  
388 - },  
389 - get: {  
390 - method: 'GET'  
391 - },  
392 - save: {  
393 - method: 'POST'  
394 - },  
395 - delete: {  
396 - method: 'DELETE'  
397 - }  
398 - }  
399 - )  
400 - };  
401 -}]);  
402 -  
403 -// 时刻表管理service  
404 -angular.module('ScheduleApp').factory('TimeTableManageService_g', ['$resource', function($resource) {  
405 - return {  
406 - rest: $resource(  
407 - '/tic/:id',  
408 - {order: 'xl,isCancel,isEnableDisTemplate,qyrq', direction: 'DESC,ASC,DESC,DESC', id: '@id'},  
409 - {  
410 - list: {  
411 - method: 'GET',  
412 - params: {  
413 - page: 0  
414 - }  
415 - }  
416 - }  
417 - )  
418 - };  
419 -}]);  
420 -  
421 -// 时刻表明细管理service  
422 -angular.module('ScheduleApp').factory('TimeTableDetailManageService_g', ['$resource', function($resource) {  
423 - return {  
424 - rest: $resource(  
425 - '/tidc/:id',  
426 - {order: 'createDate', direction: 'DESC', id: '@id_route'},  
427 - {  
428 - get: {  
429 - method: 'GET'  
430 - },  
431 - save: {  
432 - method: 'POST'  
433 - }  
434 - }  
435 - ),  
436 - import: $resource(  
437 - '/tidc/importfile',  
438 - {},  
439 - {  
440 - do: {  
441 - method: 'POST',  
442 - headers: {  
443 - 'Content-Type': 'application/x-www-form-urlencoded'  
444 - },  
445 - transformRequest: function(obj) {  
446 - var str = [];  
447 - for (var p in obj) {  
448 - str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));  
449 - }  
450 - return str.join("&");  
451 - }  
452 - }  
453 - }  
454 - ),  
455 - edit: $resource(  
456 - '/tidc/edit/:xlid/:ttid',  
457 - {},  
458 - {  
459 - list: {  
460 - method: 'GET'  
461 - }  
462 - }  
463 - ),  
464 - bcdetails: $resource(  
465 - '/tidc/bcdetail',  
466 - {},  
467 - {  
468 - list: {  
469 - method: 'GET',  
470 - isArray: true  
471 - }  
472 - }  
473 - ),  
474 - dataTools: $resource(  
475 - '/tidc/:type',  
476 - {},  
477 - {  
478 - dataExport: {  
479 - method: 'GET',  
480 - responseType: "arraybuffer",  
481 - params: {  
482 - type: "dataExportExt"  
483 - },  
484 - transformResponse: function(data, headers){  
485 - return {data : data};  
486 - }  
487 - }  
488 - }  
489 - )  
490 -  
491 - // TODO:导入数据  
492 - };  
493 -}]);  
494 -// 项目通用的全局service服务,供不同的controller使用,自定义指令不使用  
495 -  
496 -// 文件下载服务  
497 -angular.module('ScheduleApp').factory('FileDownload_g', function() {  
498 - return {  
499 - downloadFile: function (data, mimeType, fileName) {  
500 - var success = false;  
501 - var blob = new Blob([data], { type: mimeType });  
502 - try {  
503 - if (navigator.msSaveBlob)  
504 - navigator.msSaveBlob(blob, fileName);  
505 - else {  
506 - // Try using other saveBlob implementations, if available  
507 - var saveBlob = navigator.webkitSaveBlob || navigator.mozSaveBlob || navigator.saveBlob;  
508 - if (saveBlob === undefined) throw "Not supported";  
509 - saveBlob(blob, fileName);  
510 - }  
511 - success = true;  
512 - } catch (ex) {  
513 - console.log("saveBlob method failed with the following exception:");  
514 - console.log(ex);  
515 - }  
516 -  
517 - if (!success) {  
518 - // Get the blob url creator  
519 - var urlCreator = window.URL || window.webkitURL || window.mozURL || window.msURL;  
520 - if (urlCreator) {  
521 - // Try to use a download link  
522 - var link = document.createElement('a');  
523 - if ('download' in link) {  
524 - // Try to simulate a click  
525 - try {  
526 - // Prepare a blob URL  
527 - var url = urlCreator.createObjectURL(blob);  
528 - link.setAttribute('href', url);  
529 -  
530 - // Set the download attribute (Supported in Chrome 14+ / Firefox 20+)  
531 - link.setAttribute("download", fileName);  
532 -  
533 - // Simulate clicking the download link  
534 - var event = document.createEvent('MouseEvents');  
535 - event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);  
536 - link.dispatchEvent(event);  
537 - success = true;  
538 -  
539 - } catch (ex) {  
540 - console.log("Download link method with simulated click failed with the following exception:");  
541 - console.log(ex);  
542 - }  
543 - }  
544 -  
545 - if (!success) {  
546 - // Fallback to window.location method  
547 - try {  
548 - // Prepare a blob URL  
549 - // Use application/octet-stream when using window.location to force download  
550 - var url = urlCreator.createObjectURL(blob);  
551 - window.location = url;  
552 - console.log("Download link method with window.location succeeded");  
553 - success = true;  
554 - } catch (ex) {  
555 - console.log("Download link method with window.location failed with the following exception:");  
556 - console.log(ex);  
557 - }  
558 - }  
559 - }  
560 - }  
561 -  
562 - if (!success) {  
563 - // Fallback to window.open method  
564 - console.log("No methods worked for saving the arraybuffer, using last resort window.open");  
565 - window.open("", '_blank', '');  
566 - }  
567 - }  
568 - };  
569 -});  
570 -  
571 -  
572 -/**  
573 - * saSelect2指令,根据属性值,动态载入数据,然后支持拼音搜索,点击右边的按钮清除选择并重新载入数据。  
574 - * 1、compile阶段使用的属性如下:  
575 - * required:用于和表单验证连接,指定成required="true"才有效。  
576 - * 2、link阶段使用的属性如下  
577 - * model:关联的模型对象  
578 - * name:表单验证时需要的名字  
579 - * type:关联的那种数据值(xl/cl/ry)-> 对应线路信息/车辆信息/人员信息,后面有的继续加  
580 - * modelcolname1:关联的模型字段名字1(一般应该是编码字段)  
581 - * modelcolname2:关联的模型字段名字2(一般应该是名字字段)  
582 - * datacolname1;内部数据对应的字段名字1(与模型字段1对应)  
583 - * datacolname2:内部数据对应的字段名字2(与模型字段2对应)  
584 - * showcolname:下拉框显示的内部数据字段名(注意:不是模型数据字段名),TODO:以后考虑放动态表达式,并在compile阶段使用  
585 - * placeholder:select placeholder字符串描述  
586 - *  
587 - * $$pyFilter,内部的filter指令,结合简拼音进行拼音过滤。  
588 - * $$SearchInfoService_g,内部使用的数据服务  
589 - */  
590 -// saSelect2指令使用的内部信service  
591 -angular.module('ScheduleApp').factory('$$SearchInfoService_g', ['$resource', function($resource) {  
592 - return {  
593 - xl: $resource(  
594 - '/line/:type',  
595 - {order: 'name', direction: 'ASC'},  
596 - {  
597 - list: {  
598 - method: 'GET',  
599 - isArray: true  
600 - }  
601 - }  
602 - ),  
603 - xlinfo: $resource(  
604 - '/lineInformation/:type',  
605 - {order: 'line.name', direction: 'ASC'},  
606 - {  
607 - list: {  
608 - method: 'GET',  
609 - isArray: true  
610 - }  
611 - }  
612 - ),  
613 - zd: $resource(  
614 - '/stationroute/stations',  
615 - {order: 'stationCode', direction: 'ASC'},  
616 - {  
617 - list: {  
618 - method: 'GET',  
619 - isArray: true  
620 - }  
621 - }  
622 - ),  
623 - tcc: $resource(  
624 - '/carpark/:type',  
625 - {order: 'parkCode', direction: 'ASC'},  
626 - {  
627 - list: {  
628 - method: 'GET',  
629 - isArray: true  
630 - }  
631 - }  
632 - ),  
633 - ry: $resource(  
634 - '/personnel/:type',  
635 - {order: 'personnelName', direction: 'ASC'},  
636 - {  
637 - list: {  
638 - method: 'GET',  
639 - isArray: true  
640 - }  
641 - }  
642 - ),  
643 - cl: $resource(  
644 - '/cars/:type',  
645 - {order: "insideCode", direction: 'ASC'},  
646 - {  
647 - list: {  
648 - method: 'GET',  
649 - isArray: true  
650 - }  
651 - }  
652 - ),  
653 - ttInfo: $resource(  
654 - '/tic/:type',  
655 - {order: "name", direction: 'ASC'},  
656 - {  
657 - list: {  
658 - method: 'GET',  
659 - isArray: true  
660 - }  
661 - }  
662 - ),  
663 - lpInfo: $resource(  
664 - '/gic/ttlpnames',  
665 - {order: "lpName", direction: 'ASC'},  
666 - {  
667 - list: {  
668 - method: 'GET',  
669 - isArray: true  
670 - }  
671 - }  
672 - ),  
673 - lpInfo2: $resource(  
674 - '/gic/:type',  
675 - {order: "lpName", direction: 'ASC'},  
676 - {  
677 - list: {  
678 - method: 'GET',  
679 - isArray: true  
680 - }  
681 - }  
682 - ),  
683 - cci: $resource(  
684 - '/cci/cars',  
685 - {},  
686 - {  
687 - list: {  
688 - method: 'GET',  
689 - isArray: true  
690 - }  
691 - }  
692 -  
693 - ),  
694 - cci2: $resource(  
695 - '/cci/:type',  
696 - {},  
697 - {  
698 - list: {  
699 - method: 'GET',  
700 - isArray: true  
701 - }  
702 - }  
703 - ),  
704 - cci3: $resource(  
705 - '/cci/cars2',  
706 - {},  
707 - {  
708 - list: {  
709 - method: 'GET',  
710 - isArray: true  
711 - }  
712 - }  
713 -  
714 - ),  
715 - eci: $resource(  
716 - '/eci/jsy',  
717 - {},  
718 - {  
719 - list: {  
720 - method: 'GET',  
721 - isArray: true  
722 - }  
723 - }  
724 - ),  
725 - eci2: $resource(  
726 - '/eci/spy',  
727 - {},  
728 - {  
729 - list: {  
730 - method: 'GET',  
731 - isArray: true  
732 - }  
733 - }  
734 - ),  
735 - eci3: $resource(  
736 - '/eci/:type',  
737 - {},  
738 - {  
739 - list: {  
740 - method: 'GET',  
741 - isArray: true  
742 - }  
743 - }  
744 - ),  
745 -  
746 -  
747 - validate: { // remoteValidation指令用到的resource  
748 - gbv1: { // 路牌序号验证  
749 - template: {'xl.id_eq': -1, 'lpNo_eq': 'ddd'},  
750 - remote: $resource(  
751 - '/gic/validate1',  
752 - {},  
753 - {  
754 - do: {  
755 - method: 'GET'  
756 - }  
757 - }  
758 - )  
759 - },  
760 - gbv2: { // 路牌名称验证  
761 - template: {'xl.id_eq': -1, 'lpName_eq': 'ddd'},  
762 - remote: $resource(  
763 - '/gic/validate2',  
764 - {},  
765 - {  
766 - do: {  
767 - method: 'GET'  
768 - }  
769 - }  
770 - )  
771 - },  
772 -  
773 - cars_zbh: { // 自编号验证  
774 - template: {'insideCode_eq': '-1'}, // 查询参数模版  
775 - remote: $resource( // $resource封装对象  
776 - '/cars_sc/validate_zbh',  
777 - {},  
778 - {  
779 - do: {  
780 - method: 'GET'  
781 - }  
782 - }  
783 - )  
784 - },  
785 -  
786 - cars_sbbh: { // 验证设备编号  
787 - template: {'equipmentCode_eq': '-1'}, // 查询参数模版  
788 - remote: $resource( // $resource封装对象  
789 - '/cars_sc/validate_sbbh',  
790 - {},  
791 - {  
792 - do: {  
793 - method: 'GET'  
794 - }  
795 - }  
796 - )  
797 - },  
798 -  
799 - cars_clbh: { // 车辆编号验证  
800 - template: {'carCode_eq': '-1'}, // 查询参数模版  
801 - remote: $resource( // $resource封装对象  
802 - '/cars_sc/validate_clbh',  
803 - {},  
804 - {  
805 - do: {  
806 - method: 'GET'  
807 - }  
808 - }  
809 - )  
810 - },  
811 -  
812 - cars_cph: { // 车牌号验证  
813 - template: {'carPlate_eq': '-1'}, // 查询参数模版  
814 - remote: $resource( // $resource封装对象  
815 - '/cars_sc/validate_cph',  
816 - {},  
817 - {  
818 - do: {  
819 - method: 'GET'  
820 - }  
821 - }  
822 - )  
823 - },  
824 -  
825 -  
826 - cde1: { // 车辆设备启用日期验证  
827 - template: {'qyrq': 0, 'xl': 1, 'cl': 1}, // 日期毫秒  
828 - remote: $resource( // $resource封装对象  
829 - '/cde//validate/qyrq',  
830 - {},  
831 - {  
832 - do: {  
833 - method: 'GET'  
834 - }  
835 - }  
836 - )  
837 - },  
838 - ttc1: { // 时刻表名字验证  
839 - template: {'xl.id_eq': -1, 'name_eq': 'ddd'},  
840 - remote: $resource( // $resource封装对象  
841 - '/tic/validate/equale',  
842 - {},  
843 - {  
844 - do: {  
845 - method: 'GET'  
846 - }  
847 - }  
848 - )  
849 - },  
850 - sheet: { // 时刻表sheet工作区验证  
851 - template: {'filename': '', 'sheetname': '', 'lineid': -1, 'linename': ''},  
852 - remote: $resource( // $resource封装对象  
853 - '/tidc/validate/sheet',  
854 - {},  
855 - {  
856 - do: {  
857 - method: 'POST',  
858 - headers: {  
859 - 'Content-Type': 'application/x-www-form-urlencoded'  
860 - },  
861 - transformRequest: function(obj) {  
862 - var str = [];  
863 - for (var p in obj) {  
864 - str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));  
865 - }  
866 - return str.join("&");  
867 - }  
868 - }  
869 - }  
870 - )  
871 - },  
872 - sheetli: { // 时刻表线路标准验证  
873 - template: {'lineinfoid': -1},  
874 - remote: $resource( // $resource封装对象  
875 - '/tidc/validate/lineinfo',  
876 - {},  
877 - {  
878 - do: {  
879 - method: 'GET'  
880 - }  
881 - }  
882 - )  
883 - }  
884 - }  
885 -  
886 - //validate: $resource(  
887 - // '/cars/validate/:type',  
888 - // {},  
889 - // {  
890 - // insideCode: {  
891 - // method: 'GET'  
892 - // }  
893 - // }  
894 - //)  
895 -  
896 -  
897 -  
898 - }  
899 -}]);  
900 -  
901 -  
902 - 1 +//所有模块service配置
  2 +// 车辆信息service
  3 +angular.module('ScheduleApp').factory('BusInfoManageService_g', ['$resource', function($resource) {
  4 + return {
  5 + rest: $resource(
  6 + '/cars_sc/:id',
  7 + {order: 'carCode', direction: 'ASC', id: '@id_route'},
  8 + {
  9 + list: {
  10 + method: 'GET',
  11 + params: {
  12 + page: 0
  13 + },
  14 + transformResponse: function(rs) {
  15 + var dst = angular.fromJson(rs);
  16 + if (dst.status == 'SUCCESS') {
  17 + return dst.data;
  18 + } else {
  19 + return dst; // 业务错误留给控制器处理
  20 + }
  21 + }
  22 + },
  23 + get: {
  24 + method: 'GET',
  25 + transformResponse: function(rs) {
  26 + var dst = angular.fromJson(rs);
  27 + if (dst.status == 'SUCCESS') {
  28 + return dst.data;
  29 + } else {
  30 + return dst;
  31 + }
  32 + }
  33 + },
  34 + save: {
  35 + method: 'POST'
  36 + }
  37 + }
  38 + ),
  39 + import: $resource(
  40 + '/cars/importfile',
  41 + {},
  42 + {
  43 + do: {
  44 + method: 'POST',
  45 + headers: {
  46 + 'Content-Type': 'application/x-www-form-urlencoded'
  47 + },
  48 + transformRequest: function(obj) {
  49 + var str = [];
  50 + for (var p in obj) {
  51 + str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
  52 + }
  53 + return str.join("&");
  54 + }
  55 + }
  56 + }
  57 + ),
  58 + validate: $resource(
  59 + '/cars/validate/:type',
  60 + {},
  61 + {
  62 + insideCode: {
  63 + method: 'GET'
  64 + }
  65 + }
  66 + ),
  67 + dataTools: $resource(
  68 + '/cars/:type',
  69 + {},
  70 + {
  71 + dataExport: {
  72 + method: 'GET',
  73 + responseType: "arraybuffer",
  74 + params: {
  75 + type: "dataExport"
  76 + },
  77 + transformResponse: function(data, headers){
  78 + return {data : data};
  79 + }
  80 + }
  81 + }
  82 + )
  83 + };
  84 +}]);
  85 +// 车辆设备信息service
  86 +angular.module('ScheduleApp').factory('DeviceInfoManageService_g', ['$resource', function($resource) {
  87 + return $resource(
  88 + '/cde/:id',
  89 + {order: 'xl,isCancel,cl,qyrq', direction: 'ASC,ASC,ASC,DESC', id: '@id_route'},
  90 + {
  91 + list: {
  92 + method: 'GET',
  93 + params: {
  94 + page: 0
  95 + }
  96 + },
  97 + get: {
  98 + method: 'GET'
  99 + },
  100 + save: {
  101 + method: 'POST'
  102 + },
  103 + delete: {
  104 + method: 'DELETE'
  105 + }
  106 + }
  107 + );
  108 +}]);
  109 +// 人员信息service
  110 +angular.module('ScheduleApp').factory('EmployeeInfoManageService_g', ['$resource', function($resource) {
  111 + return {
  112 + rest : $resource(
  113 + '/personnel/:id',
  114 + {order: 'jobCode', direction: 'ASC', id: '@id_route'},
  115 + {
  116 + list: {
  117 + method: 'GET',
  118 + params: {
  119 + page: 0
  120 + }
  121 + },
  122 + get: {
  123 + method: 'GET'
  124 + },
  125 + save: {
  126 + method: 'POST'
  127 + }
  128 + }
  129 + ),
  130 + validate: $resource(
  131 + '/personnel/validate/:type',
  132 + {},
  133 + {
  134 + jobCode: {
  135 + method: 'GET'
  136 + }
  137 + }
  138 + ),
  139 + dataTools: $resource(
  140 + '/personnel/:type',
  141 + {},
  142 + {
  143 + dataExport: {
  144 + method: 'GET',
  145 + responseType: "arraybuffer",
  146 + params: {
  147 + type: "dataExport"
  148 + },
  149 + transformResponse: function(data, headers){
  150 + return {data : data};
  151 + }
  152 + }
  153 + }
  154 + )
  155 + };
  156 +}]);
  157 +
  158 +// 车辆配置service
  159 +angular.module('ScheduleApp').factory('BusConfigService_g', ['$resource', function($resource) {
  160 + return {
  161 + rest : $resource(
  162 + '/cci/:id',
  163 + {order: 'xl.id,cl.insideCode,isCancel', direction: 'ASC', id: '@id_route'},
  164 + {
  165 + list: {
  166 + method: 'GET',
  167 + params: {
  168 + page: 0
  169 + }
  170 + },
  171 + get: {
  172 + method: 'GET'
  173 + },
  174 + save: {
  175 + method: 'POST'
  176 + }
  177 + }
  178 + )
  179 + };
  180 +}]);
  181 +// 线路运营统计service
  182 +angular.module('ScheduleApp').factory('BusLineInfoStatService_g', ['$resource', function($resource) {
  183 + return $resource(
  184 + '/bic/:id',
  185 + {order: 'createDate', direction: 'DESC', id: '@id_route'}, // TODO:以后需要根据属性对象的属性查询
  186 + {
  187 + list: {
  188 + method: 'GET',
  189 + params: {
  190 + page: 0
  191 + }
  192 + }
  193 + }
  194 + );
  195 +}]);
  196 +
  197 +// 人员配置service
  198 +angular.module('ScheduleApp').factory('EmployeeConfigService_g', ['$resource', function($resource) {
  199 + return {
  200 + rest : $resource(
  201 + '/eci/:id',
  202 + {order: 'xl.id,isCancel,dbbmFormula', direction: 'ASC', id: '@id_route'},
  203 + {
  204 + list: {
  205 + method: 'GET',
  206 + params: {
  207 + page: 0
  208 + }
  209 + },
  210 + get: {
  211 + method: 'GET'
  212 + },
  213 + save: {
  214 + method: 'POST'
  215 + },
  216 + delete: {
  217 + method: 'DELETE'
  218 + }
  219 + }
  220 + ),
  221 + validate: $resource( // TODO:
  222 + '/personnel/validate/:type',
  223 + {},
  224 + {
  225 + jobCode: {
  226 + method: 'GET'
  227 + }
  228 + }
  229 + )
  230 + };
  231 +}]);
  232 +// 路牌管理service
  233 +angular.module('ScheduleApp').factory('GuideboardManageService_g', ['$resource', function($resource) {
  234 + return {
  235 + rest: $resource(
  236 + '/gic/:id',
  237 + {order: 'xl,isCancel', direction: 'DESC,ASC', id: '@id_route'},
  238 + {
  239 + list: {
  240 + method: 'GET',
  241 + params: {
  242 + page: 0
  243 + },
  244 + transformResponse: function(rs) {
  245 + var dst = angular.fromJson(rs);
  246 + if (dst.status == 'SUCCESS') {
  247 + return dst.data;
  248 + } else {
  249 + return dst;
  250 + }
  251 + }
  252 + },
  253 + get: {
  254 + method: 'GET',
  255 + transformResponse: function(rs) {
  256 + var dst = angular.fromJson(rs);
  257 + if (dst.status == 'SUCCESS') {
  258 + return dst.data;
  259 + } else {
  260 + return dst;
  261 + }
  262 + }
  263 + },
  264 + save: {
  265 + method: 'POST'
  266 + }
  267 + // 内部还有默认的方法delete
  268 + }
  269 + )
  270 + };
  271 +}]);
  272 +// 套跑管理service
  273 +angular.module('ScheduleApp').factory('rerunManageService_g', ['$resource', function($resource) {
  274 + return {
  275 + rest: $resource(
  276 + 'rms/:id',
  277 + {order: 'rerunXl.id,isCancel', direction: 'ASC', id: '@id_route'},
  278 + {
  279 + list: {
  280 + method: 'GET',
  281 + params: {
  282 + page: 0
  283 + }
  284 + },
  285 + get: {
  286 + method: 'GET'
  287 + },
  288 + save: {
  289 + method: 'POST'
  290 + },
  291 + delete: {
  292 + method: 'DELETE'
  293 + }
  294 + }
  295 + )
  296 + };
  297 +}]);
  298 +// 排班计划管理service
  299 +angular.module('ScheduleApp').factory('SchedulePlanManageService_g', ['$resource', function($resource) {
  300 + return {
  301 + rest : $resource(
  302 + '/spc/:id',
  303 + {order: 'xl.id,createDate', direction: 'DESC,DESC', id: '@id_route'},
  304 + {
  305 + list: {
  306 + method: 'GET',
  307 + params: {
  308 + page: 0
  309 + }
  310 + },
  311 + get: {
  312 + method: 'GET'
  313 + },
  314 + save: {
  315 + method: 'POST'
  316 + },
  317 + delete: {
  318 + method: 'DELETE'
  319 + }
  320 + }
  321 + ),
  322 + tommorw: $resource(
  323 + '/spc/tommorw',
  324 + {},
  325 + {
  326 + list: {
  327 + method: 'GET'
  328 + }
  329 + }
  330 + )
  331 + };
  332 +}]);
  333 +
  334 +// 排班计划明细管理service
  335 +angular.module('ScheduleApp').factory('SchedulePlanInfoManageService_g', ['$resource', function($resource) {
  336 + return {
  337 + rest : $resource(
  338 + '/spic/:id',
  339 + {order: 'scheduleDate,lp,fcno', direction: 'ASC,ASC,ASC', id: '@id_route'},
  340 + {
  341 + list: {
  342 + method: 'GET',
  343 + params: {
  344 + page: 0
  345 + }
  346 + },
  347 + get: {
  348 + method: 'GET'
  349 + },
  350 + save: {
  351 + method: 'POST'
  352 + }
  353 + }
  354 + ),
  355 + groupinfo : $resource(
  356 + '/spic/groupinfos/:xlid/:sdate',
  357 + {},
  358 + {
  359 + list: {
  360 + method: 'GET',
  361 + isArray: true
  362 + }
  363 + }
  364 + ),
  365 + updateGroupInfo : $resource(
  366 + '/spic/groupinfos/update',
  367 + {},
  368 + {
  369 + update: {
  370 + method: 'POST'
  371 + }
  372 + }
  373 + )
  374 + };
  375 +}]);
  376 +// 排班管理service
  377 +angular.module('ScheduleApp').factory('ScheduleRuleManageService_g', ['$resource', function($resource) {
  378 + return {
  379 + rest: $resource(
  380 + '/sr1fc/:id',
  381 + {order: 'createDate', direction: 'DESC', id: '@id_route'},
  382 + {
  383 + list: {
  384 + method: 'GET',
  385 + params: {
  386 + page: 0
  387 + }
  388 + },
  389 + get: {
  390 + method: 'GET'
  391 + },
  392 + save: {
  393 + method: 'POST'
  394 + },
  395 + delete: {
  396 + method: 'DELETE'
  397 + }
  398 + }
  399 + )
  400 + };
  401 +}]);
  402 +
  403 +// 时刻表管理service
  404 +angular.module('ScheduleApp').factory('TimeTableManageService_g', ['$resource', function($resource) {
  405 + return {
  406 + rest: $resource(
  407 + '/tic/:id',
  408 + {order: 'xl,isCancel,isEnableDisTemplate,qyrq', direction: 'DESC,ASC,DESC,DESC', id: '@id'},
  409 + {
  410 + list: {
  411 + method: 'GET',
  412 + params: {
  413 + page: 0
  414 + }
  415 + }
  416 + }
  417 + )
  418 + };
  419 +}]);
  420 +
  421 +// 时刻表明细管理service
  422 +angular.module('ScheduleApp').factory('TimeTableDetailManageService_g', ['$resource', function($resource) {
  423 + return {
  424 + rest: $resource(
  425 + '/tidc/:id',
  426 + {order: 'createDate', direction: 'DESC', id: '@id_route'},
  427 + {
  428 + get: {
  429 + method: 'GET'
  430 + },
  431 + save: {
  432 + method: 'POST'
  433 + }
  434 + }
  435 + ),
  436 + import: $resource(
  437 + '/tidc/importfile',
  438 + {},
  439 + {
  440 + do: {
  441 + method: 'POST',
  442 + headers: {
  443 + 'Content-Type': 'application/x-www-form-urlencoded'
  444 + },
  445 + transformRequest: function(obj) {
  446 + var str = [];
  447 + for (var p in obj) {
  448 + str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
  449 + }
  450 + return str.join("&");
  451 + }
  452 + }
  453 + }
  454 + ),
  455 + edit: $resource(
  456 + '/tidc/edit/:xlid/:ttid',
  457 + {},
  458 + {
  459 + list: {
  460 + method: 'GET'
  461 + }
  462 + }
  463 + ),
  464 + bcdetails: $resource(
  465 + '/tidc/bcdetail',
  466 + {},
  467 + {
  468 + list: {
  469 + method: 'GET',
  470 + isArray: true
  471 + }
  472 + }
  473 + ),
  474 + dataTools: $resource(
  475 + '/tidc/:type',
  476 + {},
  477 + {
  478 + dataExport: {
  479 + method: 'GET',
  480 + responseType: "arraybuffer",
  481 + params: {
  482 + type: "dataExportExt"
  483 + },
  484 + transformResponse: function(data, headers){
  485 + return {data : data};
  486 + }
  487 + }
  488 + }
  489 + )
  490 +
  491 + // TODO:导入数据
  492 + };
  493 +}]);
  494 +// 项目通用的全局service服务,供不同的controller使用,自定义指令不使用
  495 +
  496 +// 文件下载服务
  497 +angular.module('ScheduleApp').factory('FileDownload_g', function() {
  498 + return {
  499 + downloadFile: function (data, mimeType, fileName) {
  500 + var success = false;
  501 + var blob = new Blob([data], { type: mimeType });
  502 + try {
  503 + if (navigator.msSaveBlob)
  504 + navigator.msSaveBlob(blob, fileName);
  505 + else {
  506 + // Try using other saveBlob implementations, if available
  507 + var saveBlob = navigator.webkitSaveBlob || navigator.mozSaveBlob || navigator.saveBlob;
  508 + if (saveBlob === undefined) throw "Not supported";
  509 + saveBlob(blob, fileName);
  510 + }
  511 + success = true;
  512 + } catch (ex) {
  513 + console.log("saveBlob method failed with the following exception:");
  514 + console.log(ex);
  515 + }
  516 +
  517 + if (!success) {
  518 + // Get the blob url creator
  519 + var urlCreator = window.URL || window.webkitURL || window.mozURL || window.msURL;
  520 + if (urlCreator) {
  521 + // Try to use a download link
  522 + var link = document.createElement('a');
  523 + if ('download' in link) {
  524 + // Try to simulate a click
  525 + try {
  526 + // Prepare a blob URL
  527 + var url = urlCreator.createObjectURL(blob);
  528 + link.setAttribute('href', url);
  529 +
  530 + // Set the download attribute (Supported in Chrome 14+ / Firefox 20+)
  531 + link.setAttribute("download", fileName);
  532 +
  533 + // Simulate clicking the download link
  534 + var event = document.createEvent('MouseEvents');
  535 + event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
  536 + link.dispatchEvent(event);
  537 + success = true;
  538 +
  539 + } catch (ex) {
  540 + console.log("Download link method with simulated click failed with the following exception:");
  541 + console.log(ex);
  542 + }
  543 + }
  544 +
  545 + if (!success) {
  546 + // Fallback to window.location method
  547 + try {
  548 + // Prepare a blob URL
  549 + // Use application/octet-stream when using window.location to force download
  550 + var url = urlCreator.createObjectURL(blob);
  551 + window.location = url;
  552 + console.log("Download link method with window.location succeeded");
  553 + success = true;
  554 + } catch (ex) {
  555 + console.log("Download link method with window.location failed with the following exception:");
  556 + console.log(ex);
  557 + }
  558 + }
  559 + }
  560 + }
  561 +
  562 + if (!success) {
  563 + // Fallback to window.open method
  564 + console.log("No methods worked for saving the arraybuffer, using last resort window.open");
  565 + window.open("", '_blank', '');
  566 + }
  567 + }
  568 + };
  569 +});
  570 +
  571 +
  572 +/**
  573 + * saSelect2指令,根据属性值,动态载入数据,然后支持拼音搜索,点击右边的按钮清除选择并重新载入数据。
  574 + * 1、compile阶段使用的属性如下:
  575 + * required:用于和表单验证连接,指定成required="true"才有效。
  576 + * 2、link阶段使用的属性如下
  577 + * model:关联的模型对象
  578 + * name:表单验证时需要的名字
  579 + * type:关联的那种数据值(xl/cl/ry)-> 对应线路信息/车辆信息/人员信息,后面有的继续加
  580 + * modelcolname1:关联的模型字段名字1(一般应该是编码字段)
  581 + * modelcolname2:关联的模型字段名字2(一般应该是名字字段)
  582 + * datacolname1;内部数据对应的字段名字1(与模型字段1对应)
  583 + * datacolname2:内部数据对应的字段名字2(与模型字段2对应)
  584 + * showcolname:下拉框显示的内部数据字段名(注意:不是模型数据字段名),TODO:以后考虑放动态表达式,并在compile阶段使用
  585 + * placeholder:select placeholder字符串描述
  586 + *
  587 + * $$pyFilter,内部的filter指令,结合简拼音进行拼音过滤。
  588 + * $$SearchInfoService_g,内部使用的数据服务
  589 + */
  590 +// saSelect2指令使用的内部信service
  591 +angular.module('ScheduleApp').factory('$$SearchInfoService_g', ['$resource', function($resource) {
  592 + return {
  593 + xl: $resource(
  594 + '/line/:type',
  595 + {order: 'name', direction: 'ASC'},
  596 + {
  597 + list: {
  598 + method: 'GET',
  599 + isArray: true
  600 + }
  601 + }
  602 + ),
  603 + xlinfo: $resource(
  604 + '/lineInformation/:type',
  605 + {order: 'line.name', direction: 'ASC'},
  606 + {
  607 + list: {
  608 + method: 'GET',
  609 + isArray: true
  610 + }
  611 + }
  612 + ),
  613 + zd: $resource(
  614 + '/stationroute/stations',
  615 + {order: 'stationCode', direction: 'ASC'},
  616 + {
  617 + list: {
  618 + method: 'GET',
  619 + isArray: true
  620 + }
  621 + }
  622 + ),
  623 + tcc: $resource(
  624 + '/carpark/:type',
  625 + {order: 'parkCode', direction: 'ASC'},
  626 + {
  627 + list: {
  628 + method: 'GET',
  629 + isArray: true
  630 + }
  631 + }
  632 + ),
  633 + ry: $resource(
  634 + '/personnel/:type',
  635 + {order: 'personnelName', direction: 'ASC'},
  636 + {
  637 + list: {
  638 + method: 'GET',
  639 + isArray: true
  640 + }
  641 + }
  642 + ),
  643 + cl: $resource(
  644 + '/cars/:type',
  645 + {order: "insideCode", direction: 'ASC'},
  646 + {
  647 + list: {
  648 + method: 'GET',
  649 + isArray: true
  650 + }
  651 + }
  652 + ),
  653 + ttInfo: $resource(
  654 + '/tic/:type',
  655 + {order: "name", direction: 'ASC'},
  656 + {
  657 + list: {
  658 + method: 'GET',
  659 + isArray: true
  660 + }
  661 + }
  662 + ),
  663 + lpInfo: $resource(
  664 + '/gic/ttlpnames',
  665 + {order: "lpName", direction: 'ASC'},
  666 + {
  667 + list: {
  668 + method: 'GET',
  669 + isArray: true
  670 + }
  671 + }
  672 + ),
  673 + lpInfo2: $resource(
  674 + '/gic/:type',
  675 + {order: "lpName", direction: 'ASC'},
  676 + {
  677 + list: {
  678 + method: 'GET',
  679 + isArray: true
  680 + }
  681 + }
  682 + ),
  683 + cci: $resource(
  684 + '/cci/cars',
  685 + {},
  686 + {
  687 + list: {
  688 + method: 'GET',
  689 + isArray: true
  690 + }
  691 + }
  692 +
  693 + ),
  694 + cci2: $resource(
  695 + '/cci/:type',
  696 + {},
  697 + {
  698 + list: {
  699 + method: 'GET',
  700 + isArray: true
  701 + }
  702 + }
  703 + ),
  704 + cci3: $resource(
  705 + '/cci/cars2',
  706 + {},
  707 + {
  708 + list: {
  709 + method: 'GET',
  710 + isArray: true
  711 + }
  712 + }
  713 +
  714 + ),
  715 + eci: $resource(
  716 + '/eci/jsy',
  717 + {},
  718 + {
  719 + list: {
  720 + method: 'GET',
  721 + isArray: true
  722 + }
  723 + }
  724 + ),
  725 + eci2: $resource(
  726 + '/eci/spy',
  727 + {},
  728 + {
  729 + list: {
  730 + method: 'GET',
  731 + isArray: true
  732 + }
  733 + }
  734 + ),
  735 + eci3: $resource(
  736 + '/eci/:type',
  737 + {},
  738 + {
  739 + list: {
  740 + method: 'GET',
  741 + isArray: true
  742 + }
  743 + }
  744 + ),
  745 +
  746 +
  747 + validate: { // remoteValidation指令用到的resource
  748 + gbv1: { // 路牌序号验证
  749 + template: {'xl.id_eq': -1, 'lpNo_eq': 'ddd'},
  750 + remote: $resource(
  751 + '/gic/validate1',
  752 + {},
  753 + {
  754 + do: {
  755 + method: 'GET'
  756 + }
  757 + }
  758 + )
  759 + },
  760 + gbv2: { // 路牌名称验证
  761 + template: {'xl.id_eq': -1, 'lpName_eq': 'ddd'},
  762 + remote: $resource(
  763 + '/gic/validate2',
  764 + {},
  765 + {
  766 + do: {
  767 + method: 'GET'
  768 + }
  769 + }
  770 + )
  771 + },
  772 +
  773 + cars_zbh: { // 自编号验证
  774 + template: {'insideCode_eq': '-1'}, // 查询参数模版
  775 + remote: $resource( // $resource封装对象
  776 + '/cars_sc/validate_zbh',
  777 + {},
  778 + {
  779 + do: {
  780 + method: 'GET'
  781 + }
  782 + }
  783 + )
  784 + },
  785 +
  786 + cars_sbbh: { // 验证设备编号
  787 + template: {'equipmentCode_eq': '-1'}, // 查询参数模版
  788 + remote: $resource( // $resource封装对象
  789 + '/cars_sc/validate_sbbh',
  790 + {},
  791 + {
  792 + do: {
  793 + method: 'GET'
  794 + }
  795 + }
  796 + )
  797 + },
  798 +
  799 + cars_clbh: { // 车辆编号验证
  800 + template: {'carCode_eq': '-1'}, // 查询参数模版
  801 + remote: $resource( // $resource封装对象
  802 + '/cars_sc/validate_clbh',
  803 + {},
  804 + {
  805 + do: {
  806 + method: 'GET'
  807 + }
  808 + }
  809 + )
  810 + },
  811 +
  812 + cars_cph: { // 车牌号验证
  813 + template: {'carPlate_eq': '-1'}, // 查询参数模版
  814 + remote: $resource( // $resource封装对象
  815 + '/cars_sc/validate_cph',
  816 + {},
  817 + {
  818 + do: {
  819 + method: 'GET'
  820 + }
  821 + }
  822 + )
  823 + },
  824 +
  825 +
  826 + cde1: { // 车辆设备启用日期验证
  827 + template: {'qyrq': 0, 'xl': 1, 'cl': 1}, // 日期毫秒
  828 + remote: $resource( // $resource封装对象
  829 + '/cde//validate/qyrq',
  830 + {},
  831 + {
  832 + do: {
  833 + method: 'GET'
  834 + }
  835 + }
  836 + )
  837 + },
  838 + ttc1: { // 时刻表名字验证
  839 + template: {'xl.id_eq': -1, 'name_eq': 'ddd'},
  840 + remote: $resource( // $resource封装对象
  841 + '/tic/validate/equale',
  842 + {},
  843 + {
  844 + do: {
  845 + method: 'GET'
  846 + }
  847 + }
  848 + )
  849 + },
  850 + sheet: { // 时刻表sheet工作区验证
  851 + template: {'filename': '', 'sheetname': '', 'lineid': -1, 'linename': ''},
  852 + remote: $resource( // $resource封装对象
  853 + '/tidc/validate/sheet',
  854 + {},
  855 + {
  856 + do: {
  857 + method: 'POST',
  858 + headers: {
  859 + 'Content-Type': 'application/x-www-form-urlencoded'
  860 + },
  861 + transformRequest: function(obj) {
  862 + var str = [];
  863 + for (var p in obj) {
  864 + str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
  865 + }
  866 + return str.join("&");
  867 + }
  868 + }
  869 + }
  870 + )
  871 + },
  872 + sheetli: { // 时刻表线路标准验证
  873 + template: {'lineinfoid': -1},
  874 + remote: $resource( // $resource封装对象
  875 + '/tidc/validate/lineinfo',
  876 + {},
  877 + {
  878 + do: {
  879 + method: 'GET'
  880 + }
  881 + }
  882 + )
  883 + }
  884 + }
  885 +
  886 + //validate: $resource(
  887 + // '/cars/validate/:type',
  888 + // {},
  889 + // {
  890 + // insideCode: {
  891 + // method: 'GET'
  892 + // }
  893 + // }
  894 + //)
  895 +
  896 +
  897 +
  898 + }
  899 +}]);
  900 +
  901 +
  902 +
src/main/resources/static/pages/scheduleApp/module/core/busConfig/service.js
1 -// 车辆配置service  
2 -angular.module('ScheduleApp').factory('BusConfigService_g', ['$resource', function($resource) {  
3 - return {  
4 - rest : $resource(  
5 - '/cci/:id',  
6 - {order: 'xl.id,cl.insideCode,isCancel', direction: 'ASC', id: '@id_route'},  
7 - {  
8 - list: {  
9 - method: 'GET',  
10 - params: {  
11 - page: 0  
12 - }  
13 - },  
14 - get: {  
15 - method: 'GET'  
16 - },  
17 - save: {  
18 - method: 'POST'  
19 - }  
20 - }  
21 - )  
22 - }; 1 +// 车辆配置service
  2 +angular.module('ScheduleApp').factory('BusConfigService_g', ['$resource', function($resource) {
  3 + return {
  4 + rest : $resource(
  5 + '/cci/:id',
  6 + {order: 'xl.id,cl.insideCode,isCancel', direction: 'ASC', id: '@id_route'},
  7 + {
  8 + list: {
  9 + method: 'GET',
  10 + params: {
  11 + page: 0
  12 + }
  13 + },
  14 + get: {
  15 + method: 'GET'
  16 + },
  17 + save: {
  18 + method: 'POST'
  19 + }
  20 + }
  21 + )
  22 + };
23 }]); 23 }]);
24 \ No newline at end of file 24 \ No newline at end of file
src/main/resources/static/pages/scheduleApp/module/core/busLineInfoStat/service.js
1 -// 线路运营统计service  
2 -angular.module('ScheduleApp').factory('BusLineInfoStatService_g', ['$resource', function($resource) {  
3 - return $resource(  
4 - '/bic/:id',  
5 - {order: 'createDate', direction: 'DESC', id: '@id_route'}, // TODO:以后需要根据属性对象的属性查询  
6 - {  
7 - list: {  
8 - method: 'GET',  
9 - params: {  
10 - page: 0  
11 - }  
12 - }  
13 - }  
14 - );  
15 -}]); 1 +// 线路运营统计service
  2 +angular.module('ScheduleApp').factory('BusLineInfoStatService_g', ['$resource', function($resource) {
  3 + return $resource(
  4 + '/bic/:id',
  5 + {order: 'createDate', direction: 'DESC', id: '@id_route'}, // TODO:以后需要根据属性对象的属性查询
  6 + {
  7 + list: {
  8 + method: 'GET',
  9 + params: {
  10 + page: 0
  11 + }
  12 + }
  13 + }
  14 + );
  15 +}]);
src/main/resources/static/pages/scheduleApp/module/core/employeeConfig/service.js
1 -// 人员配置service  
2 -angular.module('ScheduleApp').factory('EmployeeConfigService_g', ['$resource', function($resource) {  
3 - return {  
4 - rest : $resource(  
5 - '/eci/:id',  
6 - {order: 'xl.id,isCancel,dbbmFormula', direction: 'ASC', id: '@id_route'},  
7 - {  
8 - list: {  
9 - method: 'GET',  
10 - params: {  
11 - page: 0  
12 - }  
13 - },  
14 - get: {  
15 - method: 'GET'  
16 - },  
17 - save: {  
18 - method: 'POST'  
19 - },  
20 - delete: {  
21 - method: 'DELETE'  
22 - }  
23 - }  
24 - ),  
25 - validate: $resource( // TODO:  
26 - '/personnel/validate/:type',  
27 - {},  
28 - {  
29 - jobCode: {  
30 - method: 'GET'  
31 - }  
32 - }  
33 - )  
34 - }; 1 +// 人员配置service
  2 +angular.module('ScheduleApp').factory('EmployeeConfigService_g', ['$resource', function($resource) {
  3 + return {
  4 + rest : $resource(
  5 + '/eci/:id',
  6 + {order: 'xl.id,isCancel,dbbmFormula', direction: 'ASC', id: '@id_route'},
  7 + {
  8 + list: {
  9 + method: 'GET',
  10 + params: {
  11 + page: 0
  12 + }
  13 + },
  14 + get: {
  15 + method: 'GET'
  16 + },
  17 + save: {
  18 + method: 'POST'
  19 + },
  20 + delete: {
  21 + method: 'DELETE'
  22 + }
  23 + }
  24 + ),
  25 + validate: $resource( // TODO:
  26 + '/personnel/validate/:type',
  27 + {},
  28 + {
  29 + jobCode: {
  30 + method: 'GET'
  31 + }
  32 + }
  33 + )
  34 + };
35 }]); 35 }]);
36 \ No newline at end of file 36 \ No newline at end of file
src/main/resources/static/pages/scheduleApp/module/core/guideboardManage/edit.html
1 -<div class="page-head">  
2 - <div class="page-title">  
3 - <h1>路牌管理</h1>  
4 - </div>  
5 -</div>  
6 -  
7 -<ul class="page-breadcrumb breadcrumb">  
8 - <li>  
9 - <a href="/pages/home.html" data-pjax="">首页</a>  
10 - <i class="fa fa-circle"></i>  
11 - </li>  
12 - <li>  
13 - <span class="active">运营计划管理</span>  
14 - <i class="fa fa-circle"></i>  
15 - </li>  
16 - <li>  
17 - <a ui-sref="guideboardManage">路牌管理</a>  
18 - <i class="fa fa-circle"></i>  
19 - </li>  
20 - <li>  
21 - <span class="active">修改路牌</span>  
22 - </li>  
23 -</ul>  
24 -  
25 -<div class="portlet light bordered" ng-controller="GuideboardManageFormCtrl as ctrl">  
26 - <div class="portlet-title">  
27 - <div class="caption">  
28 - <i class="icon-equalizer font-red-sunglo"></i> <span  
29 - class="caption-subject font-red-sunglo bold uppercase">表单</span>  
30 - </div>  
31 - </div>  
32 -  
33 - <div class="portlet-body form">  
34 - <form ng-submit="ctrl.submit()" class="form-horizontal" novalidate name="myForm">  
35 -  
36 - <div class="form-body">  
37 - <div class="form-group has-success has-feedback">  
38 - <label class="col-md-2 control-label">线路*:</label>  
39 - <div class="col-md-3">  
40 - <sa-Select5 name="xl"  
41 - model="ctrl.guideboardManageForForm"  
42 - cmaps="{'xl.id' : 'id'}"  
43 - dcname="xl.id"  
44 - icname="id"  
45 - dsparams="{{ {type: 'ajax', param:{type: 'all', 'destroy_eq': 0}, atype:'xl' } | json }}"  
46 - iterobjname="item"  
47 - iterobjexp="item.name"  
48 - searchph="请输拼音..."  
49 - searchexp="this.name"  
50 - required >  
51 - </sa-Select5>  
52 - </div>  
53 - <!-- 隐藏块,显示验证信息 -->  
54 - <div class="alert alert-danger well-sm" ng-show="myForm.xl.$error.required">  
55 - 线路必须选择  
56 - </div>  
57 - </div>  
58 -  
59 - <div class="form-group has-success has-feedback">  
60 - <label class="col-md-2 control-label">路牌编号:</label>  
61 - <div class="col-md-3">  
62 - <input type="number" class="form-control" ng-model="ctrl.guideboardManageForForm.lpNo"  
63 - name="lpNo" placeholder="请输入路牌编号..." min="1" required  
64 - remote-Validation  
65 - remotevtype="gbv1"  
66 - remotevparam="{{ {'xl.id_eq': ctrl.guideboardManageForForm.xl.id, 'lpNo_eq': ctrl.guideboardManageForForm.lpNo} | json}}"  
67 -  
68 - />  
69 - </div>  
70 - <div class="alert alert-danger well-sm" ng-show="myForm.lpNo.$error.required">  
71 - 路牌编号必须填写  
72 - </div>  
73 - <div class="alert alert-danger well-sm" ng-show="myForm.lpNo.$error.number">  
74 - 必须输入数字  
75 - </div>  
76 - <div class="alert alert-danger well-sm" ng-show="myForm.lpNo.$error.remote">  
77 - {{$remote_msg}}  
78 - </div>  
79 - </div>  
80 -  
81 - <div class="form-group has-success has-feedback">  
82 - <label class="col-md-2 control-label">路牌名称*:</label>  
83 - <div class="col-md-3">  
84 - <input type="text" class="form-control" ng-model="ctrl.guideboardManageForForm.lpName"  
85 - name="lpName" placeholder="请输入路牌名字..." required  
86 - remote-Validation  
87 - remotevtype="gbv2"  
88 - remotevparam="{{ {'xl.id_eq': ctrl.guideboardManageForForm.xl.id, 'lpName_eq': ctrl.guideboardManageForForm.lpName} | json}}"  
89 -  
90 - />  
91 - </div>  
92 -  
93 - <!-- 隐藏块,显示验证信息 -->  
94 - <div class="alert alert-danger well-sm" ng-show="myForm.lpName.$error.required">  
95 - 路牌名称必须填写  
96 - </div>  
97 - <div class="alert alert-danger well-sm" ng-show="myForm.lpName.$error.remote">  
98 - {{$remote_msg}}  
99 - </div>  
100 - </div>  
101 -  
102 - <!-- 路牌类型暂时是普通路牌,默认填写了 -->  
103 -  
104 -  
105 - </div>  
106 -  
107 - <div class="form-actions">  
108 - <div class="row">  
109 - <div class="col-md-offset-3 col-md-4">  
110 - <button type="submit" class="btn green" ng-disabled="!myForm.$valid">  
111 - <i class="fa fa-check">提交</i>  
112 - </button>  
113 - <a type="button" class="btn default" ui-sref="guideboardManage">  
114 - <i class="fa fa-times">取消</i>  
115 - </a>  
116 - </div>  
117 - </div>  
118 - </div>  
119 -  
120 - </form>  
121 -  
122 - </div>  
123 -  
124 -</div>  
125 -  
126 -  
127 -  
128 -  
129 -  
130 -  
131 -  
132 -  
133 -  
134 -  
135 -  
136 - 1 +<div class="page-head">
  2 + <div class="page-title">
  3 + <h1>路牌管理</h1>
  4 + </div>
  5 +</div>
  6 +
  7 +<ul class="page-breadcrumb breadcrumb">
  8 + <li>
  9 + <a href="/pages/home.html" data-pjax="">首页</a>
  10 + <i class="fa fa-circle"></i>
  11 + </li>
  12 + <li>
  13 + <span class="active">运营计划管理</span>
  14 + <i class="fa fa-circle"></i>
  15 + </li>
  16 + <li>
  17 + <a ui-sref="guideboardManage">路牌管理</a>
  18 + <i class="fa fa-circle"></i>
  19 + </li>
  20 + <li>
  21 + <span class="active">修改路牌</span>
  22 + </li>
  23 +</ul>
  24 +
  25 +<div class="portlet light bordered" ng-controller="GuideboardManageFormCtrl as ctrl">
  26 + <div class="portlet-title">
  27 + <div class="caption">
  28 + <i class="icon-equalizer font-red-sunglo"></i> <span
  29 + class="caption-subject font-red-sunglo bold uppercase">表单</span>
  30 + </div>
  31 + </div>
  32 +
  33 + <div class="portlet-body form">
  34 + <form ng-submit="ctrl.submit()" class="form-horizontal" novalidate name="myForm">
  35 +
  36 + <div class="form-body">
  37 + <div class="form-group has-success has-feedback">
  38 + <label class="col-md-2 control-label">线路*:</label>
  39 + <div class="col-md-3">
  40 + <sa-Select5 name="xl"
  41 + model="ctrl.guideboardManageForForm"
  42 + cmaps="{'xl.id' : 'id'}"
  43 + dcname="xl.id"
  44 + icname="id"
  45 + dsparams="{{ {type: 'ajax', param:{type: 'all', 'destroy_eq': 0}, atype:'xl' } | json }}"
  46 + iterobjname="item"
  47 + iterobjexp="item.name"
  48 + searchph="请输拼音..."
  49 + searchexp="this.name"
  50 + required >
  51 + </sa-Select5>
  52 + </div>
  53 + <!-- 隐藏块,显示验证信息 -->
  54 + <div class="alert alert-danger well-sm" ng-show="myForm.xl.$error.required">
  55 + 线路必须选择
  56 + </div>
  57 + </div>
  58 +
  59 + <div class="form-group has-success has-feedback">
  60 + <label class="col-md-2 control-label">路牌编号:</label>
  61 + <div class="col-md-3">
  62 + <input type="number" class="form-control" ng-model="ctrl.guideboardManageForForm.lpNo"
  63 + name="lpNo" placeholder="请输入路牌编号..." min="1" required
  64 + remote-Validation
  65 + remotevtype="gbv1"
  66 + remotevparam="{{ {'xl.id_eq': ctrl.guideboardManageForForm.xl.id, 'lpNo_eq': ctrl.guideboardManageForForm.lpNo} | json}}"
  67 +
  68 + />
  69 + </div>
  70 + <div class="alert alert-danger well-sm" ng-show="myForm.lpNo.$error.required">
  71 + 路牌编号必须填写
  72 + </div>
  73 + <div class="alert alert-danger well-sm" ng-show="myForm.lpNo.$error.number">
  74 + 必须输入数字
  75 + </div>
  76 + <div class="alert alert-danger well-sm" ng-show="myForm.lpNo.$error.remote">
  77 + {{$remote_msg}}
  78 + </div>
  79 + </div>
  80 +
  81 + <div class="form-group has-success has-feedback">
  82 + <label class="col-md-2 control-label">路牌名称*:</label>
  83 + <div class="col-md-3">
  84 + <input type="text" class="form-control" ng-model="ctrl.guideboardManageForForm.lpName"
  85 + name="lpName" placeholder="请输入路牌名字..." required
  86 + remote-Validation
  87 + remotevtype="gbv2"
  88 + remotevparam="{{ {'xl.id_eq': ctrl.guideboardManageForForm.xl.id, 'lpName_eq': ctrl.guideboardManageForForm.lpName} | json}}"
  89 +
  90 + />
  91 + </div>
  92 +
  93 + <!-- 隐藏块,显示验证信息 -->
  94 + <div class="alert alert-danger well-sm" ng-show="myForm.lpName.$error.required">
  95 + 路牌名称必须填写
  96 + </div>
  97 + <div class="alert alert-danger well-sm" ng-show="myForm.lpName.$error.remote">
  98 + {{$remote_msg}}
  99 + </div>
  100 + </div>
  101 +
  102 + <!-- 路牌类型暂时是普通路牌,默认填写了 -->
  103 +
  104 +
  105 + </div>
  106 +
  107 + <div class="form-actions">
  108 + <div class="row">
  109 + <div class="col-md-offset-3 col-md-4">
  110 + <button type="submit" class="btn green" ng-disabled="!myForm.$valid">
  111 + <i class="fa fa-check">提交</i>
  112 + </button>
  113 + <a type="button" class="btn default" ui-sref="guideboardManage">
  114 + <i class="fa fa-times">取消</i>
  115 + </a>
  116 + </div>
  117 + </div>
  118 + </div>
  119 +
  120 + </form>
  121 +
  122 + </div>
  123 +
  124 +</div>
  125 +
  126 +
  127 +
  128 +
  129 +
  130 +
  131 +
  132 +
  133 +
  134 +
  135 +
  136 +
src/main/resources/static/pages/scheduleApp/module/core/guideboardManage/form.html
1 -<div class="page-head">  
2 - <div class="page-title">  
3 - <h1>路牌管理</h1>  
4 - </div>  
5 -</div>  
6 -  
7 -<ul class="page-breadcrumb breadcrumb">  
8 - <li>  
9 - <a href="/pages/home.html" data-pjax="">首页</a>  
10 - <i class="fa fa-circle"></i>  
11 - </li>  
12 - <li>  
13 - <span class="active">运营计划管理</span>  
14 - <i class="fa fa-circle"></i>  
15 - </li>  
16 - <li>  
17 - <a ui-sref="guideboardManage">路牌管理</a>  
18 - <i class="fa fa-circle"></i>  
19 - </li>  
20 - <li>  
21 - <span class="active">添加路牌</span>  
22 - </li>  
23 -</ul>  
24 -  
25 -<div class="portlet light bordered" ng-controller="GuideboardManageFormCtrl as ctrl">  
26 - <div class="portlet-title">  
27 - <div class="caption">  
28 - <i class="icon-equalizer font-red-sunglo"></i> <span  
29 - class="caption-subject font-red-sunglo bold uppercase">表单</span>  
30 - </div>  
31 - </div>  
32 -  
33 - <div class="portlet-body form">  
34 - <form ng-submit="ctrl.submit()" class="form-horizontal" novalidate name="myForm">  
35 -  
36 - <div class="form-body">  
37 - <div class="form-group has-success has-feedback">  
38 - <label class="col-md-2 control-label">线路*:</label>  
39 - <div class="col-md-3">  
40 - <sa-Select5 name="xl"  
41 - model="ctrl.guideboardManageForForm"  
42 - cmaps="{'xl.id' : 'id'}"  
43 - dcname="xl.id"  
44 - icname="id"  
45 - dsparams="{{ {type: 'ajax', param:{type: 'all', 'destroy_eq': 0}, atype:'xl' } | json }}"  
46 - iterobjname="item"  
47 - iterobjexp="item.name"  
48 - searchph="请输拼音..."  
49 - searchexp="this.name"  
50 - required >  
51 - </sa-Select5>  
52 - </div>  
53 - <!-- 隐藏块,显示验证信息 -->  
54 - <div class="alert alert-danger well-sm" ng-show="myForm.xl.$error.required">  
55 - 线路必须选择  
56 - </div>  
57 - </div>  
58 -  
59 - <div class="form-group has-success has-feedback">  
60 - <label class="col-md-2 control-label">路牌编号:</label>  
61 - <div class="col-md-3">  
62 - <input type="number" class="form-control" ng-model="ctrl.guideboardManageForForm.lpNo"  
63 - name="lpNo" placeholder="请输入路牌编号..." min="1" required  
64 - remote-Validation  
65 - remotevtype="gbv1"  
66 - remotevparam="{{ {'xl.id_eq': ctrl.guideboardManageForForm.xl.id, 'lpNo_eq': ctrl.guideboardManageForForm.lpNo} | json}}"  
67 -  
68 - />  
69 - </div>  
70 - <div class="alert alert-danger well-sm" ng-show="myForm.lpNo.$error.required">  
71 - 路牌编号必须填写  
72 - </div>  
73 - <div class="alert alert-danger well-sm" ng-show="myForm.lpNo.$error.number">  
74 - 必须输入数字  
75 - </div>  
76 - <div class="alert alert-danger well-sm" ng-show="myForm.lpNo.$error.remote">  
77 - {{$remote_msg}}  
78 - </div>  
79 - </div>  
80 -  
81 - <div class="form-group has-success has-feedback">  
82 - <label class="col-md-2 control-label">路牌名称*:</label>  
83 - <div class="col-md-3">  
84 - <input type="text" class="form-control" ng-model="ctrl.guideboardManageForForm.lpName"  
85 - name="lpName" placeholder="请输入路牌名字..." required  
86 - remote-Validation  
87 - remotevtype="gbv2"  
88 - remotevparam="{{ {'xl.id_eq': ctrl.guideboardManageForForm.xl.id, 'lpName_eq': ctrl.guideboardManageForForm.lpName} | json}}"  
89 -  
90 - />  
91 - </div>  
92 -  
93 - <!-- 隐藏块,显示验证信息 -->  
94 - <div class="alert alert-danger well-sm" ng-show="myForm.lpName.$error.required">  
95 - 路牌名称必须填写  
96 - </div>  
97 - <div class="alert alert-danger well-sm" ng-show="myForm.lpName.$error.remote">  
98 - {{$remote_msg}}  
99 - </div>  
100 - </div>  
101 -  
102 - <!-- 路牌类型暂时是普通路牌,默认填写了 -->  
103 -  
104 -  
105 - </div>  
106 -  
107 - <div class="form-actions">  
108 - <div class="row">  
109 - <div class="col-md-offset-3 col-md-4">  
110 - <button type="submit" class="btn green"  
111 - ng-disabled="!myForm.$valid"  
112 - >  
113 - <i class="fa fa-check">提交</i>  
114 - </button>  
115 - <a type="button" class="btn default" ui-sref="guideboardManage">  
116 - <i class="fa fa-times">取消</i>  
117 - </a>  
118 - </div>  
119 - </div>  
120 - </div>  
121 -  
122 - </form>  
123 -  
124 - </div>  
125 -  
126 -</div>  
127 -  
128 -  
129 -  
130 - 1 +<div class="page-head">
  2 + <div class="page-title">
  3 + <h1>路牌管理</h1>
  4 + </div>
  5 +</div>
  6 +
  7 +<ul class="page-breadcrumb breadcrumb">
  8 + <li>
  9 + <a href="/pages/home.html" data-pjax="">首页</a>
  10 + <i class="fa fa-circle"></i>
  11 + </li>
  12 + <li>
  13 + <span class="active">运营计划管理</span>
  14 + <i class="fa fa-circle"></i>
  15 + </li>
  16 + <li>
  17 + <a ui-sref="guideboardManage">路牌管理</a>
  18 + <i class="fa fa-circle"></i>
  19 + </li>
  20 + <li>
  21 + <span class="active">添加路牌</span>
  22 + </li>
  23 +</ul>
  24 +
  25 +<div class="portlet light bordered" ng-controller="GuideboardManageFormCtrl as ctrl">
  26 + <div class="portlet-title">
  27 + <div class="caption">
  28 + <i class="icon-equalizer font-red-sunglo"></i> <span
  29 + class="caption-subject font-red-sunglo bold uppercase">表单</span>
  30 + </div>
  31 + </div>
  32 +
  33 + <div class="portlet-body form">
  34 + <form ng-submit="ctrl.submit()" class="form-horizontal" novalidate name="myForm">
  35 +
  36 + <div class="form-body">
  37 + <div class="form-group has-success has-feedback">
  38 + <label class="col-md-2 control-label">线路*:</label>
  39 + <div class="col-md-3">
  40 + <sa-Select5 name="xl"
  41 + model="ctrl.guideboardManageForForm"
  42 + cmaps="{'xl.id' : 'id'}"
  43 + dcname="xl.id"
  44 + icname="id"
  45 + dsparams="{{ {type: 'ajax', param:{type: 'all', 'destroy_eq': 0}, atype:'xl' } | json }}"
  46 + iterobjname="item"
  47 + iterobjexp="item.name"
  48 + searchph="请输拼音..."
  49 + searchexp="this.name"
  50 + required >
  51 + </sa-Select5>
  52 + </div>
  53 + <!-- 隐藏块,显示验证信息 -->
  54 + <div class="alert alert-danger well-sm" ng-show="myForm.xl.$error.required">
  55 + 线路必须选择
  56 + </div>
  57 + </div>
  58 +
  59 + <div class="form-group has-success has-feedback">
  60 + <label class="col-md-2 control-label">路牌编号:</label>
  61 + <div class="col-md-3">
  62 + <input type="number" class="form-control" ng-model="ctrl.guideboardManageForForm.lpNo"
  63 + name="lpNo" placeholder="请输入路牌编号..." min="1" required
  64 + remote-Validation
  65 + remotevtype="gbv1"
  66 + remotevparam="{{ {'xl.id_eq': ctrl.guideboardManageForForm.xl.id, 'lpNo_eq': ctrl.guideboardManageForForm.lpNo} | json}}"
  67 +
  68 + />
  69 + </div>
  70 + <div class="alert alert-danger well-sm" ng-show="myForm.lpNo.$error.required">
  71 + 路牌编号必须填写
  72 + </div>
  73 + <div class="alert alert-danger well-sm" ng-show="myForm.lpNo.$error.number">
  74 + 必须输入数字
  75 + </div>
  76 + <div class="alert alert-danger well-sm" ng-show="myForm.lpNo.$error.remote">
  77 + {{$remote_msg}}
  78 + </div>
  79 + </div>
  80 +
  81 + <div class="form-group has-success has-feedback">
  82 + <label class="col-md-2 control-label">路牌名称*:</label>
  83 + <div class="col-md-3">
  84 + <input type="text" class="form-control" ng-model="ctrl.guideboardManageForForm.lpName"
  85 + name="lpName" placeholder="请输入路牌名字..." required
  86 + remote-Validation
  87 + remotevtype="gbv2"
  88 + remotevparam="{{ {'xl.id_eq': ctrl.guideboardManageForForm.xl.id, 'lpName_eq': ctrl.guideboardManageForForm.lpName} | json}}"
  89 +
  90 + />
  91 + </div>
  92 +
  93 + <!-- 隐藏块,显示验证信息 -->
  94 + <div class="alert alert-danger well-sm" ng-show="myForm.lpName.$error.required">
  95 + 路牌名称必须填写
  96 + </div>
  97 + <div class="alert alert-danger well-sm" ng-show="myForm.lpName.$error.remote">
  98 + {{$remote_msg}}
  99 + </div>
  100 + </div>
  101 +
  102 + <!-- 路牌类型暂时是普通路牌,默认填写了 -->
  103 +
  104 +
  105 + </div>
  106 +
  107 + <div class="form-actions">
  108 + <div class="row">
  109 + <div class="col-md-offset-3 col-md-4">
  110 + <button type="submit" class="btn green"
  111 + ng-disabled="!myForm.$valid"
  112 + >
  113 + <i class="fa fa-check">提交</i>
  114 + </button>
  115 + <a type="button" class="btn default" ui-sref="guideboardManage">
  116 + <i class="fa fa-times">取消</i>
  117 + </a>
  118 + </div>
  119 + </div>
  120 + </div>
  121 +
  122 + </form>
  123 +
  124 + </div>
  125 +
  126 +</div>
  127 +
  128 +
  129 +
  130 +
src/main/resources/static/pages/scheduleApp/module/core/guideboardManage/module.js
1 -// 路牌管理 service controller 等写在一起  
2 -  
3 -angular.module('ScheduleApp').factory(  
4 - 'GuideboardManageService',  
5 - [  
6 - 'GuideboardManageService_g',  
7 - function(service) {  
8 -  
9 - /** 当前的查询条件信息 */  
10 - var currentSearchCondition = {page: 0, 'isCancel_eq': false};  
11 - // 当前查询返回的信息  
12 - var currentPage = { // 后台spring data返回的格式  
13 - totalElements: 0,  
14 - number: 0, // 后台返回的页码,spring返回从0开始  
15 - content: [],  
16 -  
17 - uiNumber: 1 // 页面绑定的页码  
18 - };  
19 -  
20 - // 查询对象类  
21 - var queryClass = service.rest;  
22 -  
23 - return {  
24 - getGbQueryClass: function() {  
25 - return queryClass;  
26 - },  
27 -  
28 - /**  
29 - * 获取查询条件信息,  
30 - * 用于给controller用来和页面数据绑定。  
31 - */  
32 - getSearchCondition: function() {  
33 - currentSearchCondition.page = currentPage.uiNumber - 1;  
34 - return currentSearchCondition;  
35 - },  
36 - /**  
37 - * 重置查询条件信息。  
38 - */  
39 - resetStatus: function() {  
40 - currentSearchCondition = {page: 0, 'isCancel_eq': false};  
41 - currentPage = {  
42 - totalElements: 0,  
43 - number: 0,  
44 - content: [],  
45 - uiNumber: 1  
46 - };  
47 - },  
48 - /**  
49 - * 组装查询参数,返回一个promise查询结果。  
50 - * @param params 查询参数  
51 - * @return 返回一个 promise  
52 - */  
53 - getPage: function(page) {  
54 - if (page) {  
55 - currentPage.totalElements = page.totalElements;  
56 - currentPage.number = page.number;  
57 - currentPage.content = page.content;  
58 - }  
59 - return currentPage;  
60 - },  
61 - /**  
62 - * 获取明细信息。  
63 - * @param id 车辆id  
64 - * @return 返回一个 promise  
65 - */  
66 - getDetail: function(id) {  
67 - var params = {id: id};  
68 - return service.rest.get(params).$promise;  
69 - },  
70 - /**  
71 - * 保存信息。  
72 - * @param obj 车辆详细信息  
73 - * @return 返回一个 promise  
74 - */  
75 - saveDetail: function(obj) {  
76 - return service.rest.save(obj).$promise;  
77 - }  
78 - };  
79 - }  
80 - ]  
81 -);  
82 -  
83 -angular.module('ScheduleApp').controller('GuideboardManageCtrl', ['GuideboardManageService', '$state', '$uibModal', function(guideboardManageService, $state, $uibModal) {  
84 - var self = this;  
85 -  
86 - // 切换到form状态  
87 - self.goForm = function() {  
88 - alert("切换添加");  
89 - };  
90 -  
91 - // 导入excel  
92 - self.importData = function() {  
93 - // large方式弹出模态对话框  
94 - var modalInstance = $uibModal.open({  
95 - templateUrl: '/pages/scheduleApp/module/core/guideboardManage/dataImport.html',  
96 - size: "lg",  
97 - animation: true,  
98 - backdrop: 'static',  
99 - resolve: {  
100 - // 可以传值给controller  
101 - },  
102 - windowClass: 'center-modal',  
103 - controller: "GuideboardManageToolsCtrl",  
104 - controllerAs: "ctrl",  
105 - bindToController: true  
106 - });  
107 - modalInstance.result.then(  
108 - function() {  
109 - console.log("dataImport.html打开");  
110 - },  
111 - function() {  
112 - console.log("dataImport.html消失");  
113 - }  
114 - );  
115 - };  
116 -  
117 -}]);  
118 -  
119 -angular.module('ScheduleApp').controller('GuideboardManageToolsCtrl', ['$modalInstance', 'FileUploader', function($modalInstance, FileUploader) {  
120 - var self = this;  
121 - self.data = "TODO";  
122 -  
123 - // 关闭窗口  
124 - self.close = function() {  
125 - $modalInstance.dismiss("cancel");  
126 - };  
127 -  
128 - self.clearInputFile = function() {  
129 - angular.element("input[type='file']").val(null);  
130 - };  
131 -  
132 - // 上传文件组件  
133 - self.uploader = new FileUploader({  
134 - url: "/gic/dataImport",  
135 - filters: [] // 用于过滤文件,比如只允许导入excel  
136 - });  
137 - self.uploader.onAfterAddingFile = function(fileItem)  
138 - {  
139 - console.info('onAfterAddingFile', fileItem);  
140 - console.log(self.uploader.queue.length);  
141 - if (self.uploader.queue.length > 1)  
142 - self.uploader.removeFromQueue(0);  
143 - };  
144 - self.uploader.onSuccessItem = function(fileItem, response, status, headers)  
145 - {  
146 - console.info('onSuccessItem', fileItem, response, status, headers);  
147 - };  
148 - self.uploader.onErrorItem = function(fileItem, response, status, headers)  
149 - {  
150 - console.info('onErrorItem', fileItem, response, status, headers);  
151 - };  
152 -  
153 -}]);  
154 -  
155 -// list.html控制器  
156 -angular.module('ScheduleApp').controller(  
157 - 'GuideboardManageListCtrl',  
158 - [  
159 - 'GuideboardManageService',  
160 - function(service) {  
161 - var self = this;  
162 - var Gb = service.getGbQueryClass();  
163 -  
164 - self.page = function() {  
165 - return service.getPage();  
166 - };  
167 -  
168 - self.searchCondition = function() {  
169 - return service.getSearchCondition();  
170 - };  
171 -  
172 - self.doPage = function() {  
173 - var result = Gb.list(self.searchCondition(), function(result) {  
174 - service.getPage(result);  
175 - });  
176 - };  
177 - self.reset = function() {  
178 - service.resetStatus();  
179 - var result = Gb.list(self.searchCondition(), function() {  
180 - service.getPage(result);  
181 - });  
182 - };  
183 - self.toggleTtinfo = function(id) {  
184 - Gb.delete({id: id}, function(result) {  
185 - if (result.message) { // 暂时这样做,之后全局拦截  
186 - alert("失败:" + result.message);  
187 - } else {  
188 - self.doPage();  
189 - }  
190 - });  
191 - };  
192 -  
193 - // 作废切换  
194 - self.toggleCancel = function(id) {  
195 - Gb.delete({id: id}, function(result) {  
196 - if (result.status == "ERROR") { // 暂时这样做,之后全局拦截  
197 - alert("失败:" + result.msg);  
198 - } else {  
199 - self.doPage();  
200 - }  
201 - });  
202 - };  
203 -  
204 -  
205 - // TODO:导出  
206 -  
207 -  
208 - self.doPage();  
209 - }  
210 - ]  
211 -);  
212 -  
213 -//form.html控制器  
214 -angular.module('ScheduleApp').controller(  
215 - 'GuideboardManageFormCtrl',  
216 - [  
217 - 'GuideboardManageService',  
218 - '$stateParams',  
219 - '$state',  
220 - '$scope',  
221 - function(service, $stateParams, $state, $scope) {  
222 - var self = this;  
223 - var Gb = service.getGbQueryClass();  
224 -  
225 - // 欲保存的表单信息,双向绑定  
226 - self.guideboardManageForForm = new Gb;  
227 - self.guideboardManageForForm.xl = {};  
228 -  
229 - // 如果是修改,获取传过来的id,从后台获取一份数据,用于绑定页面form值  
230 - var id = $stateParams.id;  
231 - if (id) {  
232 - Gb.get({id: id}, function(value) {  
233 - self.guideboardManageForForm = value;  
234 - });  
235 - }  
236 - // form提交方法  
237 - self.submit = function() {  
238 - console.log($scope);  
239 - console.log(self.guideboardManageForForm);  
240 -  
241 - self.guideboardManageForForm.lpType = "普通路牌";  
242 - self.guideboardManageForForm.$save(function() {  
243 - $state.go("guideboardManage");  
244 - });  
245 - };  
246 -  
247 - }  
248 - ]  
249 -);  
250 -  
251 -// detail.html控制器  
252 -angular.module('ScheduleApp').controller(  
253 - 'GuideboardManageDetailCtrl',  
254 - [  
255 - 'GuideboardManageService',  
256 - '$stateParams',  
257 - function(service, $stateParams) {  
258 - var self = this;  
259 - var Gb = service.getGbQueryClass();  
260 - var id = $stateParams.id;  
261 -  
262 - self.title = "";  
263 - self.guideboardForDetail = {};  
264 -  
265 - // 当转向到此页面时,就获取明细信息并绑定  
266 - Gb.get({id: id}, function(result) {  
267 - self.guideboardForDetail = result.data;  
268 - self.title = "路牌 " + self.guideboardForDetail.lpName + " 详细信息";  
269 - });  
270 - }  
271 - ]  
272 -);  
273 -  
274 - 1 +// 路牌管理 service controller 等写在一起
  2 +
  3 +angular.module('ScheduleApp').factory(
  4 + 'GuideboardManageService',
  5 + [
  6 + 'GuideboardManageService_g',
  7 + function(service) {
  8 +
  9 + /** 当前的查询条件信息 */
  10 + var currentSearchCondition = {page: 0, 'isCancel_eq': false};
  11 + // 当前查询返回的信息
  12 + var currentPage = { // 后台spring data返回的格式
  13 + totalElements: 0,
  14 + number: 0, // 后台返回的页码,spring返回从0开始
  15 + content: [],
  16 +
  17 + uiNumber: 1 // 页面绑定的页码
  18 + };
  19 +
  20 + // 查询对象类
  21 + var queryClass = service.rest;
  22 +
  23 + return {
  24 + getGbQueryClass: function() {
  25 + return queryClass;
  26 + },
  27 +
  28 + /**
  29 + * 获取查询条件信息,
  30 + * 用于给controller用来和页面数据绑定。
  31 + */
  32 + getSearchCondition: function() {
  33 + currentSearchCondition.page = currentPage.uiNumber - 1;
  34 + return currentSearchCondition;
  35 + },
  36 + /**
  37 + * 重置查询条件信息。
  38 + */
  39 + resetStatus: function() {
  40 + currentSearchCondition = {page: 0, 'isCancel_eq': false};
  41 + currentPage = {
  42 + totalElements: 0,
  43 + number: 0,
  44 + content: [],
  45 + uiNumber: 1
  46 + };
  47 + },
  48 + /**
  49 + * 组装查询参数,返回一个promise查询结果。
  50 + * @param params 查询参数
  51 + * @return 返回一个 promise
  52 + */
  53 + getPage: function(page) {
  54 + if (page) {
  55 + currentPage.totalElements = page.totalElements;
  56 + currentPage.number = page.number;
  57 + currentPage.content = page.content;
  58 + }
  59 + return currentPage;
  60 + },
  61 + /**
  62 + * 获取明细信息。
  63 + * @param id 车辆id
  64 + * @return 返回一个 promise
  65 + */
  66 + getDetail: function(id) {
  67 + var params = {id: id};
  68 + return service.rest.get(params).$promise;
  69 + },
  70 + /**
  71 + * 保存信息。
  72 + * @param obj 车辆详细信息
  73 + * @return 返回一个 promise
  74 + */
  75 + saveDetail: function(obj) {
  76 + return service.rest.save(obj).$promise;
  77 + }
  78 + };
  79 + }
  80 + ]
  81 +);
  82 +
  83 +angular.module('ScheduleApp').controller('GuideboardManageCtrl', ['GuideboardManageService', '$state', '$uibModal', function(guideboardManageService, $state, $uibModal) {
  84 + var self = this;
  85 +
  86 + // 切换到form状态
  87 + self.goForm = function() {
  88 + alert("切换添加");
  89 + };
  90 +
  91 + // 导入excel
  92 + self.importData = function() {
  93 + // large方式弹出模态对话框
  94 + var modalInstance = $uibModal.open({
  95 + templateUrl: '/pages/scheduleApp/module/core/guideboardManage/dataImport.html',
  96 + size: "lg",
  97 + animation: true,
  98 + backdrop: 'static',
  99 + resolve: {
  100 + // 可以传值给controller
  101 + },
  102 + windowClass: 'center-modal',
  103 + controller: "GuideboardManageToolsCtrl",
  104 + controllerAs: "ctrl",
  105 + bindToController: true
  106 + });
  107 + modalInstance.result.then(
  108 + function() {
  109 + console.log("dataImport.html打开");
  110 + },
  111 + function() {
  112 + console.log("dataImport.html消失");
  113 + }
  114 + );
  115 + };
  116 +
  117 +}]);
  118 +
  119 +angular.module('ScheduleApp').controller('GuideboardManageToolsCtrl', ['$modalInstance', 'FileUploader', function($modalInstance, FileUploader) {
  120 + var self = this;
  121 + self.data = "TODO";
  122 +
  123 + // 关闭窗口
  124 + self.close = function() {
  125 + $modalInstance.dismiss("cancel");
  126 + };
  127 +
  128 + self.clearInputFile = function() {
  129 + angular.element("input[type='file']").val(null);
  130 + };
  131 +
  132 + // 上传文件组件
  133 + self.uploader = new FileUploader({
  134 + url: "/gic/dataImport",
  135 + filters: [] // 用于过滤文件,比如只允许导入excel
  136 + });
  137 + self.uploader.onAfterAddingFile = function(fileItem)
  138 + {
  139 + console.info('onAfterAddingFile', fileItem);
  140 + console.log(self.uploader.queue.length);
  141 + if (self.uploader.queue.length > 1)
  142 + self.uploader.removeFromQueue(0);
  143 + };
  144 + self.uploader.onSuccessItem = function(fileItem, response, status, headers)
  145 + {
  146 + console.info('onSuccessItem', fileItem, response, status, headers);
  147 + };
  148 + self.uploader.onErrorItem = function(fileItem, response, status, headers)
  149 + {
  150 + console.info('onErrorItem', fileItem, response, status, headers);
  151 + };
  152 +
  153 +}]);
  154 +
  155 +// list.html控制器
  156 +angular.module('ScheduleApp').controller(
  157 + 'GuideboardManageListCtrl',
  158 + [
  159 + 'GuideboardManageService',
  160 + function(service) {
  161 + var self = this;
  162 + var Gb = service.getGbQueryClass();
  163 +
  164 + self.page = function() {
  165 + return service.getPage();
  166 + };
  167 +
  168 + self.searchCondition = function() {
  169 + return service.getSearchCondition();
  170 + };
  171 +
  172 + self.doPage = function() {
  173 + var result = Gb.list(self.searchCondition(), function(result) {
  174 + service.getPage(result);
  175 + });
  176 + };
  177 + self.reset = function() {
  178 + service.resetStatus();
  179 + var result = Gb.list(self.searchCondition(), function() {
  180 + service.getPage(result);
  181 + });
  182 + };
  183 + self.toggleTtinfo = function(id) {
  184 + Gb.delete({id: id}, function(result) {
  185 + if (result.message) { // 暂时这样做,之后全局拦截
  186 + alert("失败:" + result.message);
  187 + } else {
  188 + self.doPage();
  189 + }
  190 + });
  191 + };
  192 +
  193 + // 作废切换
  194 + self.toggleCancel = function(id) {
  195 + Gb.delete({id: id}, function(result) {
  196 + if (result.status == "ERROR") { // 暂时这样做,之后全局拦截
  197 + alert("失败:" + result.msg);
  198 + } else {
  199 + self.doPage();
  200 + }
  201 + });
  202 + };
  203 +
  204 +
  205 + // TODO:导出
  206 +
  207 +
  208 + self.doPage();
  209 + }
  210 + ]
  211 +);
  212 +
  213 +//form.html控制器
  214 +angular.module('ScheduleApp').controller(
  215 + 'GuideboardManageFormCtrl',
  216 + [
  217 + 'GuideboardManageService',
  218 + '$stateParams',
  219 + '$state',
  220 + '$scope',
  221 + function(service, $stateParams, $state, $scope) {
  222 + var self = this;
  223 + var Gb = service.getGbQueryClass();
  224 +
  225 + // 欲保存的表单信息,双向绑定
  226 + self.guideboardManageForForm = new Gb;
  227 + self.guideboardManageForForm.xl = {};
  228 +
  229 + // 如果是修改,获取传过来的id,从后台获取一份数据,用于绑定页面form值
  230 + var id = $stateParams.id;
  231 + if (id) {
  232 + Gb.get({id: id}, function(value) {
  233 + self.guideboardManageForForm = value;
  234 + });
  235 + }
  236 + // form提交方法
  237 + self.submit = function() {
  238 + console.log($scope);
  239 + console.log(self.guideboardManageForForm);
  240 +
  241 + self.guideboardManageForForm.lpType = "普通路牌";
  242 + self.guideboardManageForForm.$save(function() {
  243 + $state.go("guideboardManage");
  244 + });
  245 + };
  246 +
  247 + }
  248 + ]
  249 +);
  250 +
  251 +// detail.html控制器
  252 +angular.module('ScheduleApp').controller(
  253 + 'GuideboardManageDetailCtrl',
  254 + [
  255 + 'GuideboardManageService',
  256 + '$stateParams',
  257 + function(service, $stateParams) {
  258 + var self = this;
  259 + var Gb = service.getGbQueryClass();
  260 + var id = $stateParams.id;
  261 +
  262 + self.title = "";
  263 + self.guideboardForDetail = {};
  264 +
  265 + // 当转向到此页面时,就获取明细信息并绑定
  266 + Gb.get({id: id}, function(result) {
  267 + self.guideboardForDetail = result.data;
  268 + self.title = "路牌 " + self.guideboardForDetail.lpName + " 详细信息";
  269 + });
  270 + }
  271 + ]
  272 +);
  273 +
  274 +
src/main/resources/static/pages/scheduleApp/module/core/guideboardManage/route.js
1 -// ui route 配置  
2 -  
3 -/** 路牌管理配置所有模块页面route */  
4 -ScheduleApp.config([  
5 - '$stateProvider',  
6 - '$urlRouterProvider',  
7 - function($stateProvider, $urlRouterProvider) {  
8 - // 默认路由  
9 - //$urlRouterProvider.otherwise('/busConfig.html');  
10 -  
11 - $stateProvider  
12 - .state("guideboardManage", { // index页面  
13 - url: '/guideboardManage',  
14 - views: {  
15 - "": {  
16 - templateUrl: 'pages/scheduleApp/module/core/guideboardManage/index.html'  
17 - },  
18 - "guideboardManage_list@guideboardManage": {  
19 - templateUrl: 'pages/scheduleApp/module/core/guideboardManage/list.html'  
20 - }  
21 - },  
22 -  
23 - resolve: {  
24 - deps: ['$ocLazyLoad', function($ocLazyLoad) {  
25 - return $ocLazyLoad.load({  
26 - name: 'guideboardManage_module',  
27 - insertBefore: '#ng_load_plugins_before', // 动态载入模块时放置的位置  
28 - files: [  
29 - "assets/bower_components/angular-ui-select/dist/select.min.css",  
30 - "assets/bower_components/angular-ui-select/dist/select.min.js",  
31 - "assets/bower_components/angular-file-upload/dist/angular-file-upload.min.js",  
32 - "pages/scheduleApp/module/core/guideboardManage/module.js"  
33 - ]  
34 - });  
35 - }]  
36 - }  
37 - })  
38 - .state('guideboardManage_form', { // 添加路牌form  
39 - url: '/guideboardManage_form',  
40 - views: {  
41 - '': {templateUrl: 'pages/scheduleApp/module/core/guideboardManage/form.html'}  
42 - },  
43 - resolve: {  
44 - deps: ['$ocLazyLoad', function($ocLazyLoad) {  
45 - return $ocLazyLoad.load({  
46 - name: 'guideboardManage_form_module',  
47 - insertBefore: '#ng_load_plugins_before',  
48 - files: [  
49 - 'assets/bower_components/angular-ui-select/dist/select.min.css',  
50 - 'assets/bower_components/angular-ui-select/dist/select.min.js',  
51 - 'pages/scheduleApp/module/core/guideboardManage/module.js'  
52 - ]  
53 - });  
54 - }]  
55 - }  
56 - })  
57 - .state('guideboardManage_edit', { // 修改路牌form  
58 - url: '/guideboardManage_edit/:id',  
59 - views: {  
60 - '': {templateUrl: 'pages/scheduleApp/module/core/guideboardManage/edit.html'}  
61 - },  
62 - resolve: {  
63 - deps: ['$ocLazyLoad', function($ocLazyLoad) {  
64 - return $ocLazyLoad.load({  
65 - name: 'guideboardManage_edit_module',  
66 - insertBefore: '#ng_load_plugins_before',  
67 - files: [  
68 - 'assets/bower_components/angular-ui-select/dist/select.min.css',  
69 - 'assets/bower_components/angular-ui-select/dist/select.min.js',  
70 - 'pages/scheduleApp/module/core/guideboardManage/module.js'  
71 - ]  
72 - });  
73 - }]  
74 - }  
75 - })  
76 - .state("guideboardManage_detail", { // 详细信息页面  
77 - url: '/guideboardManage_detail/:id',  
78 - views: {  
79 - "": {templateUrl: 'pages/scheduleApp/module/core/guideboardManage/detail.html'}  
80 - },  
81 - resolve: {  
82 - deps: ['$ocLazyLoad', function($ocLazyLoad) {  
83 - return $ocLazyLoad.load({  
84 - name: 'guideboardManage_detail_module',  
85 - insertBefore: '#ng_load_plugins_before', // 动态载入模块时放置的位置  
86 - files: [  
87 - "pages/scheduleApp/module/core/guideboardManage/module.js"  
88 - ]  
89 - });  
90 - }]  
91 - }  
92 - })  
93 -  
94 - 1 +// ui route 配置
  2 +
  3 +/** 路牌管理配置所有模块页面route */
  4 +ScheduleApp.config([
  5 + '$stateProvider',
  6 + '$urlRouterProvider',
  7 + function($stateProvider, $urlRouterProvider) {
  8 + // 默认路由
  9 + //$urlRouterProvider.otherwise('/busConfig.html');
  10 +
  11 + $stateProvider
  12 + .state("guideboardManage", { // index页面
  13 + url: '/guideboardManage',
  14 + views: {
  15 + "": {
  16 + templateUrl: 'pages/scheduleApp/module/core/guideboardManage/index.html'
  17 + },
  18 + "guideboardManage_list@guideboardManage": {
  19 + templateUrl: 'pages/scheduleApp/module/core/guideboardManage/list.html'
  20 + }
  21 + },
  22 +
  23 + resolve: {
  24 + deps: ['$ocLazyLoad', function($ocLazyLoad) {
  25 + return $ocLazyLoad.load({
  26 + name: 'guideboardManage_module',
  27 + insertBefore: '#ng_load_plugins_before', // 动态载入模块时放置的位置
  28 + files: [
  29 + "assets/bower_components/angular-ui-select/dist/select.min.css",
  30 + "assets/bower_components/angular-ui-select/dist/select.min.js",
  31 + "assets/bower_components/angular-file-upload/dist/angular-file-upload.min.js",
  32 + "pages/scheduleApp/module/core/guideboardManage/module.js"
  33 + ]
  34 + });
  35 + }]
  36 + }
  37 + })
  38 + .state('guideboardManage_form', { // 添加路牌form
  39 + url: '/guideboardManage_form',
  40 + views: {
  41 + '': {templateUrl: 'pages/scheduleApp/module/core/guideboardManage/form.html'}
  42 + },
  43 + resolve: {
  44 + deps: ['$ocLazyLoad', function($ocLazyLoad) {
  45 + return $ocLazyLoad.load({
  46 + name: 'guideboardManage_form_module',
  47 + insertBefore: '#ng_load_plugins_before',
  48 + files: [
  49 + 'assets/bower_components/angular-ui-select/dist/select.min.css',
  50 + 'assets/bower_components/angular-ui-select/dist/select.min.js',
  51 + 'pages/scheduleApp/module/core/guideboardManage/module.js'
  52 + ]
  53 + });
  54 + }]
  55 + }
  56 + })
  57 + .state('guideboardManage_edit', { // 修改路牌form
  58 + url: '/guideboardManage_edit/:id',
  59 + views: {
  60 + '': {templateUrl: 'pages/scheduleApp/module/core/guideboardManage/edit.html'}
  61 + },
  62 + resolve: {
  63 + deps: ['$ocLazyLoad', function($ocLazyLoad) {
  64 + return $ocLazyLoad.load({
  65 + name: 'guideboardManage_edit_module',
  66 + insertBefore: '#ng_load_plugins_before',
  67 + files: [
  68 + 'assets/bower_components/angular-ui-select/dist/select.min.css',
  69 + 'assets/bower_components/angular-ui-select/dist/select.min.js',
  70 + 'pages/scheduleApp/module/core/guideboardManage/module.js'
  71 + ]
  72 + });
  73 + }]
  74 + }
  75 + })
  76 + .state("guideboardManage_detail", { // 详细信息页面
  77 + url: '/guideboardManage_detail/:id',
  78 + views: {
  79 + "": {templateUrl: 'pages/scheduleApp/module/core/guideboardManage/detail.html'}
  80 + },
  81 + resolve: {
  82 + deps: ['$ocLazyLoad', function($ocLazyLoad) {
  83 + return $ocLazyLoad.load({
  84 + name: 'guideboardManage_detail_module',
  85 + insertBefore: '#ng_load_plugins_before', // 动态载入模块时放置的位置
  86 + files: [
  87 + "pages/scheduleApp/module/core/guideboardManage/module.js"
  88 + ]
  89 + });
  90 + }]
  91 + }
  92 + })
  93 +
  94 +
95 }]); 95 }]);
96 \ No newline at end of file 96 \ No newline at end of file
src/main/resources/static/pages/scheduleApp/module/core/guideboardManage/service.js
1 -// 路牌管理service  
2 -angular.module('ScheduleApp').factory('GuideboardManageService_g', ['$resource', function($resource) {  
3 - return {  
4 - rest: $resource(  
5 - '/gic/:id',  
6 - {order: 'xl,isCancel', direction: 'DESC,ASC', id: '@id_route'},  
7 - {  
8 - list: {  
9 - method: 'GET',  
10 - params: {  
11 - page: 0  
12 - },  
13 - transformResponse: function(rs) {  
14 - var dst = angular.fromJson(rs);  
15 - if (dst.status == 'SUCCESS') {  
16 - return dst.data;  
17 - } else {  
18 - return dst;  
19 - }  
20 - }  
21 - },  
22 - get: {  
23 - method: 'GET',  
24 - transformResponse: function(rs) {  
25 - var dst = angular.fromJson(rs);  
26 - if (dst.status == 'SUCCESS') {  
27 - return dst.data;  
28 - } else {  
29 - return dst;  
30 - }  
31 - }  
32 - },  
33 - save: {  
34 - method: 'POST'  
35 - }  
36 - // 内部还有默认的方法delete  
37 - }  
38 - )  
39 - }; 1 +// 路牌管理service
  2 +angular.module('ScheduleApp').factory('GuideboardManageService_g', ['$resource', function($resource) {
  3 + return {
  4 + rest: $resource(
  5 + '/gic/:id',
  6 + {order: 'xl,isCancel', direction: 'DESC,ASC', id: '@id_route'},
  7 + {
  8 + list: {
  9 + method: 'GET',
  10 + params: {
  11 + page: 0
  12 + },
  13 + transformResponse: function(rs) {
  14 + var dst = angular.fromJson(rs);
  15 + if (dst.status == 'SUCCESS') {
  16 + return dst.data;
  17 + } else {
  18 + return dst;
  19 + }
  20 + }
  21 + },
  22 + get: {
  23 + method: 'GET',
  24 + transformResponse: function(rs) {
  25 + var dst = angular.fromJson(rs);
  26 + if (dst.status == 'SUCCESS') {
  27 + return dst.data;
  28 + } else {
  29 + return dst;
  30 + }
  31 + }
  32 + },
  33 + save: {
  34 + method: 'POST'
  35 + }
  36 + // 内部还有默认的方法delete
  37 + }
  38 + )
  39 + };
40 }]); 40 }]);
41 \ No newline at end of file 41 \ No newline at end of file
src/main/resources/static/pages/scheduleApp/module/core/rerunManage/service.js
1 -// 套跑管理service  
2 -angular.module('ScheduleApp').factory('rerunManageService_g', ['$resource', function($resource) {  
3 - return {  
4 - rest: $resource(  
5 - 'rms/:id',  
6 - {order: 'rerunXl.id,isCancel', direction: 'ASC', id: '@id_route'},  
7 - {  
8 - list: {  
9 - method: 'GET',  
10 - params: {  
11 - page: 0  
12 - }  
13 - },  
14 - get: {  
15 - method: 'GET'  
16 - },  
17 - save: {  
18 - method: 'POST'  
19 - },  
20 - delete: {  
21 - method: 'DELETE'  
22 - }  
23 - }  
24 - )  
25 - }; 1 +// 套跑管理service
  2 +angular.module('ScheduleApp').factory('rerunManageService_g', ['$resource', function($resource) {
  3 + return {
  4 + rest: $resource(
  5 + 'rms/:id',
  6 + {order: 'rerunXl.id,isCancel', direction: 'ASC', id: '@id_route'},
  7 + {
  8 + list: {
  9 + method: 'GET',
  10 + params: {
  11 + page: 0
  12 + }
  13 + },
  14 + get: {
  15 + method: 'GET'
  16 + },
  17 + save: {
  18 + method: 'POST'
  19 + },
  20 + delete: {
  21 + method: 'DELETE'
  22 + }
  23 + }
  24 + )
  25 + };
26 }]); 26 }]);
27 \ No newline at end of file 27 \ No newline at end of file
src/main/resources/static/pages/scheduleApp/module/core/schedulePlanManage/service.js
1 -// 排班计划管理service  
2 -angular.module('ScheduleApp').factory('SchedulePlanManageService_g', ['$resource', function($resource) {  
3 - return {  
4 - rest : $resource(  
5 - '/spc/:id',  
6 - {order: 'xl.id,createDate', direction: 'DESC,DESC', id: '@id_route'},  
7 - {  
8 - list: {  
9 - method: 'GET',  
10 - params: {  
11 - page: 0  
12 - }  
13 - },  
14 - get: {  
15 - method: 'GET'  
16 - },  
17 - save: {  
18 - method: 'POST'  
19 - },  
20 - delete: {  
21 - method: 'DELETE'  
22 - }  
23 - }  
24 - ),  
25 - tommorw: $resource(  
26 - '/spc/tommorw',  
27 - {},  
28 - {  
29 - list: {  
30 - method: 'GET'  
31 - }  
32 - }  
33 - )  
34 - };  
35 -}]);  
36 -  
37 -// 排班计划明细管理service  
38 -angular.module('ScheduleApp').factory('SchedulePlanInfoManageService_g', ['$resource', function($resource) {  
39 - return {  
40 - rest : $resource(  
41 - '/spic/:id',  
42 - {order: 'scheduleDate,lp,fcno', direction: 'ASC,ASC,ASC', id: '@id_route'},  
43 - {  
44 - list: {  
45 - method: 'GET',  
46 - params: {  
47 - page: 0  
48 - }  
49 - },  
50 - get: {  
51 - method: 'GET'  
52 - },  
53 - save: {  
54 - method: 'POST'  
55 - }  
56 - }  
57 - ),  
58 - groupinfo : $resource(  
59 - '/spic/groupinfos/:xlid/:sdate',  
60 - {},  
61 - {  
62 - list: {  
63 - method: 'GET',  
64 - isArray: true  
65 - }  
66 - }  
67 - ),  
68 - updateGroupInfo : $resource(  
69 - '/spic/groupinfos/update',  
70 - {},  
71 - {  
72 - update: {  
73 - method: 'POST'  
74 - }  
75 - }  
76 - )  
77 - }; 1 +// 排班计划管理service
  2 +angular.module('ScheduleApp').factory('SchedulePlanManageService_g', ['$resource', function($resource) {
  3 + return {
  4 + rest : $resource(
  5 + '/spc/:id',
  6 + {order: 'xl.id,createDate', direction: 'DESC,DESC', id: '@id_route'},
  7 + {
  8 + list: {
  9 + method: 'GET',
  10 + params: {
  11 + page: 0
  12 + }
  13 + },
  14 + get: {
  15 + method: 'GET'
  16 + },
  17 + save: {
  18 + method: 'POST'
  19 + },
  20 + delete: {
  21 + method: 'DELETE'
  22 + }
  23 + }
  24 + ),
  25 + tommorw: $resource(
  26 + '/spc/tommorw',
  27 + {},
  28 + {
  29 + list: {
  30 + method: 'GET'
  31 + }
  32 + }
  33 + )
  34 + };
  35 +}]);
  36 +
  37 +// 排班计划明细管理service
  38 +angular.module('ScheduleApp').factory('SchedulePlanInfoManageService_g', ['$resource', function($resource) {
  39 + return {
  40 + rest : $resource(
  41 + '/spic/:id',
  42 + {order: 'scheduleDate,lp,fcno', direction: 'ASC,ASC,ASC', id: '@id_route'},
  43 + {
  44 + list: {
  45 + method: 'GET',
  46 + params: {
  47 + page: 0
  48 + }
  49 + },
  50 + get: {
  51 + method: 'GET'
  52 + },
  53 + save: {
  54 + method: 'POST'
  55 + }
  56 + }
  57 + ),
  58 + groupinfo : $resource(
  59 + '/spic/groupinfos/:xlid/:sdate',
  60 + {},
  61 + {
  62 + list: {
  63 + method: 'GET',
  64 + isArray: true
  65 + }
  66 + }
  67 + ),
  68 + updateGroupInfo : $resource(
  69 + '/spic/groupinfos/update',
  70 + {},
  71 + {
  72 + update: {
  73 + method: 'POST'
  74 + }
  75 + }
  76 + )
  77 + };
78 }]); 78 }]);
79 \ No newline at end of file 79 \ No newline at end of file
src/main/resources/static/pages/scheduleApp/module/core/scheduleRuleManage/service.js
1 -// 排班管理service  
2 -angular.module('ScheduleApp').factory('ScheduleRuleManageService_g', ['$resource', function($resource) {  
3 - return {  
4 - rest: $resource(  
5 - '/sr1fc/:id',  
6 - {order: 'createDate', direction: 'DESC', id: '@id_route'},  
7 - {  
8 - list: {  
9 - method: 'GET',  
10 - params: {  
11 - page: 0  
12 - }  
13 - },  
14 - get: {  
15 - method: 'GET'  
16 - },  
17 - save: {  
18 - method: 'POST'  
19 - },  
20 - delete: {  
21 - method: 'DELETE'  
22 - }  
23 - }  
24 - )  
25 - };  
26 -}]); 1 +// 排班管理service
  2 +angular.module('ScheduleApp').factory('ScheduleRuleManageService_g', ['$resource', function($resource) {
  3 + return {
  4 + rest: $resource(
  5 + '/sr1fc/:id',
  6 + {order: 'createDate', direction: 'DESC', id: '@id_route'},
  7 + {
  8 + list: {
  9 + method: 'GET',
  10 + params: {
  11 + page: 0
  12 + }
  13 + },
  14 + get: {
  15 + method: 'GET'
  16 + },
  17 + save: {
  18 + method: 'POST'
  19 + },
  20 + delete: {
  21 + method: 'DELETE'
  22 + }
  23 + }
  24 + )
  25 + };
  26 +}]);
src/main/resources/static/pages/scheduleApp/module/core/ttInfoManage/route.js
1 -// ui route 配置  
2 -  
3 -/** 时刻表管理配置route */  
4 -ScheduleApp.config([  
5 - '$stateProvider',  
6 - '$urlRouterProvider',  
7 - function($stateProvider, $urlRouterProvider) {  
8 - // 默认路由  
9 - //$urlRouterProvider.otherwise('/busConfig.html');  
10 -  
11 - $stateProvider  
12 - .state("ttInfoManage", { // index页面  
13 - url: '/ttInfoManage',  
14 - views: {  
15 - "": {  
16 - templateUrl: 'pages/scheduleApp/module/core/ttInfoManage/index.html'  
17 - },  
18 - "ttInfoManage_list@ttInfoManage": {  
19 - templateUrl: 'pages/scheduleApp/module/core/ttInfoManage/list.html'  
20 - }  
21 - },  
22 -  
23 - resolve: {  
24 - deps: ['$ocLazyLoad', function($ocLazyLoad) {  
25 - return $ocLazyLoad.load({  
26 - name: 'ttInfoManage_module',  
27 - insertBefore: '#ng_load_plugins_before', // 动态载入模块时放置的位置  
28 - files: [  
29 - "assets/bower_components/angular-ui-select/dist/select.min.css",  
30 - "assets/bower_components/angular-ui-select/dist/select.min.js",  
31 - "pages/scheduleApp/module/core/ttInfoManage/module.js"  
32 - ]  
33 - });  
34 - }]  
35 - }  
36 - })  
37 - .state("ttInfoManage_form", { // 添加时刻表信息form  
38 - url: '/ttInfoManage_form',  
39 - views: {  
40 - "": {templateUrl: 'pages/scheduleApp/module/core/ttInfoManage/form.html'}  
41 - },  
42 - resolve: {  
43 - deps: ['$ocLazyLoad', function($ocLazyLoad) {  
44 - return $ocLazyLoad.load({  
45 - name: 'ttInfoManage_form_module',  
46 - insertBefore: '#ng_load_plugins_before', // 动态载入模块时放置的位置  
47 - files: [  
48 - "assets/bower_components/angular-ui-select/dist/select.min.css",  
49 - "assets/bower_components/angular-ui-select/dist/select.min.js",  
50 - "pages/scheduleApp/module/core/ttInfoManage/module.js"  
51 - ]  
52 - });  
53 - }]  
54 - }  
55 - })  
56 - .state("ttInfoManage_edit", { // 修改时刻表信息form  
57 - url: '/ttInfoManage_edit/:id',  
58 - views: {  
59 - "": {templateUrl: 'pages/scheduleApp/module/core/ttInfoManage/edit.html'}  
60 - },  
61 - resolve: {  
62 - deps: ['$ocLazyLoad', function($ocLazyLoad) {  
63 - return $ocLazyLoad.load({  
64 - name: 'ttInfoManage_edit_module',  
65 - insertBefore: '#ng_load_plugins_before', // 动态载入模块时放置的位置  
66 - files: [  
67 - "assets/bower_components/angular-ui-select/dist/select.min.css",  
68 - "assets/bower_components/angular-ui-select/dist/select.min.js",  
69 - "pages/scheduleApp/module/core/ttInfoManage/module.js"  
70 - ]  
71 - });  
72 - }]  
73 - }  
74 - })  
75 - .state("ttInfoManage_detail", { // 时刻表详细信息  
76 - url: '/ttInfoManage_detail/:id',  
77 - views: {  
78 - "": {templateUrl: 'pages/scheduleApp/module/core/ttInfoManage/detail.html'}  
79 - },  
80 - resolve: {  
81 - deps: ['$ocLazyLoad', function($ocLazyLoad) {  
82 - return $ocLazyLoad.load({  
83 - name: 'ttInfoManage_detail_module',  
84 - insertBefore: '#ng_load_plugins_before', // 动态载入模块时放置的位置  
85 - files: [  
86 - "pages/scheduleApp/module/core/ttInfoManage/module.js"  
87 - ]  
88 - });  
89 - }]  
90 - }  
91 - })  
92 - .state('ttInfoManage_test', { // TODO:测试页面  
93 - url: '/ttInfoManage_test',  
94 - views: {  
95 - '': {templateUrl: 'pages/scheduleApp/module/core/ttInfoManage/test.html'}  
96 - },  
97 - resolve: {  
98 - deps: ['$ocLazyLoad', function($ocLazyLoad) {  
99 - return $ocLazyLoad.load({  
100 - name: 'ttInfoManage_test_module',  
101 - insertBefore: '#ng_load_plugins_before', // 动态载入模块时放置的位置  
102 - files: [  
103 - 'pages/scheduleApp/module/core/ttInfoManage/test.js'  
104 - ]  
105 - });  
106 - }]  
107 - }  
108 - })  
109 -  
110 -  
111 - } 1 +// ui route 配置
  2 +
  3 +/** 时刻表管理配置route */
  4 +ScheduleApp.config([
  5 + '$stateProvider',
  6 + '$urlRouterProvider',
  7 + function($stateProvider, $urlRouterProvider) {
  8 + // 默认路由
  9 + //$urlRouterProvider.otherwise('/busConfig.html');
  10 +
  11 + $stateProvider
  12 + .state("ttInfoManage", { // index页面
  13 + url: '/ttInfoManage',
  14 + views: {
  15 + "": {
  16 + templateUrl: 'pages/scheduleApp/module/core/ttInfoManage/index.html'
  17 + },
  18 + "ttInfoManage_list@ttInfoManage": {
  19 + templateUrl: 'pages/scheduleApp/module/core/ttInfoManage/list.html'
  20 + }
  21 + },
  22 +
  23 + resolve: {
  24 + deps: ['$ocLazyLoad', function($ocLazyLoad) {
  25 + return $ocLazyLoad.load({
  26 + name: 'ttInfoManage_module',
  27 + insertBefore: '#ng_load_plugins_before', // 动态载入模块时放置的位置
  28 + files: [
  29 + "assets/bower_components/angular-ui-select/dist/select.min.css",
  30 + "assets/bower_components/angular-ui-select/dist/select.min.js",
  31 + "pages/scheduleApp/module/core/ttInfoManage/module.js"
  32 + ]
  33 + });
  34 + }]
  35 + }
  36 + })
  37 + .state("ttInfoManage_form", { // 添加时刻表信息form
  38 + url: '/ttInfoManage_form',
  39 + views: {
  40 + "": {templateUrl: 'pages/scheduleApp/module/core/ttInfoManage/form.html'}
  41 + },
  42 + resolve: {
  43 + deps: ['$ocLazyLoad', function($ocLazyLoad) {
  44 + return $ocLazyLoad.load({
  45 + name: 'ttInfoManage_form_module',
  46 + insertBefore: '#ng_load_plugins_before', // 动态载入模块时放置的位置
  47 + files: [
  48 + "assets/bower_components/angular-ui-select/dist/select.min.css",
  49 + "assets/bower_components/angular-ui-select/dist/select.min.js",
  50 + "pages/scheduleApp/module/core/ttInfoManage/module.js"
  51 + ]
  52 + });
  53 + }]
  54 + }
  55 + })
  56 + .state("ttInfoManage_edit", { // 修改时刻表信息form
  57 + url: '/ttInfoManage_edit/:id',
  58 + views: {
  59 + "": {templateUrl: 'pages/scheduleApp/module/core/ttInfoManage/edit.html'}
  60 + },
  61 + resolve: {
  62 + deps: ['$ocLazyLoad', function($ocLazyLoad) {
  63 + return $ocLazyLoad.load({
  64 + name: 'ttInfoManage_edit_module',
  65 + insertBefore: '#ng_load_plugins_before', // 动态载入模块时放置的位置
  66 + files: [
  67 + "assets/bower_components/angular-ui-select/dist/select.min.css",
  68 + "assets/bower_components/angular-ui-select/dist/select.min.js",
  69 + "pages/scheduleApp/module/core/ttInfoManage/module.js"
  70 + ]
  71 + });
  72 + }]
  73 + }
  74 + })
  75 + .state("ttInfoManage_detail", { // 时刻表详细信息
  76 + url: '/ttInfoManage_detail/:id',
  77 + views: {
  78 + "": {templateUrl: 'pages/scheduleApp/module/core/ttInfoManage/detail.html'}
  79 + },
  80 + resolve: {
  81 + deps: ['$ocLazyLoad', function($ocLazyLoad) {
  82 + return $ocLazyLoad.load({
  83 + name: 'ttInfoManage_detail_module',
  84 + insertBefore: '#ng_load_plugins_before', // 动态载入模块时放置的位置
  85 + files: [
  86 + "pages/scheduleApp/module/core/ttInfoManage/module.js"
  87 + ]
  88 + });
  89 + }]
  90 + }
  91 + })
  92 + .state('ttInfoManage_test', { // TODO:测试页面
  93 + url: '/ttInfoManage_test',
  94 + views: {
  95 + '': {templateUrl: 'pages/scheduleApp/module/core/ttInfoManage/test.html'}
  96 + },
  97 + resolve: {
  98 + deps: ['$ocLazyLoad', function($ocLazyLoad) {
  99 + return $ocLazyLoad.load({
  100 + name: 'ttInfoManage_test_module',
  101 + insertBefore: '#ng_load_plugins_before', // 动态载入模块时放置的位置
  102 + files: [
  103 + 'pages/scheduleApp/module/core/ttInfoManage/test.js'
  104 + ]
  105 + });
  106 + }]
  107 + }
  108 + })
  109 +
  110 +
  111 + }
112 ]); 112 ]);
113 \ No newline at end of file 113 \ No newline at end of file
src/main/resources/static/pages/scheduleApp/module/core/ttInfoManage/service.js
1 -// 时刻表管理service  
2 -angular.module('ScheduleApp').factory('TimeTableManageService_g', ['$resource', function($resource) {  
3 - return {  
4 - rest: $resource(  
5 - '/tic/:id',  
6 - {order: 'xl,isCancel,isEnableDisTemplate,qyrq', direction: 'DESC,ASC,DESC,DESC', id: '@id'},  
7 - {  
8 - list: {  
9 - method: 'GET',  
10 - params: {  
11 - page: 0  
12 - }  
13 - }  
14 - }  
15 - )  
16 - };  
17 -}]);  
18 -  
19 -// 时刻表明细管理service  
20 -angular.module('ScheduleApp').factory('TimeTableDetailManageService_g', ['$resource', function($resource) {  
21 - return {  
22 - rest: $resource(  
23 - '/tidc/:id',  
24 - {order: 'createDate', direction: 'DESC', id: '@id_route'},  
25 - {  
26 - get: {  
27 - method: 'GET'  
28 - },  
29 - save: {  
30 - method: 'POST'  
31 - }  
32 - }  
33 - ),  
34 - import: $resource(  
35 - '/tidc/importfile',  
36 - {},  
37 - {  
38 - do: {  
39 - method: 'POST',  
40 - headers: {  
41 - 'Content-Type': 'application/x-www-form-urlencoded'  
42 - },  
43 - transformRequest: function(obj) {  
44 - var str = [];  
45 - for (var p in obj) {  
46 - str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));  
47 - }  
48 - return str.join("&");  
49 - }  
50 - }  
51 - }  
52 - ),  
53 - edit: $resource(  
54 - '/tidc/edit/:xlid/:ttid',  
55 - {},  
56 - {  
57 - list: {  
58 - method: 'GET'  
59 - }  
60 - }  
61 - ),  
62 - bcdetails: $resource(  
63 - '/tidc/bcdetail',  
64 - {},  
65 - {  
66 - list: {  
67 - method: 'GET',  
68 - isArray: true  
69 - }  
70 - }  
71 - ),  
72 - dataTools: $resource(  
73 - '/tidc/:type',  
74 - {},  
75 - {  
76 - dataExport: {  
77 - method: 'GET',  
78 - responseType: "arraybuffer",  
79 - params: {  
80 - type: "dataExportExt"  
81 - },  
82 - transformResponse: function(data, headers){  
83 - return {data : data};  
84 - }  
85 - }  
86 - }  
87 - )  
88 -  
89 - // TODO:导入数据  
90 - }; 1 +// 时刻表管理service
  2 +angular.module('ScheduleApp').factory('TimeTableManageService_g', ['$resource', function($resource) {
  3 + return {
  4 + rest: $resource(
  5 + '/tic/:id',
  6 + {order: 'xl,isCancel,isEnableDisTemplate,qyrq', direction: 'DESC,ASC,DESC,DESC', id: '@id'},
  7 + {
  8 + list: {
  9 + method: 'GET',
  10 + params: {
  11 + page: 0
  12 + }
  13 + }
  14 + }
  15 + )
  16 + };
  17 +}]);
  18 +
  19 +// 时刻表明细管理service
  20 +angular.module('ScheduleApp').factory('TimeTableDetailManageService_g', ['$resource', function($resource) {
  21 + return {
  22 + rest: $resource(
  23 + '/tidc/:id',
  24 + {order: 'createDate', direction: 'DESC', id: '@id_route'},
  25 + {
  26 + get: {
  27 + method: 'GET'
  28 + },
  29 + save: {
  30 + method: 'POST'
  31 + }
  32 + }
  33 + ),
  34 + import: $resource(
  35 + '/tidc/importfile',
  36 + {},
  37 + {
  38 + do: {
  39 + method: 'POST',
  40 + headers: {
  41 + 'Content-Type': 'application/x-www-form-urlencoded'
  42 + },
  43 + transformRequest: function(obj) {
  44 + var str = [];
  45 + for (var p in obj) {
  46 + str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
  47 + }
  48 + return str.join("&");
  49 + }
  50 + }
  51 + }
  52 + ),
  53 + edit: $resource(
  54 + '/tidc/edit/:xlid/:ttid',
  55 + {},
  56 + {
  57 + list: {
  58 + method: 'GET'
  59 + }
  60 + }
  61 + ),
  62 + bcdetails: $resource(
  63 + '/tidc/bcdetail',
  64 + {},
  65 + {
  66 + list: {
  67 + method: 'GET',
  68 + isArray: true
  69 + }
  70 + }
  71 + ),
  72 + dataTools: $resource(
  73 + '/tidc/:type',
  74 + {},
  75 + {
  76 + dataExport: {
  77 + method: 'GET',
  78 + responseType: "arraybuffer",
  79 + params: {
  80 + type: "dataExportExt"
  81 + },
  82 + transformResponse: function(data, headers){
  83 + return {data : data};
  84 + }
  85 + }
  86 + }
  87 + )
  88 +
  89 + // TODO:导入数据
  90 + };
91 }]); 91 }]);
92 \ No newline at end of file 92 \ No newline at end of file
src/main/resources/static/pages/scheduleApp/module/core/ttInfoManage/test.html
1 -<h1>测试新的改版select指令</h1>  
2 -  
3 -<div ng-controller="TestCtrl as ctrl">  
4 - <form name="myForm" class="form-horizontal" ng-submit="ctrl.sub()">  
5 - <div class="form-body">  
6 - <div class="form-group">  
7 - <label class="col-md-2 control-label">测试文本:</label>  
8 - <div class="col-md-3">  
9 - <input type="text" class="form-control" name="txt" ng-model="ctrl.say"/>  
10 - </div>  
11 - </div>  
12 - <div class="form-group">  
13 - <my-select name="mtxt" ng-model="ctrl.say" required>  
14 - <h1>{{ctrl.say}}</h1>  
15 - </my-select>  
16 - </div>  
17 - </div>  
18 - <div class="form-actions">  
19 - <div class="row">  
20 - <button type="submit" class="btn green" ng-disabled="!myForm.$valid">  
21 - <i class="fa fa-check"></i>  
22 - 提交  
23 - </button>  
24 - </div>  
25 - </div>  
26 - </form>  
27 -</div> 1 +<h1>测试新的改版select指令</h1>
  2 +
  3 +<div ng-controller="TestCtrl as ctrl">
  4 + <form name="myForm" class="form-horizontal" ng-submit="ctrl.sub()">
  5 + <div class="form-body">
  6 + <div class="form-group">
  7 + <label class="col-md-2 control-label">测试文本:</label>
  8 + <div class="col-md-3">
  9 + <input type="text" class="form-control" name="txt" ng-model="ctrl.say"/>
  10 + </div>
  11 + </div>
  12 + <div class="form-group">
  13 + <my-select name="mtxt" ng-model="ctrl.say" required>
  14 + <h1>{{ctrl.say}}</h1>
  15 + </my-select>
  16 + </div>
  17 + </div>
  18 + <div class="form-actions">
  19 + <div class="row">
  20 + <button type="submit" class="btn green" ng-disabled="!myForm.$valid">
  21 + <i class="fa fa-check"></i>
  22 + 提交
  23 + </button>
  24 + </div>
  25 + </div>
  26 + </form>
  27 +</div>
src/main/resources/static/pages/scheduleApp/module/core/ttInfoManage/test.js
1 -// 测试controller  
2 -  
3 -angular.module('ScheduleApp').controller('TestCtrl', [  
4 - function() {  
5 - var self = this;  
6 - self.say = "say something";  
7 -  
8 - self.sub = function() {  
9 - alert("submit...");  
10 - };  
11 -  
12 - self.loaddata = function() {  
13 - alert("数据数据数据")  
14 - };  
15 - } 1 +// 测试controller
  2 +
  3 +angular.module('ScheduleApp').controller('TestCtrl', [
  4 + function() {
  5 + var self = this;
  6 + self.say = "say something";
  7 +
  8 + self.sub = function() {
  9 + alert("submit...");
  10 + };
  11 +
  12 + self.loaddata = function() {
  13 + alert("数据数据数据")
  14 + };
  15 + }
16 ]); 16 ]);
17 \ No newline at end of file 17 \ No newline at end of file
src/main/resources/static/real_control_v2/css/pace.css
1 -.pace {  
2 - width: 140px;  
3 - height: 300px;  
4 - margin-left: calc(50% - 70px);  
5 -  
6 - z-index: 2000;  
7 - -webkit-transform: scale(0);  
8 - -moz-transform: scale(0);  
9 - -ms-transform: scale(0);  
10 - -o-transform: scale(0);  
11 - transform: scale(0);  
12 - opacity: 0;  
13 - -webkit-transition: all 2s linear 0s;  
14 - -moz-transition: all 2s linear 0s;  
15 - transition: all 2s linear 0s;  
16 -}  
17 -  
18 -.pace .text{  
19 - position: absolute;  
20 - bottom: -50px;  
21 - font-size: 12px;  
22 - transform: scale(4);  
23 - color: grey;  
24 -}  
25 -  
26 -.pace.pace-active {  
27 - -webkit-transform: scale(.25);  
28 - -moz-transform: scale(.25);  
29 - -ms-transform: scale(.25);  
30 - -o-transform: scale(.25);  
31 - transform: scale(.25);  
32 - opacity: 1;  
33 -}  
34 -  
35 -.pace .pace-activity {  
36 - width: 140px;  
37 - height: 140px;  
38 - border-radius: 70px;  
39 - background: #29d;  
40 - position: absolute;  
41 - top: 0;  
42 - z-index: 1911;  
43 - -webkit-animation: pace-bounce 1s infinite;  
44 - -moz-animation: pace-bounce 1s infinite;  
45 - -o-animation: pace-bounce 1s infinite;  
46 - -ms-animation: pace-bounce 1s infinite;  
47 - animation: pace-bounce 1s infinite;  
48 -}  
49 -  
50 -.pace .pace-progress {  
51 - position: absolute;  
52 - display: block;  
53 - left: 50%;  
54 - bottom: 0;  
55 - z-index: 1910;  
56 - margin-left: -30px;  
57 - width: 60px;  
58 - height: 75px;  
59 - background: rgba(20, 20, 20, .1);  
60 - box-shadow: 0 0 20px 35px rgba(20, 20, 20, .1);  
61 - border-radius: 30px / 40px;  
62 - -webkit-transform: scaleY(.3) !important;  
63 - -moz-transform: scaleY(.3) !important;  
64 - -ms-transform: scaleY(.3) !important;  
65 - -o-transform: scaleY(.3) !important;  
66 - transform: scaleY(.3) !important;  
67 - -webkit-animation: pace-compress .5s infinite alternate;  
68 - -moz-animation: pace-compress .5s infinite alternate;  
69 - -o-animation: pace-compress .5s infinite alternate;  
70 - -ms-animation: pace-compress .5s infinite alternate;  
71 - animation: pace-compress .5s infinite alternate;  
72 -}  
73 -  
74 -@-webkit-keyframes pace-bounce {  
75 - 0% {  
76 - top: 0;  
77 - -webkit-animation-timing-function: ease-in;  
78 - }  
79 - 40% {}  
80 - 50% {  
81 - top: 140px;  
82 - height: 140px;  
83 - -webkit-animation-timing-function: ease-out;  
84 - }  
85 - 55% {  
86 - top: 160px;  
87 - height: 120px;  
88 - border-radius: 70px / 60px;  
89 - -webkit-animation-timing-function: ease-in;  
90 - }  
91 - 65% {  
92 - top: 120px;  
93 - height: 140px;  
94 - border-radius: 70px;  
95 - -webkit-animation-timing-function: ease-out;  
96 - }  
97 - 95% {  
98 - top: 0;  
99 - -webkit-animation-timing-function: ease-in;  
100 - }  
101 - 100% {  
102 - top: 0;  
103 - -webkit-animation-timing-function: ease-in;  
104 - }  
105 -}  
106 -  
107 -@-moz-keyframes pace-bounce {  
108 - 0% {  
109 - top: 0;  
110 - -moz-animation-timing-function: ease-in;  
111 - }  
112 - 40% {}  
113 - 50% {  
114 - top: 140px;  
115 - height: 140px;  
116 - -moz-animation-timing-function: ease-out;  
117 - }  
118 - 55% {  
119 - top: 160px;  
120 - height: 120px;  
121 - border-radius: 70px / 60px;  
122 - -moz-animation-timing-function: ease-in;  
123 - }  
124 - 65% {  
125 - top: 120px;  
126 - height: 140px;  
127 - border-radius: 70px;  
128 - -moz-animation-timing-function: ease-out;}  
129 - 95% {  
130 - top: 0;  
131 - -moz-animation-timing-function: ease-in;  
132 - }  
133 - 100% {top: 0;  
134 - -moz-animation-timing-function: ease-in;  
135 - }  
136 -}  
137 -  
138 -@keyframes pace-bounce {  
139 - 0% {  
140 - top: 0;  
141 - animation-timing-function: ease-in;  
142 - }  
143 - 50% {  
144 - top: 140px;  
145 - height: 140px;  
146 - animation-timing-function: ease-out;  
147 - }  
148 - 55% {  
149 - top: 160px;  
150 - height: 120px;  
151 - border-radius: 70px / 60px;  
152 - animation-timing-function: ease-in;  
153 - }  
154 - 65% {  
155 - top: 120px;  
156 - height: 140px;  
157 - border-radius: 70px;  
158 - animation-timing-function: ease-out;  
159 - }  
160 - 95% {  
161 - top: 0;  
162 - animation-timing-function: ease-in;  
163 - }  
164 - 100% {  
165 - top: 0;  
166 - animation-timing-function: ease-in;  
167 - }  
168 -}  
169 -  
170 -@-webkit-keyframes pace-compress {  
171 - 0% {  
172 - bottom: 0;  
173 - margin-left: -30px;  
174 - width: 60px;  
175 - height: 75px;  
176 - background: rgba(20, 20, 20, .1);  
177 - box-shadow: 0 0 20px 35px rgba(20, 20, 20, .1);  
178 - border-radius: 30px / 40px;  
179 - -webkit-animation-timing-function: ease-in;  
180 - }  
181 - 100% {  
182 - bottom: 30px;  
183 - margin-left: -10px;  
184 - width: 20px;  
185 - height: 5px;  
186 - background: rgba(20, 20, 20, .3);  
187 - box-shadow: 0 0 20px 35px rgba(20, 20, 20, .3);  
188 - border-radius: 20px / 20px;  
189 - -webkit-animation-timing-function: ease-out;  
190 - }  
191 -}  
192 -  
193 -@-moz-keyframes pace-compress {  
194 - 0% {  
195 - bottom: 0;  
196 - margin-left: -30px;  
197 - width: 60px;  
198 - height: 75px;  
199 - background: rgba(20, 20, 20, .1);  
200 - box-shadow: 0 0 20px 35px rgba(20, 20, 20, .1);  
201 - border-radius: 30px / 40px;  
202 - -moz-animation-timing-function: ease-in;  
203 - }  
204 - 100% {  
205 - bottom: 30px;  
206 - margin-left: -10px;  
207 - width: 20px;  
208 - height: 5px;  
209 - background: rgba(20, 20, 20, .3);  
210 - box-shadow: 0 0 20px 35px rgba(20, 20, 20, .3);  
211 - border-radius: 20px / 20px;  
212 - -moz-animation-timing-function: ease-out;  
213 - }  
214 -}  
215 -  
216 -@keyframes pace-compress {  
217 - 0% {  
218 - bottom: 0;  
219 - margin-left: -30px;  
220 - width: 60px;  
221 - height: 75px;  
222 - background: rgba(20, 20, 20, .1);  
223 - box-shadow: 0 0 20px 35px rgba(20, 20, 20, .1);  
224 - border-radius: 30px / 40px;  
225 - animation-timing-function: ease-in;  
226 - }  
227 - 100% {  
228 - bottom: 30px;  
229 - margin-left: -10px;  
230 - width: 20px;  
231 - height: 5px;  
232 - background: rgba(20, 20, 20, .3);  
233 - box-shadow: 0 0 20px 35px rgba(20, 20, 20, .3);  
234 - border-radius: 20px / 20px;  
235 - animation-timing-function: ease-out;  
236 - } 1 +.pace {
  2 + width: 140px;
  3 + height: 300px;
  4 + margin-left: calc(50% - 70px);
  5 +
  6 + z-index: 2000;
  7 + -webkit-transform: scale(0);
  8 + -moz-transform: scale(0);
  9 + -ms-transform: scale(0);
  10 + -o-transform: scale(0);
  11 + transform: scale(0);
  12 + opacity: 0;
  13 + -webkit-transition: all 2s linear 0s;
  14 + -moz-transition: all 2s linear 0s;
  15 + transition: all 2s linear 0s;
  16 +}
  17 +
  18 +.pace .text{
  19 + position: absolute;
  20 + bottom: -50px;
  21 + font-size: 12px;
  22 + transform: scale(4);
  23 + color: grey;
  24 +}
  25 +
  26 +.pace.pace-active {
  27 + -webkit-transform: scale(.25);
  28 + -moz-transform: scale(.25);
  29 + -ms-transform: scale(.25);
  30 + -o-transform: scale(.25);
  31 + transform: scale(.25);
  32 + opacity: 1;
  33 +}
  34 +
  35 +.pace .pace-activity {
  36 + width: 140px;
  37 + height: 140px;
  38 + border-radius: 70px;
  39 + background: #29d;
  40 + position: absolute;
  41 + top: 0;
  42 + z-index: 1911;
  43 + -webkit-animation: pace-bounce 1s infinite;
  44 + -moz-animation: pace-bounce 1s infinite;
  45 + -o-animation: pace-bounce 1s infinite;
  46 + -ms-animation: pace-bounce 1s infinite;
  47 + animation: pace-bounce 1s infinite;
  48 +}
  49 +
  50 +.pace .pace-progress {
  51 + position: absolute;
  52 + display: block;
  53 + left: 50%;
  54 + bottom: 0;
  55 + z-index: 1910;
  56 + margin-left: -30px;
  57 + width: 60px;
  58 + height: 75px;
  59 + background: rgba(20, 20, 20, .1);
  60 + box-shadow: 0 0 20px 35px rgba(20, 20, 20, .1);
  61 + border-radius: 30px / 40px;
  62 + -webkit-transform: scaleY(.3) !important;
  63 + -moz-transform: scaleY(.3) !important;
  64 + -ms-transform: scaleY(.3) !important;
  65 + -o-transform: scaleY(.3) !important;
  66 + transform: scaleY(.3) !important;
  67 + -webkit-animation: pace-compress .5s infinite alternate;
  68 + -moz-animation: pace-compress .5s infinite alternate;
  69 + -o-animation: pace-compress .5s infinite alternate;
  70 + -ms-animation: pace-compress .5s infinite alternate;
  71 + animation: pace-compress .5s infinite alternate;
  72 +}
  73 +
  74 +@-webkit-keyframes pace-bounce {
  75 + 0% {
  76 + top: 0;
  77 + -webkit-animation-timing-function: ease-in;
  78 + }
  79 + 40% {}
  80 + 50% {
  81 + top: 140px;
  82 + height: 140px;
  83 + -webkit-animation-timing-function: ease-out;
  84 + }
  85 + 55% {
  86 + top: 160px;
  87 + height: 120px;
  88 + border-radius: 70px / 60px;
  89 + -webkit-animation-timing-function: ease-in;
  90 + }
  91 + 65% {
  92 + top: 120px;
  93 + height: 140px;
  94 + border-radius: 70px;
  95 + -webkit-animation-timing-function: ease-out;
  96 + }
  97 + 95% {
  98 + top: 0;
  99 + -webkit-animation-timing-function: ease-in;
  100 + }
  101 + 100% {
  102 + top: 0;
  103 + -webkit-animation-timing-function: ease-in;
  104 + }
  105 +}
  106 +
  107 +@-moz-keyframes pace-bounce {
  108 + 0% {
  109 + top: 0;
  110 + -moz-animation-timing-function: ease-in;
  111 + }
  112 + 40% {}
  113 + 50% {
  114 + top: 140px;
  115 + height: 140px;
  116 + -moz-animation-timing-function: ease-out;
  117 + }
  118 + 55% {
  119 + top: 160px;
  120 + height: 120px;
  121 + border-radius: 70px / 60px;
  122 + -moz-animation-timing-function: ease-in;
  123 + }
  124 + 65% {
  125 + top: 120px;
  126 + height: 140px;
  127 + border-radius: 70px;
  128 + -moz-animation-timing-function: ease-out;}
  129 + 95% {
  130 + top: 0;
  131 + -moz-animation-timing-function: ease-in;
  132 + }
  133 + 100% {top: 0;
  134 + -moz-animation-timing-function: ease-in;
  135 + }
  136 +}
  137 +
  138 +@keyframes pace-bounce {
  139 + 0% {
  140 + top: 0;
  141 + animation-timing-function: ease-in;
  142 + }
  143 + 50% {
  144 + top: 140px;
  145 + height: 140px;
  146 + animation-timing-function: ease-out;
  147 + }
  148 + 55% {
  149 + top: 160px;
  150 + height: 120px;
  151 + border-radius: 70px / 60px;
  152 + animation-timing-function: ease-in;
  153 + }
  154 + 65% {
  155 + top: 120px;
  156 + height: 140px;
  157 + border-radius: 70px;
  158 + animation-timing-function: ease-out;
  159 + }
  160 + 95% {
  161 + top: 0;
  162 + animation-timing-function: ease-in;
  163 + }
  164 + 100% {
  165 + top: 0;
  166 + animation-timing-function: ease-in;
  167 + }
  168 +}
  169 +
  170 +@-webkit-keyframes pace-compress {
  171 + 0% {
  172 + bottom: 0;
  173 + margin-left: -30px;
  174 + width: 60px;
  175 + height: 75px;
  176 + background: rgba(20, 20, 20, .1);
  177 + box-shadow: 0 0 20px 35px rgba(20, 20, 20, .1);
  178 + border-radius: 30px / 40px;
  179 + -webkit-animation-timing-function: ease-in;
  180 + }
  181 + 100% {
  182 + bottom: 30px;
  183 + margin-left: -10px;
  184 + width: 20px;
  185 + height: 5px;
  186 + background: rgba(20, 20, 20, .3);
  187 + box-shadow: 0 0 20px 35px rgba(20, 20, 20, .3);
  188 + border-radius: 20px / 20px;
  189 + -webkit-animation-timing-function: ease-out;
  190 + }
  191 +}
  192 +
  193 +@-moz-keyframes pace-compress {
  194 + 0% {
  195 + bottom: 0;
  196 + margin-left: -30px;
  197 + width: 60px;
  198 + height: 75px;
  199 + background: rgba(20, 20, 20, .1);
  200 + box-shadow: 0 0 20px 35px rgba(20, 20, 20, .1);
  201 + border-radius: 30px / 40px;
  202 + -moz-animation-timing-function: ease-in;
  203 + }
  204 + 100% {
  205 + bottom: 30px;
  206 + margin-left: -10px;
  207 + width: 20px;
  208 + height: 5px;
  209 + background: rgba(20, 20, 20, .3);
  210 + box-shadow: 0 0 20px 35px rgba(20, 20, 20, .3);
  211 + border-radius: 20px / 20px;
  212 + -moz-animation-timing-function: ease-out;
  213 + }
  214 +}
  215 +
  216 +@keyframes pace-compress {
  217 + 0% {
  218 + bottom: 0;
  219 + margin-left: -30px;
  220 + width: 60px;
  221 + height: 75px;
  222 + background: rgba(20, 20, 20, .1);
  223 + box-shadow: 0 0 20px 35px rgba(20, 20, 20, .1);
  224 + border-radius: 30px / 40px;
  225 + animation-timing-function: ease-in;
  226 + }
  227 + 100% {
  228 + bottom: 30px;
  229 + margin-left: -10px;
  230 + width: 20px;
  231 + height: 5px;
  232 + background: rgba(20, 20, 20, .3);
  233 + box-shadow: 0 0 20px 35px rgba(20, 20, 20, .3);
  234 + border-radius: 20px / 20px;
  235 + animation-timing-function: ease-out;
  236 + }
237 } 237 }
238 \ No newline at end of file 238 \ No newline at end of file
src/main/resources/static/real_control_v2/fragments/geo/calc_station_space.html
1 -<!-- 嵌入下抽屉 -->  
2 -<div id="cal_station_space_drawer" style="width: 100%;height: 100%;">  
3 -  
4 - <div style="text-align: center;padding-top: 30px;" class="calcBeforePanel">  
5 - <p style="margin: 9px 0 9px 0;">当前站点间里程数据取自 <a target="_blank" id="stationRouteLink">基础信息->线路信息->站点详细</a>  
6 - 你可以手动编辑。</p>  
7 - <p style="margin: 9px 0 9px 0;">此外,我们提供另一种选择,根据路段和站点空间坐标计算站间距。计算后的数据将存储在本地。  
8 - </p>  
9 - <p style="margin: 0px 0 9px 0;">  
10 - <span style="color: grey;font-size: 12px;">该操作会借用本地计算能力进行,如果你同意,请点击下方按钮!</span>  
11 - </p>  
12 - <p style="margin: 9px 0 9px 0;">  
13 - <button class="uk-button uk-button-large uk-button-primary" type="button" id="startCalcBtn">开始计算</button>  
14 - </p>  
15 - </div>  
16 -  
17 - <div class="pace pace-active" style="display: none;">  
18 - <div class="pace-progress" data-progress="50" data-progress-text="50%"  
19 - style="-webkit-transform: translate3d(50%, 0px, 0px); -ms-transform: translate3d(50%, 0px, 0px); transform: translate3d(50%, 0px, 0px);">  
20 - <div class="pace-progress-inner"></div>  
21 - </div>  
22 - <div class="pace-activity"></div>  
23 - <span class="text"></span>  
24 - </div>  
25 -  
26 - <script>  
27 -  
28 - (function () {  
29 - var drawer = '#cal_station_space_drawer'  
30 - , sch, line;  
31 -  
32 - $(drawer).on('drawer-init', function (e, data) {  
33 - sch = data.sch;  
34 - line = gb_data_basic.codeToLine[sch.xlBm];  
35 - //线路路由信息调整链接  
36 - $('#stationRouteLink', drawer).attr('href', '/pages/base/stationroute/list.html?no=' + line.id);  
37 -  
38 - $('#startCalcBtn', drawer).on('click', startCalc);  
39 - });  
40 -  
41 -  
42 - function startCalc() {  
43 - $(this).attr('disabled', 'disabled');  
44 -  
45 - gb_common.$get('/realMap/findRouteAndStationByLine', {lineCode: line.lineCode}, function (spatialData) {  
46 - $('.calcBeforePanel', drawer).hide();  
47 - $('.pace', drawer).show();  
48 -  
49 - startGeoCalc(spatialData);  
50 - });  
51 - }  
52 -  
53 - function startGeoCalc(spatialData) {  
54 - setCalcText('初始化数据');  
55 - //console.log('spatialData', spatialData);  
56 - //路段上下行分组排序  
57 - var sections = gb_common.groupBy(spatialData.section, 'DIRECTIONS');  
58 - sections[0].sort(sectionArrSort);  
59 - sections[1].sort(sectionArrSort);  
60 -  
61 - //站点上下行分组排序  
62 - var stations = gb_common.groupBy(spatialData.station, 'DIRECTIONS');  
63 - stations[0].sort(stationArrSort);  
64 - stations[1].sort(stationArrSort);  
65 -  
66 - setCalcText('拼接路段,计算重叠区域');  
67 - var fullSections = [  
68 - connectSections(sections[0]),  
69 - connectSections(sections[1])  
70 - ];  
71 -  
72 - setCalcText('计算上行数据');  
73 - var upCalcRs = calcStationSpace(stations[0], fullSections[0]);  
74 -  
75 - setCalcText('计算下行数据');  
76 - var downCalcRs = calcStationSpace(stations[1], fullSections[1]);  
77 -  
78 - var locData={  
79 - stations: {up: upCalcRs,down: downCalcRs},  
80 - sections: {up: fullSections[0], down: fullSections[1]}  
81 - };  
82 -  
83 - window.localStorage.setItem('control_route_distance_'+sch.xlBm, JSON.stringify(locData));  
84 - //console.log('结果', locData);  
85 - }  
86 -  
87 - function sectionArrSort(s1, s2) {  
88 - return s1.SECTIONROUTE_CODE - s2.SECTIONROUTE_CODE;  
89 - }  
90 -  
91 - function stationArrSort(s1, s2) {  
92 - return s1.STATION_ROUTE_CODE - s2.STATION_ROUTE_CODE;  
93 - }  
94 -  
95 - function setCalcText(t) {  
96 - $('.pace .text', drawer).text(t);  
97 - }  
98 -  
99 - //连接路段数组  
100 - function connectSections(sectionArray) {  
101 - var coords = [];  
102 -  
103 - var vs, temps;  
104 - for (var i = 0, section; section = sectionArray[i++];) {  
105 - vs = section.GSECTION_VECTOR;  
106 - temps = vs.substr(11, vs.length - 2).split(',');  
107 -  
108 - connectCoords(coords, temps);  
109 - }  
110 - return coords;  
111 - }  
112 -  
113 - function connectCoords(all, subArr) {  
114 -  
115 - var point, ts, len = all.length, inLine, sIndex = 0;  
116 - if (len > 0) {  
117 - $.each(subArr, function (i, p) {  
118 - ts = p.split(' ');  
119 - point = {latitude: parseFloat(ts[1]), longitude: parseFloat(ts[0])};  
120 - //找到起始点  
121 - sIndex = 0;  
122 - for (var j = 1; j < len; j++) {  
123 - inLine = geolib.isPointInLine(point, all[j - 1], all[j]);  
124 -  
125 - if (inLine)  
126 - break;  
127 - else  
128 - sIndex = i;  
129 - }  
130 - });  
131 - }  
132 -  
133 - //拼接  
134 - for (var i = sIndex; i < subArr.length; i++) {  
135 - ts = subArr[i].split(' ');  
136 - all.push({  
137 - latitude: parseFloat(ts[1]), longitude: parseFloat(ts[0])  
138 - });  
139 - }  
140 - }  
141 -  
142 - //计算站点间距  
143 - function calcStationSpace(stations, coords) {  
144 -  
145 - var nearArray = [];  
146 - for (var i = 1; i < stations.length; i++) {  
147 -  
148 - //点到线的最短距离 并计算交点坐标  
149 - var rs = calcPointToLineNearPoint({  
150 - latitude: stations[i].G_LATY,  
151 - longitude: stations[i].G_LONX  
152 - }, coords);  
153 - rs.station = stations[i];  
154 -  
155 - //将交点插入线路中  
156 - coords.splice(rs.index, 0, rs.intersection);  
157 -  
158 - nearArray.push(rs);  
159 - //console.log('站点' + i + '计算结果', rs.intersection, rs);  
160 - }  
161 -  
162 - //根据交点截断line,并计算距离  
163 - var s = 0, e, distance;  
164 - $.each(nearArray, function (i) {  
165 - e = this.index;  
166 - distance = 0;  
167 - for (; s < e; s++) {  
168 - distance += geolib.getDistance(coords[s], coords[s + 1]);  
169 - }  
170 -  
171 - this.toDistance = distance;  
172 - s = e;  
173 - });  
174 - return nearArray;  
175 - }  
176 -  
177 - function calcPointToLineNearPoint(point, coords) {  
178 - var minRs, rs;  
179 - for (var i = 1; i < coords.length; i++) {  
180 -  
181 - var start = coords[i - 1], end = coords[i];  
182 - var d1 = geolib.getDistance(start, point, 1, 3);  
183 - var d2 = geolib.getDistance(point, end, 1, 3);  
184 - var d3 = geolib.getDistance(start, end, 1, 3);  
185 -  
186 - var alpha = Math.acos((d1 * d1 + d3 * d3 - d2 * d2) / (2 * d1 * d3));  
187 - var beta = Math.acos((d2 * d2 + d3 * d3 - d1 * d1) / (2 * d2 * d3));  
188 -  
189 - if (d3 < 0.5 || isNaN(alpha) || isNaN(beta))  
190 - continue;  
191 -  
192 - rs = {index: i};  
193 - if (alpha > Math.PI / 2) {  
194 - rs.distance = d1;  
195 - rs.intersection = start;  
196 - }  
197 - else if (beta > Math.PI / 2) {  
198 - rs.distance = d2;  
199 - rs.intersection = end;  
200 - }  
201 - else {  
202 - rs.distance = Math.sin(alpha) * d1;  
203 - rs.intersection = perpendularPoint(start, end, point);  
204 - }  
205 -  
206 - if (!minRs || minRs.distance > rs.distance)  
207 - minRs = rs  
208 - }  
209 -  
210 - return minRs;  
211 - }  
212 -  
213 - //获取点 到 线的垂直交点  
214 - function perpendularPoint(lp1, lp2, p) {  
215 - var a = lp1.latitude - lp2.latitude, b = lp2.longitude - lp1.longitude, c = lp1.longitude * lp2.latitude - lp2.longitude * lp1.latitude;  
216 - var lon = (Math.pow(b, 2) * p.longitude - a * b * p.latitude - a * c) / (Math.pow(a, 2) + Math.pow(b, 2));  
217 - var lat = (Math.pow(a, 2) * p.latitude - a * b * p.longitude - b * c) / (Math.pow(a, 2) + Math.pow(b, 2));  
218 - return {longitude: lon, latitude: lat};  
219 - }  
220 -  
221 - })();  
222 - </script> 1 +<!-- 嵌入下抽屉 -->
  2 +<div id="cal_station_space_drawer" style="width: 100%;height: 100%;">
  3 +
  4 + <div style="text-align: center;padding-top: 30px;" class="calcBeforePanel">
  5 + <p style="margin: 9px 0 9px 0;">当前站点间里程数据取自 <a target="_blank" id="stationRouteLink">基础信息->线路信息->站点详细</a>
  6 + 你可以手动编辑。</p>
  7 + <p style="margin: 9px 0 9px 0;">此外,我们提供另一种选择,根据路段和站点空间坐标计算站间距。计算后的数据将存储在本地。
  8 + </p>
  9 + <p style="margin: 0px 0 9px 0;">
  10 + <span style="color: grey;font-size: 12px;">该操作会借用本地计算能力进行,如果你同意,请点击下方按钮!</span>
  11 + </p>
  12 + <p style="margin: 9px 0 9px 0;">
  13 + <button class="uk-button uk-button-large uk-button-primary" type="button" id="startCalcBtn">开始计算</button>
  14 + </p>
  15 + </div>
  16 +
  17 + <div class="pace pace-active" style="display: none;">
  18 + <div class="pace-progress" data-progress="50" data-progress-text="50%"
  19 + style="-webkit-transform: translate3d(50%, 0px, 0px); -ms-transform: translate3d(50%, 0px, 0px); transform: translate3d(50%, 0px, 0px);">
  20 + <div class="pace-progress-inner"></div>
  21 + </div>
  22 + <div class="pace-activity"></div>
  23 + <span class="text"></span>
  24 + </div>
  25 +
  26 + <script>
  27 +
  28 + (function () {
  29 + var drawer = '#cal_station_space_drawer'
  30 + , sch, line;
  31 +
  32 + $(drawer).on('drawer-init', function (e, data) {
  33 + sch = data.sch;
  34 + line = gb_data_basic.codeToLine[sch.xlBm];
  35 + //线路路由信息调整链接
  36 + $('#stationRouteLink', drawer).attr('href', '/pages/base/stationroute/list.html?no=' + line.id);
  37 +
  38 + $('#startCalcBtn', drawer).on('click', startCalc);
  39 + });
  40 +
  41 +
  42 + function startCalc() {
  43 + $(this).attr('disabled', 'disabled');
  44 +
  45 + gb_common.$get('/realMap/findRouteAndStationByLine', {lineCode: line.lineCode}, function (spatialData) {
  46 + $('.calcBeforePanel', drawer).hide();
  47 + $('.pace', drawer).show();
  48 +
  49 + startGeoCalc(spatialData);
  50 + });
  51 + }
  52 +
  53 + function startGeoCalc(spatialData) {
  54 + setCalcText('初始化数据');
  55 + //console.log('spatialData', spatialData);
  56 + //路段上下行分组排序
  57 + var sections = gb_common.groupBy(spatialData.section, 'DIRECTIONS');
  58 + sections[0].sort(sectionArrSort);
  59 + sections[1].sort(sectionArrSort);
  60 +
  61 + //站点上下行分组排序
  62 + var stations = gb_common.groupBy(spatialData.station, 'DIRECTIONS');
  63 + stations[0].sort(stationArrSort);
  64 + stations[1].sort(stationArrSort);
  65 +
  66 + setCalcText('拼接路段,计算重叠区域');
  67 + var fullSections = [
  68 + connectSections(sections[0]),
  69 + connectSections(sections[1])
  70 + ];
  71 +
  72 + setCalcText('计算上行数据');
  73 + var upCalcRs = calcStationSpace(stations[0], fullSections[0]);
  74 +
  75 + setCalcText('计算下行数据');
  76 + var downCalcRs = calcStationSpace(stations[1], fullSections[1]);
  77 +
  78 + var locData={
  79 + stations: {up: upCalcRs,down: downCalcRs},
  80 + sections: {up: fullSections[0], down: fullSections[1]}
  81 + };
  82 +
  83 + window.localStorage.setItem('control_route_distance_'+sch.xlBm, JSON.stringify(locData));
  84 + //console.log('结果', locData);
  85 + }
  86 +
  87 + function sectionArrSort(s1, s2) {
  88 + return s1.SECTIONROUTE_CODE - s2.SECTIONROUTE_CODE;
  89 + }
  90 +
  91 + function stationArrSort(s1, s2) {
  92 + return s1.STATION_ROUTE_CODE - s2.STATION_ROUTE_CODE;
  93 + }
  94 +
  95 + function setCalcText(t) {
  96 + $('.pace .text', drawer).text(t);
  97 + }
  98 +
  99 + //连接路段数组
  100 + function connectSections(sectionArray) {
  101 + var coords = [];
  102 +
  103 + var vs, temps;
  104 + for (var i = 0, section; section = sectionArray[i++];) {
  105 + vs = section.GSECTION_VECTOR;
  106 + temps = vs.substr(11, vs.length - 2).split(',');
  107 +
  108 + connectCoords(coords, temps);
  109 + }
  110 + return coords;
  111 + }
  112 +
  113 + function connectCoords(all, subArr) {
  114 +
  115 + var point, ts, len = all.length, inLine, sIndex = 0;
  116 + if (len > 0) {
  117 + $.each(subArr, function (i, p) {
  118 + ts = p.split(' ');
  119 + point = {latitude: parseFloat(ts[1]), longitude: parseFloat(ts[0])};
  120 + //找到起始点
  121 + sIndex = 0;
  122 + for (var j = 1; j < len; j++) {
  123 + inLine = geolib.isPointInLine(point, all[j - 1], all[j]);
  124 +
  125 + if (inLine)
  126 + break;
  127 + else
  128 + sIndex = i;
  129 + }
  130 + });
  131 + }
  132 +
  133 + //拼接
  134 + for (var i = sIndex; i < subArr.length; i++) {
  135 + ts = subArr[i].split(' ');
  136 + all.push({
  137 + latitude: parseFloat(ts[1]), longitude: parseFloat(ts[0])
  138 + });
  139 + }
  140 + }
  141 +
  142 + //计算站点间距
  143 + function calcStationSpace(stations, coords) {
  144 +
  145 + var nearArray = [];
  146 + for (var i = 1; i < stations.length; i++) {
  147 +
  148 + //点到线的最短距离 并计算交点坐标
  149 + var rs = calcPointToLineNearPoint({
  150 + latitude: stations[i].G_LATY,
  151 + longitude: stations[i].G_LONX
  152 + }, coords);
  153 + rs.station = stations[i];
  154 +
  155 + //将交点插入线路中
  156 + coords.splice(rs.index, 0, rs.intersection);
  157 +
  158 + nearArray.push(rs);
  159 + //console.log('站点' + i + '计算结果', rs.intersection, rs);
  160 + }
  161 +
  162 + //根据交点截断line,并计算距离
  163 + var s = 0, e, distance;
  164 + $.each(nearArray, function (i) {
  165 + e = this.index;
  166 + distance = 0;
  167 + for (; s < e; s++) {
  168 + distance += geolib.getDistance(coords[s], coords[s + 1]);
  169 + }
  170 +
  171 + this.toDistance = distance;
  172 + s = e;
  173 + });
  174 + return nearArray;
  175 + }
  176 +
  177 + function calcPointToLineNearPoint(point, coords) {
  178 + var minRs, rs;
  179 + for (var i = 1; i < coords.length; i++) {
  180 +
  181 + var start = coords[i - 1], end = coords[i];
  182 + var d1 = geolib.getDistance(start, point, 1, 3);
  183 + var d2 = geolib.getDistance(point, end, 1, 3);
  184 + var d3 = geolib.getDistance(start, end, 1, 3);
  185 +
  186 + var alpha = Math.acos((d1 * d1 + d3 * d3 - d2 * d2) / (2 * d1 * d3));
  187 + var beta = Math.acos((d2 * d2 + d3 * d3 - d1 * d1) / (2 * d2 * d3));
  188 +
  189 + if (d3 < 0.5 || isNaN(alpha) || isNaN(beta))
  190 + continue;
  191 +
  192 + rs = {index: i};
  193 + if (alpha > Math.PI / 2) {
  194 + rs.distance = d1;
  195 + rs.intersection = start;
  196 + }
  197 + else if (beta > Math.PI / 2) {
  198 + rs.distance = d2;
  199 + rs.intersection = end;
  200 + }
  201 + else {
  202 + rs.distance = Math.sin(alpha) * d1;
  203 + rs.intersection = perpendularPoint(start, end, point);
  204 + }
  205 +
  206 + if (!minRs || minRs.distance > rs.distance)
  207 + minRs = rs
  208 + }
  209 +
  210 + return minRs;
  211 + }
  212 +
  213 + //获取点 到 线的垂直交点
  214 + function perpendularPoint(lp1, lp2, p) {
  215 + var a = lp1.latitude - lp2.latitude, b = lp2.longitude - lp1.longitude, c = lp1.longitude * lp2.latitude - lp2.longitude * lp1.latitude;
  216 + var lon = (Math.pow(b, 2) * p.longitude - a * b * p.latitude - a * c) / (Math.pow(a, 2) + Math.pow(b, 2));
  217 + var lat = (Math.pow(a, 2) * p.latitude - a * b * p.longitude - b * c) / (Math.pow(a, 2) + Math.pow(b, 2));
  218 + return {longitude: lon, latitude: lat};
  219 + }
  220 +
  221 + })();
  222 + </script>
223 </div> 223 </div>
224 \ No newline at end of file 224 \ No newline at end of file
src/main/resources/static/real_control_v2/fragments/line_schedule/context_menu/sub_task/add_sub_task_inpark.html
1 -<div class="uk-modal" id="add-sub-task-inpark-modal">  
2 - <div class="uk-modal-dialog">  
3 - <a href="" class="uk-modal-close uk-close"></a>  
4 - <div class="uk-modal-header">  
5 - <h2>回场子任务</h2></div>  
6 -  
7 - <div style="width: 100%;padding-left: 1%;">  
8 - <div class="sub-task-card">  
9 - <div class="uk-panel uk-panel-box uk-panel-box-primary">  
10 - <div class="uk-panel-badge uk-badge">营运</div>  
11 - <h3 class="uk-panel-title">线路上站点间</h3>  
12 - <form class="uk-form uk-form-horizontal" service_form>  
13 - <div class="uk-grid">  
14 - <div class="uk-width-3-10">  
15 - <div class="uk-form-row">  
16 - <label class="uk-form-label">起点 </label>  
17 - </div>  
18 - </div>  
19 - <div class="uk-width-7-10 pl5">  
20 - <select name="startStation" disabled></select>  
21 - </div>  
22 - </div>  
23 - <div class="uk-grid">  
24 - <div class="uk-width-3-10">  
25 - <div class="uk-form-row">  
26 - <label class="uk-form-label">终点 </label>  
27 - </div>  
28 - </div>  
29 - <div class="uk-width-7-10 pl5">  
30 - <select name="endStation" class="ct_focus"></select>  
31 - </div>  
32 - </div>  
33 - <div class="uk-grid">  
34 - <div class="uk-width-3-10">  
35 - <div class="uk-form-row">  
36 - <label class="uk-form-label">营运里程</label>  
37 - </div>  
38 - </div>  
39 - <div class="uk-width-7-10 pl5">  
40 - <input type="text" name="mileageType" required>  
41 - </div>  
42 - </div>  
43 - <div class="uk-grid">  
44 - <div class="uk-width-3-10">  
45 - <div class="uk-form-row">  
46 - <label class="uk-form-label">开始时间</label>  
47 - </div>  
48 - </div>  
49 - <div class="uk-width-7-10 pl5">  
50 - <input type="time" name="startDate" required>  
51 - </div>  
52 - </div>  
53 - <div class="uk-grid">  
54 - <div class="uk-width-3-10">  
55 - <div class="uk-form-row">  
56 - <label class="uk-form-label">结束时间</label>  
57 - </div>  
58 - </div>  
59 - <div class="uk-width-7-10 pl5">  
60 - <input type="time" name="endDate" required>  
61 - </div>  
62 - </div>  
63 - </form>  
64 - </div>  
65 - </div>  
66 - <div class="sub-task-card">  
67 - <div class="uk-panel uk-panel-box uk-panel-box-secondary">  
68 - <div class="uk-panel-badge uk-badge uk-badge-default">空驶</div>  
69 - <h3 class="uk-panel-title">进场</h3>  
70 - <form class="uk-form uk-form-horizontal" empty_form>  
71 - <div class="uk-grid">  
72 - <div class="uk-width-3-10">  
73 - <div class="uk-form-row">  
74 - <label class="uk-form-label">起点 </label>  
75 - </div>  
76 - </div>  
77 - <div class="uk-width-7-10 pl5">  
78 - <select name="startStation" disabled></select>  
79 - </div>  
80 - </div>  
81 - <div class="uk-grid">  
82 - <div class="uk-width-3-10">  
83 - <div class="uk-form-row">  
84 - <label class="uk-form-label">终点 </label>  
85 - </div>  
86 - </div>  
87 - <div class="uk-width-7-10 pl5">  
88 - <select name="endStation" class="ct_focus"></select>  
89 - </div>  
90 - </div>  
91 - <div class="uk-grid">  
92 - <div class="uk-width-3-10">  
93 - <div class="uk-form-row">  
94 - <label class="uk-form-label">空驶里程</label>  
95 - </div>  
96 - </div>  
97 - <div class="uk-width-7-10 pl5">  
98 - <input type="text" name="mileageType" required style="width: calc(100% - 62px);">  
99 - <a style="font-size: 12px;">路径(3)</a>  
100 - </div>  
101 - </div>  
102 - <div class="uk-grid">  
103 - <div class="uk-width-3-10">  
104 - <div class="uk-form-row">  
105 - <label class="uk-form-label">开始时间</label>  
106 - </div>  
107 - </div>  
108 - <div class="uk-width-7-10 pl5">  
109 - <input type="time" name="startDate" required>  
110 - </div>  
111 - </div>  
112 - <div class="uk-grid">  
113 - <div class="uk-width-3-10">  
114 - <div class="uk-form-row">  
115 - <label class="uk-form-label">结束时间</label>  
116 - </div>  
117 - </div>  
118 - <div class="uk-width-7-10 pl5">  
119 - <input type="time" name="endDate" required>  
120 - </div>  
121 - </div>  
122 - </form>  
123 - </div>  
124 - </div>  
125 - <div class="sub-task-card destroy-card uk-animation-scale">  
126 - <div class="uk-panel uk-panel-box uk-panel-box-danger">  
127 - <div class="uk-panel-badge uk-badge uk-badge-danger">烂班</div>  
128 - <h3 class="uk-panel-title">线路上站点间</h3>  
129 - <form class="uk-form uk-form-horizontal" destroy_form>  
130 - <div class="uk-grid">  
131 - <div class="uk-width-3-10">  
132 - <div class="uk-form-row">  
133 - <label class="uk-form-label">起点 </label>  
134 - </div>  
135 - </div>  
136 - <div class="uk-width-7-10 pl5">  
137 - <select name="startStation" disabled></select>  
138 - </div>  
139 - </div>  
140 - <div class="uk-grid">  
141 - <div class="uk-width-3-10">  
142 - <div class="uk-form-row">  
143 - <label class="uk-form-label">终点 </label>  
144 - </div>  
145 - </div>  
146 - <div class="uk-width-7-10 pl5">  
147 - <select name="endStation" class="ct_focus" disabled></select>  
148 - </div>  
149 - </div>  
150 - <div class="uk-grid">  
151 - <div class="uk-width-3-10">  
152 - <div class="uk-form-row">  
153 - <label class="uk-form-label">烂班里程</label>  
154 - </div>  
155 - </div>  
156 - <div class="uk-width-7-10 pl5">  
157 - <input type="text" name="mileageType" required>  
158 - </div>  
159 - </div>  
160 - <div class="uk-grid">  
161 - <div class="uk-width-3-10">  
162 - <div class="uk-form-row">  
163 - <label class="uk-form-label">开始时间</label>  
164 - </div>  
165 - </div>  
166 - <div class="uk-width-7-10 pl5">  
167 - <input type="time" name="startDate" required>  
168 - </div>  
169 - </div>  
170 - <div class="uk-grid">  
171 - <div class="uk-width-3-10">  
172 - <div class="uk-form-row">  
173 - <label class="uk-form-label">烂班原因</label>  
174 - </div>  
175 - </div>  
176 - <div class="uk-width-7-10 pl5">  
177 - <select name="destroyReason" required></select>  
178 - </div>  
179 - </div>  
180 - </form>  
181 - </div>  
182 - </div>  
183 -  
184 - <form class="uk-form" style="margin-top: 15px; padding: 0 10px 0 0;">  
185 - <textarea placeholder="备注" style="width: 100%;height: 70px;"></textarea>  
186 - </form>  
187 - </div>  
188 -  
189 - <div class="uk-modal-footer uk-text-right">  
190 - <button type="button" class="uk-button uk-modal-close">取消</button>  
191 - <button type="button" class="uk-button uk-button-primary">提交子任务</button>  
192 -  
193 - <div class="ct-footer-left">  
194 - <a id="betweenStationRangeCalc" data-drawer-id="cal_station_space_drawer">站点间公里不准?</a>  
195 - </div>  
196 - </div>  
197 - </div>  
198 -  
199 - <div class="ct-bottom-drawer">  
200 - <a class="ct-bottom-drawer-close"></a>  
201 -  
202 - <div class="ct-bottom-drawer-body"></div>  
203 - </div>  
204 -  
205 - <script id="sub-task-inpark-form-temp" type="text/html">  
206 - </script>  
207 -  
208 - <script>  
209 - (function () {  
210 - var modal = '#add-sub-task-inpark-modal',  
211 - serviceForm = $('form[service_form]', modal),  
212 - emptyForm = $('form[empty_form]', modal),  
213 - destroyForm = $('form[destroy_form]', modal),  
214 - sch, stationRoutes, parks, information, esCode;  
215 - var adjustExps = ['配车', '保养', '故障', '肇事', '路阻', '纠纷', '缺人', '客稀', '缺车', '气候', '援外', '吊慢', '抽减', '其他'];  
216 - $(modal).on('init', function (e, data) {  
217 - sch = data.sch;  
218 - //var formHtml = template('sub-task-inpark-form-temp', {sch:sch, adjustExps: adjustExps});  
219 - //$('form', modal).html(formHtml);  
220 - //字典转换  
221 - //dictionaryUtils.transformDom($('.nt-dictionary', modal));  
222 -  
223 - //站点路由  
224 - stationRoutes = gb_common.groupBy(gb_data_basic.stationRoutes(sch.xlBm).sort(function (a, b) {  
225 - return a.stationRouteCode - b.stationRouteCode;  
226 - }), 'directions')[sch.xlDir];  
227 - //空驶终点(停车场)  
228 - $.get('/basic/parks', function (rs) {  
229 - parks = rs;  
230 - var opts = '';  
231 - for (var code in parks) {  
232 - opts += '<option value="' + code + '">' + parks[code] + '</option>';  
233 - }  
234 - $('select[name=endStation]', emptyForm).html(opts).val(information.carPark);  
235 - });  
236 - //线路标准  
237 - information = gb_data_basic.getLineInformation(sch.xlBm);  
238 -  
239 - var routeOpts = '';  
240 - $.each(stationRoutes, function () {  
241 - routeOpts += '<option value="' + this.stationCode + '">' + this.stationName + '</option>';  
242 - });  
243 - esCode = stationRoutes[stationRoutes.length - 1].stationCode;  
244 -  
245 - //营运起终点  
246 - $('select[name=startStation],select[name=endStation]', serviceForm).html(routeOpts);  
247 - //空驶起点  
248 - $('select[name=startStation]', emptyForm).html(routeOpts).val(esCode);  
249 - //烂班起终点  
250 - $('select[name=startStation],select[name=endStation]', destroyForm).html(routeOpts).val(esCode);  
251 -  
252 - //烂班原因  
253 - var adjustExpsOpts = '<option value="">请选择...</option>';  
254 - $.each(adjustExps, function (i, str) {  
255 - adjustExpsOpts += '<option value="' + str + '">' + str + '</option>';  
256 - });  
257 - $('select[name=destroyReason]', destroyForm).html(adjustExpsOpts);  
258 -  
259 - //切换营运终点  
260 - $('select[name=endStation]', serviceForm).val(esCode).on('change', function () {  
261 - var val = $(this).val();  
262 - if (val == esCode) {  
263 - $('.uk-modal-dialog', modal).removeClass('three-children');  
264 - $('.sub-task-card.destroy-card').css("display", "none");  
265 - }  
266 - else {  
267 - $('.uk-modal-dialog', modal).addClass('three-children');  
268 - $('.sub-task-card.destroy-card').css("display", "inline-block");  
269 - }  
270 -  
271 - reClac();  
272 - });  
273 -  
274 -  
275 - //submit  
276 - /*var f = $('form', modal).formValidation({  
277 - framework: 'uikit',  
278 - locale: 'zh_CN',  
279 - });  
280 - f.on('success.form.fv', function(e) {  
281 - disabled_submit_btn(this);  
282 - e.preventDefault();  
283 - var data = $(this).serializeJSON();  
284 -  
285 - });*/  
286 - });  
287 -  
288 - function reClac() {  
289 - var serviceEnd = $('select[name=endStation]', serviceForm).val();  
290 - //空驶起点 == 营运终点  
291 - $('select[name=startStation]', emptyForm).val(serviceEnd);  
292 -  
293 - if (serviceEnd != esCode) {  
294 - //烂班起点 == 营运终点  
295 - $('select[name=startStation]', destroyForm).val(serviceEnd);  
296 - }  
297 - }  
298 -  
299 -  
300 - //------ 下抽屉 ------  
301 - $('#betweenStationRangeCalc', modal).on('click', function () {  
302 - var id = $(this).data('drawer-id');  
303 - switchBtmDrawer(id, '/real_control_v2/fragments/geo/calc_station_space.html');  
304 - });  
305 -  
306 - var btmDrawer = $('.ct-bottom-drawer', modal);  
307 - //打开事件  
308 - btmDrawer.on('drawer_show', function () {  
309 - var url = $(this).data('url');  
310 - if(!url){  
311 - alert('无效的地址');  
312 - }  
313 -  
314 - var drawerPanel=$(this).data('name');  
315 - $('.ct-bottom-drawer-body', btmDrawer).load(url, function () {  
316 - $('#'+drawerPanel).trigger('drawer-init', {sch: sch});  
317 - });  
318 - });  
319 -  
320 - function switchBtmDrawer(id, url) {  
321 - if (btmDrawer.hasClass('open') && btmDrawer.data('name') == id) {  
322 - btmDrawer.removeClass('open');  
323 - btmDrawer.removeData('name').removeData('url');  
324 - }  
325 - else {  
326 - btmDrawer.addClass('open');  
327 - btmDrawer.data('name', id).data('url', url).trigger('drawer_show');  
328 - }  
329 - }  
330 - })();  
331 - </script>  
332 -</div> 1 +<div class="uk-modal" id="add-sub-task-inpark-modal">
  2 + <div class="uk-modal-dialog">
  3 + <a href="" class="uk-modal-close uk-close"></a>
  4 + <div class="uk-modal-header">
  5 + <h2>回场子任务</h2></div>
  6 +
  7 + <div style="width: 100%;padding-left: 1%;">
  8 + <div class="sub-task-card">
  9 + <div class="uk-panel uk-panel-box uk-panel-box-primary">
  10 + <div class="uk-panel-badge uk-badge">营运</div>
  11 + <h3 class="uk-panel-title">线路上站点间</h3>
  12 + <form class="uk-form uk-form-horizontal" service_form>
  13 + <div class="uk-grid">
  14 + <div class="uk-width-3-10">
  15 + <div class="uk-form-row">
  16 + <label class="uk-form-label">起点 </label>
  17 + </div>
  18 + </div>
  19 + <div class="uk-width-7-10 pl5">
  20 + <select name="startStation" disabled></select>
  21 + </div>
  22 + </div>
  23 + <div class="uk-grid">
  24 + <div class="uk-width-3-10">
  25 + <div class="uk-form-row">
  26 + <label class="uk-form-label">终点 </label>
  27 + </div>
  28 + </div>
  29 + <div class="uk-width-7-10 pl5">
  30 + <select name="endStation" class="ct_focus"></select>
  31 + </div>
  32 + </div>
  33 + <div class="uk-grid">
  34 + <div class="uk-width-3-10">
  35 + <div class="uk-form-row">
  36 + <label class="uk-form-label">营运里程</label>
  37 + </div>
  38 + </div>
  39 + <div class="uk-width-7-10 pl5">
  40 + <input type="text" name="mileageType" required>
  41 + </div>
  42 + </div>
  43 + <div class="uk-grid">
  44 + <div class="uk-width-3-10">
  45 + <div class="uk-form-row">
  46 + <label class="uk-form-label">开始时间</label>
  47 + </div>
  48 + </div>
  49 + <div class="uk-width-7-10 pl5">
  50 + <input type="time" name="startDate" required>
  51 + </div>
  52 + </div>
  53 + <div class="uk-grid">
  54 + <div class="uk-width-3-10">
  55 + <div class="uk-form-row">
  56 + <label class="uk-form-label">结束时间</label>
  57 + </div>
  58 + </div>
  59 + <div class="uk-width-7-10 pl5">
  60 + <input type="time" name="endDate" required>
  61 + </div>
  62 + </div>
  63 + </form>
  64 + </div>
  65 + </div>
  66 + <div class="sub-task-card">
  67 + <div class="uk-panel uk-panel-box uk-panel-box-secondary">
  68 + <div class="uk-panel-badge uk-badge uk-badge-default">空驶</div>
  69 + <h3 class="uk-panel-title">进场</h3>
  70 + <form class="uk-form uk-form-horizontal" empty_form>
  71 + <div class="uk-grid">
  72 + <div class="uk-width-3-10">
  73 + <div class="uk-form-row">
  74 + <label class="uk-form-label">起点 </label>
  75 + </div>
  76 + </div>
  77 + <div class="uk-width-7-10 pl5">
  78 + <select name="startStation" disabled></select>
  79 + </div>
  80 + </div>
  81 + <div class="uk-grid">
  82 + <div class="uk-width-3-10">
  83 + <div class="uk-form-row">
  84 + <label class="uk-form-label">终点 </label>
  85 + </div>
  86 + </div>
  87 + <div class="uk-width-7-10 pl5">
  88 + <select name="endStation" class="ct_focus"></select>
  89 + </div>
  90 + </div>
  91 + <div class="uk-grid">
  92 + <div class="uk-width-3-10">
  93 + <div class="uk-form-row">
  94 + <label class="uk-form-label">空驶里程</label>
  95 + </div>
  96 + </div>
  97 + <div class="uk-width-7-10 pl5">
  98 + <input type="text" name="mileageType" required style="width: calc(100% - 62px);">
  99 + <a style="font-size: 12px;">路径(3)</a>
  100 + </div>
  101 + </div>
  102 + <div class="uk-grid">
  103 + <div class="uk-width-3-10">
  104 + <div class="uk-form-row">
  105 + <label class="uk-form-label">开始时间</label>
  106 + </div>
  107 + </div>
  108 + <div class="uk-width-7-10 pl5">
  109 + <input type="time" name="startDate" required>
  110 + </div>
  111 + </div>
  112 + <div class="uk-grid">
  113 + <div class="uk-width-3-10">
  114 + <div class="uk-form-row">
  115 + <label class="uk-form-label">结束时间</label>
  116 + </div>
  117 + </div>
  118 + <div class="uk-width-7-10 pl5">
  119 + <input type="time" name="endDate" required>
  120 + </div>
  121 + </div>
  122 + </form>
  123 + </div>
  124 + </div>
  125 + <div class="sub-task-card destroy-card uk-animation-scale">
  126 + <div class="uk-panel uk-panel-box uk-panel-box-danger">
  127 + <div class="uk-panel-badge uk-badge uk-badge-danger">烂班</div>
  128 + <h3 class="uk-panel-title">线路上站点间</h3>
  129 + <form class="uk-form uk-form-horizontal" destroy_form>
  130 + <div class="uk-grid">
  131 + <div class="uk-width-3-10">
  132 + <div class="uk-form-row">
  133 + <label class="uk-form-label">起点 </label>
  134 + </div>
  135 + </div>
  136 + <div class="uk-width-7-10 pl5">
  137 + <select name="startStation" disabled></select>
  138 + </div>
  139 + </div>
  140 + <div class="uk-grid">
  141 + <div class="uk-width-3-10">
  142 + <div class="uk-form-row">
  143 + <label class="uk-form-label">终点 </label>
  144 + </div>
  145 + </div>
  146 + <div class="uk-width-7-10 pl5">
  147 + <select name="endStation" class="ct_focus" disabled></select>
  148 + </div>
  149 + </div>
  150 + <div class="uk-grid">
  151 + <div class="uk-width-3-10">
  152 + <div class="uk-form-row">
  153 + <label class="uk-form-label">烂班里程</label>
  154 + </div>
  155 + </div>
  156 + <div class="uk-width-7-10 pl5">
  157 + <input type="text" name="mileageType" required>
  158 + </div>
  159 + </div>
  160 + <div class="uk-grid">
  161 + <div class="uk-width-3-10">
  162 + <div class="uk-form-row">
  163 + <label class="uk-form-label">开始时间</label>
  164 + </div>
  165 + </div>
  166 + <div class="uk-width-7-10 pl5">
  167 + <input type="time" name="startDate" required>
  168 + </div>
  169 + </div>
  170 + <div class="uk-grid">
  171 + <div class="uk-width-3-10">
  172 + <div class="uk-form-row">
  173 + <label class="uk-form-label">烂班原因</label>
  174 + </div>
  175 + </div>
  176 + <div class="uk-width-7-10 pl5">
  177 + <select name="destroyReason" required></select>
  178 + </div>
  179 + </div>
  180 + </form>
  181 + </div>
  182 + </div>
  183 +
  184 + <form class="uk-form" style="margin-top: 15px; padding: 0 10px 0 0;">
  185 + <textarea placeholder="备注" style="width: 100%;height: 70px;"></textarea>
  186 + </form>
  187 + </div>
  188 +
  189 + <div class="uk-modal-footer uk-text-right">
  190 + <button type="button" class="uk-button uk-modal-close">取消</button>
  191 + <button type="button" class="uk-button uk-button-primary">提交子任务</button>
  192 +
  193 + <div class="ct-footer-left">
  194 + <a id="betweenStationRangeCalc" data-drawer-id="cal_station_space_drawer">站点间公里不准?</a>
  195 + </div>
  196 + </div>
  197 + </div>
  198 +
  199 + <div class="ct-bottom-drawer">
  200 + <a class="ct-bottom-drawer-close"></a>
  201 +
  202 + <div class="ct-bottom-drawer-body"></div>
  203 + </div>
  204 +
  205 + <script id="sub-task-inpark-form-temp" type="text/html">
  206 + </script>
  207 +
  208 + <script>
  209 + (function () {
  210 + var modal = '#add-sub-task-inpark-modal',
  211 + serviceForm = $('form[service_form]', modal),
  212 + emptyForm = $('form[empty_form]', modal),
  213 + destroyForm = $('form[destroy_form]', modal),
  214 + sch, stationRoutes, parks, information, esCode;
  215 + var adjustExps = ['配车', '保养', '故障', '肇事', '路阻', '纠纷', '缺人', '客稀', '缺车', '气候', '援外', '吊慢', '抽减', '其他'];
  216 + $(modal).on('init', function (e, data) {
  217 + sch = data.sch;
  218 + //var formHtml = template('sub-task-inpark-form-temp', {sch:sch, adjustExps: adjustExps});
  219 + //$('form', modal).html(formHtml);
  220 + //字典转换
  221 + //dictionaryUtils.transformDom($('.nt-dictionary', modal));
  222 +
  223 + //站点路由
  224 + stationRoutes = gb_common.groupBy(gb_data_basic.stationRoutes(sch.xlBm).sort(function (a, b) {
  225 + return a.stationRouteCode - b.stationRouteCode;
  226 + }), 'directions')[sch.xlDir];
  227 + //空驶终点(停车场)
  228 + $.get('/basic/parks', function (rs) {
  229 + parks = rs;
  230 + var opts = '';
  231 + for (var code in parks) {
  232 + opts += '<option value="' + code + '">' + parks[code] + '</option>';
  233 + }
  234 + $('select[name=endStation]', emptyForm).html(opts).val(information.carPark);
  235 + });
  236 + //线路标准
  237 + information = gb_data_basic.getLineInformation(sch.xlBm);
  238 +
  239 + var routeOpts = '';
  240 + $.each(stationRoutes, function () {
  241 + routeOpts += '<option value="' + this.stationCode + '">' + this.stationName + '</option>';
  242 + });
  243 + esCode = stationRoutes[stationRoutes.length - 1].stationCode;
  244 +
  245 + //营运起终点
  246 + $('select[name=startStation],select[name=endStation]', serviceForm).html(routeOpts);
  247 + //空驶起点
  248 + $('select[name=startStation]', emptyForm).html(routeOpts).val(esCode);
  249 + //烂班起终点
  250 + $('select[name=startStation],select[name=endStation]', destroyForm).html(routeOpts).val(esCode);
  251 +
  252 + //烂班原因
  253 + var adjustExpsOpts = '<option value="">请选择...</option>';
  254 + $.each(adjustExps, function (i, str) {
  255 + adjustExpsOpts += '<option value="' + str + '">' + str + '</option>';
  256 + });
  257 + $('select[name=destroyReason]', destroyForm).html(adjustExpsOpts);
  258 +
  259 + //切换营运终点
  260 + $('select[name=endStation]', serviceForm).val(esCode).on('change', function () {
  261 + var val = $(this).val();
  262 + if (val == esCode) {
  263 + $('.uk-modal-dialog', modal).removeClass('three-children');
  264 + $('.sub-task-card.destroy-card').css("display", "none");
  265 + }
  266 + else {
  267 + $('.uk-modal-dialog', modal).addClass('three-children');
  268 + $('.sub-task-card.destroy-card').css("display", "inline-block");
  269 + }
  270 +
  271 + reClac();
  272 + });
  273 +
  274 +
  275 + //submit
  276 + /*var f = $('form', modal).formValidation({
  277 + framework: 'uikit',
  278 + locale: 'zh_CN',
  279 + });
  280 + f.on('success.form.fv', function(e) {
  281 + disabled_submit_btn(this);
  282 + e.preventDefault();
  283 + var data = $(this).serializeJSON();
  284 +
  285 + });*/
  286 + });
  287 +
  288 + function reClac() {
  289 + var serviceEnd = $('select[name=endStation]', serviceForm).val();
  290 + //空驶起点 == 营运终点
  291 + $('select[name=startStation]', emptyForm).val(serviceEnd);
  292 +
  293 + if (serviceEnd != esCode) {
  294 + //烂班起点 == 营运终点
  295 + $('select[name=startStation]', destroyForm).val(serviceEnd);
  296 + }
  297 + }
  298 +
  299 +
  300 + //------ 下抽屉 ------
  301 + $('#betweenStationRangeCalc', modal).on('click', function () {
  302 + var id = $(this).data('drawer-id');
  303 + switchBtmDrawer(id, '/real_control_v2/fragments/geo/calc_station_space.html');
  304 + });
  305 +
  306 + var btmDrawer = $('.ct-bottom-drawer', modal);
  307 + //打开事件
  308 + btmDrawer.on('drawer_show', function () {
  309 + var url = $(this).data('url');
  310 + if(!url){
  311 + alert('无效的地址');
  312 + }
  313 +
  314 + var drawerPanel=$(this).data('name');
  315 + $('.ct-bottom-drawer-body', btmDrawer).load(url, function () {
  316 + $('#'+drawerPanel).trigger('drawer-init', {sch: sch});
  317 + });
  318 + });
  319 +
  320 + function switchBtmDrawer(id, url) {
  321 + if (btmDrawer.hasClass('open') && btmDrawer.data('name') == id) {
  322 + btmDrawer.removeClass('open');
  323 + btmDrawer.removeData('name').removeData('url');
  324 + }
  325 + else {
  326 + btmDrawer.addClass('open');
  327 + btmDrawer.data('name', id).data('url', url).trigger('drawer_show');
  328 + }
  329 + }
  330 + })();
  331 + </script>
  332 +</div>
src/main/resources/static/real_control_v2/geolib/geolib.elevation.js
1 -/*! geolib.elevation 2.0.21 by Manuel Bieh  
2 -*  
3 -* Elevation Addon for Geolib.js  
4 -*  
5 -* @author Manuel Bieh  
6 -* @url http://www.manuelbieh.com/  
7 -* @version 2.0.21  
8 -* @license MIT  
9 -*/  
10 -;(function(global, geolib, undefined) {  
11 -  
12 - var elevation = {  
13 -  
14 - /*global google:true geolib:true require:true module:true elevationResult:true */  
15 -  
16 - /**  
17 - * @param Array Collection of coords [{latitude: 51.510, longitude: 7.1321}, {latitude: 49.1238, longitude: "8° 30' W"}, ...]  
18 - * @return Array [{lat:#lat, lng:#lng, elev:#elev},....]}  
19 - */  
20 - getElevation: function() {  
21 - if (typeof global.navigator !== 'undefined') {  
22 - this.getElevationClient.apply(this, arguments);  
23 - } else {  
24 - this.getElevationServer.apply(this, arguments);  
25 - }  
26 - },  
27 -  
28 -  
29 - /* Optional elevation addon requires Googlemaps API JS */  
30 - getElevationClient: function(coords, cb) {  
31 -  
32 - if (!global.google) {  
33 - throw new Error("Google maps api not loaded");  
34 - }  
35 -  
36 - if (coords.length === 0) {  
37 - return cb(null, null);  
38 - }  
39 -  
40 - if (coords.length === 1) {  
41 - return cb(new Error("getElevation requires at least 2 points."));  
42 - }  
43 -  
44 - var path = [];  
45 -  
46 - for(var i = 0; i < coords.length; i++) {  
47 - path.push(new google.maps.LatLng(  
48 - this.latitude(coords[i]),  
49 - this.longitude(coords[i])  
50 - ));  
51 - }  
52 -  
53 - var positionalRequest = {  
54 - 'path': path,  
55 - 'samples': path.length  
56 - };  
57 -  
58 - var elevationService = new google.maps.ElevationService();  
59 - var geolib = this;  
60 -  
61 - elevationService.getElevationAlongPath(positionalRequest, function (results, status) {  
62 - geolib.elevationHandler(results, status, coords, cb);  
63 - });  
64 -  
65 - },  
66 -  
67 -  
68 - getElevationServer: function(coords, cb) {  
69 -  
70 - if (coords.length === 0) {  
71 - return cb(null, null);  
72 - }  
73 -  
74 - if (coords.length === 1) {  
75 - return cb(new Error("getElevation requires at least 2 points."));  
76 - }  
77 -  
78 - var gm = require('googlemaps');  
79 - var path = [];  
80 -  
81 - for(var i = 0; i < coords.length; i++) {  
82 - path.push(  
83 - this.latitude(coords[i]) + ',' + this.longitude(coords[i])  
84 - );  
85 - }  
86 -  
87 - var geolib = this;  
88 -  
89 - gm.elevationFromPath(path.join('|'), path.length, function(err, results) {  
90 - geolib.elevationHandler(results.results, results.status, coords, cb);  
91 - });  
92 -  
93 - },  
94 -  
95 -  
96 - elevationHandler: function(results, status, coords, cb) {  
97 -  
98 - var latsLngsElevs = [];  
99 -  
100 - if (status == "OK" ) {  
101 -  
102 - for (var i = 0; i < results.length; i++) {  
103 - latsLngsElevs.push({  
104 - "lat": this.latitude(coords[i]),  
105 - "lng": this.longitude(coords[i]),  
106 - "elev":results[i].elevation  
107 - });  
108 - }  
109 -  
110 - cb(null, latsLngsElevs);  
111 -  
112 - } else {  
113 -  
114 - cb(new Error("Could not get elevation using Google's API"), elevationResult.status);  
115 -  
116 - }  
117 -  
118 - },  
119 -  
120 -  
121 - /**  
122 - * @param Array [{lat:#lat, lng:#lng, elev:#elev},....]}  
123 - * @return Number % grade  
124 - */  
125 - getGrade: function(coords) {  
126 -  
127 - var rise = Math.abs(  
128 - this.elevation(coords[coords.length-1]) - this.elevation(coords[0])  
129 - );  
130 -  
131 - var run = this.getPathLength(coords);  
132 -  
133 - return Math.floor((rise/run)*100);  
134 -  
135 - },  
136 -  
137 -  
138 - /**  
139 - * @param Array [{lat:#lat, lng:#lng, elev:#elev},....]}  
140 - * @return Object {gain:#gain, loss:#loss}  
141 - */  
142 - getTotalElevationGainAndLoss: function(coords) {  
143 -  
144 - var gain = 0;  
145 - var loss = 0;  
146 -  
147 - for(var i = 0; i < coords.length - 1; i++) {  
148 -  
149 - var deltaElev = this.elevation(coords[i]) - this.elevation(coords[i + 1]);  
150 -  
151 - if (deltaElev > 0) {  
152 - loss += deltaElev;  
153 - } else {  
154 - gain += Math.abs(deltaElev);  
155 - }  
156 -  
157 - }  
158 -  
159 - return {  
160 - "gain": gain,  
161 - "loss": loss  
162 - };  
163 -  
164 - }  
165 -  
166 - };  
167 -  
168 - // Node module  
169 - if (typeof module !== 'undefined' &&  
170 - typeof module.exports !== 'undefined') {  
171 -  
172 - geolib = require('geolib');  
173 - geolib.extend(elevation);  
174 -  
175 - // AMD module  
176 - } else if (typeof define === "function" && define.amd) {  
177 -  
178 - define(["geolib"], function (geolib) {  
179 - geolib.extend(elevation);  
180 - return geolib;  
181 - });  
182 -  
183 - // we're in a browser  
184 - } else {  
185 -  
186 - geolib.extend(elevation);  
187 -  
188 - }  
189 - 1 +/*! geolib.elevation 2.0.21 by Manuel Bieh
  2 +*
  3 +* Elevation Addon for Geolib.js
  4 +*
  5 +* @author Manuel Bieh
  6 +* @url http://www.manuelbieh.com/
  7 +* @version 2.0.21
  8 +* @license MIT
  9 +*/
  10 +;(function(global, geolib, undefined) {
  11 +
  12 + var elevation = {
  13 +
  14 + /*global google:true geolib:true require:true module:true elevationResult:true */
  15 +
  16 + /**
  17 + * @param Array Collection of coords [{latitude: 51.510, longitude: 7.1321}, {latitude: 49.1238, longitude: "8° 30' W"}, ...]
  18 + * @return Array [{lat:#lat, lng:#lng, elev:#elev},....]}
  19 + */
  20 + getElevation: function() {
  21 + if (typeof global.navigator !== 'undefined') {
  22 + this.getElevationClient.apply(this, arguments);
  23 + } else {
  24 + this.getElevationServer.apply(this, arguments);
  25 + }
  26 + },
  27 +
  28 +
  29 + /* Optional elevation addon requires Googlemaps API JS */
  30 + getElevationClient: function(coords, cb) {
  31 +
  32 + if (!global.google) {
  33 + throw new Error("Google maps api not loaded");
  34 + }
  35 +
  36 + if (coords.length === 0) {
  37 + return cb(null, null);
  38 + }
  39 +
  40 + if (coords.length === 1) {
  41 + return cb(new Error("getElevation requires at least 2 points."));
  42 + }
  43 +
  44 + var path = [];
  45 +
  46 + for(var i = 0; i < coords.length; i++) {
  47 + path.push(new google.maps.LatLng(
  48 + this.latitude(coords[i]),
  49 + this.longitude(coords[i])
  50 + ));
  51 + }
  52 +
  53 + var positionalRequest = {
  54 + 'path': path,
  55 + 'samples': path.length
  56 + };
  57 +
  58 + var elevationService = new google.maps.ElevationService();
  59 + var geolib = this;
  60 +
  61 + elevationService.getElevationAlongPath(positionalRequest, function (results, status) {
  62 + geolib.elevationHandler(results, status, coords, cb);
  63 + });
  64 +
  65 + },
  66 +
  67 +
  68 + getElevationServer: function(coords, cb) {
  69 +
  70 + if (coords.length === 0) {
  71 + return cb(null, null);
  72 + }
  73 +
  74 + if (coords.length === 1) {
  75 + return cb(new Error("getElevation requires at least 2 points."));
  76 + }
  77 +
  78 + var gm = require('googlemaps');
  79 + var path = [];
  80 +
  81 + for(var i = 0; i < coords.length; i++) {
  82 + path.push(
  83 + this.latitude(coords[i]) + ',' + this.longitude(coords[i])
  84 + );
  85 + }
  86 +
  87 + var geolib = this;
  88 +
  89 + gm.elevationFromPath(path.join('|'), path.length, function(err, results) {
  90 + geolib.elevationHandler(results.results, results.status, coords, cb);
  91 + });
  92 +
  93 + },
  94 +
  95 +
  96 + elevationHandler: function(results, status, coords, cb) {
  97 +
  98 + var latsLngsElevs = [];
  99 +
  100 + if (status == "OK" ) {
  101 +
  102 + for (var i = 0; i < results.length; i++) {
  103 + latsLngsElevs.push({
  104 + "lat": this.latitude(coords[i]),
  105 + "lng": this.longitude(coords[i]),
  106 + "elev":results[i].elevation
  107 + });
  108 + }
  109 +
  110 + cb(null, latsLngsElevs);
  111 +
  112 + } else {
  113 +
  114 + cb(new Error("Could not get elevation using Google's API"), elevationResult.status);
  115 +
  116 + }
  117 +
  118 + },
  119 +
  120 +
  121 + /**
  122 + * @param Array [{lat:#lat, lng:#lng, elev:#elev},....]}
  123 + * @return Number % grade
  124 + */
  125 + getGrade: function(coords) {
  126 +
  127 + var rise = Math.abs(
  128 + this.elevation(coords[coords.length-1]) - this.elevation(coords[0])
  129 + );
  130 +
  131 + var run = this.getPathLength(coords);
  132 +
  133 + return Math.floor((rise/run)*100);
  134 +
  135 + },
  136 +
  137 +
  138 + /**
  139 + * @param Array [{lat:#lat, lng:#lng, elev:#elev},....]}
  140 + * @return Object {gain:#gain, loss:#loss}
  141 + */
  142 + getTotalElevationGainAndLoss: function(coords) {
  143 +
  144 + var gain = 0;
  145 + var loss = 0;
  146 +
  147 + for(var i = 0; i < coords.length - 1; i++) {
  148 +
  149 + var deltaElev = this.elevation(coords[i]) - this.elevation(coords[i + 1]);
  150 +
  151 + if (deltaElev > 0) {
  152 + loss += deltaElev;
  153 + } else {
  154 + gain += Math.abs(deltaElev);
  155 + }
  156 +
  157 + }
  158 +
  159 + return {
  160 + "gain": gain,
  161 + "loss": loss
  162 + };
  163 +
  164 + }
  165 +
  166 + };
  167 +
  168 + // Node module
  169 + if (typeof module !== 'undefined' &&
  170 + typeof module.exports !== 'undefined') {
  171 +
  172 + geolib = require('geolib');
  173 + geolib.extend(elevation);
  174 +
  175 + // AMD module
  176 + } else if (typeof define === "function" && define.amd) {
  177 +
  178 + define(["geolib"], function (geolib) {
  179 + geolib.extend(elevation);
  180 + return geolib;
  181 + });
  182 +
  183 + // we're in a browser
  184 + } else {
  185 +
  186 + geolib.extend(elevation);
  187 +
  188 + }
  189 +
190 }(this, this.geolib)); 190 }(this, this.geolib));
191 \ No newline at end of file 191 \ No newline at end of file
src/main/resources/static/real_control_v2/geolib/geolib.elevation.min.js
1 -/*! geolib.elevation 2.0.21 by Manuel Bieh  
2 -*  
3 -* Elevation Addon for Geolib.js  
4 -*  
5 -* @author Manuel Bieh  
6 -* @url http://www.manuelbieh.com/  
7 -* @version 2.0.21  
8 -* @license MIT  
9 -*/ 1 +/*! geolib.elevation 2.0.21 by Manuel Bieh
  2 +*
  3 +* Elevation Addon for Geolib.js
  4 +*
  5 +* @author Manuel Bieh
  6 +* @url http://www.manuelbieh.com/
  7 +* @version 2.0.21
  8 +* @license MIT
  9 +*/
10 !function(a,b,c){var d={getElevation:function(){"undefined"!=typeof a.navigator?this.getElevationClient.apply(this,arguments):this.getElevationServer.apply(this,arguments)},getElevationClient:function(b,c){if(!a.google)throw new Error("Google maps api not loaded");if(0===b.length)return c(null,null);if(1===b.length)return c(new Error("getElevation requires at least 2 points."));for(var d=[],e=0;e<b.length;e++)d.push(new google.maps.LatLng(this.latitude(b[e]),this.longitude(b[e])));var f={path:d,samples:d.length},g=new google.maps.ElevationService,h=this;g.getElevationAlongPath(f,function(a,d){h.elevationHandler(a,d,b,c)})},getElevationServer:function(a,b){if(0===a.length)return b(null,null);if(1===a.length)return b(new Error("getElevation requires at least 2 points."));for(var c=require("googlemaps"),d=[],e=0;e<a.length;e++)d.push(this.latitude(a[e])+","+this.longitude(a[e]));var f=this;c.elevationFromPath(d.join("|"),d.length,function(c,d){f.elevationHandler(d.results,d.status,a,b)})},elevationHandler:function(a,b,c,d){var e=[];if("OK"==b){for(var f=0;f<a.length;f++)e.push({lat:this.latitude(c[f]),lng:this.longitude(c[f]),elev:a[f].elevation});d(null,e)}else d(new Error("Could not get elevation using Google's API"),elevationResult.status)},getGrade:function(a){var b=Math.abs(this.elevation(a[a.length-1])-this.elevation(a[0])),c=this.getPathLength(a);return Math.floor(b/c*100)},getTotalElevationGainAndLoss:function(a){for(var b=0,c=0,d=0;d<a.length-1;d++){var e=this.elevation(a[d])-this.elevation(a[d+1]);e>0?c+=e:b+=Math.abs(e)}return{gain:b,loss:c}}};"undefined"!=typeof module&&"undefined"!=typeof module.exports?(b=require("geolib"),b.extend(d)):"function"==typeof define&&define.amd?define(["geolib"],function(a){return a.extend(d),a}):b.extend(d)}(this,this.geolib); 10 !function(a,b,c){var d={getElevation:function(){"undefined"!=typeof a.navigator?this.getElevationClient.apply(this,arguments):this.getElevationServer.apply(this,arguments)},getElevationClient:function(b,c){if(!a.google)throw new Error("Google maps api not loaded");if(0===b.length)return c(null,null);if(1===b.length)return c(new Error("getElevation requires at least 2 points."));for(var d=[],e=0;e<b.length;e++)d.push(new google.maps.LatLng(this.latitude(b[e]),this.longitude(b[e])));var f={path:d,samples:d.length},g=new google.maps.ElevationService,h=this;g.getElevationAlongPath(f,function(a,d){h.elevationHandler(a,d,b,c)})},getElevationServer:function(a,b){if(0===a.length)return b(null,null);if(1===a.length)return b(new Error("getElevation requires at least 2 points."));for(var c=require("googlemaps"),d=[],e=0;e<a.length;e++)d.push(this.latitude(a[e])+","+this.longitude(a[e]));var f=this;c.elevationFromPath(d.join("|"),d.length,function(c,d){f.elevationHandler(d.results,d.status,a,b)})},elevationHandler:function(a,b,c,d){var e=[];if("OK"==b){for(var f=0;f<a.length;f++)e.push({lat:this.latitude(c[f]),lng:this.longitude(c[f]),elev:a[f].elevation});d(null,e)}else d(new Error("Could not get elevation using Google's API"),elevationResult.status)},getGrade:function(a){var b=Math.abs(this.elevation(a[a.length-1])-this.elevation(a[0])),c=this.getPathLength(a);return Math.floor(b/c*100)},getTotalElevationGainAndLoss:function(a){for(var b=0,c=0,d=0;d<a.length-1;d++){var e=this.elevation(a[d])-this.elevation(a[d+1]);e>0?c+=e:b+=Math.abs(e)}return{gain:b,loss:c}}};"undefined"!=typeof module&&"undefined"!=typeof module.exports?(b=require("geolib"),b.extend(d)):"function"==typeof define&&define.amd?define(["geolib"],function(a){return a.extend(d),a}):b.extend(d)}(this,this.geolib);
11 \ No newline at end of file 11 \ No newline at end of file
src/main/resources/static/real_control_v2/geolib/geolib.isPointInsideRobust.js
1 -/*! geolib.isPointInsideRobust 2.0.21  
2 -* !!EXPERIMENTAL!!  
3 -*  
4 -* Robust version of isPointInside for Geolib.js  
5 -*  
6 -* Based on https://github.com/mikolalysenko/robust-point-in-polygon  
7 -* by Mikola Lysenko, licensed under MIT  
8 -*  
9 -* @author Manuel Bieh  
10 -* @url http://www.manuelbieh.com/  
11 -* @version 2.0.21  
12 -* @license MIT  
13 -*  
14 -*/  
15 -;(function(global, geolib, undefined) {  
16 -  
17 - var addOn = function(geolib) {  
18 -  
19 - var SPLITTER = +(Math.pow(2, 27) + 1.0);  
20 -  
21 - var NUM_EXPAND = 5;  
22 - var EPSILON = 1.1102230246251565e-16;  
23 - var ERRBOUND3 = (3.0 + 16.0 * EPSILON) * EPSILON;  
24 - var ERRBOUND4 = (7.0 + 56.0 * EPSILON) * EPSILON;  
25 -  
26 - var twoProduct = function(a, b, result) {  
27 - var x = a * b;  
28 - var c = SPLITTER * a;  
29 - var abig = c - a;  
30 - var ahi = c - abig;  
31 - var alo = a - ahi;  
32 - var d = SPLITTER * b;  
33 - var bbig = d - b;  
34 - var bhi = d - bbig;  
35 - var blo = b - bhi;  
36 - var err1 = x - (ahi * bhi);  
37 - var err2 = err1 - (alo * bhi);  
38 - var err3 = err2 - (ahi * blo);  
39 - var y = alo * blo - err3;  
40 - if(result) {  
41 - result[0] = y;  
42 - result[1] = x;  
43 - return result;  
44 - }  
45 - return [ y, x ];  
46 - };  
47 -  
48 - var fastTwoSum = function(a, b, result) {  
49 - var x = a + b;  
50 - var bv = x - a;  
51 - var av = x - bv;  
52 - var br = b - bv;  
53 - var ar = a - av;  
54 - if(result) {  
55 - result[0] = ar + br;  
56 - result[1] = x;  
57 - return result;  
58 - }  
59 - return [ar+br, x];  
60 - };  
61 -  
62 - var twoSum = fastTwoSum;  
63 -  
64 - var linearExpansionSum = function(e, f) {  
65 - var ne = e.length|0;  
66 - var nf = f.length|0;  
67 - if(ne === 1 && nf === 1) {  
68 - return scalarScalar(e[0], f[0]);  
69 - }  
70 - var n = ne + nf;  
71 - var g = new Array(n);  
72 - var count = 0;  
73 - var eptr = 0;  
74 - var fptr = 0;  
75 - var abs = Math.abs;  
76 - var ei = e[eptr];  
77 - var ea = abs(ei);  
78 - var fi = f[fptr];  
79 - var fa = abs(fi);  
80 - var a, b;  
81 - if(ea < fa) {  
82 - b = ei;  
83 - eptr += 1;  
84 - if(eptr < ne) {  
85 - ei = e[eptr];  
86 - ea = abs(ei);  
87 - }  
88 - } else {  
89 - b = fi;  
90 - fptr += 1;  
91 - if(fptr < nf) {  
92 - fi = f[fptr];  
93 - fa = abs(fi);  
94 - }  
95 - }  
96 - if((eptr < ne && ea < fa) || (fptr >= nf)) {  
97 - a = ei;  
98 - eptr += 1;  
99 - if(eptr < ne) {  
100 - ei = e[eptr];  
101 - ea = abs(ei);  
102 - }  
103 - } else {  
104 - a = fi;  
105 - fptr += 1;  
106 - if(fptr < nf) {  
107 - fi = f[fptr];  
108 - fa = abs(fi);  
109 - }  
110 - }  
111 - var x = a + b;  
112 - var bv = x - a;  
113 - var y = b - bv;  
114 - var q0 = y;  
115 - var q1 = x;  
116 - var _x, _bv, _av, _br, _ar;  
117 - while(eptr < ne && fptr < nf) {  
118 - if(ea < fa) {  
119 - a = ei;  
120 - eptr += 1;  
121 - if(eptr < ne) {  
122 - ei = e[eptr];  
123 - ea = abs(ei);  
124 - }  
125 - } else {  
126 - a = fi;  
127 - fptr += 1;  
128 - if(fptr < nf) {  
129 - fi = f[fptr];  
130 - fa = abs(fi);  
131 - }  
132 - }  
133 - b = q0;  
134 - x = a + b;  
135 - bv = x - a;  
136 - y = b - bv;  
137 - if(y) {  
138 - g[count++] = y;  
139 - }  
140 - _x = q1 + x;  
141 - _bv = _x - q1;  
142 - _av = _x - _bv;  
143 - _br = x - _bv;  
144 - _ar = q1 - _av;  
145 - q0 = _ar + _br;  
146 - q1 = _x;  
147 - }  
148 - while(eptr < ne) {  
149 - a = ei;  
150 - b = q0;  
151 - x = a + b;  
152 - bv = x - a;  
153 - y = b - bv;  
154 - if(y) {  
155 - g[count++] = y;  
156 - }  
157 - _x = q1 + x;  
158 - _bv = _x - q1;  
159 - _av = _x - _bv;  
160 - _br = x - _bv;  
161 - _ar = q1 - _av;  
162 - q0 = _ar + _br;  
163 - q1 = _x;  
164 - eptr += 1;  
165 - if(eptr < ne) {  
166 - ei = e[eptr];  
167 - }  
168 - }  
169 - while(fptr < nf) {  
170 - a = fi;  
171 - b = q0;  
172 - x = a + b;  
173 - bv = x - a;  
174 - y = b - bv;  
175 - if(y) {  
176 - g[count++] = y;  
177 - }  
178 - _x = q1 + x;  
179 - _bv = _x - q1;  
180 - _av = _x - _bv;  
181 - _br = x - _bv;  
182 - _ar = q1 - _av;  
183 - q0 = _ar + _br;  
184 - q1 = _x;  
185 - fptr += 1;  
186 - if(fptr < nf) {  
187 - fi = f[fptr];  
188 - }  
189 - }  
190 - if(q0) {  
191 - g[count++] = q0;  
192 - }  
193 - if(q1) {  
194 - g[count++] = q1;  
195 - }  
196 - if(!count) {  
197 - g[count++] = 0.0;  
198 - }  
199 - g.length = count;  
200 - return g;  
201 - };  
202 -  
203 - var robustSum = linearExpansionSum;  
204 -  
205 - var scaleLinearExpansion = function(e, scale) {  
206 - var n = e.length;  
207 - if(n === 1) {  
208 - var ts = twoProduct(e[0], scale);  
209 - if(ts[0]) {  
210 - return ts;  
211 - }  
212 - return [ ts[1] ];  
213 - }  
214 - var g = new Array(2 * n);  
215 - var q = [0.1, 0.1];  
216 - var t = [0.1, 0.1];  
217 - var count = 0;  
218 - twoProduct(e[0], scale, q);  
219 - if(q[0]) {  
220 - g[count++] = q[0];  
221 - }  
222 - for(var i=1; i<n; ++i) {  
223 - twoProduct(e[i], scale, t);  
224 - var pq = q[1];  
225 - twoSum(pq, t[0], q);  
226 - if(q[0]) {  
227 - g[count++] = q[0];  
228 - }  
229 - var a = t[1];  
230 - var b = q[1];  
231 - var x = a + b;  
232 - var bv = x - a;  
233 - var y = b - bv;  
234 - q[1] = x;  
235 - if(y) {  
236 - g[count++] = y;  
237 - }  
238 - }  
239 - if(q[1]) {  
240 - g[count++] = q[1];  
241 - }  
242 - if(count === 0) {  
243 - g[count++] = 0.0;  
244 - }  
245 - g.length = count;  
246 - return g;  
247 - };  
248 -  
249 - var robustScale = scaleLinearExpansion;  
250 -  
251 - var scalarScalar = function(a, b) {  
252 - var x = a + b;  
253 - var bv = x - a;  
254 - var av = x - bv;  
255 - var br = b - bv;  
256 - var ar = a - av;  
257 - var y = ar + br;  
258 - if(y) {  
259 - return [y, x];  
260 - }  
261 - return [x];  
262 - };  
263 -  
264 - var robustSubtract = function(e, f) {  
265 - var ne = e.length|0;  
266 - var nf = f.length|0;  
267 - if(ne === 1 && nf === 1) {  
268 - return scalarScalar(e[0], -f[0]);  
269 - }  
270 - var n = ne + nf;  
271 - var g = new Array(n);  
272 - var count = 0;  
273 - var eptr = 0;  
274 - var fptr = 0;  
275 - var abs = Math.abs;  
276 - var ei = e[eptr];  
277 - var ea = abs(ei);  
278 - var fi = -f[fptr];  
279 - var fa = abs(fi);  
280 - var a, b;  
281 - if(ea < fa) {  
282 - b = ei;  
283 - eptr += 1;  
284 - if(eptr < ne) {  
285 - ei = e[eptr];  
286 - ea = abs(ei);  
287 - }  
288 - } else {  
289 - b = fi;  
290 - fptr += 1;  
291 - if(fptr < nf) {  
292 - fi = -f[fptr];  
293 - fa = abs(fi);  
294 - }  
295 - }  
296 - if((eptr < ne && ea < fa) || (fptr >= nf)) {  
297 - a = ei;  
298 - eptr += 1;  
299 - if(eptr < ne) {  
300 - ei = e[eptr];  
301 - ea = abs(ei);  
302 - }  
303 - } else {  
304 - a = fi;  
305 - fptr += 1;  
306 - if(fptr < nf) {  
307 - fi = -f[fptr];  
308 - fa = abs(fi);  
309 - }  
310 - }  
311 - var x = a + b;  
312 - var bv = x - a;  
313 - var y = b - bv;  
314 - var q0 = y;  
315 - var q1 = x;  
316 - var _x, _bv, _av, _br, _ar;  
317 - while(eptr < ne && fptr < nf) {  
318 - if(ea < fa) {  
319 - a = ei;  
320 - eptr += 1;  
321 - if(eptr < ne) {  
322 - ei = e[eptr];  
323 - ea = abs(ei);  
324 - }  
325 - } else {  
326 - a = fi;  
327 - fptr += 1;  
328 - if(fptr < nf) {  
329 - fi = -f[fptr];  
330 - fa = abs(fi);  
331 - }  
332 - }  
333 - b = q0;  
334 - x = a + b;  
335 - bv = x - a;  
336 - y = b - bv;  
337 - if(y) {  
338 - g[count++] = y;  
339 - }  
340 - _x = q1 + x;  
341 - _bv = _x - q1;  
342 - _av = _x - _bv;  
343 - _br = x - _bv;  
344 - _ar = q1 - _av;  
345 - q0 = _ar + _br;  
346 - q1 = _x;  
347 - }  
348 - while(eptr < ne) {  
349 - a = ei;  
350 - b = q0;  
351 - x = a + b;  
352 - bv = x - a;  
353 - y = b - bv;  
354 - if(y) {  
355 - g[count++] = y;  
356 - }  
357 - _x = q1 + x;  
358 - _bv = _x - q1;  
359 - _av = _x - _bv;  
360 - _br = x - _bv;  
361 - _ar = q1 - _av;  
362 - q0 = _ar + _br;  
363 - q1 = _x;  
364 - eptr += 1;  
365 - if(eptr < ne) {  
366 - ei = e[eptr];  
367 - }  
368 - }  
369 - while(fptr < nf) {  
370 - a = fi;  
371 - b = q0;  
372 - x = a + b;  
373 - bv = x - a;  
374 - y = b - bv;  
375 - if(y) {  
376 - g[count++] = y;  
377 - }  
378 - _x = q1 + x;  
379 - _bv = _x - q1;  
380 - _av = _x - _bv;  
381 - _br = x - _bv;  
382 - _ar = q1 - _av;  
383 - q0 = _ar + _br;  
384 - q1 = _x;  
385 - fptr += 1;  
386 - if(fptr < nf) {  
387 - fi = -f[fptr];  
388 - }  
389 - }  
390 - if(q0) {  
391 - g[count++] = q0;  
392 - }  
393 - if(q1) {  
394 - g[count++] = q1;  
395 - }  
396 - if(!count) {  
397 - g[count++] = 0.0;  
398 - }  
399 - g.length = count;  
400 - return g;  
401 - };  
402 -  
403 - var cofactor = function(m, c) {  
404 - var result = new Array(m.length-1);  
405 - for(var i=1; i<m.length; ++i) {  
406 - var r = result[i-1] = new Array(m.length-1);  
407 - for(var j=0,k=0; j<m.length; ++j) {  
408 - if(j === c) {  
409 - continue;  
410 - }  
411 - r[k++] = m[i][j];  
412 - }  
413 - }  
414 - return result;  
415 - };  
416 -  
417 - var matrix = function(n) {  
418 - var result = new Array(n);  
419 - for(var i=0; i<n; ++i) {  
420 - result[i] = new Array(n);  
421 - for(var j=0; j<n; ++j) {  
422 - result[i][j] = ["m", j, "[", (n-i-1), "]"].join("");  
423 - }  
424 - }  
425 - return result;  
426 - };  
427 -  
428 - var sign = function(n) {  
429 - if(n & 1) {  
430 - return "-";  
431 - }  
432 - return "";  
433 - };  
434 -  
435 - var generateSum = function(expr) {  
436 - if(expr.length === 1) {  
437 - return expr[0];  
438 - } else if(expr.length === 2) {  
439 - return ["sum(", expr[0], ",", expr[1], ")"].join("");  
440 - } else {  
441 - var m = expr.length>>1;  
442 - return ["sum(", generateSum(expr.slice(0, m)), ",", generateSum(expr.slice(m)), ")"].join("");  
443 - }  
444 - };  
445 -  
446 - var determinant = function(m) {  
447 - if(m.length === 2) {  
448 - return [["sum(prod(", m[0][0], ",", m[1][1], "),prod(-", m[0][1], ",", m[1][0], "))"].join("")];  
449 - } else {  
450 - var expr = [];  
451 - for(var i=0; i<m.length; ++i) {  
452 - expr.push(["scale(", generateSum(determinant(cofactor(m, i))), ",", sign(i), m[0][i], ")"].join(""));  
453 - }  
454 - return expr;  
455 - }  
456 - };  
457 -  
458 - var orientation = function(n) {  
459 - var pos = [];  
460 - var neg = [];  
461 - var m = matrix(n);  
462 - var args = [];  
463 - for(var i=0; i<n; ++i) {  
464 - if((i&1)===0) {  
465 - pos.push.apply(pos, determinant(cofactor(m, i)));  
466 - } else {  
467 - neg.push.apply(neg, determinant(cofactor(m, i)));  
468 - }  
469 - args.push("m" + i);  
470 - }  
471 - var posExpr = generateSum(pos);  
472 - var negExpr = generateSum(neg);  
473 - var funcName = "orientation" + n + "Exact";  
474 - var code = [  
475 - "function ",  
476 - funcName,  
477 - "(", args.join(), "){var p=",  
478 - posExpr,  
479 - ",n=",  
480 - negExpr,  
481 - ",d=sub(p,n);return d[d.length-1];};return ",  
482 - funcName  
483 - ].join("");  
484 - var proc = new Function("sum", "prod", "scale", "sub", code);  
485 - return proc(robustSum, twoProduct, robustScale, robustSubtract);  
486 - };  
487 -  
488 - var orient;  
489 - var orientation3Exact = orientation(3);  
490 - var orientation4Exact = orientation(4);  
491 -  
492 - var CACHED = [  
493 - function orientation0() { return 0; },  
494 - function orientation1() { return 0; },  
495 - function orientation2(a, b) {  
496 - return b[0] - a[0];  
497 - },  
498 - function orientation3(a, b, c) {  
499 - var l = (a[1] - c[1]) * (b[0] - c[0]);  
500 - var r = (a[0] - c[0]) * (b[1] - c[1]);  
501 - var det = l - r;  
502 - var s;  
503 - if(l > 0) {  
504 - if(r <= 0) {  
505 - return det;  
506 - } else {  
507 - s = l + r;  
508 - }  
509 - } else if(l < 0) {  
510 - if(r >= 0) {  
511 - return det;  
512 - } else {  
513 - s = -(l + r);  
514 - }  
515 - } else {  
516 - return det;  
517 - }  
518 - var tol = ERRBOUND3 * s;  
519 - if(det >= tol || det <= -tol) {  
520 - return det;  
521 - }  
522 - return orientation3Exact(a, b, c);  
523 - },  
524 - function orientation4(a,b,c,d) {  
525 - var adx = a[0] - d[0];  
526 - var bdx = b[0] - d[0];  
527 - var cdx = c[0] - d[0];  
528 - var ady = a[1] - d[1];  
529 - var bdy = b[1] - d[1];  
530 - var cdy = c[1] - d[1];  
531 - var adz = a[2] - d[2];  
532 - var bdz = b[2] - d[2];  
533 - var cdz = c[2] - d[2];  
534 - var bdxcdy = bdx * cdy;  
535 - var cdxbdy = cdx * bdy;  
536 - var cdxady = cdx * ady;  
537 - var adxcdy = adx * cdy;  
538 - var adxbdy = adx * bdy;  
539 - var bdxady = bdx * ady;  
540 - var det = adz * (bdxcdy - cdxbdy) +  
541 - bdz * (cdxady - adxcdy) +  
542 - cdz * (adxbdy - bdxady);  
543 - var permanent = (Math.abs(bdxcdy) + Math.abs(cdxbdy)) * Math.abs(adz) +  
544 - (Math.abs(cdxady) + Math.abs(adxcdy)) * Math.abs(bdz) +  
545 - (Math.abs(adxbdy) + Math.abs(bdxady)) * Math.abs(cdz);  
546 - var tol = ERRBOUND4 * permanent;  
547 - if ((det > tol) || (-det > tol)) {  
548 - return det;  
549 - }  
550 - return orientation4Exact(a,b,c,d);  
551 - }  
552 - ];  
553 -  
554 - var slowOrient = function(args) {  
555 - var proc = CACHED[args.length];  
556 - if(!proc) {  
557 - proc = CACHED[args.length] = orientation(args.length);  
558 - }  
559 - return proc.apply(undefined, args);  
560 - };  
561 -  
562 - var generateOrientationProc = function() {  
563 - while(CACHED.length <= NUM_EXPAND) {  
564 - CACHED.push(orientation(CACHED.length));  
565 - }  
566 - var args = [];  
567 - var procArgs = ["slow"];  
568 - for(var i=0; i<=NUM_EXPAND; ++i) {  
569 - args.push("a" + i);  
570 - procArgs.push("o" + i);  
571 - }  
572 - var code = [  
573 - "function getOrientation(",  
574 - args.join(),  
575 - "){switch(arguments.length){case 0:case 1:return 0;"  
576 - ];  
577 - for(i=2; i<=NUM_EXPAND; ++i) {  
578 - code.push("case ", i, ":return o", i, "(", args.slice(0, i).join(), ");");  
579 - }  
580 - code.push("}var s=new Array(arguments.length);for(var i=0;i<arguments.length;++i){s[i]=arguments[i]};return slow(s);}return getOrientation");  
581 - procArgs.push(code.join(""));  
582 -  
583 - var proc = Function.apply(undefined, procArgs);  
584 - orient = proc.apply(undefined, [slowOrient].concat(CACHED));  
585 - for(i=0; i<=NUM_EXPAND; ++i) {  
586 - orient[i] = CACHED[i];  
587 - }  
588 - };  
589 -  
590 - generateOrientationProc();  
591 -  
592 - var robustPointInPolygon = function(vs, point) {  
593 - // transform from geolib format to array syntax  
594 - var x = geolib.longitude(point);  
595 - var y = geolib.latitude(point);  
596 - var coords = vs.map(function(coords) {  
597 - return [geolib.longitude(coords), geolib.latitude(coords)];  
598 - });  
599 -  
600 - vs = coords;  
601 - point = [x,y];  
602 -  
603 - var n = vs.length;  
604 - var inside = 1;  
605 - var lim = n;  
606 -  
607 - var s, c, yk, px, p;  
608 -  
609 - for(var i = 0, j = n-1; i<lim; j=i++) {  
610 - var a = vs[i];  
611 - var b = vs[j];  
612 - var yi = a[1];  
613 - var yj = b[1];  
614 - if(yj < yi) {  
615 - if(yj < y && y < yi) {  
616 - s = orient(a, b, point);  
617 - if(s === 0) {  
618 - return 0;  
619 - } else {  
620 - inside ^= (0 < s)|0;  
621 - }  
622 - } else if(y === yi) {  
623 - c = vs[(i+1)%n];  
624 - yk = c[1];  
625 - if(yi < yk) {  
626 - s = orient(a, b, point);  
627 - if(s === 0) {  
628 - return 0;  
629 - } else {  
630 - inside ^= (0 < s)|0;  
631 - }  
632 - }  
633 - }  
634 - } else if(yi < yj) {  
635 - if(yi < y && y < yj) {  
636 - s = orient(a, b, point);  
637 - if(s === 0) {  
638 - return 0;  
639 - } else {  
640 - inside ^= (s < 0)|0;  
641 - }  
642 - } else if(y === yi) {  
643 - c = vs[(i+1)%n];  
644 - yk = c[1];  
645 - if(yk < yi) {  
646 - s = orient(a, b, point);  
647 - if(s === 0) {  
648 - return 0;  
649 - } else {  
650 - inside ^= (s < 0)|0;  
651 - }  
652 - }  
653 - }  
654 - } else if(y === yi) {  
655 - var x0 = Math.min(a[0], b[0]);  
656 - var x1 = Math.max(a[0], b[0]);  
657 - if(i === 0) {  
658 - while(j>0) {  
659 - var k = (j+n-1)%n;  
660 - p = vs[k];  
661 - if(p[1] !== y) {  
662 - break;  
663 - }  
664 - px = p[0];  
665 - x0 = Math.min(x0, px);  
666 - x1 = Math.max(x1, px);  
667 - j = k;  
668 - }  
669 - if(j === 0) {  
670 - if(x0 <= x && x <= x1) {  
671 - return 0;  
672 - }  
673 - return 1;  
674 - }  
675 - lim = j+1;  
676 - }  
677 - var y0 = vs[(j+n-1)%n][1];  
678 - while(i+1<lim) {  
679 - p = vs[i+1];  
680 - if(p[1] !== y) {  
681 - break;  
682 - }  
683 - px = p[0];  
684 - x0 = Math.min(x0, px);  
685 - x1 = Math.max(x1, px);  
686 - i += 1;  
687 - }  
688 - if(x0 <= x && x <= x1) {  
689 - return 0;  
690 - }  
691 - var y1 = vs[(i+1)%n][1];  
692 - if(x < x0 && (y0 < y !== y1 < y)) {  
693 - inside ^= 1;  
694 - }  
695 - }  
696 - }  
697 - return 2 * inside - 1;  
698 - };  
699 -  
700 - return {  
701 -  
702 - /**  
703 - * @param object coordinate to check e.g. {latitude: 51.5023, longitude: 7.3815}  
704 - * @param array array with coords e.g. [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]  
705 - * @return integer -1 if point is inside, 0 if point is on boundaries, 1 if point is outside  
706 - */  
707 - isPointInsideRobust: function(latlng, coords) {  
708 - return robustPointInPolygon(coords, latlng);  
709 - },  
710 -  
711 - isInside: function() {  
712 - return this.isPointInsideRobust.apply(this, arguments);  
713 - }  
714 -  
715 - };  
716 -  
717 - };  
718 -  
719 -  
720 - // Node module  
721 - if (typeof module !== 'undefined' &&  
722 - typeof module.exports !== 'undefined') {  
723 -  
724 - module.exports = function(geolib) {  
725 - geolib.extend(addOn(geolib), true);  
726 - return geolib;  
727 - };  
728 -  
729 - // AMD module  
730 - } else if (typeof define === "function" && define.amd) {  
731 -  
732 - define(["geolib"], function (geolib) {  
733 - geolib.extend(addOn(geolib), true);  
734 - return geolib;  
735 - });  
736 -  
737 - // we're in a browser  
738 - } else {  
739 -  
740 - geolib.extend(addOn(geolib), true);  
741 -  
742 - }  
743 -  
744 -}(this, this.geolib)); 1 +/*! geolib.isPointInsideRobust 2.0.21
  2 +* !!EXPERIMENTAL!!
  3 +*
  4 +* Robust version of isPointInside for Geolib.js
  5 +*
  6 +* Based on https://github.com/mikolalysenko/robust-point-in-polygon
  7 +* by Mikola Lysenko, licensed under MIT
  8 +*
  9 +* @author Manuel Bieh
  10 +* @url http://www.manuelbieh.com/
  11 +* @version 2.0.21
  12 +* @license MIT
  13 +*
  14 +*/
  15 +;(function(global, geolib, undefined) {
  16 +
  17 + var addOn = function(geolib) {
  18 +
  19 + var SPLITTER = +(Math.pow(2, 27) + 1.0);
  20 +
  21 + var NUM_EXPAND = 5;
  22 + var EPSILON = 1.1102230246251565e-16;
  23 + var ERRBOUND3 = (3.0 + 16.0 * EPSILON) * EPSILON;
  24 + var ERRBOUND4 = (7.0 + 56.0 * EPSILON) * EPSILON;
  25 +
  26 + var twoProduct = function(a, b, result) {
  27 + var x = a * b;
  28 + var c = SPLITTER * a;
  29 + var abig = c - a;
  30 + var ahi = c - abig;
  31 + var alo = a - ahi;
  32 + var d = SPLITTER * b;
  33 + var bbig = d - b;
  34 + var bhi = d - bbig;
  35 + var blo = b - bhi;
  36 + var err1 = x - (ahi * bhi);
  37 + var err2 = err1 - (alo * bhi);
  38 + var err3 = err2 - (ahi * blo);
  39 + var y = alo * blo - err3;
  40 + if(result) {
  41 + result[0] = y;
  42 + result[1] = x;
  43 + return result;
  44 + }
  45 + return [ y, x ];
  46 + };
  47 +
  48 + var fastTwoSum = function(a, b, result) {
  49 + var x = a + b;
  50 + var bv = x - a;
  51 + var av = x - bv;
  52 + var br = b - bv;
  53 + var ar = a - av;
  54 + if(result) {
  55 + result[0] = ar + br;
  56 + result[1] = x;
  57 + return result;
  58 + }
  59 + return [ar+br, x];
  60 + };
  61 +
  62 + var twoSum = fastTwoSum;
  63 +
  64 + var linearExpansionSum = function(e, f) {
  65 + var ne = e.length|0;
  66 + var nf = f.length|0;
  67 + if(ne === 1 && nf === 1) {
  68 + return scalarScalar(e[0], f[0]);
  69 + }
  70 + var n = ne + nf;
  71 + var g = new Array(n);
  72 + var count = 0;
  73 + var eptr = 0;
  74 + var fptr = 0;
  75 + var abs = Math.abs;
  76 + var ei = e[eptr];
  77 + var ea = abs(ei);
  78 + var fi = f[fptr];
  79 + var fa = abs(fi);
  80 + var a, b;
  81 + if(ea < fa) {
  82 + b = ei;
  83 + eptr += 1;
  84 + if(eptr < ne) {
  85 + ei = e[eptr];
  86 + ea = abs(ei);
  87 + }
  88 + } else {
  89 + b = fi;
  90 + fptr += 1;
  91 + if(fptr < nf) {
  92 + fi = f[fptr];
  93 + fa = abs(fi);
  94 + }
  95 + }
  96 + if((eptr < ne && ea < fa) || (fptr >= nf)) {
  97 + a = ei;
  98 + eptr += 1;
  99 + if(eptr < ne) {
  100 + ei = e[eptr];
  101 + ea = abs(ei);
  102 + }
  103 + } else {
  104 + a = fi;
  105 + fptr += 1;
  106 + if(fptr < nf) {
  107 + fi = f[fptr];
  108 + fa = abs(fi);
  109 + }
  110 + }
  111 + var x = a + b;
  112 + var bv = x - a;
  113 + var y = b - bv;
  114 + var q0 = y;
  115 + var q1 = x;
  116 + var _x, _bv, _av, _br, _ar;
  117 + while(eptr < ne && fptr < nf) {
  118 + if(ea < fa) {
  119 + a = ei;
  120 + eptr += 1;
  121 + if(eptr < ne) {
  122 + ei = e[eptr];
  123 + ea = abs(ei);
  124 + }
  125 + } else {
  126 + a = fi;
  127 + fptr += 1;
  128 + if(fptr < nf) {
  129 + fi = f[fptr];
  130 + fa = abs(fi);
  131 + }
  132 + }
  133 + b = q0;
  134 + x = a + b;
  135 + bv = x - a;
  136 + y = b - bv;
  137 + if(y) {
  138 + g[count++] = y;
  139 + }
  140 + _x = q1 + x;
  141 + _bv = _x - q1;
  142 + _av = _x - _bv;
  143 + _br = x - _bv;
  144 + _ar = q1 - _av;
  145 + q0 = _ar + _br;
  146 + q1 = _x;
  147 + }
  148 + while(eptr < ne) {
  149 + a = ei;
  150 + b = q0;
  151 + x = a + b;
  152 + bv = x - a;
  153 + y = b - bv;
  154 + if(y) {
  155 + g[count++] = y;
  156 + }
  157 + _x = q1 + x;
  158 + _bv = _x - q1;
  159 + _av = _x - _bv;
  160 + _br = x - _bv;
  161 + _ar = q1 - _av;
  162 + q0 = _ar + _br;
  163 + q1 = _x;
  164 + eptr += 1;
  165 + if(eptr < ne) {
  166 + ei = e[eptr];
  167 + }
  168 + }
  169 + while(fptr < nf) {
  170 + a = fi;
  171 + b = q0;
  172 + x = a + b;
  173 + bv = x - a;
  174 + y = b - bv;
  175 + if(y) {
  176 + g[count++] = y;
  177 + }
  178 + _x = q1 + x;
  179 + _bv = _x - q1;
  180 + _av = _x - _bv;
  181 + _br = x - _bv;
  182 + _ar = q1 - _av;
  183 + q0 = _ar + _br;
  184 + q1 = _x;
  185 + fptr += 1;
  186 + if(fptr < nf) {
  187 + fi = f[fptr];
  188 + }
  189 + }
  190 + if(q0) {
  191 + g[count++] = q0;
  192 + }
  193 + if(q1) {
  194 + g[count++] = q1;
  195 + }
  196 + if(!count) {
  197 + g[count++] = 0.0;
  198 + }
  199 + g.length = count;
  200 + return g;
  201 + };
  202 +
  203 + var robustSum = linearExpansionSum;
  204 +
  205 + var scaleLinearExpansion = function(e, scale) {
  206 + var n = e.length;
  207 + if(n === 1) {
  208 + var ts = twoProduct(e[0], scale);
  209 + if(ts[0]) {
  210 + return ts;
  211 + }
  212 + return [ ts[1] ];
  213 + }
  214 + var g = new Array(2 * n);
  215 + var q = [0.1, 0.1];
  216 + var t = [0.1, 0.1];
  217 + var count = 0;
  218 + twoProduct(e[0], scale, q);
  219 + if(q[0]) {
  220 + g[count++] = q[0];
  221 + }
  222 + for(var i=1; i<n; ++i) {
  223 + twoProduct(e[i], scale, t);
  224 + var pq = q[1];
  225 + twoSum(pq, t[0], q);
  226 + if(q[0]) {
  227 + g[count++] = q[0];
  228 + }
  229 + var a = t[1];
  230 + var b = q[1];
  231 + var x = a + b;
  232 + var bv = x - a;
  233 + var y = b - bv;
  234 + q[1] = x;
  235 + if(y) {
  236 + g[count++] = y;
  237 + }
  238 + }
  239 + if(q[1]) {
  240 + g[count++] = q[1];
  241 + }
  242 + if(count === 0) {
  243 + g[count++] = 0.0;
  244 + }
  245 + g.length = count;
  246 + return g;
  247 + };
  248 +
  249 + var robustScale = scaleLinearExpansion;
  250 +
  251 + var scalarScalar = function(a, b) {
  252 + var x = a + b;
  253 + var bv = x - a;
  254 + var av = x - bv;
  255 + var br = b - bv;
  256 + var ar = a - av;
  257 + var y = ar + br;
  258 + if(y) {
  259 + return [y, x];
  260 + }
  261 + return [x];
  262 + };
  263 +
  264 + var robustSubtract = function(e, f) {
  265 + var ne = e.length|0;
  266 + var nf = f.length|0;
  267 + if(ne === 1 && nf === 1) {
  268 + return scalarScalar(e[0], -f[0]);
  269 + }
  270 + var n = ne + nf;
  271 + var g = new Array(n);
  272 + var count = 0;
  273 + var eptr = 0;
  274 + var fptr = 0;
  275 + var abs = Math.abs;
  276 + var ei = e[eptr];
  277 + var ea = abs(ei);
  278 + var fi = -f[fptr];
  279 + var fa = abs(fi);
  280 + var a, b;
  281 + if(ea < fa) {
  282 + b = ei;
  283 + eptr += 1;
  284 + if(eptr < ne) {
  285 + ei = e[eptr];
  286 + ea = abs(ei);
  287 + }
  288 + } else {
  289 + b = fi;
  290 + fptr += 1;
  291 + if(fptr < nf) {
  292 + fi = -f[fptr];
  293 + fa = abs(fi);
  294 + }
  295 + }
  296 + if((eptr < ne && ea < fa) || (fptr >= nf)) {
  297 + a = ei;
  298 + eptr += 1;
  299 + if(eptr < ne) {
  300 + ei = e[eptr];
  301 + ea = abs(ei);
  302 + }
  303 + } else {
  304 + a = fi;
  305 + fptr += 1;
  306 + if(fptr < nf) {
  307 + fi = -f[fptr];
  308 + fa = abs(fi);
  309 + }
  310 + }
  311 + var x = a + b;
  312 + var bv = x - a;
  313 + var y = b - bv;
  314 + var q0 = y;
  315 + var q1 = x;
  316 + var _x, _bv, _av, _br, _ar;
  317 + while(eptr < ne && fptr < nf) {
  318 + if(ea < fa) {
  319 + a = ei;
  320 + eptr += 1;
  321 + if(eptr < ne) {
  322 + ei = e[eptr];
  323 + ea = abs(ei);
  324 + }
  325 + } else {
  326 + a = fi;
  327 + fptr += 1;
  328 + if(fptr < nf) {
  329 + fi = -f[fptr];
  330 + fa = abs(fi);
  331 + }
  332 + }
  333 + b = q0;
  334 + x = a + b;
  335 + bv = x - a;
  336 + y = b - bv;
  337 + if(y) {
  338 + g[count++] = y;
  339 + }
  340 + _x = q1 + x;
  341 + _bv = _x - q1;
  342 + _av = _x - _bv;
  343 + _br = x - _bv;
  344 + _ar = q1 - _av;
  345 + q0 = _ar + _br;
  346 + q1 = _x;
  347 + }
  348 + while(eptr < ne) {
  349 + a = ei;
  350 + b = q0;
  351 + x = a + b;
  352 + bv = x - a;
  353 + y = b - bv;
  354 + if(y) {
  355 + g[count++] = y;
  356 + }
  357 + _x = q1 + x;
  358 + _bv = _x - q1;
  359 + _av = _x - _bv;
  360 + _br = x - _bv;
  361 + _ar = q1 - _av;
  362 + q0 = _ar + _br;
  363 + q1 = _x;
  364 + eptr += 1;
  365 + if(eptr < ne) {
  366 + ei = e[eptr];
  367 + }
  368 + }
  369 + while(fptr < nf) {
  370 + a = fi;
  371 + b = q0;
  372 + x = a + b;
  373 + bv = x - a;
  374 + y = b - bv;
  375 + if(y) {
  376 + g[count++] = y;
  377 + }
  378 + _x = q1 + x;
  379 + _bv = _x - q1;
  380 + _av = _x - _bv;
  381 + _br = x - _bv;
  382 + _ar = q1 - _av;
  383 + q0 = _ar + _br;
  384 + q1 = _x;
  385 + fptr += 1;
  386 + if(fptr < nf) {
  387 + fi = -f[fptr];
  388 + }
  389 + }
  390 + if(q0) {
  391 + g[count++] = q0;
  392 + }
  393 + if(q1) {
  394 + g[count++] = q1;
  395 + }
  396 + if(!count) {
  397 + g[count++] = 0.0;
  398 + }
  399 + g.length = count;
  400 + return g;
  401 + };
  402 +
  403 + var cofactor = function(m, c) {
  404 + var result = new Array(m.length-1);
  405 + for(var i=1; i<m.length; ++i) {
  406 + var r = result[i-1] = new Array(m.length-1);
  407 + for(var j=0,k=0; j<m.length; ++j) {
  408 + if(j === c) {
  409 + continue;
  410 + }
  411 + r[k++] = m[i][j];
  412 + }
  413 + }
  414 + return result;
  415 + };
  416 +
  417 + var matrix = function(n) {
  418 + var result = new Array(n);
  419 + for(var i=0; i<n; ++i) {
  420 + result[i] = new Array(n);
  421 + for(var j=0; j<n; ++j) {
  422 + result[i][j] = ["m", j, "[", (n-i-1), "]"].join("");
  423 + }
  424 + }
  425 + return result;
  426 + };
  427 +
  428 + var sign = function(n) {
  429 + if(n & 1) {
  430 + return "-";
  431 + }
  432 + return "";
  433 + };
  434 +
  435 + var generateSum = function(expr) {
  436 + if(expr.length === 1) {
  437 + return expr[0];
  438 + } else if(expr.length === 2) {
  439 + return ["sum(", expr[0], ",", expr[1], ")"].join("");
  440 + } else {
  441 + var m = expr.length>>1;
  442 + return ["sum(", generateSum(expr.slice(0, m)), ",", generateSum(expr.slice(m)), ")"].join("");
  443 + }
  444 + };
  445 +
  446 + var determinant = function(m) {
  447 + if(m.length === 2) {
  448 + return [["sum(prod(", m[0][0], ",", m[1][1], "),prod(-", m[0][1], ",", m[1][0], "))"].join("")];
  449 + } else {
  450 + var expr = [];
  451 + for(var i=0; i<m.length; ++i) {
  452 + expr.push(["scale(", generateSum(determinant(cofactor(m, i))), ",", sign(i), m[0][i], ")"].join(""));
  453 + }
  454 + return expr;
  455 + }
  456 + };
  457 +
  458 + var orientation = function(n) {
  459 + var pos = [];
  460 + var neg = [];
  461 + var m = matrix(n);
  462 + var args = [];
  463 + for(var i=0; i<n; ++i) {
  464 + if((i&1)===0) {
  465 + pos.push.apply(pos, determinant(cofactor(m, i)));
  466 + } else {
  467 + neg.push.apply(neg, determinant(cofactor(m, i)));
  468 + }
  469 + args.push("m" + i);
  470 + }
  471 + var posExpr = generateSum(pos);
  472 + var negExpr = generateSum(neg);
  473 + var funcName = "orientation" + n + "Exact";
  474 + var code = [
  475 + "function ",
  476 + funcName,
  477 + "(", args.join(), "){var p=",
  478 + posExpr,
  479 + ",n=",
  480 + negExpr,
  481 + ",d=sub(p,n);return d[d.length-1];};return ",
  482 + funcName
  483 + ].join("");
  484 + var proc = new Function("sum", "prod", "scale", "sub", code);
  485 + return proc(robustSum, twoProduct, robustScale, robustSubtract);
  486 + };
  487 +
  488 + var orient;
  489 + var orientation3Exact = orientation(3);
  490 + var orientation4Exact = orientation(4);
  491 +
  492 + var CACHED = [
  493 + function orientation0() { return 0; },
  494 + function orientation1() { return 0; },
  495 + function orientation2(a, b) {
  496 + return b[0] - a[0];
  497 + },
  498 + function orientation3(a, b, c) {
  499 + var l = (a[1] - c[1]) * (b[0] - c[0]);
  500 + var r = (a[0] - c[0]) * (b[1] - c[1]);
  501 + var det = l - r;
  502 + var s;
  503 + if(l > 0) {
  504 + if(r <= 0) {
  505 + return det;
  506 + } else {
  507 + s = l + r;
  508 + }
  509 + } else if(l < 0) {
  510 + if(r >= 0) {
  511 + return det;
  512 + } else {
  513 + s = -(l + r);
  514 + }
  515 + } else {
  516 + return det;
  517 + }
  518 + var tol = ERRBOUND3 * s;
  519 + if(det >= tol || det <= -tol) {
  520 + return det;
  521 + }
  522 + return orientation3Exact(a, b, c);
  523 + },
  524 + function orientation4(a,b,c,d) {
  525 + var adx = a[0] - d[0];
  526 + var bdx = b[0] - d[0];
  527 + var cdx = c[0] - d[0];
  528 + var ady = a[1] - d[1];
  529 + var bdy = b[1] - d[1];
  530 + var cdy = c[1] - d[1];
  531 + var adz = a[2] - d[2];
  532 + var bdz = b[2] - d[2];
  533 + var cdz = c[2] - d[2];
  534 + var bdxcdy = bdx * cdy;
  535 + var cdxbdy = cdx * bdy;
  536 + var cdxady = cdx * ady;
  537 + var adxcdy = adx * cdy;
  538 + var adxbdy = adx * bdy;
  539 + var bdxady = bdx * ady;
  540 + var det = adz * (bdxcdy - cdxbdy) +
  541 + bdz * (cdxady - adxcdy) +
  542 + cdz * (adxbdy - bdxady);
  543 + var permanent = (Math.abs(bdxcdy) + Math.abs(cdxbdy)) * Math.abs(adz) +
  544 + (Math.abs(cdxady) + Math.abs(adxcdy)) * Math.abs(bdz) +
  545 + (Math.abs(adxbdy) + Math.abs(bdxady)) * Math.abs(cdz);
  546 + var tol = ERRBOUND4 * permanent;
  547 + if ((det > tol) || (-det > tol)) {
  548 + return det;
  549 + }
  550 + return orientation4Exact(a,b,c,d);
  551 + }
  552 + ];
  553 +
  554 + var slowOrient = function(args) {
  555 + var proc = CACHED[args.length];
  556 + if(!proc) {
  557 + proc = CACHED[args.length] = orientation(args.length);
  558 + }
  559 + return proc.apply(undefined, args);
  560 + };
  561 +
  562 + var generateOrientationProc = function() {
  563 + while(CACHED.length <= NUM_EXPAND) {
  564 + CACHED.push(orientation(CACHED.length));
  565 + }
  566 + var args = [];
  567 + var procArgs = ["slow"];
  568 + for(var i=0; i<=NUM_EXPAND; ++i) {
  569 + args.push("a" + i);
  570 + procArgs.push("o" + i);
  571 + }
  572 + var code = [
  573 + "function getOrientation(",
  574 + args.join(),
  575 + "){switch(arguments.length){case 0:case 1:return 0;"
  576 + ];
  577 + for(i=2; i<=NUM_EXPAND; ++i) {
  578 + code.push("case ", i, ":return o", i, "(", args.slice(0, i).join(), ");");
  579 + }
  580 + code.push("}var s=new Array(arguments.length);for(var i=0;i<arguments.length;++i){s[i]=arguments[i]};return slow(s);}return getOrientation");
  581 + procArgs.push(code.join(""));
  582 +
  583 + var proc = Function.apply(undefined, procArgs);
  584 + orient = proc.apply(undefined, [slowOrient].concat(CACHED));
  585 + for(i=0; i<=NUM_EXPAND; ++i) {
  586 + orient[i] = CACHED[i];
  587 + }
  588 + };
  589 +
  590 + generateOrientationProc();
  591 +
  592 + var robustPointInPolygon = function(vs, point) {
  593 + // transform from geolib format to array syntax
  594 + var x = geolib.longitude(point);
  595 + var y = geolib.latitude(point);
  596 + var coords = vs.map(function(coords) {
  597 + return [geolib.longitude(coords), geolib.latitude(coords)];
  598 + });
  599 +
  600 + vs = coords;
  601 + point = [x,y];
  602 +
  603 + var n = vs.length;
  604 + var inside = 1;
  605 + var lim = n;
  606 +
  607 + var s, c, yk, px, p;
  608 +
  609 + for(var i = 0, j = n-1; i<lim; j=i++) {
  610 + var a = vs[i];
  611 + var b = vs[j];
  612 + var yi = a[1];
  613 + var yj = b[1];
  614 + if(yj < yi) {
  615 + if(yj < y && y < yi) {
  616 + s = orient(a, b, point);
  617 + if(s === 0) {
  618 + return 0;
  619 + } else {
  620 + inside ^= (0 < s)|0;
  621 + }
  622 + } else if(y === yi) {
  623 + c = vs[(i+1)%n];
  624 + yk = c[1];
  625 + if(yi < yk) {
  626 + s = orient(a, b, point);
  627 + if(s === 0) {
  628 + return 0;
  629 + } else {
  630 + inside ^= (0 < s)|0;
  631 + }
  632 + }
  633 + }
  634 + } else if(yi < yj) {
  635 + if(yi < y && y < yj) {
  636 + s = orient(a, b, point);
  637 + if(s === 0) {
  638 + return 0;
  639 + } else {
  640 + inside ^= (s < 0)|0;
  641 + }
  642 + } else if(y === yi) {
  643 + c = vs[(i+1)%n];
  644 + yk = c[1];
  645 + if(yk < yi) {
  646 + s = orient(a, b, point);
  647 + if(s === 0) {
  648 + return 0;
  649 + } else {
  650 + inside ^= (s < 0)|0;
  651 + }
  652 + }
  653 + }
  654 + } else if(y === yi) {
  655 + var x0 = Math.min(a[0], b[0]);
  656 + var x1 = Math.max(a[0], b[0]);
  657 + if(i === 0) {
  658 + while(j>0) {
  659 + var k = (j+n-1)%n;
  660 + p = vs[k];
  661 + if(p[1] !== y) {
  662 + break;
  663 + }
  664 + px = p[0];
  665 + x0 = Math.min(x0, px);
  666 + x1 = Math.max(x1, px);
  667 + j = k;
  668 + }
  669 + if(j === 0) {
  670 + if(x0 <= x && x <= x1) {
  671 + return 0;
  672 + }
  673 + return 1;
  674 + }
  675 + lim = j+1;
  676 + }
  677 + var y0 = vs[(j+n-1)%n][1];
  678 + while(i+1<lim) {
  679 + p = vs[i+1];
  680 + if(p[1] !== y) {
  681 + break;
  682 + }
  683 + px = p[0];
  684 + x0 = Math.min(x0, px);
  685 + x1 = Math.max(x1, px);
  686 + i += 1;
  687 + }
  688 + if(x0 <= x && x <= x1) {
  689 + return 0;
  690 + }
  691 + var y1 = vs[(i+1)%n][1];
  692 + if(x < x0 && (y0 < y !== y1 < y)) {
  693 + inside ^= 1;
  694 + }
  695 + }
  696 + }
  697 + return 2 * inside - 1;
  698 + };
  699 +
  700 + return {
  701 +
  702 + /**
  703 + * @param object coordinate to check e.g. {latitude: 51.5023, longitude: 7.3815}
  704 + * @param array array with coords e.g. [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]
  705 + * @return integer -1 if point is inside, 0 if point is on boundaries, 1 if point is outside
  706 + */
  707 + isPointInsideRobust: function(latlng, coords) {
  708 + return robustPointInPolygon(coords, latlng);
  709 + },
  710 +
  711 + isInside: function() {
  712 + return this.isPointInsideRobust.apply(this, arguments);
  713 + }
  714 +
  715 + };
  716 +
  717 + };
  718 +
  719 +
  720 + // Node module
  721 + if (typeof module !== 'undefined' &&
  722 + typeof module.exports !== 'undefined') {
  723 +
  724 + module.exports = function(geolib) {
  725 + geolib.extend(addOn(geolib), true);
  726 + return geolib;
  727 + };
  728 +
  729 + // AMD module
  730 + } else if (typeof define === "function" && define.amd) {
  731 +
  732 + define(["geolib"], function (geolib) {
  733 + geolib.extend(addOn(geolib), true);
  734 + return geolib;
  735 + });
  736 +
  737 + // we're in a browser
  738 + } else {
  739 +
  740 + geolib.extend(addOn(geolib), true);
  741 +
  742 + }
  743 +
  744 +}(this, this.geolib));
src/main/resources/static/real_control_v2/geolib/geolib.isPointInsideRobust.min.js
1 -/*! geolib.isPointInsideRobust 2.0.21  
2 -* !!EXPERIMENTAL!!  
3 -*  
4 -* Robust version of isPointInside for Geolib.js  
5 -*  
6 -* Based on https://github.com/mikolalysenko/robust-point-in-polygon  
7 -* by Mikola Lysenko, licensed under MIT  
8 -*  
9 -* @author Manuel Bieh  
10 -* @url http://www.manuelbieh.com/  
11 -* @version 2.0.21  
12 -* @license MIT  
13 -*  
14 -*/ 1 +/*! geolib.isPointInsideRobust 2.0.21
  2 +* !!EXPERIMENTAL!!
  3 +*
  4 +* Robust version of isPointInside for Geolib.js
  5 +*
  6 +* Based on https://github.com/mikolalysenko/robust-point-in-polygon
  7 +* by Mikola Lysenko, licensed under MIT
  8 +*
  9 +* @author Manuel Bieh
  10 +* @url http://www.manuelbieh.com/
  11 +* @version 2.0.21
  12 +* @license MIT
  13 +*
  14 +*/
15 !function(a,b,c){var d=function(a){var b,d=+(Math.pow(2,27)+1),e=5,f=1.1102230246251565e-16,g=(3+16*f)*f,h=(7+56*f)*f,i=function(a,b,c){var e=a*b,f=d*a,g=f-a,h=f-g,i=a-h,j=d*b,k=j-b,l=j-k,m=b-l,n=e-h*l,o=n-i*l,p=o-h*m,q=i*m-p;return c?(c[0]=q,c[1]=e,c):[q,e]},j=function(a,b,c){var d=a+b,e=d-a,f=d-e,g=b-e,h=a-f;return c?(c[0]=h+g,c[1]=d,c):[h+g,d]},k=j,l=function(a,b){var c=0|a.length,d=0|b.length;if(1===c&&1===d)return p(a[0],b[0]);var e,f,g=c+d,h=new Array(g),i=0,j=0,k=0,l=Math.abs,m=a[j],n=l(m),o=b[k],q=l(o);q>n?(f=m,j+=1,c>j&&(m=a[j],n=l(m))):(f=o,k+=1,d>k&&(o=b[k],q=l(o))),c>j&&q>n||k>=d?(e=m,j+=1,c>j&&(m=a[j],n=l(m))):(e=o,k+=1,d>k&&(o=b[k],q=l(o)));for(var r,s,t,u,v,w=e+f,x=w-e,y=f-x,z=y,A=w;c>j&&d>k;)q>n?(e=m,j+=1,c>j&&(m=a[j],n=l(m))):(e=o,k+=1,d>k&&(o=b[k],q=l(o))),f=z,w=e+f,x=w-e,y=f-x,y&&(h[i++]=y),r=A+w,s=r-A,t=r-s,u=w-s,v=A-t,z=v+u,A=r;for(;c>j;)e=m,f=z,w=e+f,x=w-e,y=f-x,y&&(h[i++]=y),r=A+w,s=r-A,t=r-s,u=w-s,v=A-t,z=v+u,A=r,j+=1,c>j&&(m=a[j]);for(;d>k;)e=o,f=z,w=e+f,x=w-e,y=f-x,y&&(h[i++]=y),r=A+w,s=r-A,t=r-s,u=w-s,v=A-t,z=v+u,A=r,k+=1,d>k&&(o=b[k]);return z&&(h[i++]=z),A&&(h[i++]=A),i||(h[i++]=0),h.length=i,h},m=l,n=function(a,b){var c=a.length;if(1===c){var d=i(a[0],b);return d[0]?d:[d[1]]}var e=new Array(2*c),f=[.1,.1],g=[.1,.1],h=0;i(a[0],b,f),f[0]&&(e[h++]=f[0]);for(var j=1;c>j;++j){i(a[j],b,g);var l=f[1];k(l,g[0],f),f[0]&&(e[h++]=f[0]);var m=g[1],n=f[1],o=m+n,p=o-m,q=n-p;f[1]=o,q&&(e[h++]=q)}return f[1]&&(e[h++]=f[1]),0===h&&(e[h++]=0),e.length=h,e},o=n,p=function(a,b){var c=a+b,d=c-a,e=c-d,f=b-d,g=a-e,h=g+f;return h?[h,c]:[c]},q=function(a,b){var c=0|a.length,d=0|b.length;if(1===c&&1===d)return p(a[0],-b[0]);var e,f,g=c+d,h=new Array(g),i=0,j=0,k=0,l=Math.abs,m=a[j],n=l(m),o=-b[k],q=l(o);q>n?(f=m,j+=1,c>j&&(m=a[j],n=l(m))):(f=o,k+=1,d>k&&(o=-b[k],q=l(o))),c>j&&q>n||k>=d?(e=m,j+=1,c>j&&(m=a[j],n=l(m))):(e=o,k+=1,d>k&&(o=-b[k],q=l(o)));for(var r,s,t,u,v,w=e+f,x=w-e,y=f-x,z=y,A=w;c>j&&d>k;)q>n?(e=m,j+=1,c>j&&(m=a[j],n=l(m))):(e=o,k+=1,d>k&&(o=-b[k],q=l(o))),f=z,w=e+f,x=w-e,y=f-x,y&&(h[i++]=y),r=A+w,s=r-A,t=r-s,u=w-s,v=A-t,z=v+u,A=r;for(;c>j;)e=m,f=z,w=e+f,x=w-e,y=f-x,y&&(h[i++]=y),r=A+w,s=r-A,t=r-s,u=w-s,v=A-t,z=v+u,A=r,j+=1,c>j&&(m=a[j]);for(;d>k;)e=o,f=z,w=e+f,x=w-e,y=f-x,y&&(h[i++]=y),r=A+w,s=r-A,t=r-s,u=w-s,v=A-t,z=v+u,A=r,k+=1,d>k&&(o=-b[k]);return z&&(h[i++]=z),A&&(h[i++]=A),i||(h[i++]=0),h.length=i,h},r=function(a,b){for(var c=new Array(a.length-1),d=1;d<a.length;++d)for(var e=c[d-1]=new Array(a.length-1),f=0,g=0;f<a.length;++f)f!==b&&(e[g++]=a[d][f]);return c},s=function(a){for(var b=new Array(a),c=0;a>c;++c){b[c]=new Array(a);for(var d=0;a>d;++d)b[c][d]=["m",d,"[",a-c-1,"]"].join("")}return b},t=function(a){return 1&a?"-":""},u=function(a){if(1===a.length)return a[0];if(2===a.length)return["sum(",a[0],",",a[1],")"].join("");var b=a.length>>1;return["sum(",u(a.slice(0,b)),",",u(a.slice(b)),")"].join("")},v=function(a){if(2===a.length)return[["sum(prod(",a[0][0],",",a[1][1],"),prod(-",a[0][1],",",a[1][0],"))"].join("")];for(var b=[],c=0;c<a.length;++c)b.push(["scale(",u(v(r(a,c))),",",t(c),a[0][c],")"].join(""));return b},w=function(a){for(var b=[],c=[],d=s(a),e=[],f=0;a>f;++f)0===(1&f)?b.push.apply(b,v(r(d,f))):c.push.apply(c,v(r(d,f))),e.push("m"+f);var g=u(b),h=u(c),j="orientation"+a+"Exact",k=["function ",j,"(",e.join(),"){var p=",g,",n=",h,",d=sub(p,n);return d[d.length-1];};return ",j].join(""),l=new Function("sum","prod","scale","sub",k);return l(m,i,o,q)},x=w(3),y=w(4),z=[function(){return 0},function(){return 0},function(a,b){return b[0]-a[0]},function(a,b,c){var d,e=(a[1]-c[1])*(b[0]-c[0]),f=(a[0]-c[0])*(b[1]-c[1]),h=e-f;if(e>0){if(0>=f)return h;d=e+f}else{if(!(0>e))return h;if(f>=0)return h;d=-(e+f)}var i=g*d;return h>=i||-i>=h?h:x(a,b,c)},function(a,b,c,d){var e=a[0]-d[0],f=b[0]-d[0],g=c[0]-d[0],i=a[1]-d[1],j=b[1]-d[1],k=c[1]-d[1],l=a[2]-d[2],m=b[2]-d[2],n=c[2]-d[2],o=f*k,p=g*j,q=g*i,r=e*k,s=e*j,t=f*i,u=l*(o-p)+m*(q-r)+n*(s-t),v=(Math.abs(o)+Math.abs(p))*Math.abs(l)+(Math.abs(q)+Math.abs(r))*Math.abs(m)+(Math.abs(s)+Math.abs(t))*Math.abs(n),w=h*v;return u>w||-u>w?u:y(a,b,c,d)}],A=function(a){var b=z[a.length];return b||(b=z[a.length]=w(a.length)),b.apply(c,a)},B=function(){for(;z.length<=e;)z.push(w(z.length));for(var a=[],d=["slow"],f=0;e>=f;++f)a.push("a"+f),d.push("o"+f);var g=["function getOrientation(",a.join(),"){switch(arguments.length){case 0:case 1:return 0;"];for(f=2;e>=f;++f)g.push("case ",f,":return o",f,"(",a.slice(0,f).join(),");");g.push("}var s=new Array(arguments.length);for(var i=0;i<arguments.length;++i){s[i]=arguments[i]};return slow(s);}return getOrientation"),d.push(g.join(""));var h=Function.apply(c,d);for(b=h.apply(c,[A].concat(z)),f=0;e>=f;++f)b[f]=z[f]};B();var C=function(c,d){var e=a.longitude(d),f=a.latitude(d),g=c.map(function(b){return[a.longitude(b),a.latitude(b)]});c=g,d=[e,f];for(var h,i,j,k,l,m=c.length,n=1,o=m,p=0,q=m-1;o>p;q=p++){var r=c[p],s=c[q],t=r[1],u=s[1];if(t>u){if(f>u&&t>f){if(h=b(r,s,d),0===h)return 0;n^=h>0|0}else if(f===t&&(i=c[(p+1)%m],j=i[1],j>t)){if(h=b(r,s,d),0===h)return 0;n^=h>0|0}}else if(u>t){if(f>t&&u>f){if(h=b(r,s,d),0===h)return 0;n^=0>h|0}else if(f===t&&(i=c[(p+1)%m],j=i[1],t>j)){if(h=b(r,s,d),0===h)return 0;n^=0>h|0}}else if(f===t){var v=Math.min(r[0],s[0]),w=Math.max(r[0],s[0]);if(0===p){for(;q>0;){var x=(q+m-1)%m;if(l=c[x],l[1]!==f)break;k=l[0],v=Math.min(v,k),w=Math.max(w,k),q=x}if(0===q)return e>=v&&w>=e?0:1;o=q+1}for(var y=c[(q+m-1)%m][1];o>p+1&&(l=c[p+1],l[1]===f);)k=l[0],v=Math.min(v,k),w=Math.max(w,k),p+=1;if(e>=v&&w>=e)return 0;var z=c[(p+1)%m][1];v>e&&f>y!=f>z&&(n^=1)}}return 2*n-1};return{isPointInsideRobust:function(a,b){return C(b,a)},isInside:function(){return this.isPointInsideRobust.apply(this,arguments)}}};"undefined"!=typeof module&&"undefined"!=typeof module.exports?module.exports=function(a){return a.extend(d(a),!0),a}:"function"==typeof define&&define.amd?define(["geolib"],function(a){return a.extend(d(a),!0),a}):b.extend(d(b),!0)}(this,this.geolib); 15 !function(a,b,c){var d=function(a){var b,d=+(Math.pow(2,27)+1),e=5,f=1.1102230246251565e-16,g=(3+16*f)*f,h=(7+56*f)*f,i=function(a,b,c){var e=a*b,f=d*a,g=f-a,h=f-g,i=a-h,j=d*b,k=j-b,l=j-k,m=b-l,n=e-h*l,o=n-i*l,p=o-h*m,q=i*m-p;return c?(c[0]=q,c[1]=e,c):[q,e]},j=function(a,b,c){var d=a+b,e=d-a,f=d-e,g=b-e,h=a-f;return c?(c[0]=h+g,c[1]=d,c):[h+g,d]},k=j,l=function(a,b){var c=0|a.length,d=0|b.length;if(1===c&&1===d)return p(a[0],b[0]);var e,f,g=c+d,h=new Array(g),i=0,j=0,k=0,l=Math.abs,m=a[j],n=l(m),o=b[k],q=l(o);q>n?(f=m,j+=1,c>j&&(m=a[j],n=l(m))):(f=o,k+=1,d>k&&(o=b[k],q=l(o))),c>j&&q>n||k>=d?(e=m,j+=1,c>j&&(m=a[j],n=l(m))):(e=o,k+=1,d>k&&(o=b[k],q=l(o)));for(var r,s,t,u,v,w=e+f,x=w-e,y=f-x,z=y,A=w;c>j&&d>k;)q>n?(e=m,j+=1,c>j&&(m=a[j],n=l(m))):(e=o,k+=1,d>k&&(o=b[k],q=l(o))),f=z,w=e+f,x=w-e,y=f-x,y&&(h[i++]=y),r=A+w,s=r-A,t=r-s,u=w-s,v=A-t,z=v+u,A=r;for(;c>j;)e=m,f=z,w=e+f,x=w-e,y=f-x,y&&(h[i++]=y),r=A+w,s=r-A,t=r-s,u=w-s,v=A-t,z=v+u,A=r,j+=1,c>j&&(m=a[j]);for(;d>k;)e=o,f=z,w=e+f,x=w-e,y=f-x,y&&(h[i++]=y),r=A+w,s=r-A,t=r-s,u=w-s,v=A-t,z=v+u,A=r,k+=1,d>k&&(o=b[k]);return z&&(h[i++]=z),A&&(h[i++]=A),i||(h[i++]=0),h.length=i,h},m=l,n=function(a,b){var c=a.length;if(1===c){var d=i(a[0],b);return d[0]?d:[d[1]]}var e=new Array(2*c),f=[.1,.1],g=[.1,.1],h=0;i(a[0],b,f),f[0]&&(e[h++]=f[0]);for(var j=1;c>j;++j){i(a[j],b,g);var l=f[1];k(l,g[0],f),f[0]&&(e[h++]=f[0]);var m=g[1],n=f[1],o=m+n,p=o-m,q=n-p;f[1]=o,q&&(e[h++]=q)}return f[1]&&(e[h++]=f[1]),0===h&&(e[h++]=0),e.length=h,e},o=n,p=function(a,b){var c=a+b,d=c-a,e=c-d,f=b-d,g=a-e,h=g+f;return h?[h,c]:[c]},q=function(a,b){var c=0|a.length,d=0|b.length;if(1===c&&1===d)return p(a[0],-b[0]);var e,f,g=c+d,h=new Array(g),i=0,j=0,k=0,l=Math.abs,m=a[j],n=l(m),o=-b[k],q=l(o);q>n?(f=m,j+=1,c>j&&(m=a[j],n=l(m))):(f=o,k+=1,d>k&&(o=-b[k],q=l(o))),c>j&&q>n||k>=d?(e=m,j+=1,c>j&&(m=a[j],n=l(m))):(e=o,k+=1,d>k&&(o=-b[k],q=l(o)));for(var r,s,t,u,v,w=e+f,x=w-e,y=f-x,z=y,A=w;c>j&&d>k;)q>n?(e=m,j+=1,c>j&&(m=a[j],n=l(m))):(e=o,k+=1,d>k&&(o=-b[k],q=l(o))),f=z,w=e+f,x=w-e,y=f-x,y&&(h[i++]=y),r=A+w,s=r-A,t=r-s,u=w-s,v=A-t,z=v+u,A=r;for(;c>j;)e=m,f=z,w=e+f,x=w-e,y=f-x,y&&(h[i++]=y),r=A+w,s=r-A,t=r-s,u=w-s,v=A-t,z=v+u,A=r,j+=1,c>j&&(m=a[j]);for(;d>k;)e=o,f=z,w=e+f,x=w-e,y=f-x,y&&(h[i++]=y),r=A+w,s=r-A,t=r-s,u=w-s,v=A-t,z=v+u,A=r,k+=1,d>k&&(o=-b[k]);return z&&(h[i++]=z),A&&(h[i++]=A),i||(h[i++]=0),h.length=i,h},r=function(a,b){for(var c=new Array(a.length-1),d=1;d<a.length;++d)for(var e=c[d-1]=new Array(a.length-1),f=0,g=0;f<a.length;++f)f!==b&&(e[g++]=a[d][f]);return c},s=function(a){for(var b=new Array(a),c=0;a>c;++c){b[c]=new Array(a);for(var d=0;a>d;++d)b[c][d]=["m",d,"[",a-c-1,"]"].join("")}return b},t=function(a){return 1&a?"-":""},u=function(a){if(1===a.length)return a[0];if(2===a.length)return["sum(",a[0],",",a[1],")"].join("");var b=a.length>>1;return["sum(",u(a.slice(0,b)),",",u(a.slice(b)),")"].join("")},v=function(a){if(2===a.length)return[["sum(prod(",a[0][0],",",a[1][1],"),prod(-",a[0][1],",",a[1][0],"))"].join("")];for(var b=[],c=0;c<a.length;++c)b.push(["scale(",u(v(r(a,c))),",",t(c),a[0][c],")"].join(""));return b},w=function(a){for(var b=[],c=[],d=s(a),e=[],f=0;a>f;++f)0===(1&f)?b.push.apply(b,v(r(d,f))):c.push.apply(c,v(r(d,f))),e.push("m"+f);var g=u(b),h=u(c),j="orientation"+a+"Exact",k=["function ",j,"(",e.join(),"){var p=",g,",n=",h,",d=sub(p,n);return d[d.length-1];};return ",j].join(""),l=new Function("sum","prod","scale","sub",k);return l(m,i,o,q)},x=w(3),y=w(4),z=[function(){return 0},function(){return 0},function(a,b){return b[0]-a[0]},function(a,b,c){var d,e=(a[1]-c[1])*(b[0]-c[0]),f=(a[0]-c[0])*(b[1]-c[1]),h=e-f;if(e>0){if(0>=f)return h;d=e+f}else{if(!(0>e))return h;if(f>=0)return h;d=-(e+f)}var i=g*d;return h>=i||-i>=h?h:x(a,b,c)},function(a,b,c,d){var e=a[0]-d[0],f=b[0]-d[0],g=c[0]-d[0],i=a[1]-d[1],j=b[1]-d[1],k=c[1]-d[1],l=a[2]-d[2],m=b[2]-d[2],n=c[2]-d[2],o=f*k,p=g*j,q=g*i,r=e*k,s=e*j,t=f*i,u=l*(o-p)+m*(q-r)+n*(s-t),v=(Math.abs(o)+Math.abs(p))*Math.abs(l)+(Math.abs(q)+Math.abs(r))*Math.abs(m)+(Math.abs(s)+Math.abs(t))*Math.abs(n),w=h*v;return u>w||-u>w?u:y(a,b,c,d)}],A=function(a){var b=z[a.length];return b||(b=z[a.length]=w(a.length)),b.apply(c,a)},B=function(){for(;z.length<=e;)z.push(w(z.length));for(var a=[],d=["slow"],f=0;e>=f;++f)a.push("a"+f),d.push("o"+f);var g=["function getOrientation(",a.join(),"){switch(arguments.length){case 0:case 1:return 0;"];for(f=2;e>=f;++f)g.push("case ",f,":return o",f,"(",a.slice(0,f).join(),");");g.push("}var s=new Array(arguments.length);for(var i=0;i<arguments.length;++i){s[i]=arguments[i]};return slow(s);}return getOrientation"),d.push(g.join(""));var h=Function.apply(c,d);for(b=h.apply(c,[A].concat(z)),f=0;e>=f;++f)b[f]=z[f]};B();var C=function(c,d){var e=a.longitude(d),f=a.latitude(d),g=c.map(function(b){return[a.longitude(b),a.latitude(b)]});c=g,d=[e,f];for(var h,i,j,k,l,m=c.length,n=1,o=m,p=0,q=m-1;o>p;q=p++){var r=c[p],s=c[q],t=r[1],u=s[1];if(t>u){if(f>u&&t>f){if(h=b(r,s,d),0===h)return 0;n^=h>0|0}else if(f===t&&(i=c[(p+1)%m],j=i[1],j>t)){if(h=b(r,s,d),0===h)return 0;n^=h>0|0}}else if(u>t){if(f>t&&u>f){if(h=b(r,s,d),0===h)return 0;n^=0>h|0}else if(f===t&&(i=c[(p+1)%m],j=i[1],t>j)){if(h=b(r,s,d),0===h)return 0;n^=0>h|0}}else if(f===t){var v=Math.min(r[0],s[0]),w=Math.max(r[0],s[0]);if(0===p){for(;q>0;){var x=(q+m-1)%m;if(l=c[x],l[1]!==f)break;k=l[0],v=Math.min(v,k),w=Math.max(w,k),q=x}if(0===q)return e>=v&&w>=e?0:1;o=q+1}for(var y=c[(q+m-1)%m][1];o>p+1&&(l=c[p+1],l[1]===f);)k=l[0],v=Math.min(v,k),w=Math.max(w,k),p+=1;if(e>=v&&w>=e)return 0;var z=c[(p+1)%m][1];v>e&&f>y!=f>z&&(n^=1)}}return 2*n-1};return{isPointInsideRobust:function(a,b){return C(b,a)},isInside:function(){return this.isPointInsideRobust.apply(this,arguments)}}};"undefined"!=typeof module&&"undefined"!=typeof module.exports?module.exports=function(a){return a.extend(d(a),!0),a}:"function"==typeof define&&define.amd?define(["geolib"],function(a){return a.extend(d(a),!0),a}):b.extend(d(b),!0)}(this,this.geolib);
16 \ No newline at end of file 16 \ No newline at end of file
src/main/resources/static/real_control_v2/geolib/geolib.js
1 -/*! geolib 2.0.21 by Manuel Bieh  
2 -* Library to provide geo functions like distance calculation,  
3 -* conversion of decimal coordinates to sexagesimal and vice versa, etc.  
4 -* WGS 84 (World Geodetic System 1984)  
5 -*  
6 -* @author Manuel Bieh  
7 -* @url http://www.manuelbieh.com/  
8 -* @version 2.0.21  
9 -* @license MIT  
10 -**/;(function(global, undefined) {  
11 -  
12 - "use strict";  
13 -  
14 - function Geolib() {}  
15 -  
16 - // Constants  
17 - Geolib.TO_RAD = Math.PI / 180;  
18 - Geolib.TO_DEG = 180 / Math.PI;  
19 - Geolib.PI_X2 = Math.PI * 2;  
20 - Geolib.PI_DIV4 = Math.PI / 4;  
21 -  
22 - // Setting readonly defaults  
23 - var geolib = Object.create(Geolib.prototype, {  
24 - version: {  
25 - value: "2.0.21"  
26 - },  
27 - radius: {  
28 - value: 6378137  
29 - },  
30 - minLat: {  
31 - value: -90  
32 - },  
33 - maxLat: {  
34 - value: 90  
35 - },  
36 - minLon: {  
37 - value: -180  
38 - },  
39 - maxLon: {  
40 - value: 180  
41 - },  
42 - sexagesimalPattern: {  
43 - value: /^([0-9]{1,3})°\s*([0-9]{1,3}(?:\.(?:[0-9]{1,2}))?)'\s*(([0-9]{1,3}(\.([0-9]{1,4}))?)"\s*)?([NEOSW]?)$/  
44 - },  
45 - measures: {  
46 - value: Object.create(Object.prototype, {  
47 - "m" : {value: 1},  
48 - "km": {value: 0.001},  
49 - "cm": {value: 100},  
50 - "mm": {value: 1000},  
51 - "mi": {value: (1 / 1609.344)},  
52 - "sm": {value: (1 / 1852.216)},  
53 - "ft": {value: (100 / 30.48)},  
54 - "in": {value: (100 / 2.54)},  
55 - "yd": {value: (1 / 0.9144)}  
56 - })  
57 - },  
58 - prototype: {  
59 - value: Geolib.prototype  
60 - },  
61 - extend: {  
62 - value: function(methods, overwrite) {  
63 - for(var prop in methods) {  
64 - if(typeof geolib.prototype[prop] === 'undefined' || overwrite === true) {  
65 - if(typeof methods[prop] === 'function' && typeof methods[prop].bind === 'function') {  
66 - geolib.prototype[prop] = methods[prop].bind(geolib);  
67 - } else {  
68 - geolib.prototype[prop] = methods[prop];  
69 - }  
70 - }  
71 - }  
72 - }  
73 - }  
74 - });  
75 -  
76 - if (typeof(Number.prototype.toRad) === 'undefined') {  
77 - Number.prototype.toRad = function() {  
78 - return this * Geolib.TO_RAD;  
79 - };  
80 - }  
81 -  
82 - if (typeof(Number.prototype.toDeg) === 'undefined') {  
83 - Number.prototype.toDeg = function() {  
84 - return this * Geolib.TO_DEG;  
85 - };  
86 - }  
87 -  
88 - // Here comes the magic  
89 - geolib.extend({  
90 -  
91 - decimal: {},  
92 -  
93 - sexagesimal: {},  
94 -  
95 - distance: null,  
96 -  
97 - getKeys: function(point) {  
98 -  
99 - // GeoJSON Array [longitude, latitude(, elevation)]  
100 - if(Object.prototype.toString.call(point) == '[object Array]') {  
101 -  
102 - return {  
103 - longitude: point.length >= 1 ? 0 : undefined,  
104 - latitude: point.length >= 2 ? 1 : undefined,  
105 - elevation: point.length >= 3 ? 2 : undefined  
106 - };  
107 -  
108 - }  
109 -  
110 - var getKey = function(possibleValues) {  
111 -  
112 - var key;  
113 -  
114 - possibleValues.every(function(val) {  
115 - // TODO: check if point is an object  
116 - if(typeof point != 'object') {  
117 - return true;  
118 - }  
119 - return point.hasOwnProperty(val) ? (function() { key = val; return false; }()) : true;  
120 - });  
121 -  
122 - return key;  
123 -  
124 - };  
125 -  
126 - var longitude = getKey(['lng', 'lon', 'longitude']);  
127 - var latitude = getKey(['lat', 'latitude']);  
128 - var elevation = getKey(['alt', 'altitude', 'elevation', 'elev']);  
129 -  
130 - // return undefined if not at least one valid property was found  
131 - if(typeof latitude == 'undefined' &&  
132 - typeof longitude == 'undefined' &&  
133 - typeof elevation == 'undefined') {  
134 - return undefined;  
135 - }  
136 -  
137 - return {  
138 - latitude: latitude,  
139 - longitude: longitude,  
140 - elevation: elevation  
141 - };  
142 -  
143 - },  
144 -  
145 - // returns latitude of a given point, converted to decimal  
146 - // set raw to true to avoid conversion  
147 - getLat: function(point, raw) {  
148 - return raw === true ? point[this.getKeys(point).latitude] : this.useDecimal(point[this.getKeys(point).latitude]);  
149 - },  
150 -  
151 - // Alias for getLat  
152 - latitude: function(point) {  
153 - return this.getLat.call(this, point);  
154 - },  
155 -  
156 - // returns longitude of a given point, converted to decimal  
157 - // set raw to true to avoid conversion  
158 - getLon: function(point, raw) {  
159 - return raw === true ? point[this.getKeys(point).longitude] : this.useDecimal(point[this.getKeys(point).longitude]);  
160 - },  
161 -  
162 - // Alias for getLon  
163 - longitude: function(point) {  
164 - return this.getLon.call(this, point);  
165 - },  
166 -  
167 - getElev: function(point) {  
168 - return point[this.getKeys(point).elevation];  
169 - },  
170 -  
171 - // Alias for getElev  
172 - elevation: function(point) {  
173 - return this.getElev.call(this, point);  
174 - },  
175 -  
176 - coords: function(point, raw) {  
177 -  
178 - var retval = {  
179 - latitude: raw === true ? point[this.getKeys(point).latitude] : this.useDecimal(point[this.getKeys(point).latitude]),  
180 - longitude: raw === true ? point[this.getKeys(point).longitude] : this.useDecimal(point[this.getKeys(point).longitude])  
181 - };  
182 -  
183 - var elev = point[this.getKeys(point).elevation];  
184 -  
185 - if(typeof elev !== 'undefined') {  
186 - retval['elevation'] = elev;  
187 - }  
188 -  
189 - return retval;  
190 -  
191 - },  
192 -  
193 - // Alias for coords  
194 - ll: function(point, raw) {  
195 - return this.coords.call(this, point, raw);  
196 - },  
197 -  
198 -  
199 - // checks if a variable contains a valid latlong object  
200 - validate: function(point) {  
201 -  
202 - var keys = this.getKeys(point);  
203 -  
204 - if(typeof keys === 'undefined' || typeof keys.latitude === 'undefined' || keys.longitude === 'undefined') {  
205 - return false;  
206 - }  
207 -  
208 - var lat = point[keys.latitude];  
209 - var lng = point[keys.longitude];  
210 -  
211 - if(typeof lat === 'undefined' || !this.isDecimal(lat) && !this.isSexagesimal(lat)) {  
212 - return false;  
213 - }  
214 -  
215 - if(typeof lng === 'undefined' || !this.isDecimal(lng) && !this.isSexagesimal(lng)) {  
216 - return false;  
217 - }  
218 -  
219 - lat = this.useDecimal(lat);  
220 - lng = this.useDecimal(lng);  
221 -  
222 - if(lat < this.minLat || lat > this.maxLat || lng < this.minLon || lng > this.maxLon) {  
223 - return false;  
224 - }  
225 -  
226 - return true;  
227 -  
228 - },  
229 -  
230 - /**  
231 - * Calculates geodetic distance between two points specified by latitude/longitude using  
232 - * Vincenty inverse formula for ellipsoids  
233 - * Vincenty Inverse Solution of Geodesics on the Ellipsoid (c) Chris Veness 2002-2010  
234 - * (Licensed under CC BY 3.0)  
235 - *  
236 - * @param object Start position {latitude: 123, longitude: 123}  
237 - * @param object End position {latitude: 123, longitude: 123}  
238 - * @param integer Accuracy (in meters)  
239 - * @param integer Precision (in decimal cases)  
240 - * @return integer Distance (in meters)  
241 - */  
242 - getDistance: function(start, end, accuracy, precision) {  
243 -  
244 - accuracy = Math.floor(accuracy) || 1;  
245 - precision = Math.floor(precision) || 0;  
246 -  
247 - var s = this.coords(start);  
248 - var e = this.coords(end);  
249 -  
250 - var a = 6378137, b = 6356752.314245, f = 1/298.257223563; // WGS-84 ellipsoid params  
251 - var L = (e['longitude']-s['longitude']).toRad();  
252 -  
253 - var cosSigma, sigma, sinAlpha, cosSqAlpha, cos2SigmaM, sinSigma;  
254 -  
255 - var U1 = Math.atan((1-f) * Math.tan(parseFloat(s['latitude']).toRad()));  
256 - var U2 = Math.atan((1-f) * Math.tan(parseFloat(e['latitude']).toRad()));  
257 - var sinU1 = Math.sin(U1), cosU1 = Math.cos(U1);  
258 - var sinU2 = Math.sin(U2), cosU2 = Math.cos(U2);  
259 -  
260 - var lambda = L, lambdaP, iterLimit = 100;  
261 - do {  
262 - var sinLambda = Math.sin(lambda), cosLambda = Math.cos(lambda);  
263 - sinSigma = (  
264 - Math.sqrt(  
265 - (  
266 - cosU2 * sinLambda  
267 - ) * (  
268 - cosU2 * sinLambda  
269 - ) + (  
270 - cosU1 * sinU2 - sinU1 * cosU2 * cosLambda  
271 - ) * (  
272 - cosU1 * sinU2 - sinU1 * cosU2 * cosLambda  
273 - )  
274 - )  
275 - );  
276 - if (sinSigma === 0) {  
277 - return geolib.distance = 0; // co-incident points  
278 - }  
279 -  
280 - cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda;  
281 - sigma = Math.atan2(sinSigma, cosSigma);  
282 - sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma;  
283 - cosSqAlpha = 1 - sinAlpha * sinAlpha;  
284 - cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha;  
285 -  
286 - if (isNaN(cos2SigmaM)) {  
287 - cos2SigmaM = 0; // equatorial line: cosSqAlpha=0 (§6)  
288 - }  
289 - var C = (  
290 - f / 16 * cosSqAlpha * (  
291 - 4 + f * (  
292 - 4 - 3 * cosSqAlpha  
293 - )  
294 - )  
295 - );  
296 - lambdaP = lambda;  
297 - lambda = (  
298 - L + (  
299 - 1 - C  
300 - ) * f * sinAlpha * (  
301 - sigma + C * sinSigma * (  
302 - cos2SigmaM + C * cosSigma * (  
303 - -1 + 2 * cos2SigmaM * cos2SigmaM  
304 - )  
305 - )  
306 - )  
307 - );  
308 -  
309 - } while (Math.abs(lambda-lambdaP) > 1e-12 && --iterLimit>0);  
310 -  
311 - if (iterLimit === 0) {  
312 - return NaN; // formula failed to converge  
313 - }  
314 -  
315 - var uSq = (  
316 - cosSqAlpha * (  
317 - a * a - b * b  
318 - ) / (  
319 - b*b  
320 - )  
321 - );  
322 -  
323 - var A = (  
324 - 1 + uSq / 16384 * (  
325 - 4096 + uSq * (  
326 - -768 + uSq * (  
327 - 320 - 175 * uSq  
328 - )  
329 - )  
330 - )  
331 - );  
332 -  
333 - var B = (  
334 - uSq / 1024 * (  
335 - 256 + uSq * (  
336 - -128 + uSq * (  
337 - 74-47 * uSq  
338 - )  
339 - )  
340 - )  
341 - );  
342 -  
343 - var deltaSigma = (  
344 - B * sinSigma * (  
345 - cos2SigmaM + B / 4 * (  
346 - cosSigma * (  
347 - -1 + 2 * cos2SigmaM * cos2SigmaM  
348 - ) -B / 6 * cos2SigmaM * (  
349 - -3 + 4 * sinSigma * sinSigma  
350 - ) * (  
351 - -3 + 4 * cos2SigmaM * cos2SigmaM  
352 - )  
353 - )  
354 - )  
355 - );  
356 -  
357 - var distance = b * A * (sigma - deltaSigma);  
358 -  
359 - distance = distance.toFixed(precision); // round to 1mm precision  
360 -  
361 - //if (start.hasOwnProperty(elevation) && end.hasOwnProperty(elevation)) {  
362 - if (typeof this.elevation(start) !== 'undefined' && typeof this.elevation(end) !== 'undefined') {  
363 - var climb = Math.abs(this.elevation(start) - this.elevation(end));  
364 - distance = Math.sqrt(distance * distance + climb * climb);  
365 - }  
366 -  
367 - return this.distance = Math.round(distance * Math.pow(10, precision) / accuracy) * accuracy / Math.pow(10, precision);  
368 -  
369 - /*  
370 - // note: to return initial/final bearings in addition to distance, use something like:  
371 - var fwdAz = Math.atan2(cosU2*sinLambda, cosU1*sinU2-sinU1*cosU2*cosLambda);  
372 - var revAz = Math.atan2(cosU1*sinLambda, -sinU1*cosU2+cosU1*sinU2*cosLambda);  
373 -  
374 - return { distance: s, initialBearing: fwdAz.toDeg(), finalBearing: revAz.toDeg() };  
375 - */  
376 -  
377 - },  
378 -  
379 -  
380 - /**  
381 - * Calculates the distance between two spots.  
382 - * This method is more simple but also far more inaccurate  
383 - *  
384 - * @param object Start position {latitude: 123, longitude: 123}  
385 - * @param object End position {latitude: 123, longitude: 123}  
386 - * @param integer Accuracy (in meters)  
387 - * @return integer Distance (in meters)  
388 - */  
389 - getDistanceSimple: function(start, end, accuracy) {  
390 -  
391 - accuracy = Math.floor(accuracy) || 1;  
392 -  
393 - var distance =  
394 - Math.round(  
395 - Math.acos(  
396 - Math.sin(  
397 - this.latitude(end).toRad()  
398 - ) *  
399 - Math.sin(  
400 - this.latitude(start).toRad()  
401 - ) +  
402 - Math.cos(  
403 - this.latitude(end).toRad()  
404 - ) *  
405 - Math.cos(  
406 - this.latitude(start).toRad()  
407 - ) *  
408 - Math.cos(  
409 - this.longitude(start).toRad() - this.longitude(end).toRad()  
410 - )  
411 - ) * this.radius  
412 - );  
413 -  
414 - return geolib.distance = Math.floor(Math.round(distance/accuracy)*accuracy);  
415 -  
416 - },  
417 -  
418 -  
419 - /**  
420 - * Calculates the center of a collection of geo coordinates  
421 - *  
422 - * @param array Collection of coords [{latitude: 51.510, longitude: 7.1321}, {latitude: 49.1238, longitude: "8° 30' W"}, ...]  
423 - * @return object {latitude: centerLat, longitude: centerLng}  
424 - */  
425 - getCenter: function(coords) {  
426 -  
427 - var coordsArray = coords;  
428 - if(typeof coords === 'object' && !(coords instanceof Array)) {  
429 -  
430 - coordsArray = [];  
431 -  
432 - for(var key in coords) {  
433 - coordsArray.push(  
434 - this.coords(coords[key])  
435 - );  
436 - }  
437 -  
438 - }  
439 -  
440 - if(!coordsArray.length) {  
441 - return false;  
442 - }  
443 -  
444 - var X = 0.0;  
445 - var Y = 0.0;  
446 - var Z = 0.0;  
447 - var lat, lon, hyp;  
448 -  
449 - coordsArray.forEach(function(coord) {  
450 -  
451 - lat = this.latitude(coord).toRad();  
452 - lon = this.longitude(coord).toRad();  
453 -  
454 - X += Math.cos(lat) * Math.cos(lon);  
455 - Y += Math.cos(lat) * Math.sin(lon);  
456 - Z += Math.sin(lat);  
457 -  
458 - }, this);  
459 -  
460 - var nb_coords = coordsArray.length;  
461 - X = X / nb_coords;  
462 - Y = Y / nb_coords;  
463 - Z = Z / nb_coords;  
464 -  
465 - lon = Math.atan2(Y, X);  
466 - hyp = Math.sqrt(X * X + Y * Y);  
467 - lat = Math.atan2(Z, hyp);  
468 -  
469 - return {  
470 - latitude: (lat * Geolib.TO_DEG).toFixed(6),  
471 - longitude: (lon * Geolib.TO_DEG).toFixed(6)  
472 - };  
473 -  
474 - },  
475 -  
476 -  
477 - /**  
478 - * Gets the max and min, latitude, longitude, and elevation (if provided).  
479 - * @param array array with coords e.g. [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]  
480 - * @return object {maxLat: maxLat,  
481 - * minLat: minLat  
482 - * maxLng: maxLng,  
483 - * minLng: minLng,  
484 - * maxElev: maxElev,  
485 - * minElev: minElev}  
486 - */  
487 - getBounds: function(coords) {  
488 -  
489 - if (!coords.length) {  
490 - return false;  
491 - }  
492 -  
493 - var useElevation = this.elevation(coords[0]);  
494 -  
495 - var stats = {  
496 - maxLat: -Infinity,  
497 - minLat: Infinity,  
498 - maxLng: -Infinity,  
499 - minLng: Infinity  
500 - };  
501 -  
502 - if (typeof useElevation != 'undefined') {  
503 - stats.maxElev = 0;  
504 - stats.minElev = Infinity;  
505 - }  
506 -  
507 - for (var i = 0, l = coords.length; i < l; ++i) {  
508 -  
509 - stats.maxLat = Math.max(this.latitude(coords[i]), stats.maxLat);  
510 - stats.minLat = Math.min(this.latitude(coords[i]), stats.minLat);  
511 - stats.maxLng = Math.max(this.longitude(coords[i]), stats.maxLng);  
512 - stats.minLng = Math.min(this.longitude(coords[i]), stats.minLng);  
513 -  
514 - if (useElevation) {  
515 - stats.maxElev = Math.max(this.elevation(coords[i]), stats.maxElev);  
516 - stats.minElev = Math.min(this.elevation(coords[i]), stats.minElev);  
517 - }  
518 -  
519 - }  
520 -  
521 - return stats;  
522 -  
523 - },  
524 -  
525 - /**  
526 - * Calculates the center of the bounds of geo coordinates.  
527 - *  
528 - * On polygons like political borders (eg. states)  
529 - * this may gives a closer result to human expectation, than `getCenter`,  
530 - * because that function can be disturbed by uneven distribution of  
531 - * point in different sides.  
532 - * Imagine the US state Oklahoma: `getCenter` on that gives a southern  
533 - * point, because the southern border contains a lot more nodes,  
534 - * than the others.  
535 - *  
536 - * @param array Collection of coords [{latitude: 51.510, longitude: 7.1321}, {latitude: 49.1238, longitude: "8° 30' W"}, ...]  
537 - * @return object {latitude: centerLat, longitude: centerLng}  
538 - */  
539 - getCenterOfBounds: function(coords) {  
540 - var b = this.getBounds(coords);  
541 - var latitude = b.minLat + ((b.maxLat - b.minLat) / 2);  
542 - var longitude = b.minLng + ((b.maxLng - b.minLng) / 2);  
543 - return {  
544 - latitude: parseFloat(latitude.toFixed(6)),  
545 - longitude: parseFloat(longitude.toFixed(6))  
546 - };  
547 - },  
548 -  
549 -  
550 - /**  
551 - * Computes the bounding coordinates of all points on the surface  
552 - * of the earth less than or equal to the specified great circle  
553 - * distance.  
554 - *  
555 - * @param object Point position {latitude: 123, longitude: 123}  
556 - * @param number Distance (in meters).  
557 - * @return array Collection of two points defining the SW and NE corners.  
558 - */  
559 - getBoundsOfDistance: function(point, distance) {  
560 -  
561 - var latitude = this.latitude(point);  
562 - var longitude = this.longitude(point);  
563 -  
564 - var radLat = latitude.toRad();  
565 - var radLon = longitude.toRad();  
566 -  
567 - var radDist = distance / this.radius;  
568 - var minLat = radLat - radDist;  
569 - var maxLat = radLat + radDist;  
570 -  
571 - var MAX_LAT_RAD = this.maxLat.toRad();  
572 - var MIN_LAT_RAD = this.minLat.toRad();  
573 - var MAX_LON_RAD = this.maxLon.toRad();  
574 - var MIN_LON_RAD = this.minLon.toRad();  
575 -  
576 - var minLon;  
577 - var maxLon;  
578 -  
579 - if (minLat > MIN_LAT_RAD && maxLat < MAX_LAT_RAD) {  
580 -  
581 - var deltaLon = Math.asin(Math.sin(radDist) / Math.cos(radLat));  
582 - minLon = radLon - deltaLon;  
583 -  
584 - if (minLon < MIN_LON_RAD) {  
585 - minLon += Geolib.PI_X2;  
586 - }  
587 -  
588 - maxLon = radLon + deltaLon;  
589 -  
590 - if (maxLon > MAX_LON_RAD) {  
591 - maxLon -= Geolib.PI_X2;  
592 - }  
593 -  
594 - } else {  
595 - // A pole is within the distance.  
596 - minLat = Math.max(minLat, MIN_LAT_RAD);  
597 - maxLat = Math.min(maxLat, MAX_LAT_RAD);  
598 - minLon = MIN_LON_RAD;  
599 - maxLon = MAX_LON_RAD;  
600 - }  
601 -  
602 - return [  
603 - // Southwest  
604 - {  
605 - latitude: minLat.toDeg(),  
606 - longitude: minLon.toDeg()  
607 - },  
608 - // Northeast  
609 - {  
610 - latitude: maxLat.toDeg(),  
611 - longitude: maxLon.toDeg()  
612 - }  
613 - ];  
614 -  
615 - },  
616 -  
617 -  
618 - /**  
619 - * Checks whether a point is inside of a polygon or not.  
620 - * Note that the polygon coords must be in correct order!  
621 - *  
622 - * @param object coordinate to check e.g. {latitude: 51.5023, longitude: 7.3815}  
623 - * @param array array with coords e.g. [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]  
624 - * @return bool true if the coordinate is inside the given polygon  
625 - */  
626 - isPointInside: function(latlng, coords) {  
627 -  
628 - for(var c = false, i = -1, l = coords.length, j = l - 1; ++i < l; j = i) {  
629 -  
630 - if(  
631 - (  
632 - (this.longitude(coords[i]) <= this.longitude(latlng) && this.longitude(latlng) < this.longitude(coords[j])) ||  
633 - (this.longitude(coords[j]) <= this.longitude(latlng) && this.longitude(latlng) < this.longitude(coords[i]))  
634 - ) &&  
635 - (  
636 - this.latitude(latlng) < (this.latitude(coords[j]) - this.latitude(coords[i])) *  
637 - (this.longitude(latlng) - this.longitude(coords[i])) /  
638 - (this.longitude(coords[j]) - this.longitude(coords[i])) +  
639 - this.latitude(coords[i])  
640 - )  
641 - ) {  
642 - c = !c;  
643 - }  
644 -  
645 - }  
646 -  
647 - return c;  
648 -  
649 - },  
650 -  
651 -  
652 - /**  
653 - * Pre calculate the polygon coords, to speed up the point inside check.  
654 - * Use this function before calling isPointInsideWithPreparedPolygon()  
655 - * @see Algorythm from http://alienryderflex.com/polygon/  
656 - * @param array array with coords e.g. [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]  
657 - */  
658 - preparePolygonForIsPointInsideOptimized: function(coords) {  
659 -  
660 - for(var i = 0, j = coords.length-1; i < coords.length; i++) {  
661 -  
662 - if(this.longitude(coords[j]) === this.longitude(coords[i])) {  
663 -  
664 - coords[i].constant = this.latitude(coords[i]);  
665 - coords[i].multiple = 0;  
666 -  
667 - } else {  
668 -  
669 - coords[i].constant = this.latitude(coords[i]) - (  
670 - this.longitude(coords[i]) * this.latitude(coords[j])  
671 - ) / (  
672 - this.longitude(coords[j]) - this.longitude(coords[i])  
673 - ) + (  
674 - this.longitude(coords[i])*this.latitude(coords[i])  
675 - ) / (  
676 - this.longitude(coords[j])-this.longitude(coords[i])  
677 - );  
678 -  
679 - coords[i].multiple = (  
680 - this.latitude(coords[j])-this.latitude(coords[i])  
681 - ) / (  
682 - this.longitude(coords[j])-this.longitude(coords[i])  
683 - );  
684 -  
685 - }  
686 -  
687 - j=i;  
688 -  
689 - }  
690 -  
691 - },  
692 -  
693 - /**  
694 - * Checks whether a point is inside of a polygon or not.  
695 - * "This is useful if you have many points that need to be tested against the same (static) polygon."  
696 - * Please call the function preparePolygonForIsPointInsideOptimized() with the same coords object before using this function.  
697 - * Note that the polygon coords must be in correct order!  
698 - *  
699 - * @see Algorythm from http://alienryderflex.com/polygon/  
700 - *  
701 - * @param object coordinate to check e.g. {latitude: 51.5023, longitude: 7.3815}  
702 - * @param array array with coords e.g. [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]  
703 - * @return bool true if the coordinate is inside the given polygon  
704 - */  
705 - isPointInsideWithPreparedPolygon: function(point, coords) {  
706 -  
707 - var flgPointInside = false,  
708 - y = this.longitude(point),  
709 - x = this.latitude(point);  
710 -  
711 - for(var i = 0, j = coords.length-1; i < coords.length; i++) {  
712 -  
713 - if ((this.longitude(coords[i]) < y && this.longitude(coords[j]) >=y ||  
714 - this.longitude(coords[j]) < y && this.longitude(coords[i]) >= y)) {  
715 -  
716 - flgPointInside^=(y*coords[i].multiple+coords[i].constant < x);  
717 -  
718 - }  
719 -  
720 - j=i;  
721 -  
722 - }  
723 -  
724 - return flgPointInside;  
725 -  
726 - },  
727 -  
728 -  
729 - /**  
730 - * Shortcut for geolib.isPointInside()  
731 - */  
732 - isInside: function() {  
733 - return this.isPointInside.apply(this, arguments);  
734 - },  
735 -  
736 -  
737 - /**  
738 - * Checks whether a point is inside of a circle or not.  
739 - *  
740 - * @param object coordinate to check (e.g. {latitude: 51.5023, longitude: 7.3815})  
741 - * @param object coordinate of the circle's center (e.g. {latitude: 51.4812, longitude: 7.4025})  
742 - * @param integer maximum radius in meters  
743 - * @return bool true if the coordinate is within the given radius  
744 - */  
745 - isPointInCircle: function(latlng, center, radius) {  
746 - return this.getDistance(latlng, center) < radius;  
747 - },  
748 -  
749 -  
750 - /**  
751 - * Shortcut for geolib.isPointInCircle()  
752 - */  
753 - withinRadius: function() {  
754 - return this.isPointInCircle.apply(this, arguments);  
755 - },  
756 -  
757 -  
758 - /**  
759 - * Gets rhumb line bearing of two points. Find out about the difference between rhumb line and  
760 - * great circle bearing on Wikipedia. It's quite complicated. Rhumb line should be fine in most cases:  
761 - *  
762 - * http://en.wikipedia.org/wiki/Rhumb_line#General_and_mathematical_description  
763 - *  
764 - * Function heavily based on Doug Vanderweide's great PHP version (licensed under GPL 3.0)  
765 - * http://www.dougv.com/2009/07/13/calculating-the-bearing-and-compass-rose-direction-between-two-latitude-longitude-coordinates-in-php/  
766 - *  
767 - * @param object origin coordinate (e.g. {latitude: 51.5023, longitude: 7.3815})  
768 - * @param object destination coordinate  
769 - * @return integer calculated bearing  
770 - */  
771 - getRhumbLineBearing: function(originLL, destLL) {  
772 -  
773 - // difference of longitude coords  
774 - var diffLon = this.longitude(destLL).toRad() - this.longitude(originLL).toRad();  
775 -  
776 - // difference latitude coords phi  
777 - var diffPhi = Math.log(  
778 - Math.tan(  
779 - this.latitude(destLL).toRad() / 2 + Geolib.PI_DIV4  
780 - ) /  
781 - Math.tan(  
782 - this.latitude(originLL).toRad() / 2 + Geolib.PI_DIV4  
783 - )  
784 - );  
785 -  
786 - // recalculate diffLon if it is greater than pi  
787 - if(Math.abs(diffLon) > Math.PI) {  
788 - if(diffLon > 0) {  
789 - diffLon = (Geolib.PI_X2 - diffLon) * -1;  
790 - }  
791 - else {  
792 - diffLon = Geolib.PI_X2 + diffLon;  
793 - }  
794 - }  
795 -  
796 - //return the angle, normalized  
797 - return (Math.atan2(diffLon, diffPhi).toDeg() + 360) % 360;  
798 -  
799 - },  
800 -  
801 -  
802 - /**  
803 - * Gets great circle bearing of two points. See description of getRhumbLineBearing for more information  
804 - *  
805 - * @param object origin coordinate (e.g. {latitude: 51.5023, longitude: 7.3815})  
806 - * @param object destination coordinate  
807 - * @return integer calculated bearing  
808 - */  
809 - getBearing: function(originLL, destLL) {  
810 -  
811 - destLL['latitude'] = this.latitude(destLL);  
812 - destLL['longitude'] = this.longitude(destLL);  
813 - originLL['latitude'] = this.latitude(originLL);  
814 - originLL['longitude'] = this.longitude(originLL);  
815 -  
816 - var bearing = (  
817 - (  
818 - Math.atan2(  
819 - Math.sin(  
820 - destLL['longitude'].toRad() -  
821 - originLL['longitude'].toRad()  
822 - ) *  
823 - Math.cos(  
824 - destLL['latitude'].toRad()  
825 - ),  
826 - Math.cos(  
827 - originLL['latitude'].toRad()  
828 - ) *  
829 - Math.sin(  
830 - destLL['latitude'].toRad()  
831 - ) -  
832 - Math.sin(  
833 - originLL['latitude'].toRad()  
834 - ) *  
835 - Math.cos(  
836 - destLL['latitude'].toRad()  
837 - ) *  
838 - Math.cos(  
839 - destLL['longitude'].toRad() - originLL['longitude'].toRad()  
840 - )  
841 - )  
842 - ).toDeg() + 360  
843 - ) % 360;  
844 -  
845 - return bearing;  
846 -  
847 - },  
848 -  
849 -  
850 - /**  
851 - * Gets the compass direction from an origin coordinate to a destination coordinate.  
852 - *  
853 - * @param object origin coordinate (e.g. {latitude: 51.5023, longitude: 7.3815})  
854 - * @param object destination coordinate  
855 - * @param string Bearing mode. Can be either circle or rhumbline  
856 - * @return object Returns an object with a rough (NESW) and an exact direction (NNE, NE, ENE, E, ESE, etc).  
857 - */  
858 - getCompassDirection: function(originLL, destLL, bearingMode) {  
859 -  
860 - var direction;  
861 - var bearing;  
862 -  
863 - if(bearingMode == 'circle') {  
864 - // use great circle bearing  
865 - bearing = this.getBearing(originLL, destLL);  
866 - } else {  
867 - // default is rhumb line bearing  
868 - bearing = this.getRhumbLineBearing(originLL, destLL);  
869 - }  
870 -  
871 - switch(Math.round(bearing/22.5)) {  
872 - case 1:  
873 - direction = {exact: "NNE", rough: "N"};  
874 - break;  
875 - case 2:  
876 - direction = {exact: "NE", rough: "N"};  
877 - break;  
878 - case 3:  
879 - direction = {exact: "ENE", rough: "E"};  
880 - break;  
881 - case 4:  
882 - direction = {exact: "E", rough: "E"};  
883 - break;  
884 - case 5:  
885 - direction = {exact: "ESE", rough: "E"};  
886 - break;  
887 - case 6:  
888 - direction = {exact: "SE", rough: "E"};  
889 - break;  
890 - case 7:  
891 - direction = {exact: "SSE", rough: "S"};  
892 - break;  
893 - case 8:  
894 - direction = {exact: "S", rough: "S"};  
895 - break;  
896 - case 9:  
897 - direction = {exact: "SSW", rough: "S"};  
898 - break;  
899 - case 10:  
900 - direction = {exact: "SW", rough: "S"};  
901 - break;  
902 - case 11:  
903 - direction = {exact: "WSW", rough: "W"};  
904 - break;  
905 - case 12:  
906 - direction = {exact: "W", rough: "W"};  
907 - break;  
908 - case 13:  
909 - direction = {exact: "WNW", rough: "W"};  
910 - break;  
911 - case 14:  
912 - direction = {exact: "NW", rough: "W"};  
913 - break;  
914 - case 15:  
915 - direction = {exact: "NNW", rough: "N"};  
916 - break;  
917 - default:  
918 - direction = {exact: "N", rough: "N"};  
919 - }  
920 -  
921 - direction['bearing'] = bearing;  
922 - return direction;  
923 -  
924 - },  
925 -  
926 -  
927 - /**  
928 - * Shortcut for getCompassDirection  
929 - */  
930 - getDirection: function(originLL, destLL, bearingMode) {  
931 - return this.getCompassDirection.apply(this, arguments);  
932 - },  
933 -  
934 -  
935 - /**  
936 - * Sorts an array of coords by distance from a reference coordinate  
937 - *  
938 - * @param object reference coordinate e.g. {latitude: 51.5023, longitude: 7.3815}  
939 - * @param mixed array or object with coords [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]  
940 - * @return array ordered array  
941 - */  
942 - orderByDistance: function(latlng, coords) {  
943 -  
944 - var coordsArray = [];  
945 -  
946 - for(var coord in coords) {  
947 -  
948 - var distance = this.getDistance(latlng, coords[coord]);  
949 - var augmentedCoord = Object.create(coords[coord]);  
950 - augmentedCoord.distance = distance;  
951 - augmentedCoord.key = coord;  
952 -  
953 - coordsArray.push(augmentedCoord);  
954 -  
955 - }  
956 -  
957 - return coordsArray.sort(function(a, b) {  
958 - return a.distance - b.distance;  
959 - });  
960 -  
961 - },  
962 -  
963 - /**  
964 - * Check if a point lies in line created by two other points  
965 - *  
966 - * @param object Point to check: {latitude: 123, longitude: 123}  
967 - * @param object Start of line {latitude: 123, longitude: 123}  
968 - * @param object End of line {latitude: 123, longitude: 123}  
969 - * @return boolean  
970 - */  
971 - isPointInLine: function(point, start, end) {  
972 -  
973 - return (this.getDistance(start, point, 1, 3)+this.getDistance(point, end, 1, 3)).toFixed(3)==this.getDistance(start, end, 1, 3);  
974 - },  
975 -  
976 - /**  
977 - * Check if a point lies within a given distance from a line created by two other points  
978 - *  
979 - * @param object Point to check: {latitude: 123, longitude: 123}  
980 - * @param object Start of line {latitude: 123, longitude: 123}  
981 - * @param object End of line {latitude: 123, longitude: 123}  
982 - * @pararm float maximum distance from line  
983 - * @return boolean  
984 - */  
985 - isPointNearLine: function(point, start, end, distance) {  
986 - return this.getDistanceFromLine(point, start, end) < distance;  
987 - },  
988 -  
989 - /**  
990 - * return the minimum distance from a point to a line  
991 - *  
992 - * @param object Point away from line  
993 - * @param object Start of line {latitude: 123, longitude: 123}  
994 - * @param object End of line {latitude: 123, longitude: 123}  
995 - * @return float distance from point to line  
996 - */  
997 - getDistanceFromLine: function(point, start, end) {  
998 - var d1 = this.getDistance(start, point, 1, 3);  
999 - var d2 = this.getDistance(point, end, 1, 3);  
1000 - var d3 = this.getDistance(start, end, 1, 3);  
1001 - var distance = 0;  
1002 -  
1003 - // alpha is the angle between the line from start to point, and from start to end //  
1004 - var alpha = Math.acos((d1*d1 + d3*d3 - d2*d2)/(2*d1*d3));  
1005 - // beta is the angle between the line from end to point and from end to start //  
1006 - var beta = Math.acos((d2*d2 + d3*d3 - d1*d1)/(2*d2*d3));  
1007 -  
1008 - // if the angle is greater than 90 degrees, then the minimum distance is the  
1009 - // line from the start to the point //  
1010 - if(alpha>Math.PI/2) {  
1011 - distance = d1;  
1012 - }  
1013 - // same for the beta //  
1014 - else if(beta > Math.PI/2) {  
1015 - distance = d2;  
1016 - }  
1017 - // otherwise the minimum distance is achieved through a line perpendular to the start-end line,  
1018 - // which goes from the start-end line to the point //  
1019 - else {  
1020 - distance = Math.sin(alpha) * d1;  
1021 - }  
1022 -  
1023 - return distance;  
1024 - },  
1025 -  
1026 - /**  
1027 - * Finds the nearest coordinate to a reference coordinate  
1028 - *  
1029 - * @param object reference coordinate e.g. {latitude: 51.5023, longitude: 7.3815}  
1030 - * @param mixed array or object with coords [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]  
1031 - * @return array ordered array  
1032 - */  
1033 - findNearest: function(latlng, coords, offset, limit) {  
1034 -  
1035 - offset = offset || 0;  
1036 - limit = limit || 1;  
1037 - var ordered = this.orderByDistance(latlng, coords);  
1038 -  
1039 - if(limit === 1) {  
1040 - return ordered[offset];  
1041 - } else {  
1042 - return ordered.splice(offset, limit);  
1043 - }  
1044 -  
1045 - },  
1046 -  
1047 -  
1048 - /**  
1049 - * Calculates the length of a given path  
1050 - *  
1051 - * @param mixed array or object with coords [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]  
1052 - * @return integer length of the path (in meters)  
1053 - */  
1054 - getPathLength: function(coords) {  
1055 -  
1056 - var dist = 0;  
1057 - var last;  
1058 -  
1059 - for (var i = 0, l = coords.length; i < l; ++i) {  
1060 - if(last) {  
1061 - //console.log(coords[i], last, this.getDistance(coords[i], last));  
1062 - dist += this.getDistance(this.coords(coords[i]), last);  
1063 - }  
1064 - last = this.coords(coords[i]);  
1065 - }  
1066 -  
1067 - return dist;  
1068 -  
1069 - },  
1070 -  
1071 -  
1072 - /**  
1073 - * Calculates the speed between to points within a given time span.  
1074 - *  
1075 - * @param object coords with javascript timestamp {latitude: 51.5143, longitude: 7.4138, time: 1360231200880}  
1076 - * @param object coords with javascript timestamp {latitude: 51.5502, longitude: 7.4323, time: 1360245600460}  
1077 - * @param object options (currently "unit" is the only option. Default: km(h));  
1078 - * @return float speed in unit per hour  
1079 - */  
1080 - getSpeed: function(start, end, options) {  
1081 -  
1082 - var unit = options && options.unit || 'km';  
1083 -  
1084 - if(unit == 'mph') {  
1085 - unit = 'mi';  
1086 - } else if(unit == 'kmh') {  
1087 - unit = 'km';  
1088 - }  
1089 -  
1090 - var distance = geolib.getDistance(start, end);  
1091 - var time = ((end.time*1)/1000) - ((start.time*1)/1000);  
1092 - var mPerHr = (distance/time)*3600;  
1093 - var speed = Math.round(mPerHr * this.measures[unit] * 10000)/10000;  
1094 - return speed;  
1095 -  
1096 - },  
1097 -  
1098 -  
1099 - /**  
1100 - * Computes the destination point given an initial point, a distance  
1101 - * and a bearing  
1102 - *  
1103 - * see http://www.movable-type.co.uk/scripts/latlong.html for the original code  
1104 - *  
1105 - * @param object start coordinate (e.g. {latitude: 51.5023, longitude: 7.3815})  
1106 - * @param float longitude of the inital point in degree  
1107 - * @param float distance to go from the inital point in meter  
1108 - * @param float bearing in degree of the direction to go, e.g. 0 = north, 180 = south  
1109 - * @param float optional (in meter), defaults to mean radius of the earth  
1110 - * @return object {latitude: destLat (in degree), longitude: destLng (in degree)}  
1111 - */  
1112 - computeDestinationPoint: function(start, distance, bearing, radius) {  
1113 -  
1114 - var lat = this.latitude(start);  
1115 - var lng = this.longitude(start);  
1116 -  
1117 - radius = (typeof radius === 'undefined') ? this.radius : Number(radius);  
1118 -  
1119 - var δ = Number(distance) / radius; // angular distance in radians  
1120 - var θ = Number(bearing).toRad();  
1121 -  
1122 - var φ1 = Number(lat).toRad();  
1123 - var λ1 = Number(lng).toRad();  
1124 -  
1125 - var φ2 = Math.asin( Math.sin(φ1)*Math.cos(δ) +  
1126 - Math.cos(φ1)*Math.sin(δ)*Math.cos(θ) );  
1127 - var λ2 = λ1 + Math.atan2(Math.sin(θ)*Math.sin(δ)*Math.cos(φ1),  
1128 - Math.cos(δ)-Math.sin(φ1)*Math.sin(φ2));  
1129 - λ2 = (λ2+3*Math.PI) % (2*Math.PI) - Math.PI; // normalise to -180..+180°  
1130 -  
1131 - return {  
1132 - latitude: φ2.toDeg(),  
1133 - longitude: λ2.toDeg()  
1134 - };  
1135 -  
1136 - },  
1137 -  
1138 -  
1139 - /**  
1140 - * Converts a distance from meters to km, mm, cm, mi, ft, in or yd  
1141 - *  
1142 - * @param string Format to be converted in  
1143 - * @param float Distance in meters  
1144 - * @param float Decimal places for rounding (default: 4)  
1145 - * @return float Converted distance  
1146 - */  
1147 - convertUnit: function(unit, distance, round) {  
1148 -  
1149 - if(distance === 0) {  
1150 -  
1151 - return 0;  
1152 -  
1153 - } else if(typeof distance === 'undefined') {  
1154 -  
1155 - if(this.distance === null) {  
1156 - throw new Error('No distance was given');  
1157 - } else if(this.distance === 0) {  
1158 - return 0;  
1159 - } else {  
1160 - distance = this.distance;  
1161 - }  
1162 -  
1163 - }  
1164 -  
1165 - unit = unit || 'm';  
1166 - round = (null == round ? 4 : round);  
1167 -  
1168 - if(typeof this.measures[unit] !== 'undefined') {  
1169 - return this.round(distance * this.measures[unit], round);  
1170 - } else {  
1171 - throw new Error('Unknown unit for conversion.');  
1172 - }  
1173 -  
1174 - },  
1175 -  
1176 -  
1177 - /**  
1178 - * Checks if a value is in decimal format or, if neccessary, converts to decimal  
1179 - *  
1180 - * @param mixed Value(s) to be checked/converted (array of latlng objects, latlng object, sexagesimal string, float)  
1181 - * @return float Input data in decimal format  
1182 - */  
1183 - useDecimal: function(value) {  
1184 -  
1185 - if(Object.prototype.toString.call(value) === '[object Array]') {  
1186 -  
1187 - var geolib = this;  
1188 -  
1189 - value = value.map(function(val) {  
1190 -  
1191 - //if(!isNaN(parseFloat(val))) {  
1192 - if(geolib.isDecimal(val)) {  
1193 -  
1194 - return geolib.useDecimal(val);  
1195 -  
1196 - } else if(typeof val == 'object') {  
1197 -  
1198 - if(geolib.validate(val)) {  
1199 -  
1200 - return geolib.coords(val);  
1201 -  
1202 - } else {  
1203 -  
1204 - for(var prop in val) {  
1205 - val[prop] = geolib.useDecimal(val[prop]);  
1206 - }  
1207 -  
1208 - return val;  
1209 -  
1210 - }  
1211 -  
1212 - } else if(geolib.isSexagesimal(val)) {  
1213 -  
1214 - return geolib.sexagesimal2decimal(val);  
1215 -  
1216 - } else {  
1217 -  
1218 - return val;  
1219 -  
1220 - }  
1221 -  
1222 - });  
1223 -  
1224 - return value;  
1225 -  
1226 - } else if(typeof value === 'object' && this.validate(value)) {  
1227 -  
1228 - return this.coords(value);  
1229 -  
1230 - } else if(typeof value === 'object') {  
1231 -  
1232 - for(var prop in value) {  
1233 - value[prop] = this.useDecimal(value[prop]);  
1234 - }  
1235 -  
1236 - return value;  
1237 -  
1238 - }  
1239 -  
1240 -  
1241 - if (this.isDecimal(value)) {  
1242 -  
1243 - return parseFloat(value);  
1244 -  
1245 - } else if(this.isSexagesimal(value) === true) {  
1246 -  
1247 - return parseFloat(this.sexagesimal2decimal(value));  
1248 -  
1249 - }  
1250 -  
1251 - throw new Error('Unknown format.');  
1252 -  
1253 - },  
1254 -  
1255 - /**  
1256 - * Converts a decimal coordinate value to sexagesimal format  
1257 - *  
1258 - * @param float decimal  
1259 - * @return string Sexagesimal value (XX° YY' ZZ")  
1260 - */  
1261 - decimal2sexagesimal: function(dec) {  
1262 -  
1263 - if (dec in this.sexagesimal) {  
1264 - return this.sexagesimal[dec];  
1265 - }  
1266 -  
1267 - var tmp = dec.toString().split('.');  
1268 -  
1269 - var deg = Math.abs(tmp[0]);  
1270 - var min = ('0.' + (tmp[1] || 0))*60;  
1271 - var sec = min.toString().split('.');  
1272 -  
1273 - min = Math.floor(min);  
1274 - sec = (('0.' + (sec[1] || 0)) * 60).toFixed(2);  
1275 -  
1276 - this.sexagesimal[dec] = (deg + '° ' + min + "' " + sec + '"');  
1277 -  
1278 - return this.sexagesimal[dec];  
1279 -  
1280 - },  
1281 -  
1282 -  
1283 - /**  
1284 - * Converts a sexagesimal coordinate to decimal format  
1285 - *  
1286 - * @param float Sexagesimal coordinate  
1287 - * @return string Decimal value (XX.XXXXXXXX)  
1288 - */  
1289 - sexagesimal2decimal: function(sexagesimal) {  
1290 -  
1291 - if (sexagesimal in this.decimal) {  
1292 - return this.decimal[sexagesimal];  
1293 - }  
1294 -  
1295 - var regEx = new RegExp(this.sexagesimalPattern);  
1296 - var data = regEx.exec(sexagesimal);  
1297 - var min = 0, sec = 0;  
1298 -  
1299 - if(data) {  
1300 - min = parseFloat(data[2]/60);  
1301 - sec = parseFloat(data[4]/3600) || 0;  
1302 - }  
1303 -  
1304 - var dec = ((parseFloat(data[1]) + min + sec)).toFixed(8);  
1305 - //var dec = ((parseFloat(data[1]) + min + sec));  
1306 -  
1307 - // South and West are negative decimals  
1308 - dec = (data[7] == 'S' || data[7] == 'W') ? parseFloat(-dec) : parseFloat(dec);  
1309 - //dec = (data[7] == 'S' || data[7] == 'W') ? -dec : dec;  
1310 -  
1311 - this.decimal[sexagesimal] = dec;  
1312 -  
1313 - return dec;  
1314 -  
1315 - },  
1316 -  
1317 -  
1318 - /**  
1319 - * Checks if a value is in decimal format  
1320 - *  
1321 - * @param string Value to be checked  
1322 - * @return bool True if in sexagesimal format  
1323 - */  
1324 - isDecimal: function(value) {  
1325 -  
1326 - value = value.toString().replace(/\s*/, '');  
1327 -  
1328 - // looks silly but works as expected  
1329 - // checks if value is in decimal format  
1330 - return (!isNaN(parseFloat(value)) && parseFloat(value) == value);  
1331 -  
1332 - },  
1333 -  
1334 -  
1335 - /**  
1336 - * Checks if a value is in sexagesimal format  
1337 - *  
1338 - * @param string Value to be checked  
1339 - * @return bool True if in sexagesimal format  
1340 - */  
1341 - isSexagesimal: function(value) {  
1342 -  
1343 - value = value.toString().replace(/\s*/, '');  
1344 -  
1345 - return this.sexagesimalPattern.test(value);  
1346 -  
1347 - },  
1348 -  
1349 - round: function(value, n) {  
1350 - var decPlace = Math.pow(10, n);  
1351 - return Math.round(value * decPlace)/decPlace;  
1352 - }  
1353 -  
1354 - });  
1355 -  
1356 - // Node module  
1357 - if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {  
1358 -  
1359 - module.exports = geolib;  
1360 -  
1361 - // react native  
1362 - if (typeof global === 'object') {  
1363 - global.geolib = geolib;  
1364 - }  
1365 -  
1366 - // AMD module  
1367 - } else if (typeof define === "function" && define.amd) {  
1368 -  
1369 - define("geolib", [], function () {  
1370 - return geolib;  
1371 - });  
1372 -  
1373 - // we're in a browser  
1374 - } else {  
1375 -  
1376 - global.geolib = geolib;  
1377 -  
1378 - }  
1379 -  
1380 -}(this)); 1 +/*! geolib 2.0.21 by Manuel Bieh
  2 +* Library to provide geo functions like distance calculation,
  3 +* conversion of decimal coordinates to sexagesimal and vice versa, etc.
  4 +* WGS 84 (World Geodetic System 1984)
  5 +*
  6 +* @author Manuel Bieh
  7 +* @url http://www.manuelbieh.com/
  8 +* @version 2.0.21
  9 +* @license MIT
  10 +**/;(function(global, undefined) {
  11 +
  12 + "use strict";
  13 +
  14 + function Geolib() {}
  15 +
  16 + // Constants
  17 + Geolib.TO_RAD = Math.PI / 180;
  18 + Geolib.TO_DEG = 180 / Math.PI;
  19 + Geolib.PI_X2 = Math.PI * 2;
  20 + Geolib.PI_DIV4 = Math.PI / 4;
  21 +
  22 + // Setting readonly defaults
  23 + var geolib = Object.create(Geolib.prototype, {
  24 + version: {
  25 + value: "2.0.21"
  26 + },
  27 + radius: {
  28 + value: 6378137
  29 + },
  30 + minLat: {
  31 + value: -90
  32 + },
  33 + maxLat: {
  34 + value: 90
  35 + },
  36 + minLon: {
  37 + value: -180
  38 + },
  39 + maxLon: {
  40 + value: 180
  41 + },
  42 + sexagesimalPattern: {
  43 + value: /^([0-9]{1,3})°\s*([0-9]{1,3}(?:\.(?:[0-9]{1,2}))?)'\s*(([0-9]{1,3}(\.([0-9]{1,4}))?)"\s*)?([NEOSW]?)$/
  44 + },
  45 + measures: {
  46 + value: Object.create(Object.prototype, {
  47 + "m" : {value: 1},
  48 + "km": {value: 0.001},
  49 + "cm": {value: 100},
  50 + "mm": {value: 1000},
  51 + "mi": {value: (1 / 1609.344)},
  52 + "sm": {value: (1 / 1852.216)},
  53 + "ft": {value: (100 / 30.48)},
  54 + "in": {value: (100 / 2.54)},
  55 + "yd": {value: (1 / 0.9144)}
  56 + })
  57 + },
  58 + prototype: {
  59 + value: Geolib.prototype
  60 + },
  61 + extend: {
  62 + value: function(methods, overwrite) {
  63 + for(var prop in methods) {
  64 + if(typeof geolib.prototype[prop] === 'undefined' || overwrite === true) {
  65 + if(typeof methods[prop] === 'function' && typeof methods[prop].bind === 'function') {
  66 + geolib.prototype[prop] = methods[prop].bind(geolib);
  67 + } else {
  68 + geolib.prototype[prop] = methods[prop];
  69 + }
  70 + }
  71 + }
  72 + }
  73 + }
  74 + });
  75 +
  76 + if (typeof(Number.prototype.toRad) === 'undefined') {
  77 + Number.prototype.toRad = function() {
  78 + return this * Geolib.TO_RAD;
  79 + };
  80 + }
  81 +
  82 + if (typeof(Number.prototype.toDeg) === 'undefined') {
  83 + Number.prototype.toDeg = function() {
  84 + return this * Geolib.TO_DEG;
  85 + };
  86 + }
  87 +
  88 + // Here comes the magic
  89 + geolib.extend({
  90 +
  91 + decimal: {},
  92 +
  93 + sexagesimal: {},
  94 +
  95 + distance: null,
  96 +
  97 + getKeys: function(point) {
  98 +
  99 + // GeoJSON Array [longitude, latitude(, elevation)]
  100 + if(Object.prototype.toString.call(point) == '[object Array]') {
  101 +
  102 + return {
  103 + longitude: point.length >= 1 ? 0 : undefined,
  104 + latitude: point.length >= 2 ? 1 : undefined,
  105 + elevation: point.length >= 3 ? 2 : undefined
  106 + };
  107 +
  108 + }
  109 +
  110 + var getKey = function(possibleValues) {
  111 +
  112 + var key;
  113 +
  114 + possibleValues.every(function(val) {
  115 + // TODO: check if point is an object
  116 + if(typeof point != 'object') {
  117 + return true;
  118 + }
  119 + return point.hasOwnProperty(val) ? (function() { key = val; return false; }()) : true;
  120 + });
  121 +
  122 + return key;
  123 +
  124 + };
  125 +
  126 + var longitude = getKey(['lng', 'lon', 'longitude']);
  127 + var latitude = getKey(['lat', 'latitude']);
  128 + var elevation = getKey(['alt', 'altitude', 'elevation', 'elev']);
  129 +
  130 + // return undefined if not at least one valid property was found
  131 + if(typeof latitude == 'undefined' &&
  132 + typeof longitude == 'undefined' &&
  133 + typeof elevation == 'undefined') {
  134 + return undefined;
  135 + }
  136 +
  137 + return {
  138 + latitude: latitude,
  139 + longitude: longitude,
  140 + elevation: elevation
  141 + };
  142 +
  143 + },
  144 +
  145 + // returns latitude of a given point, converted to decimal
  146 + // set raw to true to avoid conversion
  147 + getLat: function(point, raw) {
  148 + return raw === true ? point[this.getKeys(point).latitude] : this.useDecimal(point[this.getKeys(point).latitude]);
  149 + },
  150 +
  151 + // Alias for getLat
  152 + latitude: function(point) {
  153 + return this.getLat.call(this, point);
  154 + },
  155 +
  156 + // returns longitude of a given point, converted to decimal
  157 + // set raw to true to avoid conversion
  158 + getLon: function(point, raw) {
  159 + return raw === true ? point[this.getKeys(point).longitude] : this.useDecimal(point[this.getKeys(point).longitude]);
  160 + },
  161 +
  162 + // Alias for getLon
  163 + longitude: function(point) {
  164 + return this.getLon.call(this, point);
  165 + },
  166 +
  167 + getElev: function(point) {
  168 + return point[this.getKeys(point).elevation];
  169 + },
  170 +
  171 + // Alias for getElev
  172 + elevation: function(point) {
  173 + return this.getElev.call(this, point);
  174 + },
  175 +
  176 + coords: function(point, raw) {
  177 +
  178 + var retval = {
  179 + latitude: raw === true ? point[this.getKeys(point).latitude] : this.useDecimal(point[this.getKeys(point).latitude]),
  180 + longitude: raw === true ? point[this.getKeys(point).longitude] : this.useDecimal(point[this.getKeys(point).longitude])
  181 + };
  182 +
  183 + var elev = point[this.getKeys(point).elevation];
  184 +
  185 + if(typeof elev !== 'undefined') {
  186 + retval['elevation'] = elev;
  187 + }
  188 +
  189 + return retval;
  190 +
  191 + },
  192 +
  193 + // Alias for coords
  194 + ll: function(point, raw) {
  195 + return this.coords.call(this, point, raw);
  196 + },
  197 +
  198 +
  199 + // checks if a variable contains a valid latlong object
  200 + validate: function(point) {
  201 +
  202 + var keys = this.getKeys(point);
  203 +
  204 + if(typeof keys === 'undefined' || typeof keys.latitude === 'undefined' || keys.longitude === 'undefined') {
  205 + return false;
  206 + }
  207 +
  208 + var lat = point[keys.latitude];
  209 + var lng = point[keys.longitude];
  210 +
  211 + if(typeof lat === 'undefined' || !this.isDecimal(lat) && !this.isSexagesimal(lat)) {
  212 + return false;
  213 + }
  214 +
  215 + if(typeof lng === 'undefined' || !this.isDecimal(lng) && !this.isSexagesimal(lng)) {
  216 + return false;
  217 + }
  218 +
  219 + lat = this.useDecimal(lat);
  220 + lng = this.useDecimal(lng);
  221 +
  222 + if(lat < this.minLat || lat > this.maxLat || lng < this.minLon || lng > this.maxLon) {
  223 + return false;
  224 + }
  225 +
  226 + return true;
  227 +
  228 + },
  229 +
  230 + /**
  231 + * Calculates geodetic distance between two points specified by latitude/longitude using
  232 + * Vincenty inverse formula for ellipsoids
  233 + * Vincenty Inverse Solution of Geodesics on the Ellipsoid (c) Chris Veness 2002-2010
  234 + * (Licensed under CC BY 3.0)
  235 + *
  236 + * @param object Start position {latitude: 123, longitude: 123}
  237 + * @param object End position {latitude: 123, longitude: 123}
  238 + * @param integer Accuracy (in meters)
  239 + * @param integer Precision (in decimal cases)
  240 + * @return integer Distance (in meters)
  241 + */
  242 + getDistance: function(start, end, accuracy, precision) {
  243 +
  244 + accuracy = Math.floor(accuracy) || 1;
  245 + precision = Math.floor(precision) || 0;
  246 +
  247 + var s = this.coords(start);
  248 + var e = this.coords(end);
  249 +
  250 + var a = 6378137, b = 6356752.314245, f = 1/298.257223563; // WGS-84 ellipsoid params
  251 + var L = (e['longitude']-s['longitude']).toRad();
  252 +
  253 + var cosSigma, sigma, sinAlpha, cosSqAlpha, cos2SigmaM, sinSigma;
  254 +
  255 + var U1 = Math.atan((1-f) * Math.tan(parseFloat(s['latitude']).toRad()));
  256 + var U2 = Math.atan((1-f) * Math.tan(parseFloat(e['latitude']).toRad()));
  257 + var sinU1 = Math.sin(U1), cosU1 = Math.cos(U1);
  258 + var sinU2 = Math.sin(U2), cosU2 = Math.cos(U2);
  259 +
  260 + var lambda = L, lambdaP, iterLimit = 100;
  261 + do {
  262 + var sinLambda = Math.sin(lambda), cosLambda = Math.cos(lambda);
  263 + sinSigma = (
  264 + Math.sqrt(
  265 + (
  266 + cosU2 * sinLambda
  267 + ) * (
  268 + cosU2 * sinLambda
  269 + ) + (
  270 + cosU1 * sinU2 - sinU1 * cosU2 * cosLambda
  271 + ) * (
  272 + cosU1 * sinU2 - sinU1 * cosU2 * cosLambda
  273 + )
  274 + )
  275 + );
  276 + if (sinSigma === 0) {
  277 + return geolib.distance = 0; // co-incident points
  278 + }
  279 +
  280 + cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda;
  281 + sigma = Math.atan2(sinSigma, cosSigma);
  282 + sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma;
  283 + cosSqAlpha = 1 - sinAlpha * sinAlpha;
  284 + cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha;
  285 +
  286 + if (isNaN(cos2SigmaM)) {
  287 + cos2SigmaM = 0; // equatorial line: cosSqAlpha=0 (§6)
  288 + }
  289 + var C = (
  290 + f / 16 * cosSqAlpha * (
  291 + 4 + f * (
  292 + 4 - 3 * cosSqAlpha
  293 + )
  294 + )
  295 + );
  296 + lambdaP = lambda;
  297 + lambda = (
  298 + L + (
  299 + 1 - C
  300 + ) * f * sinAlpha * (
  301 + sigma + C * sinSigma * (
  302 + cos2SigmaM + C * cosSigma * (
  303 + -1 + 2 * cos2SigmaM * cos2SigmaM
  304 + )
  305 + )
  306 + )
  307 + );
  308 +
  309 + } while (Math.abs(lambda-lambdaP) > 1e-12 && --iterLimit>0);
  310 +
  311 + if (iterLimit === 0) {
  312 + return NaN; // formula failed to converge
  313 + }
  314 +
  315 + var uSq = (
  316 + cosSqAlpha * (
  317 + a * a - b * b
  318 + ) / (
  319 + b*b
  320 + )
  321 + );
  322 +
  323 + var A = (
  324 + 1 + uSq / 16384 * (
  325 + 4096 + uSq * (
  326 + -768 + uSq * (
  327 + 320 - 175 * uSq
  328 + )
  329 + )
  330 + )
  331 + );
  332 +
  333 + var B = (
  334 + uSq / 1024 * (
  335 + 256 + uSq * (
  336 + -128 + uSq * (
  337 + 74-47 * uSq
  338 + )
  339 + )
  340 + )
  341 + );
  342 +
  343 + var deltaSigma = (
  344 + B * sinSigma * (
  345 + cos2SigmaM + B / 4 * (
  346 + cosSigma * (
  347 + -1 + 2 * cos2SigmaM * cos2SigmaM
  348 + ) -B / 6 * cos2SigmaM * (
  349 + -3 + 4 * sinSigma * sinSigma
  350 + ) * (
  351 + -3 + 4 * cos2SigmaM * cos2SigmaM
  352 + )
  353 + )
  354 + )
  355 + );
  356 +
  357 + var distance = b * A * (sigma - deltaSigma);
  358 +
  359 + distance = distance.toFixed(precision); // round to 1mm precision
  360 +
  361 + //if (start.hasOwnProperty(elevation) && end.hasOwnProperty(elevation)) {
  362 + if (typeof this.elevation(start) !== 'undefined' && typeof this.elevation(end) !== 'undefined') {
  363 + var climb = Math.abs(this.elevation(start) - this.elevation(end));
  364 + distance = Math.sqrt(distance * distance + climb * climb);
  365 + }
  366 +
  367 + return this.distance = Math.round(distance * Math.pow(10, precision) / accuracy) * accuracy / Math.pow(10, precision);
  368 +
  369 + /*
  370 + // note: to return initial/final bearings in addition to distance, use something like:
  371 + var fwdAz = Math.atan2(cosU2*sinLambda, cosU1*sinU2-sinU1*cosU2*cosLambda);
  372 + var revAz = Math.atan2(cosU1*sinLambda, -sinU1*cosU2+cosU1*sinU2*cosLambda);
  373 +
  374 + return { distance: s, initialBearing: fwdAz.toDeg(), finalBearing: revAz.toDeg() };
  375 + */
  376 +
  377 + },
  378 +
  379 +
  380 + /**
  381 + * Calculates the distance between two spots.
  382 + * This method is more simple but also far more inaccurate
  383 + *
  384 + * @param object Start position {latitude: 123, longitude: 123}
  385 + * @param object End position {latitude: 123, longitude: 123}
  386 + * @param integer Accuracy (in meters)
  387 + * @return integer Distance (in meters)
  388 + */
  389 + getDistanceSimple: function(start, end, accuracy) {
  390 +
  391 + accuracy = Math.floor(accuracy) || 1;
  392 +
  393 + var distance =
  394 + Math.round(
  395 + Math.acos(
  396 + Math.sin(
  397 + this.latitude(end).toRad()
  398 + ) *
  399 + Math.sin(
  400 + this.latitude(start).toRad()
  401 + ) +
  402 + Math.cos(
  403 + this.latitude(end).toRad()
  404 + ) *
  405 + Math.cos(
  406 + this.latitude(start).toRad()
  407 + ) *
  408 + Math.cos(
  409 + this.longitude(start).toRad() - this.longitude(end).toRad()
  410 + )
  411 + ) * this.radius
  412 + );
  413 +
  414 + return geolib.distance = Math.floor(Math.round(distance/accuracy)*accuracy);
  415 +
  416 + },
  417 +
  418 +
  419 + /**
  420 + * Calculates the center of a collection of geo coordinates
  421 + *
  422 + * @param array Collection of coords [{latitude: 51.510, longitude: 7.1321}, {latitude: 49.1238, longitude: "8° 30' W"}, ...]
  423 + * @return object {latitude: centerLat, longitude: centerLng}
  424 + */
  425 + getCenter: function(coords) {
  426 +
  427 + var coordsArray = coords;
  428 + if(typeof coords === 'object' && !(coords instanceof Array)) {
  429 +
  430 + coordsArray = [];
  431 +
  432 + for(var key in coords) {
  433 + coordsArray.push(
  434 + this.coords(coords[key])
  435 + );
  436 + }
  437 +
  438 + }
  439 +
  440 + if(!coordsArray.length) {
  441 + return false;
  442 + }
  443 +
  444 + var X = 0.0;
  445 + var Y = 0.0;
  446 + var Z = 0.0;
  447 + var lat, lon, hyp;
  448 +
  449 + coordsArray.forEach(function(coord) {
  450 +
  451 + lat = this.latitude(coord).toRad();
  452 + lon = this.longitude(coord).toRad();
  453 +
  454 + X += Math.cos(lat) * Math.cos(lon);
  455 + Y += Math.cos(lat) * Math.sin(lon);
  456 + Z += Math.sin(lat);
  457 +
  458 + }, this);
  459 +
  460 + var nb_coords = coordsArray.length;
  461 + X = X / nb_coords;
  462 + Y = Y / nb_coords;
  463 + Z = Z / nb_coords;
  464 +
  465 + lon = Math.atan2(Y, X);
  466 + hyp = Math.sqrt(X * X + Y * Y);
  467 + lat = Math.atan2(Z, hyp);
  468 +
  469 + return {
  470 + latitude: (lat * Geolib.TO_DEG).toFixed(6),
  471 + longitude: (lon * Geolib.TO_DEG).toFixed(6)
  472 + };
  473 +
  474 + },
  475 +
  476 +
  477 + /**
  478 + * Gets the max and min, latitude, longitude, and elevation (if provided).
  479 + * @param array array with coords e.g. [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]
  480 + * @return object {maxLat: maxLat,
  481 + * minLat: minLat
  482 + * maxLng: maxLng,
  483 + * minLng: minLng,
  484 + * maxElev: maxElev,
  485 + * minElev: minElev}
  486 + */
  487 + getBounds: function(coords) {
  488 +
  489 + if (!coords.length) {
  490 + return false;
  491 + }
  492 +
  493 + var useElevation = this.elevation(coords[0]);
  494 +
  495 + var stats = {
  496 + maxLat: -Infinity,
  497 + minLat: Infinity,
  498 + maxLng: -Infinity,
  499 + minLng: Infinity
  500 + };
  501 +
  502 + if (typeof useElevation != 'undefined') {
  503 + stats.maxElev = 0;
  504 + stats.minElev = Infinity;
  505 + }
  506 +
  507 + for (var i = 0, l = coords.length; i < l; ++i) {
  508 +
  509 + stats.maxLat = Math.max(this.latitude(coords[i]), stats.maxLat);
  510 + stats.minLat = Math.min(this.latitude(coords[i]), stats.minLat);
  511 + stats.maxLng = Math.max(this.longitude(coords[i]), stats.maxLng);
  512 + stats.minLng = Math.min(this.longitude(coords[i]), stats.minLng);
  513 +
  514 + if (useElevation) {
  515 + stats.maxElev = Math.max(this.elevation(coords[i]), stats.maxElev);
  516 + stats.minElev = Math.min(this.elevation(coords[i]), stats.minElev);
  517 + }
  518 +
  519 + }
  520 +
  521 + return stats;
  522 +
  523 + },
  524 +
  525 + /**
  526 + * Calculates the center of the bounds of geo coordinates.
  527 + *
  528 + * On polygons like political borders (eg. states)
  529 + * this may gives a closer result to human expectation, than `getCenter`,
  530 + * because that function can be disturbed by uneven distribution of
  531 + * point in different sides.
  532 + * Imagine the US state Oklahoma: `getCenter` on that gives a southern
  533 + * point, because the southern border contains a lot more nodes,
  534 + * than the others.
  535 + *
  536 + * @param array Collection of coords [{latitude: 51.510, longitude: 7.1321}, {latitude: 49.1238, longitude: "8° 30' W"}, ...]
  537 + * @return object {latitude: centerLat, longitude: centerLng}
  538 + */
  539 + getCenterOfBounds: function(coords) {
  540 + var b = this.getBounds(coords);
  541 + var latitude = b.minLat + ((b.maxLat - b.minLat) / 2);
  542 + var longitude = b.minLng + ((b.maxLng - b.minLng) / 2);
  543 + return {
  544 + latitude: parseFloat(latitude.toFixed(6)),
  545 + longitude: parseFloat(longitude.toFixed(6))
  546 + };
  547 + },
  548 +
  549 +
  550 + /**
  551 + * Computes the bounding coordinates of all points on the surface
  552 + * of the earth less than or equal to the specified great circle
  553 + * distance.
  554 + *
  555 + * @param object Point position {latitude: 123, longitude: 123}
  556 + * @param number Distance (in meters).
  557 + * @return array Collection of two points defining the SW and NE corners.
  558 + */
  559 + getBoundsOfDistance: function(point, distance) {
  560 +
  561 + var latitude = this.latitude(point);
  562 + var longitude = this.longitude(point);
  563 +
  564 + var radLat = latitude.toRad();
  565 + var radLon = longitude.toRad();
  566 +
  567 + var radDist = distance / this.radius;
  568 + var minLat = radLat - radDist;
  569 + var maxLat = radLat + radDist;
  570 +
  571 + var MAX_LAT_RAD = this.maxLat.toRad();
  572 + var MIN_LAT_RAD = this.minLat.toRad();
  573 + var MAX_LON_RAD = this.maxLon.toRad();
  574 + var MIN_LON_RAD = this.minLon.toRad();
  575 +
  576 + var minLon;
  577 + var maxLon;
  578 +
  579 + if (minLat > MIN_LAT_RAD && maxLat < MAX_LAT_RAD) {
  580 +
  581 + var deltaLon = Math.asin(Math.sin(radDist) / Math.cos(radLat));
  582 + minLon = radLon - deltaLon;
  583 +
  584 + if (minLon < MIN_LON_RAD) {
  585 + minLon += Geolib.PI_X2;
  586 + }
  587 +
  588 + maxLon = radLon + deltaLon;
  589 +
  590 + if (maxLon > MAX_LON_RAD) {
  591 + maxLon -= Geolib.PI_X2;
  592 + }
  593 +
  594 + } else {
  595 + // A pole is within the distance.
  596 + minLat = Math.max(minLat, MIN_LAT_RAD);
  597 + maxLat = Math.min(maxLat, MAX_LAT_RAD);
  598 + minLon = MIN_LON_RAD;
  599 + maxLon = MAX_LON_RAD;
  600 + }
  601 +
  602 + return [
  603 + // Southwest
  604 + {
  605 + latitude: minLat.toDeg(),
  606 + longitude: minLon.toDeg()
  607 + },
  608 + // Northeast
  609 + {
  610 + latitude: maxLat.toDeg(),
  611 + longitude: maxLon.toDeg()
  612 + }
  613 + ];
  614 +
  615 + },
  616 +
  617 +
  618 + /**
  619 + * Checks whether a point is inside of a polygon or not.
  620 + * Note that the polygon coords must be in correct order!
  621 + *
  622 + * @param object coordinate to check e.g. {latitude: 51.5023, longitude: 7.3815}
  623 + * @param array array with coords e.g. [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]
  624 + * @return bool true if the coordinate is inside the given polygon
  625 + */
  626 + isPointInside: function(latlng, coords) {
  627 +
  628 + for(var c = false, i = -1, l = coords.length, j = l - 1; ++i < l; j = i) {
  629 +
  630 + if(
  631 + (
  632 + (this.longitude(coords[i]) <= this.longitude(latlng) && this.longitude(latlng) < this.longitude(coords[j])) ||
  633 + (this.longitude(coords[j]) <= this.longitude(latlng) && this.longitude(latlng) < this.longitude(coords[i]))
  634 + ) &&
  635 + (
  636 + this.latitude(latlng) < (this.latitude(coords[j]) - this.latitude(coords[i])) *
  637 + (this.longitude(latlng) - this.longitude(coords[i])) /
  638 + (this.longitude(coords[j]) - this.longitude(coords[i])) +
  639 + this.latitude(coords[i])
  640 + )
  641 + ) {
  642 + c = !c;
  643 + }
  644 +
  645 + }
  646 +
  647 + return c;
  648 +
  649 + },
  650 +
  651 +
  652 + /**
  653 + * Pre calculate the polygon coords, to speed up the point inside check.
  654 + * Use this function before calling isPointInsideWithPreparedPolygon()
  655 + * @see Algorythm from http://alienryderflex.com/polygon/
  656 + * @param array array with coords e.g. [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]
  657 + */
  658 + preparePolygonForIsPointInsideOptimized: function(coords) {
  659 +
  660 + for(var i = 0, j = coords.length-1; i < coords.length; i++) {
  661 +
  662 + if(this.longitude(coords[j]) === this.longitude(coords[i])) {
  663 +
  664 + coords[i].constant = this.latitude(coords[i]);
  665 + coords[i].multiple = 0;
  666 +
  667 + } else {
  668 +
  669 + coords[i].constant = this.latitude(coords[i]) - (
  670 + this.longitude(coords[i]) * this.latitude(coords[j])
  671 + ) / (
  672 + this.longitude(coords[j]) - this.longitude(coords[i])
  673 + ) + (
  674 + this.longitude(coords[i])*this.latitude(coords[i])
  675 + ) / (
  676 + this.longitude(coords[j])-this.longitude(coords[i])
  677 + );
  678 +
  679 + coords[i].multiple = (
  680 + this.latitude(coords[j])-this.latitude(coords[i])
  681 + ) / (
  682 + this.longitude(coords[j])-this.longitude(coords[i])
  683 + );
  684 +
  685 + }
  686 +
  687 + j=i;
  688 +
  689 + }
  690 +
  691 + },
  692 +
  693 + /**
  694 + * Checks whether a point is inside of a polygon or not.
  695 + * "This is useful if you have many points that need to be tested against the same (static) polygon."
  696 + * Please call the function preparePolygonForIsPointInsideOptimized() with the same coords object before using this function.
  697 + * Note that the polygon coords must be in correct order!
  698 + *
  699 + * @see Algorythm from http://alienryderflex.com/polygon/
  700 + *
  701 + * @param object coordinate to check e.g. {latitude: 51.5023, longitude: 7.3815}
  702 + * @param array array with coords e.g. [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]
  703 + * @return bool true if the coordinate is inside the given polygon
  704 + */
  705 + isPointInsideWithPreparedPolygon: function(point, coords) {
  706 +
  707 + var flgPointInside = false,
  708 + y = this.longitude(point),
  709 + x = this.latitude(point);
  710 +
  711 + for(var i = 0, j = coords.length-1; i < coords.length; i++) {
  712 +
  713 + if ((this.longitude(coords[i]) < y && this.longitude(coords[j]) >=y ||
  714 + this.longitude(coords[j]) < y && this.longitude(coords[i]) >= y)) {
  715 +
  716 + flgPointInside^=(y*coords[i].multiple+coords[i].constant < x);
  717 +
  718 + }
  719 +
  720 + j=i;
  721 +
  722 + }
  723 +
  724 + return flgPointInside;
  725 +
  726 + },
  727 +
  728 +
  729 + /**
  730 + * Shortcut for geolib.isPointInside()
  731 + */
  732 + isInside: function() {
  733 + return this.isPointInside.apply(this, arguments);
  734 + },
  735 +
  736 +
  737 + /**
  738 + * Checks whether a point is inside of a circle or not.
  739 + *
  740 + * @param object coordinate to check (e.g. {latitude: 51.5023, longitude: 7.3815})
  741 + * @param object coordinate of the circle's center (e.g. {latitude: 51.4812, longitude: 7.4025})
  742 + * @param integer maximum radius in meters
  743 + * @return bool true if the coordinate is within the given radius
  744 + */
  745 + isPointInCircle: function(latlng, center, radius) {
  746 + return this.getDistance(latlng, center) < radius;
  747 + },
  748 +
  749 +
  750 + /**
  751 + * Shortcut for geolib.isPointInCircle()
  752 + */
  753 + withinRadius: function() {
  754 + return this.isPointInCircle.apply(this, arguments);
  755 + },
  756 +
  757 +
  758 + /**
  759 + * Gets rhumb line bearing of two points. Find out about the difference between rhumb line and
  760 + * great circle bearing on Wikipedia. It's quite complicated. Rhumb line should be fine in most cases:
  761 + *
  762 + * http://en.wikipedia.org/wiki/Rhumb_line#General_and_mathematical_description
  763 + *
  764 + * Function heavily based on Doug Vanderweide's great PHP version (licensed under GPL 3.0)
  765 + * http://www.dougv.com/2009/07/13/calculating-the-bearing-and-compass-rose-direction-between-two-latitude-longitude-coordinates-in-php/
  766 + *
  767 + * @param object origin coordinate (e.g. {latitude: 51.5023, longitude: 7.3815})
  768 + * @param object destination coordinate
  769 + * @return integer calculated bearing
  770 + */
  771 + getRhumbLineBearing: function(originLL, destLL) {
  772 +
  773 + // difference of longitude coords
  774 + var diffLon = this.longitude(destLL).toRad() - this.longitude(originLL).toRad();
  775 +
  776 + // difference latitude coords phi
  777 + var diffPhi = Math.log(
  778 + Math.tan(
  779 + this.latitude(destLL).toRad() / 2 + Geolib.PI_DIV4
  780 + ) /
  781 + Math.tan(
  782 + this.latitude(originLL).toRad() / 2 + Geolib.PI_DIV4
  783 + )
  784 + );
  785 +
  786 + // recalculate diffLon if it is greater than pi
  787 + if(Math.abs(diffLon) > Math.PI) {
  788 + if(diffLon > 0) {
  789 + diffLon = (Geolib.PI_X2 - diffLon) * -1;
  790 + }
  791 + else {
  792 + diffLon = Geolib.PI_X2 + diffLon;
  793 + }
  794 + }
  795 +
  796 + //return the angle, normalized
  797 + return (Math.atan2(diffLon, diffPhi).toDeg() + 360) % 360;
  798 +
  799 + },
  800 +
  801 +
  802 + /**
  803 + * Gets great circle bearing of two points. See description of getRhumbLineBearing for more information
  804 + *
  805 + * @param object origin coordinate (e.g. {latitude: 51.5023, longitude: 7.3815})
  806 + * @param object destination coordinate
  807 + * @return integer calculated bearing
  808 + */
  809 + getBearing: function(originLL, destLL) {
  810 +
  811 + destLL['latitude'] = this.latitude(destLL);
  812 + destLL['longitude'] = this.longitude(destLL);
  813 + originLL['latitude'] = this.latitude(originLL);
  814 + originLL['longitude'] = this.longitude(originLL);
  815 +
  816 + var bearing = (
  817 + (
  818 + Math.atan2(
  819 + Math.sin(
  820 + destLL['longitude'].toRad() -
  821 + originLL['longitude'].toRad()
  822 + ) *
  823 + Math.cos(
  824 + destLL['latitude'].toRad()
  825 + ),
  826 + Math.cos(
  827 + originLL['latitude'].toRad()
  828 + ) *
  829 + Math.sin(
  830 + destLL['latitude'].toRad()
  831 + ) -
  832 + Math.sin(
  833 + originLL['latitude'].toRad()
  834 + ) *
  835 + Math.cos(
  836 + destLL['latitude'].toRad()
  837 + ) *
  838 + Math.cos(
  839 + destLL['longitude'].toRad() - originLL['longitude'].toRad()
  840 + )
  841 + )
  842 + ).toDeg() + 360
  843 + ) % 360;
  844 +
  845 + return bearing;
  846 +
  847 + },
  848 +
  849 +
  850 + /**
  851 + * Gets the compass direction from an origin coordinate to a destination coordinate.
  852 + *
  853 + * @param object origin coordinate (e.g. {latitude: 51.5023, longitude: 7.3815})
  854 + * @param object destination coordinate
  855 + * @param string Bearing mode. Can be either circle or rhumbline
  856 + * @return object Returns an object with a rough (NESW) and an exact direction (NNE, NE, ENE, E, ESE, etc).
  857 + */
  858 + getCompassDirection: function(originLL, destLL, bearingMode) {
  859 +
  860 + var direction;
  861 + var bearing;
  862 +
  863 + if(bearingMode == 'circle') {
  864 + // use great circle bearing
  865 + bearing = this.getBearing(originLL, destLL);
  866 + } else {
  867 + // default is rhumb line bearing
  868 + bearing = this.getRhumbLineBearing(originLL, destLL);
  869 + }
  870 +
  871 + switch(Math.round(bearing/22.5)) {
  872 + case 1:
  873 + direction = {exact: "NNE", rough: "N"};
  874 + break;
  875 + case 2:
  876 + direction = {exact: "NE", rough: "N"};
  877 + break;
  878 + case 3:
  879 + direction = {exact: "ENE", rough: "E"};
  880 + break;
  881 + case 4:
  882 + direction = {exact: "E", rough: "E"};
  883 + break;
  884 + case 5:
  885 + direction = {exact: "ESE", rough: "E"};
  886 + break;
  887 + case 6:
  888 + direction = {exact: "SE", rough: "E"};
  889 + break;
  890 + case 7:
  891 + direction = {exact: "SSE", rough: "S"};
  892 + break;
  893 + case 8:
  894 + direction = {exact: "S", rough: "S"};
  895 + break;
  896 + case 9:
  897 + direction = {exact: "SSW", rough: "S"};
  898 + break;
  899 + case 10:
  900 + direction = {exact: "SW", rough: "S"};
  901 + break;
  902 + case 11:
  903 + direction = {exact: "WSW", rough: "W"};
  904 + break;
  905 + case 12:
  906 + direction = {exact: "W", rough: "W"};
  907 + break;
  908 + case 13:
  909 + direction = {exact: "WNW", rough: "W"};
  910 + break;
  911 + case 14:
  912 + direction = {exact: "NW", rough: "W"};
  913 + break;
  914 + case 15:
  915 + direction = {exact: "NNW", rough: "N"};
  916 + break;
  917 + default:
  918 + direction = {exact: "N", rough: "N"};
  919 + }
  920 +
  921 + direction['bearing'] = bearing;
  922 + return direction;
  923 +
  924 + },
  925 +
  926 +
  927 + /**
  928 + * Shortcut for getCompassDirection
  929 + */
  930 + getDirection: function(originLL, destLL, bearingMode) {
  931 + return this.getCompassDirection.apply(this, arguments);
  932 + },
  933 +
  934 +
  935 + /**
  936 + * Sorts an array of coords by distance from a reference coordinate
  937 + *
  938 + * @param object reference coordinate e.g. {latitude: 51.5023, longitude: 7.3815}
  939 + * @param mixed array or object with coords [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]
  940 + * @return array ordered array
  941 + */
  942 + orderByDistance: function(latlng, coords) {
  943 +
  944 + var coordsArray = [];
  945 +
  946 + for(var coord in coords) {
  947 +
  948 + var distance = this.getDistance(latlng, coords[coord]);
  949 + var augmentedCoord = Object.create(coords[coord]);
  950 + augmentedCoord.distance = distance;
  951 + augmentedCoord.key = coord;
  952 +
  953 + coordsArray.push(augmentedCoord);
  954 +
  955 + }
  956 +
  957 + return coordsArray.sort(function(a, b) {
  958 + return a.distance - b.distance;
  959 + });
  960 +
  961 + },
  962 +
  963 + /**
  964 + * Check if a point lies in line created by two other points
  965 + *
  966 + * @param object Point to check: {latitude: 123, longitude: 123}
  967 + * @param object Start of line {latitude: 123, longitude: 123}
  968 + * @param object End of line {latitude: 123, longitude: 123}
  969 + * @return boolean
  970 + */
  971 + isPointInLine: function(point, start, end) {
  972 +
  973 + return (this.getDistance(start, point, 1, 3)+this.getDistance(point, end, 1, 3)).toFixed(3)==this.getDistance(start, end, 1, 3);
  974 + },
  975 +
  976 + /**
  977 + * Check if a point lies within a given distance from a line created by two other points
  978 + *
  979 + * @param object Point to check: {latitude: 123, longitude: 123}
  980 + * @param object Start of line {latitude: 123, longitude: 123}
  981 + * @param object End of line {latitude: 123, longitude: 123}
  982 + * @pararm float maximum distance from line
  983 + * @return boolean
  984 + */
  985 + isPointNearLine: function(point, start, end, distance) {
  986 + return this.getDistanceFromLine(point, start, end) < distance;
  987 + },
  988 +
  989 + /**
  990 + * return the minimum distance from a point to a line
  991 + *
  992 + * @param object Point away from line
  993 + * @param object Start of line {latitude: 123, longitude: 123}
  994 + * @param object End of line {latitude: 123, longitude: 123}
  995 + * @return float distance from point to line
  996 + */
  997 + getDistanceFromLine: function(point, start, end) {
  998 + var d1 = this.getDistance(start, point, 1, 3);
  999 + var d2 = this.getDistance(point, end, 1, 3);
  1000 + var d3 = this.getDistance(start, end, 1, 3);
  1001 + var distance = 0;
  1002 +
  1003 + // alpha is the angle between the line from start to point, and from start to end //
  1004 + var alpha = Math.acos((d1*d1 + d3*d3 - d2*d2)/(2*d1*d3));
  1005 + // beta is the angle between the line from end to point and from end to start //
  1006 + var beta = Math.acos((d2*d2 + d3*d3 - d1*d1)/(2*d2*d3));
  1007 +
  1008 + // if the angle is greater than 90 degrees, then the minimum distance is the
  1009 + // line from the start to the point //
  1010 + if(alpha>Math.PI/2) {
  1011 + distance = d1;
  1012 + }
  1013 + // same for the beta //
  1014 + else if(beta > Math.PI/2) {
  1015 + distance = d2;
  1016 + }
  1017 + // otherwise the minimum distance is achieved through a line perpendular to the start-end line,
  1018 + // which goes from the start-end line to the point //
  1019 + else {
  1020 + distance = Math.sin(alpha) * d1;
  1021 + }
  1022 +
  1023 + return distance;
  1024 + },
  1025 +
  1026 + /**
  1027 + * Finds the nearest coordinate to a reference coordinate
  1028 + *
  1029 + * @param object reference coordinate e.g. {latitude: 51.5023, longitude: 7.3815}
  1030 + * @param mixed array or object with coords [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]
  1031 + * @return array ordered array
  1032 + */
  1033 + findNearest: function(latlng, coords, offset, limit) {
  1034 +
  1035 + offset = offset || 0;
  1036 + limit = limit || 1;
  1037 + var ordered = this.orderByDistance(latlng, coords);
  1038 +
  1039 + if(limit === 1) {
  1040 + return ordered[offset];
  1041 + } else {
  1042 + return ordered.splice(offset, limit);
  1043 + }
  1044 +
  1045 + },
  1046 +
  1047 +
  1048 + /**
  1049 + * Calculates the length of a given path
  1050 + *
  1051 + * @param mixed array or object with coords [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]
  1052 + * @return integer length of the path (in meters)
  1053 + */
  1054 + getPathLength: function(coords) {
  1055 +
  1056 + var dist = 0;
  1057 + var last;
  1058 +
  1059 + for (var i = 0, l = coords.length; i < l; ++i) {
  1060 + if(last) {
  1061 + //console.log(coords[i], last, this.getDistance(coords[i], last));
  1062 + dist += this.getDistance(this.coords(coords[i]), last);
  1063 + }
  1064 + last = this.coords(coords[i]);
  1065 + }
  1066 +
  1067 + return dist;
  1068 +
  1069 + },
  1070 +
  1071 +
  1072 + /**
  1073 + * Calculates the speed between to points within a given time span.
  1074 + *
  1075 + * @param object coords with javascript timestamp {latitude: 51.5143, longitude: 7.4138, time: 1360231200880}
  1076 + * @param object coords with javascript timestamp {latitude: 51.5502, longitude: 7.4323, time: 1360245600460}
  1077 + * @param object options (currently "unit" is the only option. Default: km(h));
  1078 + * @return float speed in unit per hour
  1079 + */
  1080 + getSpeed: function(start, end, options) {
  1081 +
  1082 + var unit = options && options.unit || 'km';
  1083 +
  1084 + if(unit == 'mph') {
  1085 + unit = 'mi';
  1086 + } else if(unit == 'kmh') {
  1087 + unit = 'km';
  1088 + }
  1089 +
  1090 + var distance = geolib.getDistance(start, end);
  1091 + var time = ((end.time*1)/1000) - ((start.time*1)/1000);
  1092 + var mPerHr = (distance/time)*3600;
  1093 + var speed = Math.round(mPerHr * this.measures[unit] * 10000)/10000;
  1094 + return speed;
  1095 +
  1096 + },
  1097 +
  1098 +
  1099 + /**
  1100 + * Computes the destination point given an initial point, a distance
  1101 + * and a bearing
  1102 + *
  1103 + * see http://www.movable-type.co.uk/scripts/latlong.html for the original code
  1104 + *
  1105 + * @param object start coordinate (e.g. {latitude: 51.5023, longitude: 7.3815})
  1106 + * @param float longitude of the inital point in degree
  1107 + * @param float distance to go from the inital point in meter
  1108 + * @param float bearing in degree of the direction to go, e.g. 0 = north, 180 = south
  1109 + * @param float optional (in meter), defaults to mean radius of the earth
  1110 + * @return object {latitude: destLat (in degree), longitude: destLng (in degree)}
  1111 + */
  1112 + computeDestinationPoint: function(start, distance, bearing, radius) {
  1113 +
  1114 + var lat = this.latitude(start);
  1115 + var lng = this.longitude(start);
  1116 +
  1117 + radius = (typeof radius === 'undefined') ? this.radius : Number(radius);
  1118 +
  1119 + var δ = Number(distance) / radius; // angular distance in radians
  1120 + var θ = Number(bearing).toRad();
  1121 +
  1122 + var φ1 = Number(lat).toRad();
  1123 + var λ1 = Number(lng).toRad();
  1124 +
  1125 + var φ2 = Math.asin( Math.sin(φ1)*Math.cos(δ) +
  1126 + Math.cos(φ1)*Math.sin(δ)*Math.cos(θ) );
  1127 + var λ2 = λ1 + Math.atan2(Math.sin(θ)*Math.sin(δ)*Math.cos(φ1),
  1128 + Math.cos(δ)-Math.sin(φ1)*Math.sin(φ2));
  1129 + λ2 = (λ2+3*Math.PI) % (2*Math.PI) - Math.PI; // normalise to -180..+180°
  1130 +
  1131 + return {
  1132 + latitude: φ2.toDeg(),
  1133 + longitude: λ2.toDeg()
  1134 + };
  1135 +
  1136 + },
  1137 +
  1138 +
  1139 + /**
  1140 + * Converts a distance from meters to km, mm, cm, mi, ft, in or yd
  1141 + *
  1142 + * @param string Format to be converted in
  1143 + * @param float Distance in meters
  1144 + * @param float Decimal places for rounding (default: 4)
  1145 + * @return float Converted distance
  1146 + */
  1147 + convertUnit: function(unit, distance, round) {
  1148 +
  1149 + if(distance === 0) {
  1150 +
  1151 + return 0;
  1152 +
  1153 + } else if(typeof distance === 'undefined') {
  1154 +
  1155 + if(this.distance === null) {
  1156 + throw new Error('No distance was given');
  1157 + } else if(this.distance === 0) {
  1158 + return 0;
  1159 + } else {
  1160 + distance = this.distance;
  1161 + }
  1162 +
  1163 + }
  1164 +
  1165 + unit = unit || 'm';
  1166 + round = (null == round ? 4 : round);
  1167 +
  1168 + if(typeof this.measures[unit] !== 'undefined') {
  1169 + return this.round(distance * this.measures[unit], round);
  1170 + } else {
  1171 + throw new Error('Unknown unit for conversion.');
  1172 + }
  1173 +
  1174 + },
  1175 +
  1176 +
  1177 + /**
  1178 + * Checks if a value is in decimal format or, if neccessary, converts to decimal
  1179 + *
  1180 + * @param mixed Value(s) to be checked/converted (array of latlng objects, latlng object, sexagesimal string, float)
  1181 + * @return float Input data in decimal format
  1182 + */
  1183 + useDecimal: function(value) {
  1184 +
  1185 + if(Object.prototype.toString.call(value) === '[object Array]') {
  1186 +
  1187 + var geolib = this;
  1188 +
  1189 + value = value.map(function(val) {
  1190 +
  1191 + //if(!isNaN(parseFloat(val))) {
  1192 + if(geolib.isDecimal(val)) {
  1193 +
  1194 + return geolib.useDecimal(val);
  1195 +
  1196 + } else if(typeof val == 'object') {
  1197 +
  1198 + if(geolib.validate(val)) {
  1199 +
  1200 + return geolib.coords(val);
  1201 +
  1202 + } else {
  1203 +
  1204 + for(var prop in val) {
  1205 + val[prop] = geolib.useDecimal(val[prop]);
  1206 + }
  1207 +
  1208 + return val;
  1209 +
  1210 + }
  1211 +
  1212 + } else if(geolib.isSexagesimal(val)) {
  1213 +
  1214 + return geolib.sexagesimal2decimal(val);
  1215 +
  1216 + } else {
  1217 +
  1218 + return val;
  1219 +
  1220 + }
  1221 +
  1222 + });
  1223 +
  1224 + return value;
  1225 +
  1226 + } else if(typeof value === 'object' && this.validate(value)) {
  1227 +
  1228 + return this.coords(value);
  1229 +
  1230 + } else if(typeof value === 'object') {
  1231 +
  1232 + for(var prop in value) {
  1233 + value[prop] = this.useDecimal(value[prop]);
  1234 + }
  1235 +
  1236 + return value;
  1237 +
  1238 + }
  1239 +
  1240 +
  1241 + if (this.isDecimal(value)) {
  1242 +
  1243 + return parseFloat(value);
  1244 +
  1245 + } else if(this.isSexagesimal(value) === true) {
  1246 +
  1247 + return parseFloat(this.sexagesimal2decimal(value));
  1248 +
  1249 + }
  1250 +
  1251 + throw new Error('Unknown format.');
  1252 +
  1253 + },
  1254 +
  1255 + /**
  1256 + * Converts a decimal coordinate value to sexagesimal format
  1257 + *
  1258 + * @param float decimal
  1259 + * @return string Sexagesimal value (XX° YY' ZZ")
  1260 + */
  1261 + decimal2sexagesimal: function(dec) {
  1262 +
  1263 + if (dec in this.sexagesimal) {
  1264 + return this.sexagesimal[dec];
  1265 + }
  1266 +
  1267 + var tmp = dec.toString().split('.');
  1268 +
  1269 + var deg = Math.abs(tmp[0]);
  1270 + var min = ('0.' + (tmp[1] || 0))*60;
  1271 + var sec = min.toString().split('.');
  1272 +
  1273 + min = Math.floor(min);
  1274 + sec = (('0.' + (sec[1] || 0)) * 60).toFixed(2);
  1275 +
  1276 + this.sexagesimal[dec] = (deg + '° ' + min + "' " + sec + '"');
  1277 +
  1278 + return this.sexagesimal[dec];
  1279 +
  1280 + },
  1281 +
  1282 +
  1283 + /**
  1284 + * Converts a sexagesimal coordinate to decimal format
  1285 + *
  1286 + * @param float Sexagesimal coordinate
  1287 + * @return string Decimal value (XX.XXXXXXXX)
  1288 + */
  1289 + sexagesimal2decimal: function(sexagesimal) {
  1290 +
  1291 + if (sexagesimal in this.decimal) {
  1292 + return this.decimal[sexagesimal];
  1293 + }
  1294 +
  1295 + var regEx = new RegExp(this.sexagesimalPattern);
  1296 + var data = regEx.exec(sexagesimal);
  1297 + var min = 0, sec = 0;
  1298 +
  1299 + if(data) {
  1300 + min = parseFloat(data[2]/60);
  1301 + sec = parseFloat(data[4]/3600) || 0;
  1302 + }
  1303 +
  1304 + var dec = ((parseFloat(data[1]) + min + sec)).toFixed(8);
  1305 + //var dec = ((parseFloat(data[1]) + min + sec));
  1306 +
  1307 + // South and West are negative decimals
  1308 + dec = (data[7] == 'S' || data[7] == 'W') ? parseFloat(-dec) : parseFloat(dec);
  1309 + //dec = (data[7] == 'S' || data[7] == 'W') ? -dec : dec;
  1310 +
  1311 + this.decimal[sexagesimal] = dec;
  1312 +
  1313 + return dec;
  1314 +
  1315 + },
  1316 +
  1317 +
  1318 + /**
  1319 + * Checks if a value is in decimal format
  1320 + *
  1321 + * @param string Value to be checked
  1322 + * @return bool True if in sexagesimal format
  1323 + */
  1324 + isDecimal: function(value) {
  1325 +
  1326 + value = value.toString().replace(/\s*/, '');
  1327 +
  1328 + // looks silly but works as expected
  1329 + // checks if value is in decimal format
  1330 + return (!isNaN(parseFloat(value)) && parseFloat(value) == value);
  1331 +
  1332 + },
  1333 +
  1334 +
  1335 + /**
  1336 + * Checks if a value is in sexagesimal format
  1337 + *
  1338 + * @param string Value to be checked
  1339 + * @return bool True if in sexagesimal format
  1340 + */
  1341 + isSexagesimal: function(value) {
  1342 +
  1343 + value = value.toString().replace(/\s*/, '');
  1344 +
  1345 + return this.sexagesimalPattern.test(value);
  1346 +
  1347 + },
  1348 +
  1349 + round: function(value, n) {
  1350 + var decPlace = Math.pow(10, n);
  1351 + return Math.round(value * decPlace)/decPlace;
  1352 + }
  1353 +
  1354 + });
  1355 +
  1356 + // Node module
  1357 + if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
  1358 +
  1359 + module.exports = geolib;
  1360 +
  1361 + // react native
  1362 + if (typeof global === 'object') {
  1363 + global.geolib = geolib;
  1364 + }
  1365 +
  1366 + // AMD module
  1367 + } else if (typeof define === "function" && define.amd) {
  1368 +
  1369 + define("geolib", [], function () {
  1370 + return geolib;
  1371 + });
  1372 +
  1373 + // we're in a browser
  1374 + } else {
  1375 +
  1376 + global.geolib = geolib;
  1377 +
  1378 + }
  1379 +
  1380 +}(this));
src/main/resources/static/real_control_v2/geolib/geolib.min.js
1 -/*! geolib 2.0.21 by Manuel Bieh  
2 -* Library to provide geo functions like distance calculation,  
3 -* conversion of decimal coordinates to sexagesimal and vice versa, etc.  
4 -* WGS 84 (World Geodetic System 1984)  
5 -*  
6 -* @author Manuel Bieh  
7 -* @url http://www.manuelbieh.com/  
8 -* @version 2.0.21  
9 -* @license MIT  
10 -**/ 1 +/*! geolib 2.0.21 by Manuel Bieh
  2 +* Library to provide geo functions like distance calculation,
  3 +* conversion of decimal coordinates to sexagesimal and vice versa, etc.
  4 +* WGS 84 (World Geodetic System 1984)
  5 +*
  6 +* @author Manuel Bieh
  7 +* @url http://www.manuelbieh.com/
  8 +* @version 2.0.21
  9 +* @license MIT
  10 +**/
11 !function(a,b){"use strict";function c(){}c.TO_RAD=Math.PI/180,c.TO_DEG=180/Math.PI,c.PI_X2=2*Math.PI,c.PI_DIV4=Math.PI/4;var d=Object.create(c.prototype,{version:{value:"2.0.21"},radius:{value:6378137},minLat:{value:-90},maxLat:{value:90},minLon:{value:-180},maxLon:{value:180},sexagesimalPattern:{value:/^([0-9]{1,3})°\s*([0-9]{1,3}(?:\.(?:[0-9]{1,2}))?)'\s*(([0-9]{1,3}(\.([0-9]{1,4}))?)"\s*)?([NEOSW]?)$/},measures:{value:Object.create(Object.prototype,{m:{value:1},km:{value:.001},cm:{value:100},mm:{value:1e3},mi:{value:1/1609.344},sm:{value:1/1852.216},ft:{value:100/30.48},"in":{value:100/2.54},yd:{value:1/.9144}})},prototype:{value:c.prototype},extend:{value:function(a,b){for(var c in a)("undefined"==typeof d.prototype[c]||b===!0)&&("function"==typeof a[c]&&"function"==typeof a[c].bind?d.prototype[c]=a[c].bind(d):d.prototype[c]=a[c])}}});"undefined"==typeof Number.prototype.toRad&&(Number.prototype.toRad=function(){return this*c.TO_RAD}),"undefined"==typeof Number.prototype.toDeg&&(Number.prototype.toDeg=function(){return this*c.TO_DEG}),d.extend({decimal:{},sexagesimal:{},distance:null,getKeys:function(a){if("[object Array]"==Object.prototype.toString.call(a))return{longitude:a.length>=1?0:b,latitude:a.length>=2?1:b,elevation:a.length>=3?2:b};var c=function(b){var c;return b.every(function(b){return"object"!=typeof a?!0:a.hasOwnProperty(b)?function(){return c=b,!1}():!0}),c},d=c(["lng","lon","longitude"]),e=c(["lat","latitude"]),f=c(["alt","altitude","elevation","elev"]);return"undefined"==typeof e&&"undefined"==typeof d&&"undefined"==typeof f?b:{latitude:e,longitude:d,elevation:f}},getLat:function(a,b){return b===!0?a[this.getKeys(a).latitude]:this.useDecimal(a[this.getKeys(a).latitude])},latitude:function(a){return this.getLat.call(this,a)},getLon:function(a,b){return b===!0?a[this.getKeys(a).longitude]:this.useDecimal(a[this.getKeys(a).longitude])},longitude:function(a){return this.getLon.call(this,a)},getElev:function(a){return a[this.getKeys(a).elevation]},elevation:function(a){return this.getElev.call(this,a)},coords:function(a,b){var c={latitude:b===!0?a[this.getKeys(a).latitude]:this.useDecimal(a[this.getKeys(a).latitude]),longitude:b===!0?a[this.getKeys(a).longitude]:this.useDecimal(a[this.getKeys(a).longitude])},d=a[this.getKeys(a).elevation];return"undefined"!=typeof d&&(c.elevation=d),c},ll:function(a,b){return this.coords.call(this,a,b)},validate:function(a){var b=this.getKeys(a);if("undefined"==typeof b||"undefined"==typeof b.latitude||"undefined"===b.longitude)return!1;var c=a[b.latitude],d=a[b.longitude];return"undefined"==typeof c||!this.isDecimal(c)&&!this.isSexagesimal(c)?!1:"undefined"==typeof d||!this.isDecimal(d)&&!this.isSexagesimal(d)?!1:(c=this.useDecimal(c),d=this.useDecimal(d),c<this.minLat||c>this.maxLat||d<this.minLon||d>this.maxLon?!1:!0)},getDistance:function(a,b,c,e){c=Math.floor(c)||1,e=Math.floor(e)||0;var f,g,h,i,j,k,l,m=this.coords(a),n=this.coords(b),o=6378137,p=6356752.314245,q=1/298.257223563,r=(n.longitude-m.longitude).toRad(),s=Math.atan((1-q)*Math.tan(parseFloat(m.latitude).toRad())),t=Math.atan((1-q)*Math.tan(parseFloat(n.latitude).toRad())),u=Math.sin(s),v=Math.cos(s),w=Math.sin(t),x=Math.cos(t),y=r,z=100;do{var A=Math.sin(y),B=Math.cos(y);if(k=Math.sqrt(x*A*(x*A)+(v*w-u*x*B)*(v*w-u*x*B)),0===k)return d.distance=0;f=u*w+v*x*B,g=Math.atan2(k,f),h=v*x*A/k,i=1-h*h,j=f-2*u*w/i,isNaN(j)&&(j=0);var C=q/16*i*(4+q*(4-3*i));l=y,y=r+(1-C)*q*h*(g+C*k*(j+C*f*(-1+2*j*j)))}while(Math.abs(y-l)>1e-12&&--z>0);if(0===z)return NaN;var D=i*(o*o-p*p)/(p*p),E=1+D/16384*(4096+D*(-768+D*(320-175*D))),F=D/1024*(256+D*(-128+D*(74-47*D))),G=F*k*(j+F/4*(f*(-1+2*j*j)-F/6*j*(-3+4*k*k)*(-3+4*j*j))),H=p*E*(g-G);if(H=H.toFixed(e),"undefined"!=typeof this.elevation(a)&&"undefined"!=typeof this.elevation(b)){var I=Math.abs(this.elevation(a)-this.elevation(b));H=Math.sqrt(H*H+I*I)}return this.distance=Math.round(H*Math.pow(10,e)/c)*c/Math.pow(10,e)},getDistanceSimple:function(a,b,c){c=Math.floor(c)||1;var e=Math.round(Math.acos(Math.sin(this.latitude(b).toRad())*Math.sin(this.latitude(a).toRad())+Math.cos(this.latitude(b).toRad())*Math.cos(this.latitude(a).toRad())*Math.cos(this.longitude(a).toRad()-this.longitude(b).toRad()))*this.radius);return d.distance=Math.floor(Math.round(e/c)*c)},getCenter:function(a){var b=a;if("object"==typeof a&&!(a instanceof Array)){b=[];for(var d in a)b.push(this.coords(a[d]))}if(!b.length)return!1;var e,f,g,h=0,i=0,j=0;b.forEach(function(a){e=this.latitude(a).toRad(),f=this.longitude(a).toRad(),h+=Math.cos(e)*Math.cos(f),i+=Math.cos(e)*Math.sin(f),j+=Math.sin(e)},this);var k=b.length;return h/=k,i/=k,j/=k,f=Math.atan2(i,h),g=Math.sqrt(h*h+i*i),e=Math.atan2(j,g),{latitude:(e*c.TO_DEG).toFixed(6),longitude:(f*c.TO_DEG).toFixed(6)}},getBounds:function(a){if(!a.length)return!1;var b=this.elevation(a[0]),c={maxLat:-(1/0),minLat:1/0,maxLng:-(1/0),minLng:1/0};"undefined"!=typeof b&&(c.maxElev=0,c.minElev=1/0);for(var d=0,e=a.length;e>d;++d)c.maxLat=Math.max(this.latitude(a[d]),c.maxLat),c.minLat=Math.min(this.latitude(a[d]),c.minLat),c.maxLng=Math.max(this.longitude(a[d]),c.maxLng),c.minLng=Math.min(this.longitude(a[d]),c.minLng),b&&(c.maxElev=Math.max(this.elevation(a[d]),c.maxElev),c.minElev=Math.min(this.elevation(a[d]),c.minElev));return c},getCenterOfBounds:function(a){var b=this.getBounds(a),c=b.minLat+(b.maxLat-b.minLat)/2,d=b.minLng+(b.maxLng-b.minLng)/2;return{latitude:parseFloat(c.toFixed(6)),longitude:parseFloat(d.toFixed(6))}},getBoundsOfDistance:function(a,b){var d,e,f=this.latitude(a),g=this.longitude(a),h=f.toRad(),i=g.toRad(),j=b/this.radius,k=h-j,l=h+j,m=this.maxLat.toRad(),n=this.minLat.toRad(),o=this.maxLon.toRad(),p=this.minLon.toRad();if(k>n&&m>l){var q=Math.asin(Math.sin(j)/Math.cos(h));d=i-q,p>d&&(d+=c.PI_X2),e=i+q,e>o&&(e-=c.PI_X2)}else k=Math.max(k,n),l=Math.min(l,m),d=p,e=o;return[{latitude:k.toDeg(),longitude:d.toDeg()},{latitude:l.toDeg(),longitude:e.toDeg()}]},isPointInside:function(a,b){for(var c=!1,d=-1,e=b.length,f=e-1;++d<e;f=d)(this.longitude(b[d])<=this.longitude(a)&&this.longitude(a)<this.longitude(b[f])||this.longitude(b[f])<=this.longitude(a)&&this.longitude(a)<this.longitude(b[d]))&&this.latitude(a)<(this.latitude(b[f])-this.latitude(b[d]))*(this.longitude(a)-this.longitude(b[d]))/(this.longitude(b[f])-this.longitude(b[d]))+this.latitude(b[d])&&(c=!c);return c},preparePolygonForIsPointInsideOptimized:function(a){for(var b=0,c=a.length-1;b<a.length;b++)this.longitude(a[c])===this.longitude(a[b])?(a[b].constant=this.latitude(a[b]),a[b].multiple=0):(a[b].constant=this.latitude(a[b])-this.longitude(a[b])*this.latitude(a[c])/(this.longitude(a[c])-this.longitude(a[b]))+this.longitude(a[b])*this.latitude(a[b])/(this.longitude(a[c])-this.longitude(a[b])),a[b].multiple=(this.latitude(a[c])-this.latitude(a[b]))/(this.longitude(a[c])-this.longitude(a[b]))),c=b},isPointInsideWithPreparedPolygon:function(a,b){for(var c=!1,d=this.longitude(a),e=this.latitude(a),f=0,g=b.length-1;f<b.length;f++)(this.longitude(b[f])<d&&this.longitude(b[g])>=d||this.longitude(b[g])<d&&this.longitude(b[f])>=d)&&(c^=d*b[f].multiple+b[f].constant<e),g=f;return c},isInside:function(){return this.isPointInside.apply(this,arguments)},isPointInCircle:function(a,b,c){return this.getDistance(a,b)<c},withinRadius:function(){return this.isPointInCircle.apply(this,arguments)},getRhumbLineBearing:function(a,b){var d=this.longitude(b).toRad()-this.longitude(a).toRad(),e=Math.log(Math.tan(this.latitude(b).toRad()/2+c.PI_DIV4)/Math.tan(this.latitude(a).toRad()/2+c.PI_DIV4));return Math.abs(d)>Math.PI&&(d=d>0?-1*(c.PI_X2-d):c.PI_X2+d),(Math.atan2(d,e).toDeg()+360)%360},getBearing:function(a,b){b.latitude=this.latitude(b),b.longitude=this.longitude(b),a.latitude=this.latitude(a),a.longitude=this.longitude(a);var c=(Math.atan2(Math.sin(b.longitude.toRad()-a.longitude.toRad())*Math.cos(b.latitude.toRad()),Math.cos(a.latitude.toRad())*Math.sin(b.latitude.toRad())-Math.sin(a.latitude.toRad())*Math.cos(b.latitude.toRad())*Math.cos(b.longitude.toRad()-a.longitude.toRad())).toDeg()+360)%360;return c},getCompassDirection:function(a,b,c){var d,e;switch(e="circle"==c?this.getBearing(a,b):this.getRhumbLineBearing(a,b),Math.round(e/22.5)){case 1:d={exact:"NNE",rough:"N"};break;case 2:d={exact:"NE",rough:"N"};break;case 3:d={exact:"ENE",rough:"E"};break;case 4:d={exact:"E",rough:"E"};break;case 5:d={exact:"ESE",rough:"E"};break;case 6:d={exact:"SE",rough:"E"};break;case 7:d={exact:"SSE",rough:"S"};break;case 8:d={exact:"S",rough:"S"};break;case 9:d={exact:"SSW",rough:"S"};break;case 10:d={exact:"SW",rough:"S"};break;case 11:d={exact:"WSW",rough:"W"};break;case 12:d={exact:"W",rough:"W"};break;case 13:d={exact:"WNW",rough:"W"};break;case 14:d={exact:"NW",rough:"W"};break;case 15:d={exact:"NNW",rough:"N"};break;default:d={exact:"N",rough:"N"}}return d.bearing=e,d},getDirection:function(a,b,c){return this.getCompassDirection.apply(this,arguments)},orderByDistance:function(a,b){var c=[];for(var d in b){var e=this.getDistance(a,b[d]),f=Object.create(b[d]);f.distance=e,f.key=d,c.push(f)}return c.sort(function(a,b){return a.distance-b.distance})},isPointInLine:function(a,b,c){return(this.getDistance(b,a,1,3)+this.getDistance(a,c,1,3)).toFixed(3)==this.getDistance(b,c,1,3)},isPointNearLine:function(a,b,c,d){return this.getDistanceFromLine(a,b,c)<d},getDistanceFromLine:function(a,b,c){var d=this.getDistance(b,a,1,3),e=this.getDistance(a,c,1,3),f=this.getDistance(b,c,1,3),g=0,h=Math.acos((d*d+f*f-e*e)/(2*d*f)),i=Math.acos((e*e+f*f-d*d)/(2*e*f));return g=h>Math.PI/2?d:i>Math.PI/2?e:Math.sin(h)*d},findNearest:function(a,b,c,d){c=c||0,d=d||1;var e=this.orderByDistance(a,b);return 1===d?e[c]:e.splice(c,d)},getPathLength:function(a){for(var b,c=0,d=0,e=a.length;e>d;++d)b&&(c+=this.getDistance(this.coords(a[d]),b)),b=this.coords(a[d]);return c},getSpeed:function(a,b,c){var e=c&&c.unit||"km";"mph"==e?e="mi":"kmh"==e&&(e="km");var f=d.getDistance(a,b),g=1*b.time/1e3-1*a.time/1e3,h=f/g*3600,i=Math.round(h*this.measures[e]*1e4)/1e4;return i},computeDestinationPoint:function(a,b,c,d){var e=this.latitude(a),f=this.longitude(a);d="undefined"==typeof d?this.radius:Number(d);var g=Number(b)/d,h=Number(c).toRad(),i=Number(e).toRad(),j=Number(f).toRad(),k=Math.asin(Math.sin(i)*Math.cos(g)+Math.cos(i)*Math.sin(g)*Math.cos(h)),l=j+Math.atan2(Math.sin(h)*Math.sin(g)*Math.cos(i),Math.cos(g)-Math.sin(i)*Math.sin(k));return l=(l+3*Math.PI)%(2*Math.PI)-Math.PI,{latitude:k.toDeg(),longitude:l.toDeg()}},convertUnit:function(a,b,c){if(0===b)return 0;if("undefined"==typeof b){if(null===this.distance)throw new Error("No distance was given");if(0===this.distance)return 0;b=this.distance}if(a=a||"m",c=null==c?4:c,"undefined"!=typeof this.measures[a])return this.round(b*this.measures[a],c);throw new Error("Unknown unit for conversion.")},useDecimal:function(a){if("[object Array]"===Object.prototype.toString.call(a)){var b=this;return a=a.map(function(a){if(b.isDecimal(a))return b.useDecimal(a);if("object"==typeof a){if(b.validate(a))return b.coords(a);for(var c in a)a[c]=b.useDecimal(a[c]);return a}return b.isSexagesimal(a)?b.sexagesimal2decimal(a):a})}if("object"==typeof a&&this.validate(a))return this.coords(a);if("object"==typeof a){for(var c in a)a[c]=this.useDecimal(a[c]);return a}if(this.isDecimal(a))return parseFloat(a);if(this.isSexagesimal(a)===!0)return parseFloat(this.sexagesimal2decimal(a));throw new Error("Unknown format.")},decimal2sexagesimal:function(a){if(a in this.sexagesimal)return this.sexagesimal[a];var b=a.toString().split("."),c=Math.abs(b[0]),d=60*("0."+(b[1]||0)),e=d.toString().split(".");return d=Math.floor(d),e=(60*("0."+(e[1]||0))).toFixed(2),this.sexagesimal[a]=c+"° "+d+"' "+e+'"',this.sexagesimal[a]},sexagesimal2decimal:function(a){if(a in this.decimal)return this.decimal[a];var b=new RegExp(this.sexagesimalPattern),c=b.exec(a),d=0,e=0;c&&(d=parseFloat(c[2]/60),e=parseFloat(c[4]/3600)||0);var f=(parseFloat(c[1])+d+e).toFixed(8);return f="S"==c[7]||"W"==c[7]?parseFloat(-f):parseFloat(f),this.decimal[a]=f,f},isDecimal:function(a){return a=a.toString().replace(/\s*/,""),!isNaN(parseFloat(a))&&parseFloat(a)==a},isSexagesimal:function(a){return a=a.toString().replace(/\s*/,""),this.sexagesimalPattern.test(a)},round:function(a,b){var c=Math.pow(10,b);return Math.round(a*c)/c}}),"undefined"!=typeof module&&"undefined"!=typeof module.exports?(module.exports=d,"object"==typeof a&&(a.geolib=d)):"function"==typeof define&&define.amd?define("geolib",[],function(){return d}):a.geolib=d}(this); 11 !function(a,b){"use strict";function c(){}c.TO_RAD=Math.PI/180,c.TO_DEG=180/Math.PI,c.PI_X2=2*Math.PI,c.PI_DIV4=Math.PI/4;var d=Object.create(c.prototype,{version:{value:"2.0.21"},radius:{value:6378137},minLat:{value:-90},maxLat:{value:90},minLon:{value:-180},maxLon:{value:180},sexagesimalPattern:{value:/^([0-9]{1,3})°\s*([0-9]{1,3}(?:\.(?:[0-9]{1,2}))?)'\s*(([0-9]{1,3}(\.([0-9]{1,4}))?)"\s*)?([NEOSW]?)$/},measures:{value:Object.create(Object.prototype,{m:{value:1},km:{value:.001},cm:{value:100},mm:{value:1e3},mi:{value:1/1609.344},sm:{value:1/1852.216},ft:{value:100/30.48},"in":{value:100/2.54},yd:{value:1/.9144}})},prototype:{value:c.prototype},extend:{value:function(a,b){for(var c in a)("undefined"==typeof d.prototype[c]||b===!0)&&("function"==typeof a[c]&&"function"==typeof a[c].bind?d.prototype[c]=a[c].bind(d):d.prototype[c]=a[c])}}});"undefined"==typeof Number.prototype.toRad&&(Number.prototype.toRad=function(){return this*c.TO_RAD}),"undefined"==typeof Number.prototype.toDeg&&(Number.prototype.toDeg=function(){return this*c.TO_DEG}),d.extend({decimal:{},sexagesimal:{},distance:null,getKeys:function(a){if("[object Array]"==Object.prototype.toString.call(a))return{longitude:a.length>=1?0:b,latitude:a.length>=2?1:b,elevation:a.length>=3?2:b};var c=function(b){var c;return b.every(function(b){return"object"!=typeof a?!0:a.hasOwnProperty(b)?function(){return c=b,!1}():!0}),c},d=c(["lng","lon","longitude"]),e=c(["lat","latitude"]),f=c(["alt","altitude","elevation","elev"]);return"undefined"==typeof e&&"undefined"==typeof d&&"undefined"==typeof f?b:{latitude:e,longitude:d,elevation:f}},getLat:function(a,b){return b===!0?a[this.getKeys(a).latitude]:this.useDecimal(a[this.getKeys(a).latitude])},latitude:function(a){return this.getLat.call(this,a)},getLon:function(a,b){return b===!0?a[this.getKeys(a).longitude]:this.useDecimal(a[this.getKeys(a).longitude])},longitude:function(a){return this.getLon.call(this,a)},getElev:function(a){return a[this.getKeys(a).elevation]},elevation:function(a){return this.getElev.call(this,a)},coords:function(a,b){var c={latitude:b===!0?a[this.getKeys(a).latitude]:this.useDecimal(a[this.getKeys(a).latitude]),longitude:b===!0?a[this.getKeys(a).longitude]:this.useDecimal(a[this.getKeys(a).longitude])},d=a[this.getKeys(a).elevation];return"undefined"!=typeof d&&(c.elevation=d),c},ll:function(a,b){return this.coords.call(this,a,b)},validate:function(a){var b=this.getKeys(a);if("undefined"==typeof b||"undefined"==typeof b.latitude||"undefined"===b.longitude)return!1;var c=a[b.latitude],d=a[b.longitude];return"undefined"==typeof c||!this.isDecimal(c)&&!this.isSexagesimal(c)?!1:"undefined"==typeof d||!this.isDecimal(d)&&!this.isSexagesimal(d)?!1:(c=this.useDecimal(c),d=this.useDecimal(d),c<this.minLat||c>this.maxLat||d<this.minLon||d>this.maxLon?!1:!0)},getDistance:function(a,b,c,e){c=Math.floor(c)||1,e=Math.floor(e)||0;var f,g,h,i,j,k,l,m=this.coords(a),n=this.coords(b),o=6378137,p=6356752.314245,q=1/298.257223563,r=(n.longitude-m.longitude).toRad(),s=Math.atan((1-q)*Math.tan(parseFloat(m.latitude).toRad())),t=Math.atan((1-q)*Math.tan(parseFloat(n.latitude).toRad())),u=Math.sin(s),v=Math.cos(s),w=Math.sin(t),x=Math.cos(t),y=r,z=100;do{var A=Math.sin(y),B=Math.cos(y);if(k=Math.sqrt(x*A*(x*A)+(v*w-u*x*B)*(v*w-u*x*B)),0===k)return d.distance=0;f=u*w+v*x*B,g=Math.atan2(k,f),h=v*x*A/k,i=1-h*h,j=f-2*u*w/i,isNaN(j)&&(j=0);var C=q/16*i*(4+q*(4-3*i));l=y,y=r+(1-C)*q*h*(g+C*k*(j+C*f*(-1+2*j*j)))}while(Math.abs(y-l)>1e-12&&--z>0);if(0===z)return NaN;var D=i*(o*o-p*p)/(p*p),E=1+D/16384*(4096+D*(-768+D*(320-175*D))),F=D/1024*(256+D*(-128+D*(74-47*D))),G=F*k*(j+F/4*(f*(-1+2*j*j)-F/6*j*(-3+4*k*k)*(-3+4*j*j))),H=p*E*(g-G);if(H=H.toFixed(e),"undefined"!=typeof this.elevation(a)&&"undefined"!=typeof this.elevation(b)){var I=Math.abs(this.elevation(a)-this.elevation(b));H=Math.sqrt(H*H+I*I)}return this.distance=Math.round(H*Math.pow(10,e)/c)*c/Math.pow(10,e)},getDistanceSimple:function(a,b,c){c=Math.floor(c)||1;var e=Math.round(Math.acos(Math.sin(this.latitude(b).toRad())*Math.sin(this.latitude(a).toRad())+Math.cos(this.latitude(b).toRad())*Math.cos(this.latitude(a).toRad())*Math.cos(this.longitude(a).toRad()-this.longitude(b).toRad()))*this.radius);return d.distance=Math.floor(Math.round(e/c)*c)},getCenter:function(a){var b=a;if("object"==typeof a&&!(a instanceof Array)){b=[];for(var d in a)b.push(this.coords(a[d]))}if(!b.length)return!1;var e,f,g,h=0,i=0,j=0;b.forEach(function(a){e=this.latitude(a).toRad(),f=this.longitude(a).toRad(),h+=Math.cos(e)*Math.cos(f),i+=Math.cos(e)*Math.sin(f),j+=Math.sin(e)},this);var k=b.length;return h/=k,i/=k,j/=k,f=Math.atan2(i,h),g=Math.sqrt(h*h+i*i),e=Math.atan2(j,g),{latitude:(e*c.TO_DEG).toFixed(6),longitude:(f*c.TO_DEG).toFixed(6)}},getBounds:function(a){if(!a.length)return!1;var b=this.elevation(a[0]),c={maxLat:-(1/0),minLat:1/0,maxLng:-(1/0),minLng:1/0};"undefined"!=typeof b&&(c.maxElev=0,c.minElev=1/0);for(var d=0,e=a.length;e>d;++d)c.maxLat=Math.max(this.latitude(a[d]),c.maxLat),c.minLat=Math.min(this.latitude(a[d]),c.minLat),c.maxLng=Math.max(this.longitude(a[d]),c.maxLng),c.minLng=Math.min(this.longitude(a[d]),c.minLng),b&&(c.maxElev=Math.max(this.elevation(a[d]),c.maxElev),c.minElev=Math.min(this.elevation(a[d]),c.minElev));return c},getCenterOfBounds:function(a){var b=this.getBounds(a),c=b.minLat+(b.maxLat-b.minLat)/2,d=b.minLng+(b.maxLng-b.minLng)/2;return{latitude:parseFloat(c.toFixed(6)),longitude:parseFloat(d.toFixed(6))}},getBoundsOfDistance:function(a,b){var d,e,f=this.latitude(a),g=this.longitude(a),h=f.toRad(),i=g.toRad(),j=b/this.radius,k=h-j,l=h+j,m=this.maxLat.toRad(),n=this.minLat.toRad(),o=this.maxLon.toRad(),p=this.minLon.toRad();if(k>n&&m>l){var q=Math.asin(Math.sin(j)/Math.cos(h));d=i-q,p>d&&(d+=c.PI_X2),e=i+q,e>o&&(e-=c.PI_X2)}else k=Math.max(k,n),l=Math.min(l,m),d=p,e=o;return[{latitude:k.toDeg(),longitude:d.toDeg()},{latitude:l.toDeg(),longitude:e.toDeg()}]},isPointInside:function(a,b){for(var c=!1,d=-1,e=b.length,f=e-1;++d<e;f=d)(this.longitude(b[d])<=this.longitude(a)&&this.longitude(a)<this.longitude(b[f])||this.longitude(b[f])<=this.longitude(a)&&this.longitude(a)<this.longitude(b[d]))&&this.latitude(a)<(this.latitude(b[f])-this.latitude(b[d]))*(this.longitude(a)-this.longitude(b[d]))/(this.longitude(b[f])-this.longitude(b[d]))+this.latitude(b[d])&&(c=!c);return c},preparePolygonForIsPointInsideOptimized:function(a){for(var b=0,c=a.length-1;b<a.length;b++)this.longitude(a[c])===this.longitude(a[b])?(a[b].constant=this.latitude(a[b]),a[b].multiple=0):(a[b].constant=this.latitude(a[b])-this.longitude(a[b])*this.latitude(a[c])/(this.longitude(a[c])-this.longitude(a[b]))+this.longitude(a[b])*this.latitude(a[b])/(this.longitude(a[c])-this.longitude(a[b])),a[b].multiple=(this.latitude(a[c])-this.latitude(a[b]))/(this.longitude(a[c])-this.longitude(a[b]))),c=b},isPointInsideWithPreparedPolygon:function(a,b){for(var c=!1,d=this.longitude(a),e=this.latitude(a),f=0,g=b.length-1;f<b.length;f++)(this.longitude(b[f])<d&&this.longitude(b[g])>=d||this.longitude(b[g])<d&&this.longitude(b[f])>=d)&&(c^=d*b[f].multiple+b[f].constant<e),g=f;return c},isInside:function(){return this.isPointInside.apply(this,arguments)},isPointInCircle:function(a,b,c){return this.getDistance(a,b)<c},withinRadius:function(){return this.isPointInCircle.apply(this,arguments)},getRhumbLineBearing:function(a,b){var d=this.longitude(b).toRad()-this.longitude(a).toRad(),e=Math.log(Math.tan(this.latitude(b).toRad()/2+c.PI_DIV4)/Math.tan(this.latitude(a).toRad()/2+c.PI_DIV4));return Math.abs(d)>Math.PI&&(d=d>0?-1*(c.PI_X2-d):c.PI_X2+d),(Math.atan2(d,e).toDeg()+360)%360},getBearing:function(a,b){b.latitude=this.latitude(b),b.longitude=this.longitude(b),a.latitude=this.latitude(a),a.longitude=this.longitude(a);var c=(Math.atan2(Math.sin(b.longitude.toRad()-a.longitude.toRad())*Math.cos(b.latitude.toRad()),Math.cos(a.latitude.toRad())*Math.sin(b.latitude.toRad())-Math.sin(a.latitude.toRad())*Math.cos(b.latitude.toRad())*Math.cos(b.longitude.toRad()-a.longitude.toRad())).toDeg()+360)%360;return c},getCompassDirection:function(a,b,c){var d,e;switch(e="circle"==c?this.getBearing(a,b):this.getRhumbLineBearing(a,b),Math.round(e/22.5)){case 1:d={exact:"NNE",rough:"N"};break;case 2:d={exact:"NE",rough:"N"};break;case 3:d={exact:"ENE",rough:"E"};break;case 4:d={exact:"E",rough:"E"};break;case 5:d={exact:"ESE",rough:"E"};break;case 6:d={exact:"SE",rough:"E"};break;case 7:d={exact:"SSE",rough:"S"};break;case 8:d={exact:"S",rough:"S"};break;case 9:d={exact:"SSW",rough:"S"};break;case 10:d={exact:"SW",rough:"S"};break;case 11:d={exact:"WSW",rough:"W"};break;case 12:d={exact:"W",rough:"W"};break;case 13:d={exact:"WNW",rough:"W"};break;case 14:d={exact:"NW",rough:"W"};break;case 15:d={exact:"NNW",rough:"N"};break;default:d={exact:"N",rough:"N"}}return d.bearing=e,d},getDirection:function(a,b,c){return this.getCompassDirection.apply(this,arguments)},orderByDistance:function(a,b){var c=[];for(var d in b){var e=this.getDistance(a,b[d]),f=Object.create(b[d]);f.distance=e,f.key=d,c.push(f)}return c.sort(function(a,b){return a.distance-b.distance})},isPointInLine:function(a,b,c){return(this.getDistance(b,a,1,3)+this.getDistance(a,c,1,3)).toFixed(3)==this.getDistance(b,c,1,3)},isPointNearLine:function(a,b,c,d){return this.getDistanceFromLine(a,b,c)<d},getDistanceFromLine:function(a,b,c){var d=this.getDistance(b,a,1,3),e=this.getDistance(a,c,1,3),f=this.getDistance(b,c,1,3),g=0,h=Math.acos((d*d+f*f-e*e)/(2*d*f)),i=Math.acos((e*e+f*f-d*d)/(2*e*f));return g=h>Math.PI/2?d:i>Math.PI/2?e:Math.sin(h)*d},findNearest:function(a,b,c,d){c=c||0,d=d||1;var e=this.orderByDistance(a,b);return 1===d?e[c]:e.splice(c,d)},getPathLength:function(a){for(var b,c=0,d=0,e=a.length;e>d;++d)b&&(c+=this.getDistance(this.coords(a[d]),b)),b=this.coords(a[d]);return c},getSpeed:function(a,b,c){var e=c&&c.unit||"km";"mph"==e?e="mi":"kmh"==e&&(e="km");var f=d.getDistance(a,b),g=1*b.time/1e3-1*a.time/1e3,h=f/g*3600,i=Math.round(h*this.measures[e]*1e4)/1e4;return i},computeDestinationPoint:function(a,b,c,d){var e=this.latitude(a),f=this.longitude(a);d="undefined"==typeof d?this.radius:Number(d);var g=Number(b)/d,h=Number(c).toRad(),i=Number(e).toRad(),j=Number(f).toRad(),k=Math.asin(Math.sin(i)*Math.cos(g)+Math.cos(i)*Math.sin(g)*Math.cos(h)),l=j+Math.atan2(Math.sin(h)*Math.sin(g)*Math.cos(i),Math.cos(g)-Math.sin(i)*Math.sin(k));return l=(l+3*Math.PI)%(2*Math.PI)-Math.PI,{latitude:k.toDeg(),longitude:l.toDeg()}},convertUnit:function(a,b,c){if(0===b)return 0;if("undefined"==typeof b){if(null===this.distance)throw new Error("No distance was given");if(0===this.distance)return 0;b=this.distance}if(a=a||"m",c=null==c?4:c,"undefined"!=typeof this.measures[a])return this.round(b*this.measures[a],c);throw new Error("Unknown unit for conversion.")},useDecimal:function(a){if("[object Array]"===Object.prototype.toString.call(a)){var b=this;return a=a.map(function(a){if(b.isDecimal(a))return b.useDecimal(a);if("object"==typeof a){if(b.validate(a))return b.coords(a);for(var c in a)a[c]=b.useDecimal(a[c]);return a}return b.isSexagesimal(a)?b.sexagesimal2decimal(a):a})}if("object"==typeof a&&this.validate(a))return this.coords(a);if("object"==typeof a){for(var c in a)a[c]=this.useDecimal(a[c]);return a}if(this.isDecimal(a))return parseFloat(a);if(this.isSexagesimal(a)===!0)return parseFloat(this.sexagesimal2decimal(a));throw new Error("Unknown format.")},decimal2sexagesimal:function(a){if(a in this.sexagesimal)return this.sexagesimal[a];var b=a.toString().split("."),c=Math.abs(b[0]),d=60*("0."+(b[1]||0)),e=d.toString().split(".");return d=Math.floor(d),e=(60*("0."+(e[1]||0))).toFixed(2),this.sexagesimal[a]=c+"° "+d+"' "+e+'"',this.sexagesimal[a]},sexagesimal2decimal:function(a){if(a in this.decimal)return this.decimal[a];var b=new RegExp(this.sexagesimalPattern),c=b.exec(a),d=0,e=0;c&&(d=parseFloat(c[2]/60),e=parseFloat(c[4]/3600)||0);var f=(parseFloat(c[1])+d+e).toFixed(8);return f="S"==c[7]||"W"==c[7]?parseFloat(-f):parseFloat(f),this.decimal[a]=f,f},isDecimal:function(a){return a=a.toString().replace(/\s*/,""),!isNaN(parseFloat(a))&&parseFloat(a)==a},isSexagesimal:function(a){return a=a.toString().replace(/\s*/,""),this.sexagesimalPattern.test(a)},round:function(a,b){var c=Math.pow(10,b);return Math.round(a*c)/c}}),"undefined"!=typeof module&&"undefined"!=typeof module.exports?(module.exports=d,"object"==typeof a&&(a.geolib=d)):"function"==typeof define&&define.amd?define("geolib",[],function(){return d}):a.geolib=d}(this);
12 \ No newline at end of file 12 \ No newline at end of file