import { createSelector } from 'reselect'; import Global from './Common'; import { latLngDegreesToDecimal, isObject } 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 getDefaultStyle() { let imageName = 'BA_oval' let lineWidth = Global.amapLineWidth let strokeColor = Global.amapStrokeColor let fillColor = Global.amapFillColor return {imageName, lineWidth, strokeColor, fillColor} } function getCircles(airspaceInfos, setStyle, currentAirspaceIndex) { let circles = []; if (!Array.isArray(airspaceInfos)) { return circles; } let {lineWidth, strokeColor, fillColor} = getDefaultStyle() //通过该方法获取样式 let circleStyle = setStyle('circle'); if(circleStyle) { lineWidth = circleStyle.lineWidth strokeColor = circleStyle.strokeColor fillColor = circleStyle.fillColor } for (let i = 0; i < airspaceInfos.length; i++) { let tmpCircle = airspaceInfos[i] let airspaceTypeFix, radiusFix if (tmpCircle.airspaceType) { airspaceTypeFix = 'airspaceType'; radiusFix = 'radius' } else { airspaceTypeFix = 'airspace_type'; radiusFix = 'radius_of_flying' } 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[radiusFix]; let circle = {lineWidth, strokeColor, fillColor, radius, coordinate} circles.push(circle); } } return circles; } function getCircleSelector(airspaceInfos, setStyle, currentAirspaceIndex) { return createSelector( airspaceInfos, () => setStyle, currentAirspaceIndex, getCircles ); } function getLatLng(latlng, dataType) { if(dataType == 1) { // 驼峰模式,新建计划的时候的格式 return latLngDegreesToDecimal(latlng) } else { return latlng } } function drawLineConfig(lat, lng, dataType) { return { latitude: getLatLng(lat, dataType), longitude: getLatLng(lng, dataType) }; } function addOvalPointConfig(lat, lng, imageName, dataType) { return { coordinate: { latitude: getLatLng(lat, dataType), longitude: getLatLng(lng, dataType) }, imageName: imageName }; } function getCrossPoint(points1, points2) { for(let point1 of points1) { for(let point2 of points2) { if (point1.point_id == point2.point_id) return point1 } } } function getAirwayPoints(airway, pointBefore, pointAfter) { let found = 0 let points = [] let pointTypeFix, pointsFix if ('points' in airway) { pointTypeFix = 'point_type'; pointsFix = 'points' } else { pointTypeFix = 'pointType' pointsFix = 'airlines' } // 如果前后是其他航线,那么找到交叉点作为前后的点 if ( pointBefore[pointTypeFix] == Global.pointTypes.line ) { pointBefore = getCrossPoint(airway[pointsFix], pointBefore[pointsFix]) } if(pointAfter[pointTypeFix] == Global.pointTypes.line) { pointAfter = getCrossPoint(airway[pointsFix], pointAfter[pointsFix]) } for (let point of airway[pointsFix]) { 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[pointsFix] } return points; } function getLinesRouter(lineProps, lineAndMarkerStyle) { let coordinates = new Array(); let markers = new Array(); let lines = [] let {imageName, lineWidth, strokeColor} = getDefaultStyle() if (lineAndMarkerStyle) { imageName = lineAndMarkerStyle.imageName lineWidth = lineAndMarkerStyle.lineWidth strokeColor = lineAndMarkerStyle.strokeColor } let startPoint, passPoints, endPoint, pointTypeFix, dataType if (lineProps.start_point) { dataType = 2 // 下划线模式 startPoint = lineProps['start_point'] passPoints = lineProps['passing_points'] endPoint = lineProps['end_point'] pointTypeFix = 'point_type'; } else { dataType = 1 // 驼峰模式 startPoint = lineProps['dep'] passPoints = lineProps['passPoints'] endPoint = lineProps['arrive'] pointTypeFix = 'pointType' } if (startPoint) { coordinates.push(drawLineConfig(startPoint.lat, startPoint.lng, dataType)); markers.push(addOvalPointConfig(startPoint.lat, startPoint.lng, imageName, dataType)); } 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[pointTypeFix] if ( pointType == Global.pointTypes.point || pointType == Global.pointTypes.nav) { coordinates.push(drawLineConfig(obj.lat, obj.lng, dataType)); markers.push(addOvalPointConfig(obj.lat, obj.lng, imageName, dataType)); } else { // 遇到一个航线,不需要和前前面的点连起来 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 : passPoints[i + 1] lines.push({lineWidth, strokeColor, coordinates: getAirwayPoints(obj, pointBefore, pointAfter)}) } } } if (endPoint) { coordinates.push(drawLineConfig(endPoint.lat, endPoint.lng, dataType)); markers.push(addOvalPointConfig(endPoint.lat, endPoint.lng, imageName, dataType)); } if (coordinates.length > 1) { lines.push({lineWidth, strokeColor, 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 {imageName, lineWidth, strokeColor, fillColor} = getDefaultStyle() if (polygonAndMarkerStyle) { imageName = polygonAndMarkerStyle.imageName lineWidth = polygonAndMarkerStyle.lineWidth strokeColor = polygonAndMarkerStyle.strokeColor fillColor = polygonAndMarkerStyle.fillColor } let pointsFix, dataType; if (polygonProps.points) { pointsFix = 'points'; dataType = 2 } else { pointsFix = 'polygonPoints'; dataType = 1 // 驼峰模式 } if (Array.isArray(polygonProps[pointsFix])) { for (let obj of polygonProps[pointsFix]) { coordinates.push(drawLineConfig(obj.lat, obj.lng, dataType)); markers.push(addOvalPointConfig(obj.lat, obj.lng, imageName, dataType)); } } let polygon = {lineWidth, strokeColor, fillColor, 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[i].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 null } else return (shapeName) => style[shapeName] } //获取selector export function getShapesSelector(airspaceInfos, style, currentAirspaceIndex) { 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) { let {markers, polygons, circles, lines, regionPoints} = getShapesSelector((airspaceInfos)=>airspaceInfos, style, currentAirspaceIndex) return { markers: markers(airspaceInfos), circles: circles(airspaceInfos), lines: lines(airspaceInfos), polygons: polygons(airspaceInfos), regionPoints: regionPoints(airspaceInfos) } }