Example #1
0
		/// <summary>
		/// Serialises a Rectangle into a TomTom skipper record
		/// </summary>
		/// <param name="Rectangle">The rectangle to serialise</param>
		/// <returns>The serialised rectangle</returns>
		private byte[] SerialiseRectangle(GeoRect Rectangle) {
			byte[] bReturn = new byte[SkipperStructSize];
			Int32 AllPOIsSize = SkipperStructSize;
			
			//Calculate Size of POIs
			foreach(POI CurrentPOI in Rectangle.POIs) {
				AllPOIsSize += GetPOISize(CurrentPOI);
			}
			
			//Serialise
			bReturn[0] = 0x01;
			ConvertToLEBytes(AllPOIsSize).CopyTo(bReturn, 1);
			ConvertToLEBytes((Int32)(Rectangle.TopRight.TomTomXPos)).CopyTo(bReturn, 5);
			ConvertToLEBytes((Int32)(Rectangle.TopRight.TomTomYPos)).CopyTo(bReturn, 9);
			ConvertToLEBytes((Int32)(Rectangle.BottomLeft.TomTomXPos)).CopyTo(bReturn, 13);
			ConvertToLEBytes((Int32)(Rectangle.BottomLeft.TomTomYPos)).CopyTo(bReturn, 17);

			return bReturn;
		}
Example #2
0
		/// <summary>
		/// Creates the OV2 file header
		/// </summary>
		/// <param name="BoundingRect">The full bounding rectangle for all POIs within the OV2</param>
		/// <param name="Rectangles">List containing all rectangles and POIs contained in the OV2</param>
		/// <param name="AllPOIs">A list of all POIs within all the calculated rectangles</param>
		/// <returns>The byte array file header</returns>
		private byte[] GenerateOV2Header(GeoRect BoundingRect, List<GeoRect> Rectangles, List<POI> AllPOIs) {
			byte[] bReturn = new byte[SkipperStructSize];
			Int32 Size = SkipperStructSize;

			//Calculate total size for every POI in the OV2
			foreach (POI CurrentPOI in AllPOIs) {
				Size += GetPOISize(CurrentPOI);
			}

			//Calculate total size of all skipper records in teh database
			Size += (Rectangles.Count * SkipperStructSize);

			//Serialise data
			bReturn[0] = 0x01;
			ConvertToLEBytes(Size).CopyTo(bReturn, 1);
			ConvertToLEBytes((Int32)(BoundingRect.TopRight.TomTomXPos)).CopyTo(bReturn, 5);
			ConvertToLEBytes((Int32)(BoundingRect.TopRight.TomTomYPos)).CopyTo(bReturn, 9);
			ConvertToLEBytes((Int32)(BoundingRect.BottomLeft.TomTomXPos)).CopyTo(bReturn, 13);
			ConvertToLEBytes((Int32)(BoundingRect.BottomLeft.TomTomYPos)).CopyTo(bReturn, 17);

			return bReturn;
		}
Example #3
0
		/// <summary>
		/// Calculates the full dounding rectangle around a list of POIs
		/// </summary>
		/// <param name="POIs">The list of POIs</param>
		/// <returns>The bounding rectangle</returns>
		private GeoRect CalculateBoundingRect(List<POI> POIs) {
			GeoRect ReturnRect = new GeoRect();
			
			//Initialise rect with max/min values
			ReturnRect.BottomLeft.x = 90;	//West co-ordinates are negative, so set to max value
			ReturnRect.BottomLeft.y = 180;	//South co-ordinates are negative, so set to max value
			ReturnRect.TopRight.x = -90;	//East co-ordinates are positive, so set to min value
			ReturnRect.TopRight.y = -180;	//North co-ordinates are positive, so set to min value
			
			//For all POIs
			foreach(POI CurrentPOI in POIs) {
				//Calculate bounding rectangle for all POIs
				if (CurrentPOI.Long < ReturnRect.BottomLeft.x) {
					ReturnRect.BottomLeft.x = CurrentPOI.Long;
				}
				if (CurrentPOI.Long > ReturnRect.TopRight.x) {
					ReturnRect.TopRight.x = CurrentPOI.Long;
				}
				if (CurrentPOI.Lat < ReturnRect.BottomLeft.y) {
					ReturnRect.BottomLeft.y = CurrentPOI.Lat;
				}
				if (CurrentPOI.Lat > ReturnRect.TopRight.y) {
					ReturnRect.TopRight.y = CurrentPOI.Lat;
				}
			}
			
			//All POIs are in this rectangle
			ReturnRect.POIs = POIs;
			
			return ReturnRect;
		}
