From: <lk...@us...> - 2007-08-08 10:14:02
|
Revision: 812 http://mp-plugins.svn.sourceforge.net/mp-plugins/?rev=812&view=rev Author: lkuech Date: 2007-08-08 03:14:00 -0700 (Wed, 08 Aug 2007) Log Message: ----------- Added Paths: ----------- trunk/plugins/WorldMap/GUIWorldMap.csproj trunk/plugins/WorldMap/MAPS/ trunk/plugins/WorldMap/MAPS/ImageFunctions.cs trunk/plugins/WorldMap/MAPS/MapFunctions.cs trunk/plugins/WorldMap/MAPS/MapTile.cs trunk/plugins/WorldMap/MAPS/MapTiles.cs trunk/plugins/WorldMap/MAPS/SearchGeoCodes.cs trunk/plugins/WorldMap/MAPS/ThreadedDownload.cs trunk/plugins/WorldMap/MAPS/TileCacheDatabase.cs trunk/plugins/WorldMap/NewVirtualKeyboard.cs trunk/plugins/WorldMap/PlugInBase.cs trunk/plugins/WorldMap/Properties/ trunk/plugins/WorldMap/Properties/AssemblyInfo.cs trunk/plugins/WorldMap/Properties/Resources.Designer.cs trunk/plugins/WorldMap/Properties/Resources.resx trunk/plugins/WorldMap/Resources/ trunk/plugins/WorldMap/Settings.cs trunk/plugins/WorldMap/WorldMap.cs trunk/plugins/WorldMap/WorldMapSearchResults.cs trunk/plugins/WorldMap/WorldmapConfig.Designer.cs trunk/plugins/WorldMap/WorldmapConfig.cs trunk/plugins/WorldMap/WorldmapConfig.resx trunk/plugins/WorldMap/WorldmapMenu.cs trunk/plugins/WorldMap/WorldmapSearch.cs trunk/plugins/WorldMap/mediaTemplates/ trunk/plugins/WorldMap/mediaTemplates/Thumbs.db trunk/plugins/WorldMap/mediaTemplates/WMprogressBarActive.png trunk/plugins/WorldMap/mediaTemplates/WMprogressBarActive.pspimage trunk/plugins/WorldMap/skinFiles/ trunk/plugins/WorldMap/skinFiles/BlueTwo/ trunk/plugins/WorldMap/skinFiles/BlueTwo/Media/ trunk/plugins/WorldMap/skinFiles/BlueTwo/Media/WMIPBlocked.jpeg trunk/plugins/WorldMap/skinFiles/BlueTwo/Media/WMTileNotAvailable.jpeg trunk/plugins/WorldMap/skinFiles/BlueTwo/Media/WMTilePlaceholder.jpeg trunk/plugins/WorldMap/skinFiles/BlueTwo/Media/WMprogressBarActive.png trunk/plugins/WorldMap/skinFiles/BlueTwo/Media/WMprogressBarQueued.png trunk/plugins/WorldMap/skinFiles/BlueTwo/Media/WMprogressDummy.png trunk/plugins/WorldMap/skinFiles/BlueTwo/Media/hover_worldmap.png trunk/plugins/WorldMap/skinFiles/BlueTwo/MyWorldMap.xml trunk/plugins/WorldMap/skinFiles/BlueTwo/MyWorldmapMenu.xml trunk/plugins/WorldMap/skinFiles/BlueTwo/MyWorldmapSearch.xml trunk/plugins/WorldMap/skinFiles/BlueTwo/MyWorldmapSearchResults.xml trunk/plugins/WorldMap/skinFiles/BlueTwo wide/ trunk/plugins/WorldMap/skinFiles/BlueTwo wide/Media/ trunk/plugins/WorldMap/skinFiles/BlueTwo wide/Media/WMIPBlocked.jpeg trunk/plugins/WorldMap/skinFiles/BlueTwo wide/Media/WMTileNotAvailable.jpeg trunk/plugins/WorldMap/skinFiles/BlueTwo wide/Media/WMTilePlaceholder.jpeg trunk/plugins/WorldMap/skinFiles/BlueTwo wide/Media/WMprogressBarActive.png trunk/plugins/WorldMap/skinFiles/BlueTwo wide/Media/WMprogressBarQueued.png trunk/plugins/WorldMap/skinFiles/BlueTwo wide/Media/WMprogressDummy.png trunk/plugins/WorldMap/skinFiles/BlueTwo wide/Media/hover_worldmap.png trunk/plugins/WorldMap/skinFiles/BlueTwo wide/MyWorldMap.xml trunk/plugins/WorldMap/skinFiles/BlueTwo wide/MyWorldmapMenu.xml trunk/plugins/WorldMap/skinFiles/BlueTwo wide/MyWorldmapSearch.xml trunk/plugins/WorldMap/skinFiles/BlueTwo wide/MyWorldmapSearchResults.xml Added: trunk/plugins/WorldMap/GUIWorldMap.csproj =================================================================== --- trunk/plugins/WorldMap/GUIWorldMap.csproj (rev 0) +++ trunk/plugins/WorldMap/GUIWorldMap.csproj 2007-08-08 10:14:00 UTC (rev 812) @@ -0,0 +1,109 @@ +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>8.0.50727</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{857D8A0C-FB95-4A26-8ED6-8E51586D2116}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>GUIWorldmap</RootNamespace> + <AssemblyName>GUIWorldmap</AssemblyName> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="Core, Version=0.2.2.0, Culture=neutral, processorArchitecture=x86"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\Core\bin\Debug\Core.dll</HintPath> + </Reference> + <Reference Include="Dialogs, Version=0.0.0.0, Culture=neutral, processorArchitecture=x86"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\Dialogs\bin\Debug\Dialogs.dll</HintPath> + </Reference> + <Reference Include="Microsoft.DirectX, Version=1.0.2902.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> + <Reference Include="Microsoft.DirectX.Direct3D, Version=1.0.2902.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> + <Reference Include="Microsoft.DirectX.Direct3DX, Version=1.0.2911.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> + <Reference Include="Microsoft.DirectX.DirectDraw, Version=1.0.2902.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> + <Reference Include="System" /> + <Reference Include="System.Data" /> + <Reference Include="System.Data.SQLite, Version=1.0.41.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x86"> + <SpecificVersion>False</SpecificVersion> + <HintPath>bin\Debug\System.Data.SQLite.DLL</HintPath> + </Reference> + <Reference Include="System.Drawing" /> + <Reference Include="System.Windows.Forms" /> + <Reference Include="System.Xml" /> + <Reference Include="Utils, Version=2.1.2.0, Culture=neutral, processorArchitecture=x86"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\Utils\bin\Debug\Utils.dll</HintPath> + </Reference> + </ItemGroup> + <ItemGroup> + <Compile Include="Properties\Resources.Designer.cs"> + <AutoGen>True</AutoGen> + <DesignTime>True</DesignTime> + <DependentUpon>Resources.resx</DependentUpon> + </Compile> + <Compile Include="WorldmapConfig.cs"> + <SubType>Form</SubType> + </Compile> + <Compile Include="WorldmapConfig.Designer.cs"> + <DependentUpon>WorldmapConfig.cs</DependentUpon> + </Compile> + <Compile Include="MAPS\ImageFunctions.cs" /> + <Compile Include="MAPS\MapFunctions.cs" /> + <Compile Include="MAPS\MapTile.cs" /> + <Compile Include="MAPS\MapTiles.cs" /> + <Compile Include="MAPS\SearchGeoCodes.cs" /> + <Compile Include="MAPS\ThreadedDownload.cs" /> + <Compile Include="MAPS\TileCacheDatabase.cs" /> + <Compile Include="NewVirtualKeyboard.cs" /> + <Compile Include="Settings.cs" /> + <Compile Include="WorldMap.cs" /> + <Compile Include="PlugInBase.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="WorldmapMenu.cs" /> + <Compile Include="WorldmapSearch.cs" /> + <Compile Include="WorldMapSearchResults.cs" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="WorldmapConfig.resx"> + <SubType>Designer</SubType> + <DependentUpon>WorldmapConfig.cs</DependentUpon> + </EmbeddedResource> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Properties\Resources.resx"> + <SubType>Designer</SubType> + <Generator>ResXFileCodeGenerator</Generator> + <LastGenOutput>Resources.Designer.cs</LastGenOutput> + </EmbeddedResource> + </ItemGroup> + <ItemGroup> + <Folder Include="Resources\" /> + </ItemGroup> + <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project> \ No newline at end of file Added: trunk/plugins/WorldMap/MAPS/ImageFunctions.cs =================================================================== --- trunk/plugins/WorldMap/MAPS/ImageFunctions.cs (rev 0) +++ trunk/plugins/WorldMap/MAPS/ImageFunctions.cs 2007-08-08 10:14:00 UTC (rev 812) @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; +using System.Drawing.Drawing2D; + +namespace MAPS +{ + class ImageFunctions + { + public static Bitmap MergeBitmaps(Bitmap Background, Bitmap Overlay) + { + Graphics graphics = Graphics.FromImage(Background); + graphics.DrawImage(Overlay, 0, 0, Background.Width, Background.Height); + + return new Bitmap(Background); + } + + public static Bitmap GetUpperLeftPart(Bitmap Tile) + { + Bitmap tmpBitmap = new Bitmap(256,256); + Graphics graphic = Graphics.FromImage(tmpBitmap); + + Rectangle tmpDestRect = new Rectangle(0,0,Tile.Width,Tile.Height);; + Rectangle tmpSourceRect = new Rectangle(0, 0, 128, 128); + + graphic.DrawImage(tmpBitmap,tmpDestRect,0,0,128,128,GraphicsUnit.Pixel); + //(Tile, 0, 0, tmpSourceRect, GraphicsUnit.Pixel) + + return tmpBitmap; + } + + public static Bitmap GetUpperRightPart(Bitmap Tile) + { + Bitmap tmpBitmap = new Bitmap(256, 256); + Graphics graphic = Graphics.FromImage(tmpBitmap); + + Rectangle tmpDestRect = new Rectangle(0, 0, Tile.Width, Tile.Height); ; + Rectangle tmpSourceRect = new Rectangle(129, 0, 256, 128); + + graphic.DrawImage(tmpBitmap, tmpDestRect, 129, 0, 256, 128, GraphicsUnit.Pixel); + + return tmpBitmap; + + } + + public static Bitmap GetLowerLeftPart(Bitmap Tile) + { + Bitmap tmpBitmap = new Bitmap(256, 256); + Graphics graphic = Graphics.FromImage(tmpBitmap); + + Rectangle tmpDestRect = new Rectangle(0, 0, Tile.Width, Tile.Height); ; + Rectangle tmpSourceRect = new Rectangle(0, 129, 128, 256); + + graphic.DrawImage(tmpBitmap, tmpDestRect, 0, 129, 128, 256, GraphicsUnit.Pixel); + + return tmpBitmap; + } + + public static Bitmap GetLowerRightPart(Bitmap Tile) + { + Bitmap tmpBitmap = new Bitmap(256, 256); + Graphics graphic = Graphics.FromImage(tmpBitmap); + + Rectangle tmpDestRect = new Rectangle(0, 0, Tile.Width, Tile.Height); ; + Rectangle tmpSourceRect = new Rectangle(129, 129, 256, 256); + + graphic.DrawImage(tmpBitmap, tmpDestRect, 129, 129, 256, 256, GraphicsUnit.Pixel); + + return tmpBitmap; + } + + + } +} + + Added: trunk/plugins/WorldMap/MAPS/MapFunctions.cs =================================================================== --- trunk/plugins/WorldMap/MAPS/MapFunctions.cs (rev 0) +++ trunk/plugins/WorldMap/MAPS/MapFunctions.cs 2007-08-08 10:14:00 UTC (rev 812) @@ -0,0 +1,434 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MAPS +{ + public class MapFunctions + { + public enum MapType + { + GMRoad, + GMAerial, + GMHybrid, + VERoad, + VEAerial, + VEHybrid + } + + public static MapType GetNextMapType(MapType currentMapType) + { + Array tmpMapTypes = Enum.GetValues(typeof(MapFunctions.MapType)); + int IntMapType = Convert.ToInt32(currentMapType); + IntMapType++; + if (IntMapType > tmpMapTypes.Length - 1) IntMapType = 0; + return (MapFunctions.MapType)(Enum.ToObject(typeof(MapFunctions.MapType), IntMapType)); + } + + public static MapType GetNextRoadMap(MapType currentMapType) + { + if (currentMapType == MapType.GMAerial || currentMapType == MapType.GMHybrid) return MapType.GMRoad; + if (currentMapType == MapType.VEAerial || currentMapType == MapType.VEHybrid) return MapType.VERoad; + if (currentMapType == MapType.GMRoad) return MapType.VERoad; + + return MapType.GMRoad; + } + + public static MapType GetNextSateliteMap(MapType currentMapType) + { + if (currentMapType == MapType.GMRoad || currentMapType == MapType.GMHybrid) return MapType.GMAerial; + if (currentMapType == MapType.VERoad || currentMapType == MapType.VEHybrid) return MapType.VEAerial; + if (currentMapType == MapType.GMAerial) return MapType.VEAerial; + + return MapType.GMAerial; + } + + public static MapType GetNextHybridMap(MapType currentMapType) + { + if (currentMapType == MapType.GMAerial || currentMapType == MapType.GMRoad) return MapType.GMHybrid; + if (currentMapType == MapType.VEAerial || currentMapType == MapType.VERoad) return MapType.VEHybrid; + if (currentMapType == MapType.GMHybrid) return MapType.VEHybrid; + + return MapType.GMHybrid; + } + + /// <summary> + /// Get the vertical tile number from a latitude using mercator ptrojection formula + /// </summary> + public static int ConvertLatitudeToTileY(double latitude, int zoomLevel) + { + double maxlat = Math.PI; + + double lat = latitude; + + if (lat > 90) lat = lat - 180; + if (lat < -90) lat = lat + 180; + + // conversion degre=>radians + double phi = Math.PI * lat / 180; + + double res; + //double temp = Math.Tan(Math.PI / 4 - phi / 2); + //res = Math.Log(temp); + res = 0.5 * Math.Log((1 + Math.Sin(phi)) / (1 - Math.Sin(phi))); + double maxTileY = Math.Pow(2, zoomLevel); + int result = (int)(((1 - res / maxlat) / 2) * (maxTileY)); + + return (result); + } + + /// <summary> + /// Get the horizontal tile number from a longitude using mercator ptrojection formula + /// </summary> + public static int ConvertLongitudeToTileX(double longitude, int zoomLevel) + { + if (longitude > 180) + { + longitude = longitude - 360; + } + if (longitude < -180) + { + longitude = longitude + 360; + } + + double res = (longitude + 180) / 360; + return (int)(res * Math.Pow(2, zoomLevel)); + } + + /// <summary> + /// get latitude/longitude mini of a tile + /// </summary> + //private PointF getMinBounds(int numlat, int numlong, int zoom) + //{ + // PointF res = new PointF(); + + // double maxlat = Math.PI; + // double maxTile = Math.Pow(2, zoom); + // double numlatrel = maxlat * (1 - 2 * ((numlat + 1) / maxTile)); + + // res.Y = (float)((2 * Math.Atan(Math.Exp(numlatrel)) - Math.PI / 2) * 180 / Math.PI); + // res.X = (float)(360 * (numlong / maxTile) - 180); + // return res; + //} + + /** get latitude/longitude maxi of a tile*/ + //private PointF getMaxBounds(int numlat, int numlong, int zoom) + //{ + // PointF res = new PointF(); + // double maxlat = Math.PI; + // double maxTile = Math.Pow(2, zoom); + // double numlatrel = maxlat * (1 - 2 * (numlat / maxTile)); + + // res.Y = (float)((2 * Math.Atan(Math.Exp(numlatrel)) - Math.PI / 2) * 180 / Math.PI); + // res.X = (float)(360 * (numlong + 1) / maxTile - 180); + // return res; + //} + + + public static double ConvertTileXToLongitude(int TileX, int ZoomLevel) + { + double maxTile = Math.Pow(2, ZoomLevel); + return (float)(360 * (TileX ) / maxTile - 180); + } + + public static double ConvertTileYToLatitude(int TileY, int ZoomLevel) + { + double maxlat = Math.PI; + double maxTile = Math.Pow(2, ZoomLevel); + double numlatrel = maxlat * (1 - 2 * (TileY / maxTile)); + + return (float)((2 * Math.Atan(Math.Exp(numlatrel)) - Math.PI / 2) * 180 / Math.PI); + } + + public static double ConvertZoomLevelToTileSizeDegree(int zoomLevel) + { + double LevelTileSizeDegrees = 360; + + for (int i = 1; i <= zoomLevel; i++) + { + LevelTileSizeDegrees /= 2; + } + return LevelTileSizeDegrees; + } + + public static int ConvertTileSizeDegreeToZoomLevel(double TileSizeDegree) + { + int zoomLevel = 0; + while (TileSizeDegree < 360) + { + TileSizeDegree *= 2; + zoomLevel++; + } + return zoomLevel; + } + + public static string GetGMapSatUrl(double Longitude, double Latitude, int zoomLevel, ref MapConfig curConfig) + { + return GetGMapSatUrl(ConvertLongitudeToTileX(Longitude, zoomLevel), ConvertLatitudeToTileY(Latitude, zoomLevel), zoomLevel, ref curConfig); + } + + public static string GetGMapSatUrl(int TileX, int TileY, int zoomLevel, ref MapConfig curConfig) + { + string tileCode = GetGMapSatUrlTileCode(TileX, TileY, zoomLevel); + if(tileCode=="") return ""; + + int servNum = -1; + + try + { + switch (tileCode[tileCode.Length - 1]) + { + case 'q': servNum = 0; + break; + case 'r': servNum = 1; + break; + case 's': servNum = 2; + break; + case 't': servNum = 3; + break; + } + } + catch (Exception err) + { } + + string StringServNum; + if (servNum == -1) StringServNum = ""; + else StringServNum = servNum.ToString(); + + string fullurl = string.Format(curConfig.GMAUrl,StringServNum, tileCode); + if (tileCode == "transparent") + { + //fullurl = "http://www.google.com/intl/en_ALL/mapfiles/transparent.png"; + fullurl = "***"; + } + return fullurl; + } + + public static string GetGMapSatUrlTileCode(int TileX, int TileY, int zoomLevel) + { + string tileid = "t"; + double halflat = TileY; /**/ + double locxmin, locxmax, locymin, locymax, locxmoy, locymoy; + + locxmin = 0; locxmax = Math.Pow(2, zoomLevel); + locymin = 0; locymax = Math.Pow(2, zoomLevel); + + for (int i = 0; i < zoomLevel; i++) + { + locxmoy = (locxmax + locxmin) / 2; + locymoy = (locymax + locymin) / 2; + if ((halflat < locymin) || + (halflat > locymax) || + (TileX < locxmin) || + (TileX > locxmax)) + { + return ("transparent"); + } + if (halflat < locymoy) + { + locymax = locymoy; + if (TileX < locxmoy) + { /*q quadrant (top left)*/ + tileid += "q"; + locxmax = locxmoy; + } + else + {/*r quadrant (top right)*/ + tileid += "r"; + locxmin = locxmoy; + } + } + else + { + locymin = locymoy; + if (TileX < locxmoy) + { /*t quadrant (bottom right)*/ + tileid += "t"; + locxmax = locxmoy; + } + else + {/*s quadrant (bottom left)*/ + tileid += "s"; + locxmin = locxmoy; + } + } + } + return tileid; + + + } + + public static string GetGMapUrl(int TileX, int TileY, int zoomLevel, ref MapConfig curConfig) + { + string tileCode = GetGMapSatUrlTileCode(TileX, TileY, zoomLevel); + if (tileCode == "") return ""; + + int servNum = -1; + + try + { + switch (tileCode[tileCode.Length - 1]) + { + case 'q': servNum = 0; + break; + case 'r': servNum = 1; + break; + case 's': servNum = 2; + break; + case 't': servNum = 3; + break; + } + } + catch (Exception err) + { } + + string StringServNum; + if (servNum == -1) StringServNum = ""; + else StringServNum = servNum.ToString(); + + string TileCode = GetGMapTileCode(TileX, TileY, zoomLevel); + string[] urltab = TileCode.Split('_'); + string fullurl = string.Format(curConfig.GMRUrl, StringServNum, urltab[0],urltab[1],urltab[2]); + return fullurl; + + } + + public static string GetGHybridOverlayUrl(int TileX, int TileY, int zoomLevel, ref MapConfig curConfig) + { + string tileCode = GetGMapSatUrlTileCode(TileX, TileY, zoomLevel); + if (tileCode == "") return ""; + + int servNum = -1; + + try + { + switch (tileCode[tileCode.Length - 1]) + { + case 'q': servNum = 0; + break; + case 'r': servNum = 1; + break; + case 's': servNum = 2; + break; + case 't': servNum = 3; + break; + } + } + catch (Exception err) + { } + + string StringServNum; + if (servNum == -1) StringServNum = ""; + else StringServNum = servNum.ToString(); + + string TileCode = GetGMapTileCode(TileX, TileY, zoomLevel); + string[] urltab = TileCode.Split('_'); + string fullurl = string.Format(curConfig.GMHUrl, StringServNum, urltab[0], urltab[1], urltab[2]); // a small "t" make the big differens + return fullurl; + } + + public static string GetGMapTileCode(int TileX, int TileY, int zoomLevel) + { + int localzoom = (17 - zoomLevel); + string tileid = ""; + double numLong = (int)TileX; + double numLat = (int)TileY; + tileid = numLong.ToString() + "_" + ((int)numLat).ToString() + "_" + localzoom.ToString(); + return tileid; + } + + public static string GetGMTileUrl(MapType mapType, int TileX, int TileY, int zoomLevel, ref MapConfig curConfig) + { + string url = null; + switch (mapType) + { + case MapType.GMRoad: url = GetGMapUrl(TileX, TileY, zoomLevel, ref curConfig); + break; + case MapType.GMAerial: url = GetGMapSatUrl(TileX, TileY, zoomLevel, ref curConfig); + break; + case MapType.GMHybrid: url = GetGMapSatUrl(TileX, TileY, zoomLevel, ref curConfig); + break; + } + return url; + } + + public static string GetVETileUrl(MapType mapType, int TileX, int TileY, int zoomLevel, ref MapConfig curConfig) + { + string url = null; + string mapTypePreFix = null; + string mapExtension = null; + switch (mapType) + { + case MapType.VERoad: + { + mapTypePreFix = "r"; + mapExtension = ".png"; + } + break; + case MapType.VEAerial: + { + mapTypePreFix = "a"; + mapExtension = ".jpeg"; + } + break; + case MapType.VEHybrid: + { + mapTypePreFix = "h"; + mapExtension = ".jpeg"; + } + break; + } + + string quadKey = VETileToQuadKey(TileX, TileY, zoomLevel); + try + { + url = string.Format(curConfig.VEUrl, mapTypePreFix, quadKey[quadKey.Length - 1], quadKey, mapExtension); + } + catch(Exception err) + { } + return url; + } + + public static string VETileToQuadKey(int TileX, int TileY, int zoomLevel) + { + string quad = ""; + + for (int i = zoomLevel; i > 0; i--) + { + int mask = 1 << (i - 1); + int cell = 0; + + if ((TileX & mask) != 0) + { + cell++; + } + + if ((TileY & mask) != 0) + { + cell += 2; + } + quad += cell; + } + return quad; + } + + public static string GetTileUrl(MapType mapType, int TileX, int TileY, int zoomLevel, ref MapConfig curConfig) + { + string url = null; + + switch (mapType) + { + case MapType.GMAerial: + case MapType.GMHybrid: + case MapType.GMRoad: url = GetGMTileUrl(mapType,TileX,TileY,zoomLevel, ref curConfig); + break; + case MapType.VERoad: + case MapType.VEAerial: + case MapType.VEHybrid: url = GetVETileUrl(mapType, TileX, TileY, zoomLevel, ref curConfig); + break; + } + + return url; + } + } +} Added: trunk/plugins/WorldMap/MAPS/MapTile.cs =================================================================== --- trunk/plugins/WorldMap/MAPS/MapTile.cs (rev 0) +++ trunk/plugins/WorldMap/MAPS/MapTile.cs 2007-08-08 10:14:00 UTC (rev 812) @@ -0,0 +1,120 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; + +namespace MAPS +{ + public delegate void ImageChangedEventHandler(object sender, ImageChangedEventArgs e); + + public class ImageChangedEventArgs : EventArgs + { + private int TileX, TileY, ZoomMode; + public ImageChangedEventArgs(int tileX, int tileY, int zoomMode) + { + this.TileX = tileX; + this.TileY = tileY; + this.ZoomMode = zoomMode; + } + } + + public class MapTile + { + public event ImageChangedEventHandler ImageChangedEvent; + + protected virtual void OnImageChangedEvent(ImageChangedEventArgs e) + { + ImageChangedEvent(this, e); + } + + MapFunctions.MapType _mapType; + private int _PosX; + private int _PosY; + private int _ZoomLevel; + private double _LeftLongitude; + private double _RightLongitude; + private double _TopLatitude; + private double _BottomLatitude; + private double _TileWidthDegree; + private double _TileHeightDegree; + + private Bitmap _Image; + + public MapFunctions.MapType MapType + { + get { return _mapType; } + } + public int PosX + { + get { return _PosX; } + } + public int PosY + { + get { return _PosY; } + } + public int ZoomLevel + { + get { return _ZoomLevel; } + } + public double LeftLongitude + { + get { return _LeftLongitude; } + } + public double RigthLongitude + { + get { return _RightLongitude; } + } + public double TopLatitude + { + get { return _TopLatitude; } + } + public double BottomLatitude + { + get { return _BottomLatitude; } + } + public double TileWidthDegree + { + get { return _TileWidthDegree; } + } + public double TileHeightDegree + { + get { return _TileHeightDegree; } + } + public Bitmap Image + { + get { return _Image;} + set + { + _Image = value; + OnImageChangedEvent(new ImageChangedEventArgs(_PosX, _PosY, _ZoomLevel)); + } + } + + public MapTile(MapFunctions.MapType mapType, int TileX, int TileY, int ZoomLevel) + { + _mapType = mapType; + + _PosX = TileX; + _PosY = TileY; + + _ZoomLevel = ZoomLevel; + _TileWidthDegree = MapFunctions.ConvertZoomLevelToTileSizeDegree(_ZoomLevel); + + _LeftLongitude = MapFunctions.ConvertTileXToLongitude(_PosX, _ZoomLevel); + _RightLongitude = MapFunctions.ConvertTileXToLongitude(_PosX+1, _ZoomLevel); + + _TopLatitude = MapFunctions.ConvertTileYToLatitude(_PosY, _ZoomLevel); + _BottomLatitude = MapFunctions.ConvertTileYToLatitude(_PosY+1, _ZoomLevel); + + _TileWidthDegree = RigthLongitude - LeftLongitude; + if (_TileWidthDegree < 0) _TileWidthDegree *= -1; + + _TileHeightDegree = BottomLatitude - TopLatitude; + if (_TileHeightDegree < 0) _TileHeightDegree *= -1; + + _Image = new Bitmap(256, 256); + + } + + } +} Added: trunk/plugins/WorldMap/MAPS/MapTiles.cs =================================================================== --- trunk/plugins/WorldMap/MAPS/MapTiles.cs (rev 0) +++ trunk/plugins/WorldMap/MAPS/MapTiles.cs 2007-08-08 10:14:00 UTC (rev 812) @@ -0,0 +1,198 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; +using System.Threading; + +namespace MAPS +{ + public class MapConfig + { + public string CacheFolder; + public int ThreadCountGMR; + public int ThreadCountGMA; + public int ThreadCountGMH; + public int ThreadCountVER; + public int ThreadCountVEA; + public int ThreadCountVEH; + public int DaysToKeepCachedDetailedTiles; + public int DaysToKeepCachedOverviewTiles; + public string GMAUrl; + public string GMRUrl; + public string GMHUrl; + public string VEUrl; + public Bitmap TileNotAvailable; + public Bitmap IPBlocked; + public Bitmap DownloadPlaceholder; + + public MapConfig() + { + CacheFolder = "C:\\"; + ThreadCountGMR = 4; + ThreadCountGMA = 1; + ThreadCountGMH = 1; + ThreadCountVER = 5; + ThreadCountVEA = 5; + ThreadCountVEH = 5; + DaysToKeepCachedDetailedTiles = 30; + DaysToKeepCachedDetailedTiles = 200; + } + } + + public delegate void CombinedImageChangedEventHandler(object sender, ImageChangedEventArgs e); + + public class MapTiles + { + public event CombinedImageChangedEventHandler CombinedImageChangedEvent; + + public MapConfig mapConfig; + + public ThreadedDownload ImageGrabber; + public MapTile[][] Tiles; + + public int ImageResolutionX; + public int ImageResolutionY; + + public int TileCountX; + public int TileCountY; + + public int StartTileX; + public int StartTileY; + + public double Longitude; + public double Latitude; + + public int OffsetX; + public int OffsetY; + + public int ZoomLevel; + public MapFunctions.MapType mapType; + + public Bitmap combinedTiles; + public Bitmap croppedCombinedTiles; + + public MapTiles(int ImageResulotionX, int ImageResulotionY, MapConfig mapConfig) + { + this.ImageResolutionX = ImageResulotionX; + this.ImageResolutionY = ImageResulotionY; + + this.mapConfig = mapConfig; + + ImageGrabber = new ThreadedDownload(mapConfig); + + TileCountX = CalcTileCount(ImageResulotionX + 256); + TileCountY = CalcTileCount(ImageResulotionY + 256); + + combinedTiles = new Bitmap(TileCountX * 256, TileCountY * 256); + } + + protected virtual void OnCombinedImageChangedEvent(ImageChangedEventArgs e) + { + try + { + CombinedImageChangedEvent(this, e); + } + catch (NullReferenceException err) + { + + } + } + + public void Refresh() + { + int CenterTileX = MapFunctions.ConvertLongitudeToTileX(Longitude,ZoomLevel); + int CenterTileY = MapFunctions.ConvertLatitudeToTileY(Latitude,ZoomLevel); + + StartTileX = CenterTileX - ((int)(TileCountX / 2)); + StartTileY = CenterTileY - ((int)(TileCountY / 2)); + + MapTile tmpTile = new MapTile(mapType, CenterTileX, CenterTileY, ZoomLevel); + + double tmpLongitudeDelta; + tmpLongitudeDelta = Longitude - tmpTile.LeftLongitude; + if (tmpLongitudeDelta < 0) tmpLongitudeDelta *= -1; + + OffsetX = (int)(256 * (((100 / tmpTile.TileWidthDegree) * tmpLongitudeDelta) / 100)); + + double tmpLatitudeDelta; + tmpLatitudeDelta = Latitude - tmpTile.TopLatitude; + if (tmpLatitudeDelta < 0) tmpLatitudeDelta *= -1; + + OffsetY = (int)(256 * (((100 / tmpTile.TileHeightDegree) * tmpLatitudeDelta) / 100)); + + Tiles = new MapTile[TileCountX][]; + + //MapTile tmpTile; + tmpTile = null; + + for (int X = 0; X < TileCountX; X++) + { + Tiles[X] = new MapTile[TileCountY]; + for (int Y = 0; Y < TileCountY; Y++) + { + tmpTile = new MapTile(mapType, StartTileX + X, StartTileY + Y, ZoomLevel); + Tiles[X][Y] = tmpTile; + tmpTile.ImageChangedEvent += new ImageChangedEventHandler(tmpTile_ImageChangedEvent); + ImageGrabber.DownloadImage(Tiles[X][Y]); + } + } + } + + void tmpTile_ImageChangedEvent(object sender, ImageChangedEventArgs e) + { + lock (combinedTiles) + { + bool newTiles = false; + MapTile tmpTile = (MapTile)sender; + try + { + if (tmpTile == null) + { + return; + } + int insertX = (tmpTile.PosX - StartTileX) * 256; + int insertY = (tmpTile.PosY - StartTileY) * 256; + + Graphics graphics = Graphics.FromImage(combinedTiles); + graphics.DrawImage(tmpTile.Image, insertX, insertY, tmpTile.Image.Width, tmpTile.Image.Height); + newTiles = true; + } + catch (NullReferenceException err) + { } + catch (InvalidOperationException err) + { } + catch (ArgumentOutOfRangeException err) + { } + + if (newTiles) + { + croppedCombinedTiles = new Bitmap(ImageResolutionX, ImageResolutionY); + Graphics cropGraphics = Graphics.FromImage(croppedCombinedTiles); + + int cropPosX = (((combinedTiles.Width / 2) - 128) + OffsetX) - (ImageResolutionX / 2); //(((combinedTiles.Width / 2) - (ImageResolutionX / 2)) + 128) - OffsetX; + int cropPosY = (((combinedTiles.Height / 2) - 128) + OffsetY) - (ImageResolutionY / 2); // (((combinedTiles.Height / 2) - (ImageResolutionY / 2)) + 128) - OffsetY; + + //System.Diagnostics.Debug.WriteLine(OffsetX + " : " + OffsetY + " :: " + cropPosX + " : " + cropPosY); + Rectangle tmpSource = new Rectangle(cropPosX, cropPosY, ImageResolutionX, ImageResolutionY); + Rectangle tmpDest = new Rectangle(0, 0, ImageResolutionX, ImageResolutionY); + cropGraphics.DrawImage(combinedTiles, tmpDest, tmpSource, GraphicsUnit.Pixel); + + OnCombinedImageChangedEvent(null); + } + } + } + + public int CalcTileCount(int Pixel) + { + int ret = (int)(Pixel / 256); + if ((Pixel % 256) != 0) ret++; // if the division does not fit + if ((ret % 2) == 0) ret++; // if the the tile count is unpair + return ret; + } + + public void ClearTileDownloadQueue() + { + ImageGrabber.ClearDownloadQueue(); + } + } +} Added: trunk/plugins/WorldMap/MAPS/SearchGeoCodes.cs =================================================================== --- trunk/plugins/WorldMap/MAPS/SearchGeoCodes.cs (rev 0) +++ trunk/plugins/WorldMap/MAPS/SearchGeoCodes.cs 2007-08-08 10:14:00 UTC (rev 812) @@ -0,0 +1,204 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Net; +using System.Web; +using System.IO; +using System.Xml; +using System.Diagnostics; + +namespace MAPS +{ + enum GeoCodeService + { + OpenGeoCoding, + YahooGeoCoding, + GeoNames + } + + class GeoCode + { + public string Name; + public string Street; + public string City; + public string State; + public string Country; + public double Longitude; + public double Latitude; + } + + class SearchGeoCodes + { + public string Street = ""; + public string City = ""; + public string Country = ""; + public string Placename = ""; + public GeoCodeService ServiceName = GeoCodeService.YahooGeoCoding; + public List<GeoCode> SearchResult = null; + + public void SearchNow() + { + if (ServiceName == GeoCodeService.YahooGeoCoding) + { + Uri url = GetYahooAdress(); + string XMLString = GetXMLResult(url); + PushYahooResultToSearchResult(XMLString); + } + if (ServiceName == GeoCodeService.GeoNames) + { + Uri url = GetGeoNamesAdress(); + string XMLString = GetXMLResult(url); + PushGeoNamesResultToSearchResult(XMLString); + } + } + + public string GetXMLResult(Uri url) + { + string ret = null; + + HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(url); + httpRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"; + httpRequest.Timeout = 15000; + httpRequest.ReadWriteTimeout = 15000; + httpRequest.Method = "GET"; + + HttpWebResponse httpResponse = null; + + try + { + httpResponse = (HttpWebResponse)httpRequest.GetResponse(); + Stream tmpStream = httpResponse.GetResponseStream(); + + using (StreamReader reader = new StreamReader(tmpStream)) + { + ret = reader.ReadToEnd(); + } + } + catch (WebException err) + { + Debug.WriteLine(err.ToString()); + } + + return ret; + } + + public void PushYahooResultToSearchResult(string XMLString) + { + if (XMLString == null) return; + SearchResult = new List<GeoCode>(); + SearchResult.Clear(); + + XmlDocument doc = new XmlDocument(); + doc.LoadXml(XMLString); + + //XmlNode root = doc.DocumentElement; + //XmlNodeList nodes = doc.SelectNodes("//ResultSet/Result"); + //nodes = doc.DocumentElement.SelectNodes("Result"); + + XmlNodeList nodes = doc.DocumentElement.ChildNodes; + + System.Globalization.CultureInfo ci = System.Globalization.CultureInfo.InstalledUICulture; + System.Globalization.NumberFormatInfo ni = (System.Globalization.NumberFormatInfo)ci.NumberFormat.Clone(); + ni.NumberDecimalSeparator = "."; + ni.NumberGroupSeparator = ","; + + foreach (XmlNode node in nodes) + { + GeoCode tmpGeoCode = new GeoCode(); + tmpGeoCode.Name = ""; + tmpGeoCode.Street = node["Address"].InnerText; + tmpGeoCode.City = node["City"].InnerText; + tmpGeoCode.State = node["State"].InnerText; + tmpGeoCode.Country = node["Country"].InnerText; + tmpGeoCode.Latitude = double.Parse(node["Latitude"].InnerText, ni); + tmpGeoCode.Longitude = double.Parse(node["Longitude"].InnerText, ni); + SearchResult.Add(tmpGeoCode); + } + } + + public void PushGeoNamesResultToSearchResult(string XMLString) + { + SearchResult = new List<GeoCode>(); + SearchResult.Clear(); + + XmlDocument doc = new XmlDocument(); + doc.LoadXml(XMLString); + + XmlNode root = doc.DocumentElement; + //XmlNodeList nodes = doc.SelectNodes("//ResultSet/Result"); + //nodes = doc.DocumentElement.SelectNodes("Result"); + + XmlNodeList nodes = doc.DocumentElement.ChildNodes; + + System.Globalization.CultureInfo ci = System.Globalization.CultureInfo.InstalledUICulture; + System.Globalization.NumberFormatInfo ni = (System.Globalization.NumberFormatInfo)ci.NumberFormat.Clone(); + ni.NumberDecimalSeparator = "."; + ni.NumberGroupSeparator = ","; + + foreach (XmlNode node in nodes) + { + if (node.Name == "geoname") + { + GeoCode tmpGeoCode = new GeoCode(); + tmpGeoCode.Name = node["name"].InnerText; + try + { + tmpGeoCode.Name += " (" + node["adminName1"].InnerText + ")"; + } + catch (Exception err) + { } + tmpGeoCode.Country = node["countryName"].InnerText; + tmpGeoCode.Latitude = double.Parse(node["lat"].InnerText, ni); + tmpGeoCode.Longitude = double.Parse(node["lng"].InnerText, ni); + SearchResult.Add(tmpGeoCode); + } + } + } + + public Uri GetYahooAdress() + { + string url = "http://local.yahooapis.com/MapsService/V1/geocode?appid=MediaPortalWorldmap&output=xml"; + + if (Street != "") url += "&street=" + Street; + if (City != "") url += "&city=" + City; + if (Country != "") url += "&state=" + Country; + + url = ConvertStringToSafeUrl(url); + + return new Uri(url); + } + + public Uri GetGeoNamesAdress() + { + string url = "http://ws.geonames.org/search?maxRows=20&style=full"; + + if (Placename != "") url += "&q=" + Placename; + + url = ConvertStringToSafeUrl(url); + + return new Uri(url); + } + + + /// <summary> + /// Converts special characters to safe ones (e.g. \xFC becomes %FC) + /// </summary> + public string ConvertStringToSafeUrl(string url) + { + string ret = string.Empty; + string safeChars = "0123456789" + // Numeric + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + // Alphabetic + "abcdefghijklmnopqrstuvwxyz" + + ":-_.!~*'()?\\/=&"; // special + foreach (char Char in url) + { + if (safeChars.Contains(Char.ToString())) ret += Char; + else { ret += String.Format("%{0:X2}", (int)Char); } // convert to % plus the "hex value" + } + + return ret; + } + + } + +} Added: trunk/plugins/WorldMap/MAPS/ThreadedDownload.cs =================================================================== --- trunk/plugins/WorldMap/MAPS/ThreadedDownload.cs (rev 0) +++ trunk/plugins/WorldMap/MAPS/ThreadedDownload.cs 2007-08-08 10:14:00 UTC (rev 812) @@ -0,0 +1,372 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; +using System.IO; +using System.Net; +using System.Diagnostics; +using System.Drawing; +using System.Threading; + +namespace MAPS +{ + delegate void ProcessDownloadQueue(); + delegate void ImageThread(Object stateInfo); + public class ThreadedDownload + { + public List<MapTile> QueuedImageDownloads = new List<MapTile>(); + public List<Thread> ImageDownloadThreads = new List<Thread>(); + + public MapConfig mapConfig; + public TileCacheDatabase cacheDatabase; + + public ThreadedDownload(MapConfig mapConfig) + { + this.mapConfig = mapConfig; + + DatabaseOptions databaseOptions = new DatabaseOptions(); + databaseOptions.cacheFolder = mapConfig.CacheFolder; + databaseOptions.DaysToKeepCachedDetailedTiles = mapConfig.DaysToKeepCachedDetailedTiles; + databaseOptions.DaysToKeepCachedOverviewTiles = mapConfig.DaysToKeepCachedOverviewTiles; + + cacheDatabase = new TileCacheDatabase(databaseOptions); + } + + public void DownloadImage(MapTile mapTile) + { + string FilePreFix = null; + + switch (mapTile.MapType) + { + case MapFunctions.MapType.GMRoad: FilePreFix = "gmr"; + break; + case MapFunctions.MapType.GMAerial: FilePreFix = "gma"; + break; + case MapFunctions.MapType.GMHybrid: FilePreFix = "gmh"; + break; + case MapFunctions.MapType.VERoad: FilePreFix = "ver"; + break; + case MapFunctions.MapType.VEAerial: FilePreFix = "vea"; + break; + case MapFunctions.MapType.VEHybrid: FilePreFix = "veh"; + break; + } + + Bitmap tmpTileImage = null; + + try + { + tmpTileImage = cacheDatabase.GetImage(FilePreFix, mapTile.PosX, mapTile.PosY, mapTile.ZoomLevel); + if (tmpTileImage != null) + { + mapTile.Image = tmpTileImage; + return; + } + } + catch (NullReferenceException err) + { } + catch (Exception err) + { + Debug.WriteLine(err.ToString()); + }; + + //tmpTileImage = GetParentTilePart(FilePreFix,mapTile.PosX, mapTile.PosY, mapTile.ZoomLevel); + + if (tmpTileImage == null) + { + tmpTileImage = mapConfig.DownloadPlaceholder; + } + + mapTile.Image = tmpTileImage; + + //System.Threading.ThreadPool.QueueUserWorkItem(new WaitCallback(ImageThread), tmpImage); + + QueuedImageDownloads.Add(mapTile); + ProcessDownloadQueue(); + } + + Bitmap GetParentTilePart(string mapPreFix, int TileX, int TileY, int zoomLevel) + { + Bitmap ret = null; + + double curLongitude = MapFunctions.ConvertTileXToLongitude(TileX,zoomLevel); + double curLatitude = MapFunctions.ConvertTileYToLatitude(TileY,zoomLevel); + + int parentX = MapFunctions.ConvertLongitudeToTileX(curLongitude, zoomLevel - 1); + int parentY = MapFunctions.ConvertLatitudeToTileY(curLatitude, zoomLevel - 1); + + try + { + Bitmap parentTile = cacheDatabase.GetImage(mapPreFix, parentX, parentY, (zoomLevel - 1)); + if (parentTile != null) + { + string tmpTileCode = MapFunctions.GetGMapSatUrlTileCode(TileX, TileY, zoomLevel); + switch (tmpTileCode[tmpTileCode.Length - 1]) + { + case 'q': ret = ImageFunctions.GetUpperLeftPart(parentTile); + break; + case 'r': ret = ImageFunctions.GetUpperRightPart(parentTile); + break; + case 's': ret = ImageFunctions.GetLowerLeftPart(parentTile); + break; + case 't': ret = ImageFunctions.GetLowerRightPart(parentTile); + break; + } + } + } + catch (Exception err) + { + // Debug.WriteLine(err.ToString()); + }; + + return ret; + } + + public void ProcessDownloadQueue() + { + int maxThreadCount = 1; + try + { + switch (QueuedImageDownloads[0].MapType) + { + case MapFunctions.MapType.GMRoad: maxThreadCount = mapConfig.ThreadCountGMR; + break; + case MapFunctions.MapType.GMAerial: maxThreadCount = mapConfig.ThreadCountGMA; + break; + case MapFunctions.MapType.GMHybrid: maxThreadCount = mapConfig.ThreadCountGMH; + break; + case MapFunctions.MapType.VERoad: maxThreadCount = mapConfig.ThreadCountVER; + break; + case MapFunctions.MapType.VEAerial: maxThreadCount = mapConfig.ThreadCountVEA; + break; + case MapFunctions.MapType.VEHybrid: maxThreadCount = mapConfig.ThreadCountVEH; + break; + } + } + catch(Exception err) + { } + + if (ImageDownloadThreads.Count < maxThreadCount) + { + if (QueuedImageDownloads.Count > 0) + { + MapTile tmpTile = QueuedImageDownloads[0]; + QueuedImageDownloads.RemoveAt(0); + + Thread t = new Thread(new ParameterizedThreadStart(ImageThread)); + t.Priority = ThreadPriority.BelowNormal; + t.Name = "MapTileDownloader"; + t.IsBackground = true; + ImageDownloadThreads.Add(t); + try + { + t.Start(tmpTile); + } + catch (ThreadStartException err) + { } + + //if(QueuedImageDownloads.Count>0) QueuedImageDownloads.RemoveAt(0); + } + } + Debug.WriteLine(QueuedImageDownloads.Count + " : " + ImageDownloadThreads.Count); + } + + public void ClearDownloadQueue() + { + QueuedImageDownloads.Clear(); + + while (ImageThreadIsRunning()) + { + for (int i = 0; i < ImageDownloadThreads.Count; i++) + { + try + { + ImageDownloadThreads[i].Abort(); + //while (ImageDownloadThreads[0].IsAlive) { Thread.Sleep(100); } + + //ImageDownloadThreads.RemoveAt(0); + } + catch(Exception err) + { } + } + Thread.Sleep(250); + } + + + ImageDownloadThreads.Clear(); + + System.GC.ReRegisterForFinalize(QueuedImageDownloads); + System.GC.ReRegisterForFinalize(ImageDownloadThreads); + System.GC.Collect(); + //currentlyRunningThreads = 0; + } + + bool ImageThreadIsRunning() + { + bool ret = false; + for (int i = 0; i < ImageDownloadThreads.Count; i++) + { + try + { + ret |= ImageDownloadThreads[i].IsAlive; + } + catch (Exception err) + { } + } + return ret; + } + + void RemoveCurrentThreadFromList() + { + for (int i = 0; i < ImageDownloadThreads.Count; i++) + { + try + { + if (ImageDownloadThreads[i].Equals(Thread.CurrentThread)) + { + try + { + ImageDownloadThreads.RemoveAt(i); + } + catch (Exception err) + { } + } + } + catch (Exception err) + { } + } + } + + void ImageThread(Object stateInfo) + { + MapTile tmpImage = (MapTile)stateInfo; + Bitmap tmpTileImage = null; + + string url; + string FilePreFix = null; + + url = MapFunctions.GetTileUrl(tmpImage.MapType, tmpImage.PosX, tmpImage.PosY, tmpImage.ZoomLevel, ref mapConfig); + if (url == "***" || url == null) + { + tmpImage.Image = mapConfig.TileNotAvailable; + + RemoveCurrentThreadFromList(); + ProcessDownloadQueue(); + return; + } + + switch (tmpImage.MapType) + { + case MapFunctions.MapType.GMRoad: FilePreFix = "gmr"; + break; + case MapFunctions.MapType.GMAerial: FilePreFix = "gma"; + break; + case MapFunctions.MapType.GMHybrid: FilePreFix = "gmh"; + break; + case MapFunctions.MapType.VERoad: FilePreFix = "ver"; + break; + case MapFunctions.MapType.VEAerial: FilePreFix = "vea"; + break; + case MapFunctions.MapType.VEHybrid: FilePreFix = "veh"; + break; + } + + string UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.1.4) Gecko/20070515 Firefox/2.0.0.4"; + if (tmpImage.MapType == MapFunctions.MapType.VEAerial || tmpImage.MapType == MapFunctions.MapType.VEHybrid || tmpImage.MapType == MapFunctions.MapType.VERoad) + { + UserAgent = "Virtual Earth 3D"; + } + + HttpWebRequest httpRequest = (HttpWebRequest) WebRequest.Create(url); + httpRequest.UserAgent = UserAgent; + httpRequest.Timeout = 7000; + httpRequest.ReadWriteTimeout = 7000; + httpRequest.Method = "GET"; + HttpWebResponse httpResponse = null; + + try + { + Stream tmpImageStream; + Debug.WriteLine(url); + //Thread.Sleep(6500); + + if (tmpImage.MapType == MapFunctions.MapType.GMHybrid) + { + try + { + tmpTileImage = cacheDatabase.GetImage("gma", tmpImage.PosX, tmpImage.PosY, tmpImage.ZoomLevel); + } + catch (Exception err) + { } + } + + if (tmpTileImage == null) + { + httpResponse = (HttpWebResponse)httpRequest.GetResponse(); + tmpImageStream = httpResponse.GetResponseStream(); + + tmpTileImage = new Bitmap(tmpImageStream); + if (tmpImage.MapType == MapFunctions.MapType.GMHybrid) + { + cacheDatabase.InsertImage("gma", tmpImage.PosX, tmpImage.PosY, tmpImage.ZoomLevel, tmpTileImage); + } + } + + if (tmpTileImage != null && tmpImage.MapType == MapFunctions.MapType.GMHybrid) + { + url = MapFunctions.GetGHybridOverlayUrl(tmpImage.PosX, tmpImage.PosY, tmpImage.ZoomLevel, ref mapConfig); + Debug.WriteLine(url); + httpRequest = (HttpWebRequest)WebRequest.Create(url); + httpRequest.UserAgent = UserAgent; + httpRequest.Timeout = 7000; + httpRequest.ReadWriteTimeout = 7000; + httpRequest.Method = "GET"; + httpResponse = (HttpWebResponse)httpRequest.GetResponse(); + tmpImageStream = httpResponse.GetResponseStream(); + + Bitmap tmpHybridOverlay = new Bitmap(tmpImageStream); + tmpTileImage = ImageFunctions.MergeBitmaps(tmpTileImage, tmpHybridOverlay); + } + + cacheDatabase.InsertImage(FilePreFix, tmpImage.PosX, tmpImage.PosY, tmpImage.ZoomLevel, tmpTileImage); + tmpImage.Image = tmpTileImage; + } + catch (WebException err) + { + Debug.WriteLine(err.ToString()); + if (err.Status == WebExceptionStatus.ProtocolError) + { + httpResponse = (HttpWebResponse)err.Response; + if (httpResponse.StatusCode == HttpStatusCode.Forbidden) + { + tmpImage.Image = mapConfig.IPBlocked; + } + if (httpResponse.StatusCode == HttpStatusCode.BadRequest || httpResponse.StatusCode == HttpStatusCode.NotFound) + { + tmpImage.Image = mapConfig.TileNotAvailable; + } + } + } + catch (ThreadAbortException err) + { + Debug.WriteLine(err.ToString()); + try + { + httpRequest.Abort(); + } + catch (Exception err2) + { } + } + catch (Exception err) + { + Debug.WriteLine(err.ToString()); + } + + //httpResponse.Close(); + //tmpTileImage.Dispose(); + + RemoveCurrentThreadFromList(); + ProcessDownloadQueue(); + } + } +} Added: trunk/plugins/WorldMap/MAPS/TileCacheDatabase.cs =================================================================== --- trunk/plugins/WorldMap/MAPS/TileCacheDatabase.cs (rev 0) +++ trunk/plugins/WorldMap/MAPS/TileCacheDatabase.cs 2007-08-08 10:14:00 UTC (rev 812) @@ -0,0 +1,267 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Diagnostics; +using System.Data.SQLite; +using System.Data; +using System.IO; +using System.Drawing; + +namespace MAPS +{ + public class DatabaseOptions + { + public string cacheFolder; + public int DaysToKeepCachedDetailedTiles; + public int DaysToKeepCachedOverviewTiles; + } + + public class TileCacheDatabase + { + private DatabaseOptions options; + private SQLiteConnection CurrentConnection = null; + + public TileCacheDatabase(DatabaseOptions DatabaseOptions) + { + options = DatabaseOptions; + //options.DaysToKeepCachedDetailedTiles = 30; + //options.DaysToKeepCachedOverviewTiles = 200; + + CreateDatebase(); + } + + public void CreateDatebase() + { + string dbpath = options.cacheFolder + @"\MapTileCache.db"; + string connString = @"Data Source=" + dbpath + ";New=True;UTF8Encoding=True;Version=3"; + // if the db file doesn't exist, create a new db (New=True to create a db)--- + if (!File.Exists(dbpath)) + { + SQLiteConnection con = new SQLiteConnection(connString); + SQLiteCommand cmd = con.CreateCommand(); + cmd.CommandText = "CREATE TABLE MapTiles (TimeStamp timestamp DEFAULT CURRENT_TIMESTAMP NULL, MapType varchar(3), zoomLevel integer, TileX integer, TileY integer,image BLOB)"; + con.Open(); + cmd.ExecuteNonQuery(); + + cmd = con.CreateCommand(); + cmd.CommandText = "CREATE INDEX TimeStampIndex ON MapTiles (TimeStamp)"; + cmd.ExecuteNonQuery(); + + cmd = con.CreateCommand(); + cmd.CommandText = "CREATE INDEX MapTypeIndex ON MapTiles (MapType)"; + cmd.ExecuteNonQuery(); + + cmd = con.CreateCommand(); + cmd.CommandText = "CREATE INDEX zoomLevelIndex ON MapTiles (zoomLevel)"; + cmd.ExecuteNonQuery(); + + cmd = con.CreateCommand(); + cmd.CommandText = "CREATE INDEX TileXIndex ON MapTiles (TileX)"; + cmd.ExecuteNonQuery(); + + cmd = con.CreateCommand(); + cmd.CommandText = "CREATE INDEX TileYIndex ON MapTiles (TileY)"; + cmd.ExecuteNonQuery(); + + con.Close(); + cmd.Dispose(); + } + + } + + public void InsertImage(string MapType, int TileX, int TileY, int zoomLevel, Bitmap image) + { + if (CurrentConnection == null) + { + + string dbpath = options.cacheFolder + @"\MapTileCache.db"; + string connString = @"Data Source=" + dbpath + ";UTF8Encoding=True;Version=3"; + CurrentConnection = new SQLiteConnection(connString); + } + // stream to save the bitmap to + MemoryStream ms = new MemoryStream(); + // Save to memory using the Jpeg format + image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); + + // read to end + byte[] imageBytes = ms.GetBuffer(); + ms.Close(); + + IDbCommand cmd = CurrentConnection.CreateCommand(); + cmd.CommandText = "INSERT INTO MapTiles (MapType,zoomLevel,TileX,TileY,image) VALUES (@MapType,@zoomLevel,@TileX,@TileY,@image)"; + + SQLiteParameter paramMapType = new SQLiteParameter("@MapType", DbType.String); + paramMapType.Value = MapType; + cmd.Parameters.Add(paramMapType); + + SQLiteParameter paramZoomLevel = new SQLiteParameter("@zoomLevel", DbType.Int16); + paramZoomLevel.Value = zoomLevel; + cmd.Parameters.Add(paramZoomLevel); + + SQLiteParameter paramTileX = new SQLiteParameter("@TileX", DbType.Int32); + paramTileX.Value = TileX; + cmd.Parameters.Add(paramTileX); + + SQLiteParameter paramTileY = new SQLiteParameter("@TileY", DbType.Int32); + paramTileY.Value = TileY; + cmd.Parameters.Add(paramTileY); + + SQLiteParameter paramImage = new SQLiteParameter("@image", DbType.Binary); + paramImage.Value = imageBytes; + cmd.Parameters.Add(paramImage); + try + { + if(CurrentConnection.State == ConnectionState.Closed) CurrentConnection.Open(); + cmd.ExecuteNonQuery(); + + } + catch (Exception err) + { } + finally + { + cmd.Dispose(); + //CurrentConnection.Close(); + } + } + + public Bitmap GetImage(string MapType, int TileX, int TileY, int zoomLevel) + { + Bitmap tmpImage = null; + + if (CurrentConnection == null) + { + string dbpath = options.cacheFolder + @"\MapTileCache.db"; + string connString = @"Data Source=" + dbpath + ";UTF8Encoding=True;Version=3"; + CurrentConnection = new SQLiteConnection(connString); + } + + //IDbCommand cmd = CurrentConnection.CreateCommand(); + SQLiteCommand cmd = new SQLiteCommand(CurrentConnection); + cmd.CommandText = "Select * From MapTiles Where MapType=@MapType AND zoomLevel=@zoomLevel AND TileX=@TileX AND TileY=@TileY"; + + SQLiteParameter paramMapType = new SQLiteParameter("@MapType", DbType.String); + paramMapType.Value = MapType; + cmd.Parameters.Add(paramMapType); + + SQLiteParameter paramZoomLevel = new SQLiteParameter("@zoomLevel", DbType.Int16); + paramZoomLevel.Value = zoomLevel; + cmd.Parameters.Add(paramZoomLevel); + + SQLiteParameter paramTileX = new SQLiteParameter("@TileX", DbType.Int32); + paramTileX.Value = TileX; + cmd.Parameters.Add(paramTileX); + + SQLiteParameter paramTileY = new SQLiteParameter("@TileY", DbType.Int32); + paramTileY.Value = TileY; + cmd.Parameters.Add(paramTileY); + + MemoryStream ms = null; + try + { + SQLiteDataAdapter da = new SQLiteDataAdapter(cmd); + SQLiteCommandBuilder MyCB = new SQLiteCommandBuilder(da); + DataSet ds = new DataSet("MapTileImage"); + da.Fill(ds, "MapTileImage"); + DataRow myRow; + // get the latest row + myRow = ds.Tables["MapTileImage"].Rows[ds.Tables["MapTileImage"].Rows.Count - 1]; + + byte[] imageBytes = (byte[])myRow["image"]; + ms = new MemoryStream(imageBytes); + tmpImage = new Bitmap(ms); + ms.Close(); + } + catch (IndexOutOfRangeException err) + { Debug.WriteLine("The map tile was not in the database!"); } + catch (Exception err) + { } + finally + { + //CurrentConnection.Close(); + cmd.Dispose(); + ms.Dispose(); + } + + return tmpImage; + } + + public void DeleteOldCacheEntries() + { + if (CurrentConnection == null) + { + + string dbpath = options.cacheFolder + @"\MapTileCache.db"; + string connString = @"Data Source=" + dbpath + ";UTF8Encoding=True;Version=3"; + CurrentConnection = new SQLiteConnection(connString); + } + IDbCommand cmd = CurrentConnection.CreateCommand(); + cmd.CommandText = String.Format("DELETE FROM MapTiles WHERE zoomLevel < 15 AND TimeStamp < datetime('now','-{0} day')", options.DaysToKeepCachedOverviewTiles); + + try + { + CurrentConnection.Open(); + } + catch (InvalidOperationException err) + { } + + try + { + Debug.WriteLine(cmd.ExecuteNonQuery().ToString() + " overview tiles affected"); + } + catch (Exception err) + { + Debug.WriteLine(err); + } + finally + { + cmd.Dispose(); + } + + cmd = CurrentConnection.CreateCommand(); + cmd.CommandText = String.Format("DELETE FROM MapTiles WHERE zoomLevel >= 15 AND TimeStamp < datetime('now','-{0} day')", options.DaysToKeepCachedDetailedTiles); + + try + { + Debug.WriteLine(cmd.ExecuteNonQuery().ToString() + " detailed tiles affected"); + } + catch (Exception err) + { + Debug.WriteLine(err); + } + + finally + ... [truncated message content] |