import { createSelector } from 'reselect'; import Global from './Common'; import { latLngDegreesToDecimal, isObject, isUndefined, isString, isSafeString, hasLine, hasPoint } from './Utils' let LatLon = require('geodesy').LatLonSpherical; function getCircleRegions(circle) { let latlon = new LatLon(circle.coordinate.latitude, circle.coordinate.longitude) 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 getCircles(airspaceInfos, setStyle, currentAirspaceIndex) { let circles = []; if (!Array.isArray(airspaceInfos)) { return circles; } //通过该方法获取样式 let circleStyle = setStyle('circle'); for (let i = 0; i < airspaceInfos.length; i++) { let tmpCircle = airspaceInfos[i] let airspaceTypeFix; if (tmpCircle.airspaceType) airspaceTypeFix = 'airspaceType'; else airspaceTypeFix = 'airspace_type'; if (tmpCircle[airspaceTypeFix] == Global.airspaceType.circle && currentAirspaceIndex != i) { let coordinate = {}; if (tmpCircle.center_point_of_flying) { coordinate.latitude = tmpCircle.center_point_of_flying.lat; coordinate.longitude = tmpCircle.center_point_of_flying.lng; } else { coordinate.latitude = latLngDegreesToDecimal(tmpCircle.lat); coordinate.longitude = latLngDegreesToDecimal(tmpCircle.lng); } let radius = tmpCircle.radius_of_flying; let circle = { lineWidth: circleStyle.lineWidth ? circleStyle.lineWidth : Global.amapLineWidth, strokeColor: circleStyle.strokeColor ? circleStyle.strokeColor : Global.amapStrokeColor, fillColor: circleStyle.fillColor ? circleStyle.fillColor : Global.amapFillColor, radius, coordinate } circles.push(circle); } } return circles; } function getCircleSelector(airspaceInfos, setStyle, currentAirspaceIndex) { return createSelector( airspaceInfos, () => setStyle, currentAirspaceIndex, getCircles ); } function drawLineConfig(lat, lng) { let coordinate = {}; coordinate.latitude = latLngDegreesToDecimal(lat); coordinate.longitude = latLngDegreesToDecimal(lng); return coordinate; } function addOvalPointConfig(lat, lng, imageName) { let coordinate = {}; coordinate.latitude = latLngDegreesToDecimal(lat); coordinate.longitude = latLngDegreesToDecimal(lng); let annotationConfig = {}; annotationConfig.coordinate = coordinate; annotationConfig.imageName = imageName; return annotationConfig } function getAirwayLine(airway, pointBefore, pointAfter, lineAndMarkerStyle) { let found = 0 let points = [] for (let point of airway.points) { if (pointBefore.point_id == point.point_id || pointAfter.point_id == point.point_id) { found++ points.push(Object.assign({}, point)) continue } if (found == 1) { points.push(Object.assign({}, point)) } } if (!(points.length > 0 && found == 2)) { // 如果两个点不全在航线上面,那么画全部航线 points = airway.points } let line = { lineWidth: lineAndMarkerStyle.lineWidth ? lineAndMarkerStyle.lineWidth : Global.amapLineWidth, strokeColor: lineAndMarkerStyle.strokeColor ? lineAndMarkerStyle.strokeColor : Global.amapStrokeColor, coordinates: points } return { line }; } function getLinesRouter(lineProps, lineAndMarkerStyle) { let coordinates = new Array(); let markers = new Array(); let lines = [] let startPointFix; if (lineProps.start_point) startPointFix = 'start_point'; else startPointFix = 'dep'; if (hasLine(lineProps[startPointFix])) { coordinates.push(startPointFix == 'dep' ? drawLineConfig(lineProps[startPointFix].lat, lineProps[startPointFix].lng) : { latitude: lineProps[startPointFix].lat, longitude: lineProps[startPointFix].lng }); markers.push(startPointFix == 'dep' ? addOvalPointConfig(lineProps[startPointFix].lat, lineProps[startPointFix].lng, lineAndMarkerStyle.imageName ? lineAndMarkerStyle.imageName : 'BA_oval') : { coordinate: { latitude: lineProps[startPointFix].lat, longitude: lineProps[startPointFix].lng }, imageName: lineAndMarkerStyle.imageName ? lineAndMarkerStyle.imageName : 'BA_oval' }); } let passingPointsFix; if (lineProps.passing_points) passingPointsFix = 'passing_points'; else passingPointsFix = 'passPoints'; let endPointFix; if (lineProps.end_point) endPointFix = 'end_point'; else endPointFix = 'arrive' if (Array.isArray(lineProps[passingPointsFix])) { for (let i = 0; i < lineProps[passingPointsFix].length; i++) { let obj = lineProps[passingPointsFix][i] if (isObject(obj)) { continue; } let pointTypeFix; if (obj.point_type) pointTypeFix = 'point_type'; else pointTypeFix = 'pointType' if (obj[pointTypeFix] == Global.pointTypes.point || obj[pointTypeFix] == Global.pointTypes.nav) { coordinates.push(pointTypeFix == 'pointType' ? drawLineConfig(obj.lat, obj.lng) : { latitude: obj.lat, longitude: obj.lng }); markers.push(pointTypeFix == 'pointType' ? addOvalPointConfig(obj.lat, obj.lng, lineAndMarkerStyle.imageName ? lineAndMarkerStyle.imageName : 'BA_oval') : { coordinate: { latitude: obj.lat, longitude: obj.lng }, imageName: lineAndMarkerStyle.imageName ? lineAndMarkerStyle.imageName : 'BA_oval' }); } else { // 遇到一个航线,不需要和前前面的点连起来 if (coordinates.length > 1) { lines.push({ lineWidth: lineAndMarkerStyle.lineWidth ? lineAndMarkerStyle.lineWidth : Global.amapLineWidth, strokeColor: lineAndMarkerStyle.strokeColor ? lineAndMarkerStyle.strokeColor : Global.amapStrokeColor, coordinates: coordinates }) } coordinates = [] const pointBefore = i == 0 ? lineProps[startPointFix] : lineProps[passingPointsFix][i - 1] const pointAfter = i == lineProps[passingPointsFix].length - 1 ? lineProps[endPointFix] : lineProps[passingPointsFix][i + 1] lines.push(getAirwayLine(obj, pointBefore, pointAfter, lineAndMarkerStyle)) } } } if (hasLine(lineProps[endPointFix])) { coordinates.push(endPointFix == 'arrive' ? drawLineConfig(lineProps[endPointFix].lat, lineProps[endPointFix].lng) : { latitude: lineProps[endPointFix].lat, longitude: lineProps[endPointFix].lng }); markers.push(endPointFix == 'arrive' ? addOvalPointConfig(lineProps[endPointFix].lat, lineProps[endPointFix].lng, lineAndMarkerStyle.imageName ? lineAndMarkerStyle.imageName : 'BA_oval') : { coordinate: { latitude: lineProps[endPointFix].lat, longitude: lineProps[endPointFix].lng }, imageName: lineAndMarkerStyle.imageName ? lineAndMarkerStyle.imageName : 'BA_oval' }); } if (coordinates.length > 1) { lines.push({ lineWidth: lineAndMarkerStyle.lineWidth ? lineAndMarkerStyle.lineWidth : Global.amapLineWidth, strokeColor: lineAndMarkerStyle.strokeColor ? lineAndMarkerStyle.strokeColor : Global.amapStrokeColor, coordinates: coordinates }); } return { lines, markers }; } function getLinesAndMarkers(airspaceInfos, setStyle, currentAirspaceIndex) { let retLines = []; let retMarkers = []; if (!Array.isArray(airspaceInfos)) { return { lines: retLines, markers: retMarkers }; } let lineStyle = setStyle('line'); for (let i = 0; i < airspaceInfos.length; i++) { let tmpLine = airspaceInfos[i] let airspaceTypeFix; if (tmpLine.airspaceType) airspaceTypeFix = 'airspaceType'; else airspaceTypeFix = 'airspace_type'; if (tmpLine[airspaceTypeFix] == Global.airspaceType.line && currentAirspaceIndex != i) { let { lines, markers } = getLinesRouter(tmpLine, lineStyle); retMarkers.push(...markers); retLines.push(...lines); } } return { lines: retLines, markers: retMarkers }; } function getLineAndMarkerSelector(airspaceInfos, setStyle, currentAirspaceIndex) { return createSelector( airspaceInfos, () => setStyle, currentAirspaceIndex, getLinesAndMarkers ); } function getPolygon(polygonProps, polygonAndMarkerStyle) { let coordinates = new Array(); let markers = new Array(); let pointsFix; if (polygonProps.points) pointsFix = 'points'; else pointsFix = 'polygonPoints'; if (Array.isArray(polygonProps[pointsFix])) { for (let obj of polygonProps[pointsFix]) { if (!hasPoint(obj)) { continue; } coordinates.push(pointsFix == 'polygonPoints' ? drawLineConfig(obj.lat, obj.lng) : { latitude: obj.lat, longitude: obj.lng }); markers.push(pointsFix == 'polygonPoints' ? addOvalPointConfig(obj.lat, obj.lng, polygonAndMarkerStyle.imageName ? polygonAndMarkerStyle.imageName : 'BA_oval') : { coordinate: { latitude: obj.lat, longitude: obj.lng }, imageName: polygonAndMarkerStyle.imageName ? polygonAndMarkerStyle.imageName : 'BA_oval' }); } } if (coordinates.length > 0) { let polygon = { lineWidth: polygonAndMarkerStyle.lineWidth ? polygonAndMarkerStyle.lineWidth : Global.amapLineWidth, strokeColor: polygonAndMarkerStyle.strokeColor ? polygonAndMarkerStyle.strokeColor : Global.amapStrokeColor, fillColor: polygonAndMarkerStyle.fillColor ? polygonAndMarkerStyle.fillColor : Global.amapFillColor, coordinates: coordinates }; return { markers, polygon }; } } function getPolygonsAndMarkers(airspaceInfos, setStyle, currentAirspaceIndex) { let markers = []; let polygons = []; if (!Array.isArray(airspaceInfos)) { return { markers, polygons }; } let polygonAndMarkerStyle = setStyle('polygon'); for (let i = 0; i < airspaceInfos.length; i++) { let polygon = airspaceInfos[i] let airspaceTypeFix; if (polygon.airspaceType) airspaceTypeFix = 'airspaceType'; else airspaceTypeFix = 'airspace_type'; if (polygon[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, setStyle, currentAirspaceIndex) { return createSelector( airspaceInfos, () => setStyle, currentAirspaceIndex, getPolygonsAndMarkers ); } function getMarkers(polygonAndMarkers, lineAndMarkers) { let markers = []; if (polygonAndMarkers) { markers = [...polygonAndMarkers.markers] } if (lineAndMarkers) { markers = [...markers, ...lineAndMarkers.markers] } return markers } function getMarkerSelector(polygonAndMarkers, lineAndMarkers) { return createSelector( polygonAndMarkers, lineAndMarkers, getMarkers ) } function getRegionPoints(circles, lineAndMarkers, polygonAndMarkers) { let regionPoints = 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.coordinates); } return regionPoints; } function getRegionPointsSelector(circles, lineAndMarkers, polygonAndMarkers) { return createSelector( circles, lineAndMarkers, polygonAndMarkers, getRegionPoints ); } function getLines(lineAndMarker) { return lineAndMarker.lines; } function getLineSelector(lineAndMarker) { return createSelector( lineAndMarker, getLines ); } function getPolygons(polygonAndMarkers) { return polygonAndMarkers.polygons; } function getPolygonSelector(polygonAndMarkers) { return createSelector( polygonAndMarkers, getPolygons ); } let setStyle = (style) => { if (!style) return (shapeName) => { return {key:0} } else return (shapeName) => style[shapeName] } //获取selector export function getShapesSelector(airspaceInfos, style, currentAirspaceIndex) { if (!style) style = {}; currentAirspaceIndex = currentAirspaceIndex ? currentAirspaceIndex : () => -1; let circles = getCircleSelector(airspaceInfos, setStyle(style), currentAirspaceIndex); let lineAndMarkers = getLineAndMarkerSelector(airspaceInfos, setStyle(style), currentAirspaceIndex); let lines = getLineSelector(lineAndMarkers); let polygonAndMarkers = getPolygonAndMarkerSelector(airspaceInfos, setStyle(style), currentAirspaceIndex); let polygons = getPolygonSelector(polygonAndMarkers); let markers = getMarkerSelector(polygonAndMarkers, lineAndMarkers); let regionPoints = getRegionPointsSelector(circles, lineAndMarkers, polygonAndMarkers); return { markers, circles, lines, polygons, regionPoints } } //获取数组 export function getShapes(airspaceInfos, style, currentAirspaceIndex) { if (!style) style = {}; currentAirspaceIndex = currentAirspaceIndex ? currentAirspaceIndex : () => -1; let circles = getCircles(airspaceInfos, setStyle(style), currentAirspaceIndex); let lineAndMarkers = getLinesAndMarkers(airspaceInfos, setStyle(style), currentAirspaceIndex); let lines = getLines(lineAndMarkers); let polygonAndMarkers = getPolygonsAndMarkers(airspaceInfos, setStyle(style), currentAirspaceIndex); let polygons = getPolygons(polygonAndMarkers); let markers = getMarkers(polygonAndMarkers, lineAndMarkers); let regionPoints = getRegionPoints(circles, lineAndMarkers, polygonAndMarkers); return { markers, circles, lines, polygons, regionPoints } }