Removed MapImages library

This commit is contained in:
Clemens 2022-01-18 21:31:24 +01:00
parent 135473b799
commit b04ed4eebe
9 changed files with 0 additions and 859 deletions

View file

@ -1,204 +0,0 @@
// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
// © 2022 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL)
using MapControl.Projections;
using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
#if WINUI
using Windows.Foundation;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Media.Imaging;
#elif UWP
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
#else
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
#endif
namespace MapControl.Images
{
public partial class GeoImage
{
private const string PixelScaleQuery = "/ifd/{ushort=33550}";
private const string TiePointQuery = "/ifd/{ushort=33922}";
private const string TransformQuery = "/ifd/{ushort=34264}";
private const string NoDataQuery = "/ifd/{ushort=42113}";
public static readonly DependencyProperty PathProperty = DependencyProperty.RegisterAttached(
"Path", typeof(string), typeof(GeoImage), new PropertyMetadata(null, PathPropertyChanged));
public BitmapSource Bitmap { get; }
public Matrix Transform { get; }
public MapProjection Projection { get; }
public BoundingBox BoundingBox { get; }
public double Rotation { get; }
public GeoImage(BitmapSource bitmap, Matrix transform, MapProjection projection)
{
Bitmap = bitmap;
Transform = transform;
Projection = projection;
if (transform.M12 != 0 || transform.M21 != 0)
{
Rotation = (Math.Atan2(transform.M12, transform.M11) + Math.Atan2(transform.M21, -transform.M22)) * 90d / Math.PI;
// effective unrotated transform
transform.M11 = Math.Sqrt(transform.M11 * transform.M11 + transform.M12 * transform.M12);
transform.M22 = -Math.Sqrt(transform.M22 * transform.M22 + transform.M21 * transform.M21);
transform.M12 = 0;
transform.M21 = 0;
}
var rect = new Rect(
transform.Transform(new Point()),
transform.Transform(new Point(bitmap.PixelWidth, bitmap.PixelHeight)));
BoundingBox = projection != null
? projection.RectToBoundingBox(rect)
: new BoundingBox
{
West = rect.X,
East = rect.X + rect.Width,
South = rect.Y,
North = rect.Y + rect.Height
};
}
public static string GetPath(Image image)
{
return (string)image.GetValue(PathProperty);
}
public static void SetPath(Image image, string path)
{
image.SetValue(PathProperty, path);
}
public static Task<GeoImage> ReadImage(string imageFilePath)
{
var ext = Path.GetExtension(imageFilePath);
if (ext.Length < 4)
{
throw new ArgumentException("Invalid image file path extension, must have at least three characters.");
}
var dir = Path.GetDirectoryName(imageFilePath);
var file = Path.GetFileNameWithoutExtension(imageFilePath);
var worldFilePath = Path.Combine(dir, file + ext.Remove(2, 1) + "w");
if (File.Exists(worldFilePath))
{
return ReadImage(imageFilePath, worldFilePath, Path.Combine(dir, file + ".prj"));
}
return ReadGeoTiff(imageFilePath);
}
public static async Task<GeoImage> ReadImage(string imageFilePath, string worldFilePath, string projFilePath = null)
{
var transform = ReadWorldFile(worldFilePath);
var projection = (projFilePath != null && File.Exists(projFilePath))
? ReadProjectionFile(projFilePath)
: null;
var bitmap = (BitmapSource)await ImageLoader.LoadImageAsync(imageFilePath);
return new GeoImage(bitmap, transform, projection);
}
public static Matrix ReadWorldFile(string path)
{
var parameters = File.ReadLines(path)
.Take(6)
.Select((line, i) =>
{
if (!double.TryParse(line, NumberStyles.Float, CultureInfo.InvariantCulture, out double parameter))
{
throw new ArgumentException("Failed parsing line " + (i + 1) + " in world file \"" + path + "\".");
}
return parameter;
})
.ToList();
if (parameters.Count != 6)
{
throw new ArgumentException("Insufficient number of parameters in world file \"" + path + "\".");
}
return new Matrix(
parameters[0], // line 1: A or M11
parameters[1], // line 2: D or M12
parameters[2], // line 3: B or M21
parameters[3], // line 4: E or M22
parameters[4], // line 5: C or OffsetX
parameters[5]); // line 6: F or OffsetY
}
public static MapProjection ReadProjectionFile(string path)
{
return new GeoApiProjection { WKT = File.ReadAllText(path) };
}
public void ApplyToImage(Image image)
{
if (Rotation != 0d)
{
throw new InvalidOperationException("Rotation must be zero.");
}
image.Source = Bitmap;
image.Stretch = Stretch.Fill;
MapPanel.SetBoundingBox(image, BoundingBox);
}
public FrameworkElement CreateImage()
{
FrameworkElement image = new Image
{
Source = Bitmap,
Stretch = Stretch.Fill
};
if (Rotation != 0d)
{
image.RenderTransform = new RotateTransform { Angle = Rotation };
var panel = new Grid();
panel.Children.Add(image);
image = panel;
}
MapPanel.SetBoundingBox(image, BoundingBox);
return image;
}
public static async Task<FrameworkElement> CreateImage(string imageFilePath)
{
return (await ReadImage(imageFilePath)).CreateImage();
}
private static async void PathPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
if (o is Image image && e.NewValue is string imageFilePath)
{
(await ReadImage(imageFilePath)).ApplyToImage(image);
}
}
}
}

