public void createBackgroundMapsForLinearFeature(List<LINEAR_FEATURE> linearFeatures, String UTMZone, bool downloadMap) { /////////////////TODO -- put in a input file //////////////////////////////////////////////////////////////////////////// double maxIncrementAlonPathMeters = 5.0 * 5280.0 * 0.3048; // 5.0 miles //////////////////////////////////////////////////////////////////////////// for (int iFeat = 0; iFeat < linearFeatures.Count; iFeat++) { LINEAR_FEATURE linearFeature = linearFeatures[iFeat]; polygonMath polyMath = new polygonMath(linearFeature.EastingProNavS, linearFeature.NorthingProNavS, datasetFolder); UTM2Geodetic utm = new UTM2Geodetic(); linearFeature.NWMapCorner = new List<PointD>(); linearFeature.SEMapCorner = new List<PointD>(); linearFeature.mapNames = new List<string>(); //find a deltaRange along the path < maxIncrementAlonPathMeters such that deltaRange * N = totalPathLength int nMaps = (int)(linearFeature.pathLength / maxIncrementAlonPathMeters); //above gives a number of increments such that one additional increment will fall outside the endpoint. double incrementAlongPath = linearFeature.pathLength / (nMaps + 1); //this gives an incerment that is < maxIncrementAlonPathMeters such that //there will be nMaps+1 increments that end exactly on the end of the path //We will need nMaps + 2 maps with one map at the beginning and one map at the end int totalMaps = nMaps + 2; //this lets us put N equispaced 10mix10mi maps along the path. for (int i = 0; i < totalMaps; i++) { ///////////////////// //get a map ///////////////////// //build up the URL to retrieve the Google Map -- see the above model for the syntax //this zoom level gives ~ 10mi X 10mi int zoom = 12; //increment the path PointD pap = polyMath.pointAlongPathFromStart(i * incrementAlongPath); double latitude = 0.0, longitude = 0.0; utm.UTMtoLL(pap.Y, pap.X, UTMZone, ref latitude, ref longitude); setMap(zoom, new PointD(longitude, latitude)); /* below used only to get the width & height of the returned map with zoom = 12 double NWNorthing = 0.0, NWEasting = 0.0; double SENorthing = 0.0, SEEasting = 0.0; utm.LLtoUTM(mapNWCornerCordinates.Y * Constants.Deg2Rad, mapNWCornerCordinates.X * Constants.Deg2Rad, ref NWNorthing, ref NWEasting, ref UTMZone, true); utm.LLtoUTM(mapSECornerCordinates.Y * Constants.Deg2Rad, mapSECornerCordinates.X * Constants.Deg2Rad, ref SENorthing, ref SEEasting, ref UTMZone, true); double mapNSDimensionMi = (NWNorthing - SENorthing) / 0.3048 / 5280.0; double mapEWDimensionMi = (SEEasting - NWEasting) / 0.3048 / 5280.0; * */ linearFeature.NWMapCorner.Add(mapNWCornerCordinates); linearFeature.SEMapCorner.Add(mapSECornerCordinates); String GoogleMapsURL = "http://maps.googleapis.com/maps/api/staticmap?center=" + latitude.ToString() + "," + longitude.ToString() + "&zoom=" + zoom.ToString() + "&size=640x480&sensor=false"; //this downloads a map that can be opened --- need to figure out the scaling... //GoogleMapsURL = "http://dev.virtualearth.net/REST/v1/Imagery/Map/Road/Routes?wp.0=Seattle,WA;64;1&wp.1=Redmond,WA;66;2&key=" + // Constants.bingKey; //set the file storage location String backgroundImageFolder = datasetFolder + "\\" + polygonName + "_Background"; if (!Directory.Exists(backgroundImageFolder)) Directory.CreateDirectory(backgroundImageFolder); String SaveToFile = backgroundImageFolder + "\\linearMap_" + iFeat.ToString("D2") +"_" + i.ToString("D3") + ".png"; if (downloadMap) { //get the file from the web using a webClient getFileFromWeb(GoogleMapsURL, SaveToFile); } linearFeature.mapNames.Add(SaveToFile); } } }
void LinearFeaturePlanner(Polygon p, double flightAlt, double swathWidthKm, double aircraftSpeedKnots, double aircraftSpeedKPH, double DRImageHeightKm) { //if (p.polyCoverageType == COVERAGE_TYPE.linearFeature) //{ //show the "PLAN" button button3.Visible = true; button3.Enabled = true; /////////////////////////////////////////////////////////////////////////////////// // wait here til user clicks considers the coverage options and clicks: "PLAN" /////////////////////////////////////////////////////////////////////////////////// while (!MissionPlanningInitiated) { Application.DoEvents(); //wait for user inputs } //TODO //get the flyable aircraft paths that will cover the input linear feature path //there will be one linearFeature object for each of the parallel paths List<LINEAR_FEATURE> linearFeatures = linearFeatureCoverage(numParallelPaths, linearPathCentering, flightAlt, swathWidthKm * 1000.0, aircraftSpeedKnots * 0.514); //the above procedure writes kml files for forward, backward, & smoothed trajectory //also writes out the image boresight projection and the image endpoints as kml files GoogleMaps ggl = new GoogleMaps(datasetFolder, p.PolygonName); //get the project map for the path -- shows complete extent of the path and takeoff airport ggl.getGoogleMapToCoverProject(ref p, downloadMap); //get the path-segment maps that will be used to form a aircraft-centered sliding window map //get rectangular maps sized 10mi x 10mi at 5mi intervals along the path ggl.createBackgroundMapsForLinearFeature(linearFeatures, p.UTMZone, downloadMap); double totalPathDistance = 0.0; polygonMath polymath = new polygonMath(linearFeatures[0].EastingProNavS, linearFeatures[0].NorthingProNavS, datasetFolder); //get the along-path altitudes for (int iLF = 0; iLF < linearFeatures.Count; iLF++) { totalPathDistance += linearFeatures[iLF].pathLength; List<PointD> pointsAlongPath = new List<PointD>(); UTM2Geodetic utm = new UTM2Geodetic(); //create a sequence of points along path based on the smoothed trajectory for (int i = 0; i < linearFeatures[iLF].NorthingProNavS.Count; i++) { double lat = 0.0, lon = 0.0; utm.UTMtoLL(linearFeatures[iLF].NorthingProNavS[i], linearFeatures[iLF].EastingProNavS[i], p.UTMZone, ref lat, ref lon); pointsAlongPath.Add(new PointD(lon, lat)); } //get the terrain heights using the Google Elevation API linearFeatures[iLF].alongPathAltitude = polymath.getTerrainHeightsFromPointList(pointsAlongPath); //number of triggered images along the path linearFeatures[iLF].numImages = (int)(linearFeatures[iLF].pathLength / (DRImageHeightKm * 1000.0)); //get stats of the along-path altitudes double maxAlt = -99999.0, minAlt = 99999.0, meanAlt = 0.0; foreach (double alt in linearFeatures[iLF].alongPathAltitude) { if (alt > maxAlt) maxAlt = alt; if (alt < minAlt) minAlt = alt; meanAlt += alt; } meanAlt /= linearFeatures[iLF].alongPathAltitude.Count; linearFeatures[iLF].maxAltitude = maxAlt; linearFeatures[iLF].minAltitude = minAlt; linearFeatures[iLF].meanAltitude = meanAlt; linearFeatures[iLF].pathNumber = iLF; } //get the 2way ferry distance double total2WayFerryDistance = 0.0; //start: always start for 0th path to the selected airport //distance from selected airport to start of first line double delNS = linearFeatures[0].NorthingProNavS[0] - p.airports[selectedAirportIndex].northing; double delES = linearFeatures[0].EastingProNavS[0] - p.airports[selectedAirportIndex].easting; double distanceToAptS = Math.Sqrt(delNS * delNS + delES * delES); total2WayFerryDistance += distanceToAptS; //always return to the airport from the end of the last path int endIndex = linearFeatures[linearFeatures.Count - 1].NorthingProNavS.Count - 1; //distance from selected airport to start of first line delNS = linearFeatures[linearFeatures.Count - 1].NorthingProNavS[endIndex] - p.airports[selectedAirportIndex].northing; delES = linearFeatures[linearFeatures.Count - 1].EastingProNavS[endIndex] - p.airports[selectedAirportIndex].easting; distanceToAptS = Math.Sqrt(delNS * delNS + delES * delES); //final 2-way ferry distance is the sum of the to- and from- ferry distances total2WayFerryDistance += distanceToAptS; double totalPathTime = totalPathDistance / (aircraftSpeedKPH * 1000.0); int totalLFImages = (int)(totalPathDistance / (DRImageHeightKm * 1000.0)); writeKmlLinearFeatureMissonPlan(p, DRImageHeightKm, numParallelPaths, flightAlt, swathWidthKm, totalPathDistance, total2WayFerryDistance, aircraftSpeedKPH, totalPathTime, totalLFImages, linearFeatures); ////////////////////////////////////////////// //show the END button button2.Visible = true; button2.Enabled = true; ////////////////////////////////////////////// //wait here to see if the user clicks the "END" button while (true) { Application.DoEvents(); } //Environment.Exit(-1); //} //////////////////////// end of linear feature Planner ////////////////// }