| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319 |
- import { createSelector, OutputSelector } from 'reselect';
- import Global from './Common';
- import { Marker, Circle, Line, Polygon} from 'react-native-amap-kit';
- import {
- latLngDegreesToDecimal,
- latLngDecimalToDegrees,
- isObject,
- isSafeString,
- hasPoint,
- isNumber
- } from './Utils'
- export { Marker, Circle, Line, Polygon };
- let LatLon = require('geodesy').LatLonSpherical;
- declare namespace LatLon {
- export interface Spherical {
- lat: number;
- lon: number;
- bearingTo: (point: LatLon.Spherical) => number;
- destinationPoint: (distance: number, bearing: number, radius?: number) => LatLon.Spherical
- }
- }
- export interface CoordinateShort {
- lat: number;
- lng: number;
- }
- export interface CoordinateLong {
- latitude: number;
- longitude: number;
- }
- // Server
- export interface LatLngAddrServer extends CoordinateShort {
- addr: string;
- }
- export interface LatLngPointServer extends LatLngAddrServer {
- altitude: number;
- unit: 0 | 1 | 2 | 3;
- }
- export interface StartPointServer extends CoordinateShort {
- altitude: number;
- unit: 0 | 1 | 2 | 3;
- }
- export interface AirRoutePoint extends CoordinateShort {
- point_id: number;
- point_name: string;
- point_code: string;
- }
- // Passpoints
- export interface PassingPointNavServer extends CoordinateShort {
- point_type: 1;
- altitude: number;
- unit: 0 | 1 | 2 | 3;
- point_id: number;
- point_code: string;
- point_name: string;
- }
- export interface PassingPointAirlineServer {
- point_type: 2;
- altitude: number;
- unit: 0 | 1 | 2 | 3;
- airway?: number;
- air_route_code: string;
- points: Array<AirRoutePoint>;
- }
- export interface PassingPointNormalServer extends CoordinateShort{
- point_type: 3;
- altitude: number;
- unit: 0 | 1 | 2 | 3;
- point_name: string;
- }
- // Airspace
- export interface AirspaceInfoCircleServer {
- airspace_name: string;
- airspace_type: 1;
- airspace_id: string;
- note: string;
- center_loc: string;
- center_point_of_flying: CoordinateShort;
- radius_of_flying: number;
- altitude: number;
- unit: number;
- free_draw?: boolean;
- }
- export interface AirspaceInfoLineServer {
- airspace_name: string;
- airspace_type: 2;
- airspace_id: string;
- note: string;
- start_loc: string;
- start_point: StartPointServer;
- end_loc: string;
- end_point: CoordinateShort;
- passing_points: Array<PassingPointServer>;
- airline_width?: number;
- free_draw?: boolean;
- }
- export interface AirspaceInfoPolygonServer {
- airspace_name: string;
- airspace_type: 3;
- airspace_id: string;
- note: string;
- points: Array<LatLngAddrServer>;
- altitude: number;
- unit: number;
- free_draw?: boolean;
- }
- // Local
- export interface CoordinateShort {
- lat: number;
- lng: number;
- }
- export interface LatLngAddrLocal extends CoordinateShort {
- addr: string;
- }
- export interface LatLngPointLocal extends LatLngAddrLocal{
- height: string;
- heightStandard: string;
- }
- // Passpoint
- export interface PassingPointNavLocal extends CoordinateShort {
- pointType: 1;
- height: string;
- heightStandard: string;
- pointId: number;
- pointCode: string;
- pointName: string;
- }
- export interface PassingPointAirlineLocal {
- pointType: 2;
- height: string;
- heightStandard: string;
- airRouteId: number;
- airlineCode: string;
- airlines: Array<AirRoutePoint>;
- }
- export interface PassingPointNormalLocal extends CoordinateShort {
- pointType: 3;
- height: string;
- heightStandard: string;
- addr: string;
- }
- // Airspace
- export interface AirspaceInfoCircleLocal {
- airspaceType: 1;
- airspaceId: string;
- name: string;
- note: string;
- addr: string;
- lat: number;
- lng: number;
- radius: number;
- height: string;
- heightStandard: string;
- isDraw?: boolean;
- }
- export interface AirspaceInfoLineLocal {
- airspaceType: 2;
- airspaceId: string;
- name: string;
- note: string;
- dep: LatLngPointLocal;
- arrive: LatLngAddrLocal;
- passPoints: Array<PassingPointLocal>;
- airlineWidth?: number;
- isDraw?: boolean;
- }
- export interface AirspaceInfoPolygonLocal {
- airspaceType: 3;
- airspaceId: string;
- name: string;
- note: string;
- polygonPoints: Array<LatLngAddrLocal>;
- height: string;
- heightStandard: string;
- isDraw?: boolean;
- }
- declare type AirspaceInfoCircle = AirspaceInfoCircleLocal | AirspaceInfoCircleServer;
- declare type AirspaceInfoLine = AirspaceInfoLineLocal | AirspaceInfoLineServer;
- declare type AirspaceInfoPolygon = AirspaceInfoPolygonLocal | AirspaceInfoPolygonServer;
- declare type AirspaceInfoLocal = AirspaceInfoCircleLocal | AirspaceInfoLineLocal | AirspaceInfoPolygonLocal;
- declare type AirspaceInfoServer = AirspaceInfoCircleServer | AirspaceInfoLineServer | AirspaceInfoPolygonServer;
- declare type AirspaceInfo = AirspaceInfoLocal | AirspaceInfoServer
- declare type PassingPointNav = PassingPointNavLocal | PassingPointNavServer
- declare type PassingPointNormal = PassingPointNormalLocal | PassingPointNormalServer
- declare type PassingPointAirline = PassingPointAirlineLocal | PassingPointAirlineServer
- declare type PassingPointLocal = PassingPointNavLocal | PassingPointNormalLocal | PassingPointAirlineLocal
- declare type PassingPointServer = PassingPointNavServer | PassingPointNormalServer | PassingPointAirlineServer
- declare type PassingPoint = PassingPointLocal | PassingPointServer
- // shapes
- export type Coordinate = CoordinateLong | CoordinateShort
- export interface CirclesAndMarkers {
- circles: Circle[];
- markers: Marker[];
- }
- export interface LinesAndMarkes {
- lines: Line[];
- markers: Marker[];
- }
- export interface LinesPolygonsAndMarkers {
- polygons: Polygon[];
- markers: Marker[];
- lines: Line[];
- }
- export interface PolygonsAndMarkers {
- polygons: Polygon[];
- markers: Marker[];
- }
- export interface ShapeStyle {
- imageName: string;
- lineWidth: number;
- strokeColor: string;
- fillColor: string;
- }
- export interface ShapeStyles {
- [styleName: string]: ShapeStyle
- }
- export function convertAirspaceInfoServerToLocal(airspaceInfo
- : AirspaceInfoCircleServer | AirspaceInfoLineServer | AirspaceInfoPolygonServer)
- : AirspaceInfoCircleLocal | AirspaceInfoLineLocal | AirspaceInfoPolygonLocal | null {
- const airspaceType = airspaceInfo.airspace_type
- if (airspaceType == Global.airspaceType.circle) {
- const ai: AirspaceInfoCircleServer = <AirspaceInfoCircleServer> airspaceInfo
- return <AirspaceInfoCircleLocal>{
- airspaceType,
- airspaceId: ai.airspace_id,
- name: ai.airspace_name,
- note: ai.note,
- addr: ai.center_loc,
- lat: ai.center_point_of_flying.lat,
- lng: ai.center_point_of_flying.lng,
- radius: ai.radius_of_flying,
- height: ai.altitude + "",
- heightStandard: Global.heightStandardsById.get(ai.unit),
- isDraw: ai.free_draw? ai.free_draw: false
- };
- }
- if (airspaceType == Global.airspaceType.line) {
- const ai: AirspaceInfoLineServer = <AirspaceInfoLineServer> airspaceInfo
- let dep = {
- addr: ai.start_loc,
- lat: ai.start_point.lat,
- lng: ai.start_point.lng,
- height: ai.start_point.altitude + "",
- heightStandard: Global.heightStandardsById.get(ai.start_point.unit)
- }
- let arrive = {
- addr: ai.end_loc,
- lat: ai.end_point.lat,
- lng: ai.end_point.lng
- }
- let passPoints: (PassingPointNavLocal | PassingPointAirlineLocal | PassingPointNormalLocal)[] = []
- if(Array.isArray(ai.passing_points)) {
- for(let obj of ai.passing_points) {
- let point: PassingPointNavLocal | PassingPointAirlineLocal | PassingPointNormalLocal;
- if (obj.point_type == Global.pointTypes.point) {
- const pp = <PassingPointNormalServer>obj;
- const lat = pp.lat
- const lng = pp.lng
- point = <PassingPointNormalLocal>{
- pointType: pp.point_type,
- addr: pp.point_name,
- lat, lng
- }
- } else if (obj.point_type == Global.pointTypes.nav) {
- const pp = <PassingPointNavServer>obj;
- const lat = pp.lat
- const lng = pp.lng
- point = <PassingPointNavLocal>{
- pointType: pp.point_type,
- pointId: pp.point_id,
- pointCode: pp.point_code,
- pointName: pp.point_name,
- lat, lng
- }
- } else {
- const pp = <PassingPointAirlineServer>obj;
- point = <PassingPointAirlineLocal>{
- pointType: pp.point_type,
- airRouteId: pp.airway,
- airlineCode: pp.air_route_code,
- airlines: pp.points
- }
- }
- if(isNumber(obj.altitude) && isNumber(obj.unit)) {
- point.height = obj.altitude + "";
- point.heightStandard = Global.heightStandardsById.get(obj.unit);
- } else {
- point.height = ""
- point.heightStandard = [...Global.heightStandards.keys()][0];
- }
- passPoints.push(point)
- }
- }
- return <AirspaceInfoLineLocal>{ ...{
- airspaceType,
- airspaceId: ai.airspace_id,
- name: ai.airspace_name,
- note: ai.note,
- dep,
- arrive,
- passPoints,
- isDraw: ai.free_draw? ai.free_draw: false
- }, ...(ai.airline_width ? {airlineWidth: ai.airline_width} : {})}
- }
- if (airspaceType == Global.airspaceType.polygon) {
- const ai = <AirspaceInfoPolygonServer>airspaceInfo;
- if(Array.isArray(ai.points)) {
- let polygonPoints = new Array();
- let defaultPointName = 'A'
- for(let obj of ai.points) {
- let addr = obj.addr
- if(!addr) {
- addr = defaultPointName
- defaultPointName = String.fromCharCode(defaultPointName.charCodeAt(0) + 1)
- }
- polygonPoints.push({addr, lat: obj.lat, lng: obj.lng})
- }
- return <AirspaceInfoPolygonLocal>{
- airspaceType,
- airspaceId: ai.airspace_id,
- name: ai.airspace_name,
- note: ai.note,
- height: ai.altitude + '',
- heightStandard: Global.heightStandardsById.get(ai.unit),
- polygonPoints,
- isDraw: ai.free_draw? ai.free_draw: false
- };
- }
- }
- return null;
- }
- export function convertAirspaceInfoLocalToServer(airspace
- : AirspaceInfoCircleLocal | AirspaceInfoLineLocal | AirspaceInfoPolygonLocal)
- : AirspaceInfoCircleServer | AirspaceInfoLineServer | AirspaceInfoPolygonServer {
- if (airspace.airspaceType == Global.airspaceType.circle) {
- const ai = <AirspaceInfoCircleLocal> airspace;
- const circle = <AirspaceInfoCircleServer>{
- airspace_name: ai.name,
- airspace_id: ai.airspaceId,
- airspace_type: Global.airspaceType.circle,
- note: isSafeString(ai.note) ? ai.note : null,
- radius_of_flying: parseInt(ai.radius + ''),
- center_point_of_flying: {
- lng: ai.lng,
- lat: ai.lat
- },
- center_loc: ai.addr,
- altitude: parseInt(ai.height),
- unit: Global.heightStandards.get(ai.heightStandard),
- free_draw: ai.isDraw? ai.isDraw: false
- };
- return circle
- } else if (airspace.airspaceType == Global.airspaceType.line) {
- const ai = <AirspaceInfoLineLocal> airspace;
- let line = <AirspaceInfoLineServer>{
- airspace_name: ai.name,
- airspace_id: ai.airspaceId,
- airspace_type: Global.airspaceType.line,
- note: ai.note,
- start_loc: ai.dep.addr,
- start_point: {
- lng: ai.dep.lng,
- lat: ai.dep.lat,
- altitude: parseInt(ai.dep.height),
- unit: Global.heightStandards.get(ai.dep.heightStandard)
- },
- end_loc: ai.arrive.addr,
- end_point: {
- lng: ai.arrive.lng,
- lat: ai.arrive.lat
- },
- free_draw: ai.isDraw? ai.isDraw: false
- }
- if(ai.airlineWidth) {
- line['airline_width'] = ai.airlineWidth
- }
- if (Array.isArray(ai.passPoints) && ai.passPoints.length > 0) {
- let passing_points = [];
- for (let obj of ai.passPoints) {
- let retObj: PassingPointNormalServer | PassingPointNavServer | PassingPointAirlineServer;
- if (obj.pointType == Global.pointTypes.point && hasPoint(<PassingPointNormalLocal>obj)) {
- const pp = <PassingPointNormalLocal>obj;
- retObj = <PassingPointNormalServer>{
- point_type: Global.pointTypes.point,
- point_name: pp.addr,
- lat: pp.lat,
- lng: pp.lng
- };
- } else if (obj.pointType == Global.pointTypes.nav) {
- const pp = <PassingPointNavLocal>obj;
- retObj = <PassingPointNavServer>{
- point_type: Global.pointTypes.nav,
- point_name: pp.pointName,
- point_id: pp.pointId,
- point_code: pp.pointCode,
- lat: pp.lat,
- lng: pp.lng
- };
- } else {
- const pp = <PassingPointAirlineLocal>obj;
- retObj = <PassingPointAirlineServer>{
- point_type: Global.pointTypes.line,
- airway: pp.airRouteId,
- air_route_code: pp.airlineCode,
- points: pp.airlines
- };
- }
- if (isSafeString(obj.height) && isSafeString(obj.heightStandard)) {
- retObj.altitude = parseInt(obj.height);
- // @ts-ignore
- retObj.unit = Global.heightStandards.get(obj.heightStandard);
- }
- passing_points.push(retObj)
- }
- line.passing_points = passing_points;
- } else {
- line.passing_points = [];
- }
- return line;
- } else {
- const ai = <AirspaceInfoPolygonLocal> airspace;
- const polygon = <AirspaceInfoPolygonServer>{
- airspace_name: ai.name,
- airspace_id: ai.airspaceId,
- airspace_type: Global.airspaceType.polygon,
- note: ai.note,
- altitude: parseInt(ai.height),
- unit: Global.heightStandards.get(ai.heightStandard),
- points: ai.polygonPoints,
- free_draw: ai.isDraw? ai.isDraw: false
- };
- return polygon;
- }
- }
- function getCircleRegions(circle: Circle): CoordinateShort[] {
- let lat, lng;
- if((circle.coordinate as any).latitude) {
- let coord = <CoordinateLong> circle.coordinate;
- lat = coord.latitude;
- lng = coord.longitude;
- } else {
- let coord = <CoordinateShort> circle.coordinate;
- lat = coord.lat;
- lng = coord.lng;
- }
- let latlon = new LatLon(lat, lng)
- let d1 = latlon.destinationPoint(circle.radius, 0)
- let d2 = latlon.destinationPoint(circle.radius, 90)
- let d3 = latlon.destinationPoint(circle.radius, 180)
- let d4 = latlon.destinationPoint(circle.radius, 270)
- return [{ lat: d1.lat, lng: d1.lon }, { lat: d2.lat, lng: d2.lon }, { lat: d3.lat, lng: d3.lon }, { lat: d4.lat, lng: d4.lon }]
- }
- function getDefaultStyle(): ShapeStyle {
- let imageName = 'BA_oval'
- let lineWidth = Global.amapLineWidth
- let strokeColor = Global.amapStrokeColor
- let fillColor = Global.amapFillColor
- return {imageName, lineWidth, strokeColor, fillColor}
- }
- function getCirclesAndMarkers(airspaceInfos: AirspaceInfo[], setStyle: (styleName: string) => ShapeStyle | null, currentAirspaceIndex: number | undefined): CirclesAndMarkers {
- let circles: Circle[] = [];
- let markers: Marker[] = [];
- if (!Array.isArray(airspaceInfos)) {
- return {circles, markers};
- }
- let {imageName, lineWidth, strokeColor, fillColor} = getDefaultStyle()
- //通过该方法获取样式
- let circleStyle = setStyle('circle');
- if(circleStyle) {
- lineWidth = circleStyle.lineWidth
- strokeColor = circleStyle.strokeColor
- fillColor = circleStyle.fillColor
- imageName = circleStyle.imageName
- }
- for (let i = 0; i < airspaceInfos.length; i++) {
- let tmpCircle = airspaceInfos[i]
- let airspaceTypeFix, radiusFix
- if ((tmpCircle as any).airspaceType) {
- airspaceTypeFix = 'airspaceType';
- radiusFix = 'radius'
- } else {
- airspaceTypeFix = 'airspace_type';
- radiusFix = 'radius_of_flying'
- }
- if ((tmpCircle as any)[airspaceTypeFix] == Global.airspaceType.circle && currentAirspaceIndex != i) {
- let coordinate = {latitude: 0, longitude: 0};
- if ((tmpCircle as any).center_point_of_flying) {
- let ai = <AirspaceInfoCircleServer>tmpCircle;
- coordinate.latitude = ai.center_point_of_flying.lat;
- coordinate.longitude = ai.center_point_of_flying.lng;
- } else {
- let ai = <AirspaceInfoCircleLocal>tmpCircle;
- coordinate.latitude = ai.lat;
- coordinate.longitude = ai.lng;
- }
- let radius = (tmpCircle as any)[radiusFix];
- if(radius) {
- let circle = <Circle>{lineWidth, strokeColor, fillColor, radius, coordinate}
- circles.push(circle);
- } else {
- markers.push(addOvalPointConfig(coordinate.latitude, coordinate.longitude, imageName));
- }
- }
- }
- return {circles, markers};
- }
- function getCircleAndMarkerSelector(airspaceInfos: () => AirspaceInfo[], setStyle: (styleName: string)=> ShapeStyle | null, currentAirspaceIndex: () => number | undefined) {
- return createSelector(
- airspaceInfos,
- () => setStyle,
- currentAirspaceIndex,
- getCirclesAndMarkers
- );
- }
- function drawLineConfig(lat: number, lng: number) {
- return {
- latitude: lat,
- longitude: lng
- };
- }
- function addOvalPointConfig(lat: number, lng: number, imageName: string) {
- return {
- coordinate: {
- latitude: lat,
- longitude: lng
- },
- imageName: imageName
- };
- }
- function pointCompare(point1: AirRoutePoint | undefined, point2: AirRoutePoint | undefined) {
- if (!point1 || !point2) {
- return false
- }
- const pointId1 = point1.point_id;
- const pointId2 = point2.point_id;
- if(pointId1 == pointId2) {
- return true;
- }
- let [point1Lat, point1lng] = getFixedLatLng(point1)
- let [point2lat, point2lng] = getFixedLatLng(point2)
- if(myRound(point1Lat) == myRound(point2lat)
- && myRound(point1lng) == myRound(point2lng)) {
- return true
- } else {
- return false
- }
- }
- function getCrossPoint(points1: AirRoutePoint[], points2: AirRoutePoint[]) {
- for(let point1 of points1) {
- for(let point2 of points2) {
- if (pointCompare(point1, point2))
- return point1
- }
- }
- return undefined
- }
- function getAirwayPoints(airway: PassingPointAirline, pointBefore: PassingPoint, pointAfter: PassingPoint) {
- let found = 0
- let points = []
- let pointTypeFix, pointsFix, airRoutePoint
- if ('points' in airway) {
- pointTypeFix = 'point_type';
- pointsFix = 'points'
- airRoutePoint = airway['points']
- } else {
- pointTypeFix = 'pointType'
- pointsFix = 'airlines'
- airRoutePoint = airway['airlines']
- }
- let crossPointBefore, crossPointAfter;
- // 如果前后是其他航线,那么找到交叉点作为前后的点
- if ( (pointBefore as any)[pointTypeFix] == Global.pointTypes.line ) {
- crossPointBefore = getCrossPoint(airRoutePoint, <AirRoutePoint[]>(pointBefore as any)[pointsFix])
- }
- if((pointAfter as any)[pointTypeFix] == Global.pointTypes.line) {
- crossPointAfter = getCrossPoint(airRoutePoint, <AirRoutePoint[]>(pointAfter as any)[pointsFix])
- }
- for (let point of airRoutePoint) {
- if (pointCompare(crossPointBefore, point) || pointCompare(crossPointAfter, point)) {
- found++
- points.push(Object.assign({}, point))
- continue
- }
- if (found == 1) {
- points.push(Object.assign({}, point))
- }
- }
- if (!(points.length > 0 && found == 2)) {
- // 如果两个点不全在航线上面,那么画全部航线
- points = airRoutePoint
- }
- return points;
- }
- function getLinesRouter(lineProps: AirspaceInfoLine, lineAndMarkerStyle: ShapeStyle | null) {
- let coordinates: Coordinate[] = new Array();
- let markers: Marker[] = new Array();
- let lines: Line[] = []
- let {imageName, lineWidth, strokeColor} = getDefaultStyle()
- if (lineAndMarkerStyle) {
- imageName = lineAndMarkerStyle.imageName
- lineWidth = lineAndMarkerStyle.lineWidth
- strokeColor = lineAndMarkerStyle.strokeColor
- }
- let startPoint, passPoints, endPoint, pointTypeFix, airlineWidth
- if ((lineProps as any).start_point) {
- let ll = <AirspaceInfoLineServer>lineProps;
- startPoint = ll['start_point']
- passPoints = ll['passing_points']
- endPoint = ll['end_point']
- pointTypeFix = 'point_type';
- airlineWidth = parseInt(ll['airline_width'] + '', 10)
- } else {
- let ll = <AirspaceInfoLineLocal>lineProps;
- startPoint = ll['dep']
- passPoints = ll['passPoints']
- endPoint = ll['arrive']
- pointTypeFix = 'pointType'
- airlineWidth = parseInt(ll['airlineWidth'] + '', 10)
- }
- if (startPoint) {
- coordinates.push(drawLineConfig(startPoint.lat, startPoint.lng));
- markers.push(addOvalPointConfig(startPoint.lat, startPoint.lng, imageName));
- }
- if (Array.isArray(passPoints)) {
- for (let i = 0; i < passPoints.length; i++) {
- let obj = passPoints[i]
- if (!isObject(obj)) { // 所有的 points/airway 都必须是 obj
- continue;
- }
- let pointType = (obj as any)[pointTypeFix]
- if ( pointType == Global.pointTypes.point
- || pointType == Global.pointTypes.nav) {
- let pp = <PassingPointNav | PassingPointNormal>obj
- coordinates.push(drawLineConfig(pp.lat, pp.lng));
- markers.push(addOvalPointConfig(pp.lat, pp.lng, imageName));
- } else {
- // 遇到一个航线,不需要和前前面的点连起来
- let pp = <PassingPointAirline>obj
- if (coordinates.length > 1) {
- lines.push({lineWidth, strokeColor, coordinates})
- }
- coordinates = []
- const pointBefore = i == 0 ? startPoint : passPoints[i - 1]
- const pointAfter = i == passPoints.length - 1 ? (endPoint ? endPoint : passPoints[passPoints.length - 1]) : passPoints[i + 1]
- lines.push({lineWidth, strokeColor, coordinates: getAirwayPoints(pp, <PassingPoint>pointBefore, <PassingPoint>pointAfter)})
- }
- }
- }
- if (endPoint) {
- coordinates.push(drawLineConfig(endPoint.lat, endPoint.lng));
- markers.push(addOvalPointConfig(endPoint.lat, endPoint.lng, imageName));
- }
- if (coordinates.length > 1) {
- lines.push({lineWidth, strokeColor, coordinates});
- }
- if(airlineWidth > 0) {
- // 有宽度的空域,需要线周围多画宽度的多边形
- let polygons = processAirlineWidth(lines, airlineWidth)
- return { lines, markers, polygons };
- } else {
- return { lines, markers, polygons: [] };
- }
- }
- function getFixedLatLng(point: {lat?: string | number, lng?: string | number, latitude?: string | number, longitude?: string | number}): [number, number] {
- let pp = <any> point;
- let lat = pp.latitude ? pp.latitude : pp.lat
- let lng = pp.longitude ? pp.longitude : pp.lng
- return [lat, lng]
- }
- function processAirlineWidth(lines: Line[], airlineWidth: number) {
- let polygons: Polygon[] = []
- let {strokeColor, fillColor} = getDefaultStyle()
- for(let line of lines) {
- let points = line.coordinates
- for(let i=0; i<points.length-1; i++) {
- let [lat1, lng1] = getFixedLatLng(points[i])
- let [lat2, lng2] = getFixedLatLng(points[i+1])
- let point1: LatLon.Spherical = new LatLon(lat1, lng1)
- let point2: LatLon.Spherical = new LatLon(lat2, lng2)
- let coordinates = getCirclePoints(point1, point2, airlineWidth)
- polygons.push({lineWidth: 1, strokeColor, fillColor, coordinates})
- }
- }
- return polygons
- }
- function getCirclePoints(point1: LatLon.Spherical, point2: LatLon.Spherical, width: number) {
- let percision = 10 // 半圆处理为多边形的时候,半圆上取几个点
- let step = 180/percision
- let bearing = (360 + point1.bearingTo(point2) - 90) % 360 // 取正值
- let points = []
- for(let diff = 0; diff <= 180; diff += step) {
- let point = point2.destinationPoint(width, bearing + diff)
- points.push({lat: point.lat, lng: point.lon})
- }
- for(let diff = 180; diff <= 360; diff += step) {
- let point = point1.destinationPoint(width, bearing + diff)
- points.push({lat: point.lat, lng: point.lon})
- }
- return points
- }
- function myRound(num: number, digits?: number) {
- if(digits == null)
- digits = 6 // 比较的精度,经纬度会被经过度分秒方式到浮点方式的转化
- return Math.round(num * Math.pow(10, digits)) / Math.pow(10, digits)
- }
- function getLinesPolygonsAndMarkers(airspaceInfos: AirspaceInfo[], setStyle: FnSetStyle, currentAirspaceIndex: number | undefined): LinesPolygonsAndMarkers {
- let retLines: Line[] = [];
- let retMarkers: Marker[] = [];
- let retPolygons: Polygon[] = [];
- if (!Array.isArray(airspaceInfos)) {
- return { lines: retLines, markers: retMarkers, polygons: retPolygons };
- }
- let lineStyle = setStyle('line');
- for (let i = 0; i < airspaceInfos.length; i++) {
- let tmpLine = airspaceInfos[i]
- let airspaceTypeFix;
- if ((tmpLine as any).airspaceType)
- airspaceTypeFix = 'airspaceType';
- else
- airspaceTypeFix = 'airspace_type';
- if ((tmpLine as any)[airspaceTypeFix] == Global.airspaceType.line && currentAirspaceIndex != i) {
- let lineProps = <AirspaceInfoLine>tmpLine;
- let { lines, markers, polygons } = getLinesRouter(lineProps, lineStyle);
- retMarkers.push(...markers);
- retLines.push(...lines);
- retPolygons.push(...polygons)
- }
- }
- return { lines: retLines, markers: retMarkers, polygons: retPolygons };
- }
- function getLinePolygonsAndMarkerSelector(airspaceInfos: () => AirspaceInfo[], setStyle: FnSetStyle, currentAirspaceIndex: () => number | undefined) {
- return createSelector(
- airspaceInfos,
- () => setStyle,
- currentAirspaceIndex,
- getLinesPolygonsAndMarkers
- );
- }
- function getPolygon(polygonProps: AirspaceInfoPolygon, polygonAndMarkerStyle: ShapeStyle | null) {
- let coordinates: Coordinate[] = new Array();
- let markers: Marker[] = new Array();
- let {imageName, lineWidth, strokeColor, fillColor} = getDefaultStyle()
- if (polygonAndMarkerStyle) {
- imageName = polygonAndMarkerStyle.imageName
- lineWidth = polygonAndMarkerStyle.lineWidth
- strokeColor = polygonAndMarkerStyle.strokeColor
- fillColor = polygonAndMarkerStyle.fillColor
- }
- let pointsFix;
- if ((polygonProps as any).points) {
- pointsFix = 'points';
- } else {
- pointsFix = 'polygonPoints';
- }
- if (Array.isArray((polygonProps as any)[pointsFix])) {
- for (let obj of (polygonProps as any)[pointsFix]) {
- if (!obj) {
- continue
- }
- coordinates.push(drawLineConfig(obj.lat, obj.lng));
- markers.push(addOvalPointConfig(obj.lat, obj.lng, imageName));
- }
- }
- let polygon = <Polygon>{lineWidth, strokeColor, fillColor, coordinates};
- return { markers, polygon };
- }
- function getPolygonsAndMarkers(airspaceInfos: AirspaceInfo[], setStyle: FnSetStyle, currentAirspaceIndex: number | undefined): PolygonsAndMarkers {
- let markers: Marker[] = [];
- let polygons: Polygon[] = [];
- if (!Array.isArray(airspaceInfos)) {
- return { markers, polygons };
- }
- let polygonAndMarkerStyle = setStyle('polygon');
- for (let i = 0; i < airspaceInfos.length; i++) {
- let polygon = <AirspaceInfoPolygon>airspaceInfos[i]
- let airspaceTypeFix;
- if ((polygon as any).airspaceType)
- airspaceTypeFix = 'airspaceType';
- else
- airspaceTypeFix = 'airspace_type';
- if ((polygon as any)[airspaceTypeFix] == Global.airspaceType.polygon && currentAirspaceIndex != i) {
- let retObj = getPolygon(polygon, polygonAndMarkerStyle);
- markers.push(...retObj.markers);
- polygons.push(retObj.polygon);
- }
- }
- return { markers, polygons };
- }
- function getPolygonAndMarkerSelector(airspaceInfos: () => AirspaceInfo[], setStyle: FnSetStyle, currentAirspaceIndex: () => number | undefined) {
- return createSelector(
- airspaceInfos,
- () => setStyle,
- currentAirspaceIndex,
- getPolygonsAndMarkers
- );
- }
- function getMarkers(circlesAndMarkers: CirclesAndMarkers, polygonAndMarkers: PolygonsAndMarkers, lineAndMarkers: LinesAndMarkes) {
- let markers: Marker[] = [];
- if (circlesAndMarkers) {
- markers = [...circlesAndMarkers.markers]
- }
- if (polygonAndMarkers) {
- markers = [...markers, ...polygonAndMarkers.markers]
- }
- if (lineAndMarkers) {
- markers = [...markers, ...lineAndMarkers.markers]
- }
- return markers
- }
- function getMarkerSelector(
- circlesAndMarkers: OutputSelector<any, any, (...params: any[]) => CirclesAndMarkers>,
- polygonAndMarkers: OutputSelector<any, any, (...params: any[]) => PolygonsAndMarkers>,
- lineAndMarkers: OutputSelector<any, any, (...params: any[]) => LinesAndMarkes>) {
- return createSelector(
- circlesAndMarkers,
- polygonAndMarkers,
- lineAndMarkers,
- getMarkers
- )
- }
- function getRegionPoints(circles: Circle[], lineAndMarkers: LinesAndMarkes, polygonAndMarkers: PolygonsAndMarkers) {
- let regionPoints: Coordinate[] = new Array();
- for (let i = 0; i < circles.length; i++) {
- regionPoints.push(...getCircleRegions(circles[i]));
- }
- let lines = lineAndMarkers.lines;
- for (let i = 0; i < lines.length; i++) {
- regionPoints.push(...lines[i].coordinates);
- }
- let polygons = polygonAndMarkers.polygons;
- for (let i = 0; i < polygons.length; i++) {
- regionPoints.push(...polygons[i].coordinates);
- }
- return regionPoints;
- }
- function getRegionPointsSelector(
- circles: OutputSelector<any, any, (...params: any[])=>Circle[]>,
- lineAndMarkers: OutputSelector<any, any, (...params: any[])=>LinesAndMarkes>,
- polygonAndMarkers: OutputSelector<any, any, (...params: any[])=>PolygonsAndMarkers>) {
- return createSelector(
- circles,
- lineAndMarkers,
- polygonAndMarkers,
- getRegionPoints
- );
- }
- function getCircles(circlesAndMarkers: CirclesAndMarkers) {
- return circlesAndMarkers.circles;
- }
- function getCircleSelector(circlesAndMarkers: OutputSelector<any, any, (...params: any[])=> CirclesAndMarkers>) {
- return createSelector(
- circlesAndMarkers,
- getCircles
- );
- }
- function getLines(lineAndMarker: LinesAndMarkes) {
- return lineAndMarker.lines;
- }
- function getLineSelector(lineAndMarker: OutputSelector<any, any, (...params: any[])=>LinesAndMarkes>) {
- return createSelector(
- lineAndMarker,
- getLines
- );
- }
- function getPolygons(polygonAndMarkers: PolygonsAndMarkers, linePolygonsAndMarkers: LinesPolygonsAndMarkers) {
- return [...polygonAndMarkers.polygons, ...linePolygonsAndMarkers.polygons];
- }
- function getPolygonSelector(
- polygonAndMarkers: OutputSelector<any, any, (...params: any[]) => PolygonsAndMarkers>,
- linePolygonsAndMarkers: OutputSelector<any, any, (...params: any[]) => LinesPolygonsAndMarkers>) {
- return createSelector(
- polygonAndMarkers,
- linePolygonsAndMarkers,
- getPolygons
- );
- }
- export type FnSetStyle = (styleName: string) => null | ShapeStyle
- let setStyle: (style: undefined | ShapeStyles) => FnSetStyle = (styles) => {
- if (!styles)
- return () => null
- else
- return (shapeName: string): ShapeStyle => styles[shapeName]
- }
- //获取selector
- export function getShapesSelector(airspaceInfos: () => AirspaceInfo[], style?: ShapeStyles, currentAirspaceIndex?: () => number | undefined) {
- currentAirspaceIndex = currentAirspaceIndex ? currentAirspaceIndex : () => -1;
- let circlesAndMarkers = getCircleAndMarkerSelector(airspaceInfos, setStyle(style), currentAirspaceIndex);
- let circles = getCircleSelector(circlesAndMarkers);
- let linePolygonsAndMarkers = getLinePolygonsAndMarkerSelector(airspaceInfos, setStyle(style), currentAirspaceIndex);
- let lines = getLineSelector(linePolygonsAndMarkers);
- let polygonAndMarkers = getPolygonAndMarkerSelector(airspaceInfos, setStyle(style), currentAirspaceIndex);
- let polygons = getPolygonSelector(polygonAndMarkers, linePolygonsAndMarkers);
- let markers = getMarkerSelector(circlesAndMarkers, polygonAndMarkers, linePolygonsAndMarkers);
- let regionPoints = getRegionPointsSelector(circles, linePolygonsAndMarkers, polygonAndMarkers);
- return {
- markers,
- circles,
- lines,
- polygons,
- regionPoints
- }
- }
- //获取数组
- export function getShapes(airspaceInfos: AirspaceInfo[], style?: ShapeStyles, currentAirspaceIndex?: number) {
- let {markers, polygons, circles, lines, regionPoints} =
- getShapesSelector(()=>airspaceInfos, style, ()=>currentAirspaceIndex)
- return {
- markers: markers(airspaceInfos),
- circles: circles(airspaceInfos),
- lines: lines(airspaceInfos),
- polygons: polygons(airspaceInfos),
- regionPoints: regionPoints(airspaceInfos)
- }
- }
- // 总共 5 种格式, http://git.corp.brilliantaero.com/BA/Coco/issues/99#note_6358
- // 1. 全输出格式
- // 2. 简化格式
- // 3. 传真格式
- // 4. 用户端用的简化格式
- // 5. 极简格式
- function getHeight(height: number | string, unit: string | number, type: number) {
- let shortNum
- const num = +height; // to number
- if(num >= 100) {
- shortNum = parseInt(num/100 + '').toString()
- if(shortNum.length <2) {
- shortNum = '0' + shortNum
- }
- }
- let heightStandard = Global.heightStandardsById.get(unit)
- if(!heightStandard) {
- heightStandard = unit
- }
- // 这里统一使用数字判断
- let standardUnit = Global.heightStandards.get(heightStandard)
- let heightDesc
- switch(standardUnit) {
- case 1:
- heightDesc = ['H*真', '真高*米']
- break;
- case 2:
- heightDesc = ['H*标(含以下)', '标高*米(含以下)']
- break;
- case 3:
- heightDesc = ['H*真(含以下)', '真高*米(含以下)']
- break;
- default:
- heightDesc = ['H*标', '标高*米']
- }
- if(shortNum && (type == 1 || type == 2)) {
- // H02真,H02真(含以下)
- return heightDesc[0].replace('*', shortNum)
- } else {
- // 真高200米,真高200米(含以下)
- return heightDesc[1].replace('*', height + '')
- }
- }
- function getAirspaceName(airspaceInfo: AirspaceInfo) {
- if((airspaceInfo as any).airspace_name) {
- const ai = <AirspaceInfoServer> airspaceInfo;
- return ai.airspace_name
- } else {
- const ai = <AirspaceInfoLocal> airspaceInfo;
- return ai.name
- }
- }
- export function circleContent(airspaceInfo: AirspaceInfoCircle, type=3) {
- if(type == 5)
- return getAirspaceName(airspaceInfo)
- if('airspace_name' in airspaceInfo) {
- const lat = latLngDecimalToDegrees(airspaceInfo.center_point_of_flying.lat);
- const lng = latLngDecimalToDegrees(airspaceInfo.center_point_of_flying.lng);
- let content = [];
- let loc = `以${airspaceInfo.center_loc}`
- if(type == 1 || type == 3)
- loc += `(E${lng}, N${lat})`;
- content.push(`${loc}为中心`)
- content.push(`半径${airspaceInfo.radius_of_flying}米`);
- content.push(getHeight(airspaceInfo.altitude, airspaceInfo.unit, type))
- if (airspaceInfo.note)
- content.push(`备注:${airspaceInfo.note}`)
- return content.join(',');
- } else {
- let content = []
- let loc = `以${airspaceInfo.addr}`
- if(type == 1 || type == 3)
- loc += `(E${latLngDecimalToDegrees(airspaceInfo.lng)}, N${latLngDecimalToDegrees(airspaceInfo.lat)})`;
- content.push(`${loc}为中心`)
- content.push(`半径${airspaceInfo.radius}米`);
- content.push(getHeight(airspaceInfo.height, airspaceInfo.heightStandard, type))
- if (airspaceInfo.note)
- content.push(`备注:${airspaceInfo.note}`)
- return content.join(',');
- }
- }
- function flyingCenter(item: CoordinateShort | {} = {}): string{
- if(item == {}){
- return "";
- }
- const pp = <CoordinateShort> item;
- return (
- "(E" + latLngDecimalToDegrees(pp.lng) +
- ', ' +
- "N" + latLngDecimalToDegrees(pp.lat) + ")"
- );
- }
- export function lineContent(airspaceInfo: AirspaceInfoLine, type=3): string {
- if(type == 5)
- return getAirspaceName(airspaceInfo)
- if('airspace_name' in airspaceInfo) {
- let content = [];
- content.push(`${airspaceInfo.start_loc}`)
- if(type == 1 || type == 3)
- content.push(`${flyingCenter(airspaceInfo.start_point)}`)
- content.push(` - `)
- content.push(getHeight(airspaceInfo.start_point.altitude, airspaceInfo.start_point.unit, type))
- const passing_points = airspaceInfo.passing_points;
- if(Array.isArray(passing_points)) {
- for(let i = 0; i < passing_points.length; i++) {
- const obj = passing_points[i];
- if (obj.point_type == Global.pointTypes.point) {
- let pp = <PassingPointNormalServer>obj;
- const lat = latLngDecimalToDegrees(pp.lat)
- const lng = latLngDecimalToDegrees(pp.lng)
- content.push(` - ${pp.point_name}`)
- if(type == 1 || type == 3)
- content.push(`(E${lng}, N${lat})`)
- } else if (obj.point_type == Global.pointTypes.nav) {
- let pp = <PassingPointNavServer>obj;
- const lat = latLngDecimalToDegrees(pp.lat)
- const lng = latLngDecimalToDegrees(pp.lng)
- content.push(` - ${pp.point_code}`)
- if(type == 1 || type == 3)
- content.push(`(E${lng}, N${lat})`)
- } else {
- let pp = <PassingPointAirlineServer>obj;
- content.push(` - ${pp.air_route_code}`)
- }
- if(obj.altitude) {
- content.push(` - ${getHeight(obj.altitude, obj.unit, type)}`)
- }
- }
- }
- content.push(` - ${airspaceInfo.end_loc}`)
- if(type == 1 || type == 3)
- content.push(`${flyingCenter(airspaceInfo.end_point)}`)
- if(isSafeString(airspaceInfo.airline_width)) {
- content.push(`,宽度:${airspaceInfo.airline_width}米`)
- }
- if(isSafeString(airspaceInfo.note)) {
- content.push(`,备注: ${airspaceInfo.note}`)
- }
- let result = content.join("")
- return result;
- } else {
- let content = [];
- content.push(`${airspaceInfo.dep.addr}`)
- if(type == 1 || type == 3)
- content.push(`(E${latLngDecimalToDegrees(airspaceInfo.dep.lng)}, N${latLngDecimalToDegrees(airspaceInfo.dep.lat)})`)
- content.push(` - ${getHeight(airspaceInfo.dep.height, airspaceInfo.dep.heightStandard, type)}`);
- if (Array.isArray(airspaceInfo.passPoints)) {
- let length = airspaceInfo.passPoints.length;
- for (let i = 0; i < length; i++) {
- let obj = airspaceInfo.passPoints[i];
- if (obj.pointType == Global.pointTypes.point) {
- let pp = <PassingPointNormalLocal>obj;
- content.push(` - ${pp.addr}`)
- if(type == 1 || type == 3)
- content.push(`(E${latLngDecimalToDegrees(pp.lng)}, N${latLngDecimalToDegrees(pp.lat)})`);
- } else if (obj.pointType == Global.pointTypes.nav) {
- let pp = <PassingPointNavLocal>obj;
- content.push(` - ${pp.pointCode}`)
- if(type == 1 || type == 3)
- content.push(`(E${latLngDecimalToDegrees(pp.lng)}, N${latLngDecimalToDegrees(pp.lat)})`);
- } else {
- let pp = <PassingPointAirlineLocal>obj;
- content.push(` - ${pp.airlineCode}`);
- }
- if(obj.height) {
- content.push(` - ${getHeight(obj.height, obj.heightStandard, type)}`)
- }
- }
- }
- content.push(` - ${airspaceInfo.arrive.addr}`)
- if(type == 1 || type == 3)
- content.push(`(E${latLngDecimalToDegrees(airspaceInfo.arrive.lng)}, N${latLngDecimalToDegrees(airspaceInfo.arrive.lat)})`);
- if(airspaceInfo.airlineWidth) {
- content.push(`,宽度:${airspaceInfo.airlineWidth}米`)
- }
- if (airspaceInfo.note)
- content.push(`,备注:${airspaceInfo.note}`)
- return content.join('');
- }
- }
- export function polygonContent(airspaceInfo: AirspaceInfoPolygon, type=3): string {
- if(type == 5)
- return getAirspaceName(airspaceInfo)
- if('airspace_name' in airspaceInfo) {
- let res = []
- let points = airspaceInfo.points
- for (let i = 0; i < points.length; i++) {
- let c = `${points[i].addr ? points[i].addr : ''}`
- if(type == 1 || type == 3)
- c += `(E${latLngDecimalToDegrees(points[i].lng)}, N${latLngDecimalToDegrees(points[i].lat)})`;
- res.push(c)
- }
- let content = [res.join('、')]
- content.push(`${airspaceInfo.points.length}点连线范围内`)
- content.push(`,${getHeight(airspaceInfo.altitude, airspaceInfo.unit, type)}`)
- if(isSafeString(airspaceInfo.note)) {
- content.push(`,备注:${airspaceInfo.note}`)
- }
- return content.join('');
- } else {
- let content = [];
- let length = airspaceInfo.polygonPoints.length;
- for (let i = 0; i < length; i++) {
- let obj = airspaceInfo.polygonPoints[i];
- let c = `${obj.addr ? obj.addr : ''}`
- if(type == 1 || type == 3)
- c += `(E${latLngDecimalToDegrees(obj.lng)}, N${latLngDecimalToDegrees(obj.lat)})`
- content.push(c)
- }
- let cc = content.join('、') + `${length}点连线范围内`
- cc += `,${getHeight(airspaceInfo.height, airspaceInfo.heightStandard, type)}`
- if (airspaceInfo.note)
- cc += `,备注:${airspaceInfo.note}`
- return cc;
- }
- }
- export {latLngDegreesToDecimal, latLngDecimalToDegrees}
|