Example #4
0
		/// <summary>
		/// Splits a rectangle along its longest side
		/// </summary>
		/// <param name="Rectangle">The ectangle to split</param>
		/// <returns>A list containing the split rectangles</returns>
		private List<GeoRect> SplitRectangle(GeoRect Rectangle) {
			List<GeoRect> lReturn = new List<GeoRect>();
			
			double NorthSouthDistance = GeoDifference(Rectangle.BottomLeft.y, Rectangle.TopRight.y);
			double WestEastDifference = GeoDifference(Rectangle.BottomLeft.x, Rectangle.TopRight.x);

			//Is the North to South line the longest?
			if (NorthSouthDistance >= WestEastDifference) {
				//Split rectangle along North-South
				GeoRect TopRect = new GeoRect(	new GeoPoint(Rectangle.BottomLeft.x, Rectangle.BottomLeft.y + (NorthSouthDistance / 2)),
												new GeoPoint(Rectangle.TopRight.x, Rectangle.TopRight.y)
											  );
				GeoRect BottomRect = new GeoRect(	new GeoPoint(Rectangle.BottomLeft.x, Rectangle.BottomLeft.y),
													new GeoPoint(Rectangle.TopRight.x, Rectangle.TopRight.y - (NorthSouthDistance / 2))
												);
				
				//Add new rectangles to array
				lReturn.Add(TopRect);
				lReturn.Add(BottomRect);

			}
			//The West to East line is longest
			else {
				//Split rectangle along West-East
				GeoRect LeftRect = new GeoRect(	new GeoPoint(Rectangle.BottomLeft.x, Rectangle.BottomLeft.y),
												new GeoPoint(Rectangle.TopRight.x - (WestEastDifference / 2), Rectangle.TopRight.y)
											  );
				GeoRect RightRect = new GeoRect(	new GeoPoint(Rectangle.BottomLeft.x + (WestEastDifference / 2), Rectangle.BottomLeft.y),
													new GeoPoint(Rectangle.TopRight.x, Rectangle.TopRight.y)
												);
				
				//Add new rectangles to array
				lReturn.Add(LeftRect);
				lReturn.Add(RightRect);
			}
			
			return lReturn;
		}
Example #5
0
		/// <summary>
		/// Determins if the rectangle is equal to or smaller than the minimum size of a POI bounding rectangle
		/// </summary>
		/// <param name="Rectangle">The Rectangle</param>
		/// <returns>True if the rectangle is equal to or smaller than the minimum size for a POI bounding rectangle</returns>
		private bool RectangleIsMinSize(GeoRect Rectangle) {
			bool bReturn = false;
			
			if(	GeoDifference(Rectangle.BottomLeft.x, Rectangle.TopRight.x) <= minRectSize.Width &&
				GeoDifference(Rectangle.BottomLeft.y, Rectangle.TopRight.y) <= minRectSize.Height) {
					bReturn = true;
			}
			
			return bReturn;
		}
Example #6
0
		/// <summary>
		/// Creates a list of rectangles with a maximum of 'MaxPOIsInRectangle' POIs in each rectangle
		/// </summary>
		/// <param name="Rectangles">The rectangles to process</param>
		/// <returns>A list containing the processed rectangles</returns>
		private List<GeoRect> ProcessPOIs(GeoRect BoundingRectangle) {
			List<GeoRect> lReturn = new List<GeoRect>();
			bool bSplitRect = true;
			int i = 0;
			GeoRect CurrentRect = null;
			List<GeoRect> RectsToProcess = new List<GeoRect>();
			List<GeoRect> ProcessedRects = null;
			
			//Initialise rectangles to process with full bounding rectangle
			RectsToProcess.Add(BoundingRectangle);
			
			//Keep looping until we do not split anything! - Replaced recurrsive call with loop due to stack overflows with large areas!
			while(bSplitRect) {
				bSplitRect = false;
				ProcessedRects = new List<GeoRect>();
				
				for(i = 0; i < RectsToProcess.Count; i++) {
					CurrentRect = RectsToProcess[i];
					if(CurrentRect.POIs.Count > maxPOIsInRectangle && !RectangleIsMinSize(CurrentRect)) {
						//Split the rectangle into 2
						List<GeoRect> SplitRectangles = SplitRectangle(CurrentRect);

						//Determine which POIs reside in which of the split rectangles
						DeterminePOIsInSplitRectangles(SplitRectangles, CurrentRect.POIs);
						
						//Add our 2 new rectangles for further processing
						ProcessedRects.AddRange(SplitRectangles);
						
						//We have split the rectangle!
						bSplitRect = true;
					}
					else if (CurrentRect.POIs.Count != 0) {
						lReturn.Add(CurrentRect);
					}
				}
				
				RectsToProcess = new List<GeoRect>(ProcessedRects);
			}
			
			return lReturn;
		}