View file

@ -1,276 +0,0 @@
// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
// © 2022 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL)
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Threading.Tasks;
using System.Xml;
#if WINUI
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
#elif UWP
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
#else
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
#endif
namespace MapControl.Images
{
public class GroundOverlayPanel : MapPanel
{
class LatLonBox : BoundingBox
{
public LatLonBox(double south, double west, double north, double east, double rotation)
: base(south, west, north, east)
{
Rotation = rotation;
}
public double Rotation { get; }
}
class ImageOverlay
{
public ImageOverlay(LatLonBox latLonBox, string imagePath, int zIndex)
{
LatLonBox = latLonBox;
ImagePath = imagePath;
ZIndex = zIndex;
}
public LatLonBox LatLonBox { get; }
public string ImagePath { get; }
public int ZIndex { get; }
public ImageSource ImageSource { get; set; }
}
public static readonly DependencyProperty KmlFileProperty = DependencyProperty.Register(
nameof(KmlFile), typeof(string), typeof(GroundOverlayPanel),
new PropertyMetadata(null, async (o, e) => await ((GroundOverlayPanel)o).KmlFilePropertyChanged((string)e.NewValue)));
public string KmlFile
{
get { return (string)GetValue(KmlFileProperty); }
set { SetValue(KmlFileProperty, value); }
}
private async Task KmlFilePropertyChanged(string path)
{
IEnumerable<ImageOverlay> imageOverlays = null;
if (!string.IsNullOrEmpty(path))
{
try
{
var ext = Path.GetExtension(path).ToLower();
if (ext == ".kmz")
{
imageOverlays = await ReadGroundOverlaysFromArchiveAsync(path);
}
else if (ext == ".kml")
{
imageOverlays = await ReadGroundOverlaysFromFileAsync(path);
}
}
catch (Exception ex)
{
Debug.WriteLine($"GroundOverlayPanel: {path}: {ex.Message}");
}
}
Children.Clear();
if (imageOverlays != null)
{
AddImageOverlays(imageOverlays);
}
}
private void AddImageOverlays(IEnumerable<ImageOverlay> imageOverlays)
{
foreach (var imageOverlay in imageOverlays.Where(i => i.ImageSource != null))
{
FrameworkElement overlay = new Image
{
Source = imageOverlay.ImageSource,
Stretch = Stretch.Fill,
UseLayoutRounding = false
};
if (imageOverlay.LatLonBox.Rotation != 0d)
{
overlay.RenderTransform = new RotateTransform { Angle = -imageOverlay.LatLonBox.Rotation };
overlay.RenderTransformOrigin = new Point(0.5, 0.5);
// additional Panel for map rotation, see MapPanel.ArrangeElementWithBoundingBox
var panel = new Grid { UseLayoutRounding = false };
panel.Children.Add(overlay);
overlay = panel;
}
SetBoundingBox(overlay, imageOverlay.LatLonBox);
Canvas.SetZIndex(overlay, imageOverlay.ZIndex);
Children.Add(overlay);
}
}
private static async Task<IEnumerable<ImageOverlay>> ReadGroundOverlaysFromArchiveAsync(string archiveFile)
{
using (var archive = await Task.Run(() => ZipFile.OpenRead(archiveFile)))
{
var docEntry = await Task.Run(() => archive.GetEntry("doc.kml") ?? archive.Entries.FirstOrDefault(e => e.Name.EndsWith(".kml")));
if (docEntry == null)
{
throw new ArgumentException("No KML entry found in " + archiveFile);
}
var imageOverlays = await Task.Run(() =>
{
var kmlDocument = new XmlDocument();
using (var docStream = docEntry.Open())
{
kmlDocument.Load(docStream);
}
return ReadGroundOverlays(kmlDocument).ToList();
});
foreach (var imageOverlay in imageOverlays)
{
var imageEntry = await Task.Run(() => archive.GetEntry(imageOverlay.ImagePath));
if (imageEntry != null)
{
using (var zipStream = imageEntry.Open())
using (var memoryStream = new MemoryStream())
{
await zipStream.CopyToAsync(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
imageOverlay.ImageSource = await ImageLoader.LoadImageAsync(memoryStream);
}
}
}
return imageOverlays;
}
}
private static async Task<IEnumerable<ImageOverlay>> ReadGroundOverlaysFromFileAsync(string docFile)
{
docFile = Path.GetFullPath(docFile);
var docUri = new Uri(docFile);
var imageOverlays = await Task.Run(() =>
{
var kmlDocument = new XmlDocument();
kmlDocument.Load(docFile);
return ReadGroundOverlays(kmlDocument).ToList();
});
foreach (var imageOverlay in imageOverlays)
{
imageOverlay.ImageSource = await ImageLoader.LoadImageAsync(new Uri(docUri, imageOverlay.ImagePath));
}
return imageOverlays;
}
private static IEnumerable<ImageOverlay> ReadGroundOverlays(XmlDocument kmlDocument)
{
foreach (XmlElement groundOverlayElement in kmlDocument.GetElementsByTagName("GroundOverlay"))
{
LatLonBox latLonBox = null;
string imagePath = null;
int zIndex = 0;
foreach (var childElement in groundOverlayElement.ChildNodes.OfType<XmlElement>())
{
switch (childElement.LocalName)
{
case "LatLonBox":
latLonBox = ReadLatLonBox(childElement);
break;
case "Icon":
imagePath = ReadImagePath(childElement);
break;
case "drawOrder":
int.TryParse(childElement.InnerText.Trim(), out zIndex);
break;
}
}
if (latLonBox != null && imagePath != null)
{
yield return new ImageOverlay(latLonBox, imagePath, zIndex);
}
}
}
private static string ReadImagePath(XmlElement element)
{
string href = null;
foreach (var childElement in element.ChildNodes.OfType<XmlElement>())
{
switch (childElement.LocalName)
{
case "href":
href = childElement.InnerText.Trim();
break;
}
}
return href;
}
private static LatLonBox ReadLatLonBox(XmlElement element)
{
double north = double.NaN;
double south = double.NaN;
double east = double.NaN;
double west = double.NaN;
double rotation = 0d;
foreach (var childElement in element.ChildNodes.OfType<XmlElement>())
{
switch (childElement.LocalName)
{
case "north":
double.TryParse(childElement.InnerText.Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out north);
break;
case "south":
double.TryParse(childElement.InnerText.Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out south);
break;
case "east":
double.TryParse(childElement.InnerText.Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out east);
break;
case "west":
double.TryParse(childElement.InnerText.Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out west);
break;
case "rotation":
double.TryParse(childElement.InnerText.Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out rotation);
break;
}
}
return !double.IsNaN(north) && !double.IsNaN(south) && !double.IsNaN(east) && !double.IsNaN(west)
? new LatLonBox(south, west, north, east, rotation)
: null;
}
}
}

View file

@ -1,85 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{BE08B7BC-8C89-4837-BCE7-EDDDABEAB372}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MapControl.Images</RootNamespace>
<AssemblyName>MapImages.UWP</AssemblyName>
<DefaultLanguage>en-US</DefaultLanguage>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion Condition=" '$(TargetPlatformVersion)' == '' ">10.0.19041.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.17134.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;UWP</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>UWP</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\Shared\GeoImage.cs">
<Link>GeoImage.cs</Link>
</Compile>
<Compile Include="..\Shared\GroundOverlayPanel.cs">
<Link>GroundOverlayPanel.cs</Link>
</Compile>
<Compile Include="..\WinUI\GeoImage.WinUI.cs">
<Link>GeoImage.WinUI.cs</Link>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Properties\MapImages.UWP.rd.xml" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
<Version>6.2.13</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\MapControl\UWP\MapControl.UWP.csproj">
<Project>{9545f73c-9c35-4cf6-baae-19a0baebd344}</Project>
<Name>MapControl.UWP</Name>
</ProjectReference>
<ProjectReference Include="..\..\MapProjections\UWP\MapProjections.UWP.csproj">
<Project>{9ee69591-5edc-45e3-893e-2f9a4b82d538}</Project>
<Name>MapProjections.UWP</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="..\..\MapControl.snk">
<Link>MapControl.snk</Link>
</None>
</ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
<VisualStudioVersion>14.0</VisualStudioVersion>
</PropertyGroup>
<PropertyGroup>
<SignAssembly>true</SignAssembly>
</PropertyGroup>
<PropertyGroup>
<AssemblyOriginatorKeyFile>..\..\MapControl.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
</Project>

View file

@ -1,13 +0,0 @@
using System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("XAML Map Control Image Support Library for UWP")]
[assembly: AssemblyProduct("XAML Map Control")]
[assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © 2022 Clemens Fischer")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("7.1.0")]
[assembly: AssemblyFileVersion("7.1.0")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]

View file

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file contains Runtime Directives, specifications about types your application accesses
through reflection and other dynamic code patterns. Runtime Directives are used to control the
.NET Native optimizer and ensure that it does not remove code accessed by your library. If your
library does not do any reflection, then you generally do not need to edit this file. However,
if your library reflects over types, especially types passed to it or derived from its types,
then you should write Runtime Directives.
The most common use of reflection in libraries is to discover information about types passed
to the library. Runtime Directives have three ways to express requirements on types passed to
your library.
1. Parameter, GenericParameter, TypeParameter, TypeEnumerableParameter
Use these directives to reflect over types passed as a parameter.
2. SubTypes
Use a SubTypes directive to reflect over types derived from another type.
3. AttributeImplies
Use an AttributeImplies directive to indicate that your library needs to reflect over
types or methods decorated with an attribute.
For more information on writing Runtime Directives for libraries, please visit
https://go.microsoft.com/fwlink/?LinkID=391919
-->
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Library Name="MapImages.UWP">
<!-- add directives for your library here -->
</Library>
</Directives>

View file

@ -1,109 +0,0 @@
// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
// © 2022 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL)
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace MapControl.Images
{
public partial class GeoImage
{
public static Task<GeoImage> ReadGeoTiff(string imageFilePath)
{
return Task.Run(() =>
{
BitmapSource bitmap;
Matrix transform;
using (var stream = File.OpenRead(imageFilePath))
{
bitmap = BitmapFrame.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}
var metadata = bitmap.Metadata as BitmapMetadata;
if (metadata.GetQuery((string)PixelScaleQuery) is double[] pixelScale && pixelScale.Length == 3 &&
metadata.GetQuery((string)TiePointQuery) is double[] tiePoint && tiePoint.Length >= 6)
{
transform = new Matrix(pixelScale[0], 0d, 0d, -pixelScale[1], tiePoint[3], tiePoint[4]);
}
else if (metadata.GetQuery((string)TransformQuery) is double[] tform && tform.Length == 16)
{
transform = new Matrix(tform[0], tform[1], tform[4], tform[5], tform[3], tform[7]);
}
else
{
throw new ArgumentException("No coordinate transformation found in \"" + imageFilePath + "\".");
}
if (metadata.GetQuery((string)NoDataQuery) is string noData && int.TryParse(noData, out int noDataValue))
{
bitmap = ConvertTransparentPixel(bitmap, noDataValue);
}
return new GeoImage(bitmap, transform, (MapProjection)null);
});
}
public static BitmapSource ConvertTransparentPixel(BitmapSource source, int transparentPixel)
{
BitmapPalette sourcePalette = null;
var targetFormat = source.Format;
if (source.Format == PixelFormats.Indexed8 ||
source.Format == PixelFormats.Indexed4 ||
source.Format == PixelFormats.Indexed2 ||
source.Format == PixelFormats.Indexed1)
{
sourcePalette = source.Palette;
}
else if (source.Format == PixelFormats.Gray8)
{
sourcePalette = BitmapPalettes.Gray256;
targetFormat = PixelFormats.Indexed8;
}
else if (source.Format == PixelFormats.Gray4)
{
sourcePalette = BitmapPalettes.Gray16;
targetFormat = PixelFormats.Indexed4;
}
else if (source.Format == PixelFormats.Gray2)
{
sourcePalette = BitmapPalettes.Gray4;
targetFormat = PixelFormats.Indexed2;
}
else if (source.Format == PixelFormats.BlackWhite)
{
sourcePalette = BitmapPalettes.BlackAndWhite;
targetFormat = PixelFormats.Indexed1;
}
if (sourcePalette == null || transparentPixel >= sourcePalette.Colors.Count)
{
return source;
}
var colors = sourcePalette.Colors.ToList();
colors[transparentPixel] = Colors.Transparent;
var stride = (source.PixelWidth * source.Format.BitsPerPixel + 7) / 8;
var buffer = new byte[stride * source.PixelHeight];
source.CopyPixels(buffer, stride, 0);
var target = BitmapSource.Create(
source.PixelWidth, source.PixelHeight, source.DpiX, source.DpiY,
targetFormat, new BitmapPalette(colors), buffer, stride);
target.Freeze();
return target;
}
}
}

View file

@ -1,35 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0-windows;net5.0-windows;netcoreapp3.1;net48;net462</TargetFrameworks>
<UseWPF>true</UseWPF>
<RootNamespace>MapControl.Images</RootNamespace>
<AssemblyTitle>XAML Map Control Image Support Library for WPF</AssemblyTitle>
<Product>XAML Map Control</Product>
<Version>7.1.0</Version>
<Authors>Clemens Fischer</Authors>
<Copyright>Copyright © 2022 Clemens Fischer</Copyright>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\..\MapControl.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<PackageId>XAML.MapControl.MapImages</PackageId>
<DefineConstants></DefineConstants>
</PropertyGroup>
<ItemGroup>
<None Include="..\..\MapControl.snk" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\Shared\*.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'=='net48' or '$(TargetFramework)'=='net462'">
<Reference Include="System.IO.Compression" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\MapControl\WPF\MapControl.WPF.csproj" />
<ProjectReference Include="..\..\MapProjections\WPF\MapProjections.WPF.csproj" />
</ItemGroup>
</Project>

View file

@ -1,66 +0,0 @@
// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
// © 2022 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL)
using System;
using System.IO;
using System.Threading.Tasks;
using System.Collections.Generic;
using Windows.Graphics.Imaging;
using Windows.Storage;
#if WINUI
using Microsoft.UI.Xaml.Media.Imaging;
#else
using Windows.UI.Xaml.Media.Imaging;
#endif
namespace MapControl.Images
{
public partial class GeoImage
{
public static async Task<GeoImage> ReadGeoTiff(string imageFilePath)
{
var file = await StorageFile.GetFileFromPathAsync(Path.GetFullPath(imageFilePath));
using (var stream = await file.OpenReadAsync())
{
WriteableBitmap bitmap;
Matrix transform;
var decoder = await BitmapDecoder.CreateAsync(stream);
using (var swbmp = await decoder.GetSoftwareBitmapAsync())
{
bitmap = new WriteableBitmap(swbmp.PixelWidth, swbmp.PixelHeight);
swbmp.CopyToBuffer(bitmap.PixelBuffer);
}
var query = new List<string>
{
PixelScaleQuery, TiePointQuery, TransformQuery //, NoDataQuery
};
var metadata = await decoder.BitmapProperties.GetPropertiesAsync(query);
if (metadata.TryGetValue(PixelScaleQuery, out BitmapTypedValue pixelScaleValue) &&
pixelScaleValue.Value is double[] pixelScale && pixelScale.Length == 3 &&
metadata.TryGetValue(TiePointQuery, out BitmapTypedValue tiePointValue) &&
tiePointValue.Value is double[] tiePoint && tiePoint.Length >= 6)
{
transform = new Matrix(pixelScale[0], 0d, 0d, -pixelScale[1], tiePoint[3], tiePoint[4]);
}
else if (metadata.TryGetValue(TransformQuery, out BitmapTypedValue tformValue) &&
tformValue.Value is double[] tform && tform.Length == 16)
{
transform = new Matrix(tform[0], tform[1], tform[4], tform[5], tform[3], tform[7]);
}
else
{
throw new ArgumentException("No coordinate transformation found in \"" + imageFilePath + "\".");
}
return new GeoImage(bitmap, transform, null);
}
}
}
}

View file

@ -1,38 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0-windows10.0.19041.0</TargetFramework>
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
<UseWinUI>true</UseWinUI>
<RootNamespace>MapControl.Images</RootNamespace>
<AssemblyTitle>XAML Map Control Image Support Library for WinUI</AssemblyTitle>
<Product>XAML Map Control</Product>
<Version>7.1.0</Version>
<Authors>Clemens Fischer</Authors>
<Copyright>Copyright © 2022 Clemens Fischer</Copyright>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\..\MapControl.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<PackageId>XAML.MapControl.MapImages</PackageId>
<DefineConstants>WINUI</DefineConstants>
</PropertyGroup>
<ItemGroup>
<None Include="..\..\MapControl.snk" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\Shared\*.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.0.0" />
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22000.196" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\MapControl\WinUI\MapControl.WinUI.csproj" />
<ProjectReference Include="..\..\MapProjections\WinUI\MapProjections.WinUI.csproj" />
</ItemGroup>
</Project>