Rilascia gestione completa progetti e aggiornamenti 0.4.0
This commit is contained in:
1 parent
620a4bec26
commit
205a520708
10 files changed
+1366
-65
No files matched your search
@@ -135,11 +135,43 @@ public sealed class MapExportService
|
||||
|
||||
private static byte[] BuildPdfReport(JsonElement features, string title)
|
||||
{
|
||||
var paths = features.EnumerateArray()
|
||||
.Where(feature => feature.TryGetProperty("geometry", out _))
|
||||
.SelectMany(feature => PdfCoordinatePaths(feature.GetProperty("geometry")))
|
||||
.Where(path => path.Count > 0)
|
||||
.ToArray();
|
||||
var points = paths.SelectMany(path => path).ToArray();
|
||||
var minLon = points.Length == 0 ? 0 : points.Min(point => point.Lon);
|
||||
var maxLon = points.Length == 0 ? 1 : points.Max(point => point.Lon);
|
||||
var minLat = points.Length == 0 ? 0 : points.Min(point => point.Lat);
|
||||
var maxLat = points.Length == 0 ? 1 : points.Max(point => point.Lat);
|
||||
var lonSpan = Math.Max(0.0000001, maxLon - minLon);
|
||||
var latSpan = Math.Max(0.0000001, maxLat - minLat);
|
||||
const double mapLeft = 48, mapBottom = 438, mapWidth = 499, mapHeight = 330;
|
||||
var scale = Math.Min(mapWidth / lonSpan, mapHeight / latSpan);
|
||||
var drawing = new StringBuilder("0.08 0.44 0.37 RG 0.86 0.94 0.91 rg 1.4 w ");
|
||||
foreach (var path in paths.Take(400))
|
||||
{
|
||||
for (var pointIndex = 0; pointIndex < path.Count; pointIndex++)
|
||||
{
|
||||
var x = mapLeft + (path[pointIndex].Lon - minLon) * scale;
|
||||
var y = mapBottom + (path[pointIndex].Lat - minLat) * scale;
|
||||
drawing.AppendFormat(CultureInfo.InvariantCulture, "{0:0.##} {1:0.##} {2} ", x, y, pointIndex == 0 ? "m" : "l");
|
||||
}
|
||||
drawing.Append("S ");
|
||||
}
|
||||
drawing.Append("0 0 0 RG 1 w 497 730 m 497 758 l S 497 758 m 491 746 l 503 746 l h f ");
|
||||
var middleLatitude = (minLat + maxLat) / 2;
|
||||
var widthMeters = lonSpan * 111_320 * Math.Cos(middleLatitude * Math.PI / 180);
|
||||
var scaleMeters = Math.Max(1, NiceScaleDistance(widthMeters / 4));
|
||||
var scalePixels = widthMeters <= 0 ? 80 : Math.Clamp(scaleMeters / widthMeters * mapWidth, 35, 150);
|
||||
drawing.AppendFormat(CultureInfo.InvariantCulture, "48 422 m {0:0.##} 422 l S 48 418 m 48 426 l S {0:0.##} 418 m {0:0.##} 426 l S ", 48 + scalePixels);
|
||||
var lines = new List<string>
|
||||
{
|
||||
title,
|
||||
$"Rapporto LME Mappe Catastali - {DateTime.Now:dd/MM/yyyy HH:mm}",
|
||||
$"Oggetti: {features.GetArrayLength()}",
|
||||
$"Scala grafica: {scaleMeters:0} m | Nord: alto pagina",
|
||||
""
|
||||
};
|
||||
var index = 1;
|
||||
@@ -148,14 +180,17 @@ public sealed class MapExportService
|
||||
var properties = feature.TryGetProperty("properties", out var value) ? value : default;
|
||||
var category = GetString(properties, "_lmeCategory") ?? "drawing";
|
||||
var geometry = feature.TryGetProperty("geometry", out var geo) ? geo.GetProperty("type").GetString() : "-";
|
||||
lines.Add($"{index++}. {FeatureName(properties, category)} [{category}, {geometry}]");
|
||||
var sheet = GetString(properties, "foglio") ?? GetString(properties, "FOGLIO");
|
||||
var parcel = GetString(properties, "particella") ?? GetString(properties, "PARTICELLA") ?? GetString(properties, "LABEL");
|
||||
var reference = string.Join(" ", new[] { sheet is null ? null : $"F.{sheet}", parcel is null ? null : $"P.{parcel}" }.Where(item => item is not null));
|
||||
lines.Add($"{index++}. {FeatureName(properties, category)} [{category}, {geometry}] {reference}".TrimEnd());
|
||||
}
|
||||
var content = new StringBuilder("BT /F1 16 Tf 48 790 Td ");
|
||||
foreach (var line in lines.Take(42))
|
||||
var content = drawing.Append("BT /F1 12 Tf 48 810 Td ");
|
||||
foreach (var line in lines.Take(21))
|
||||
{
|
||||
var safe = line.Replace("\\", "\\\\").Replace("(", "\\(").Replace(")", "\\)")
|
||||
.Select(character => character <= 255 ? character : '?').ToArray();
|
||||
content.Append('(').Append(safe).Append(") Tj 0 -18 Td ");
|
||||
content.Append('(').Append(safe).Append(") Tj 0 -16 Td ");
|
||||
}
|
||||
content.Append("ET");
|
||||
var stream = Encoding.Latin1.GetBytes(content.ToString());
|
||||
@@ -183,6 +218,36 @@ public sealed class MapExportService
|
||||
return output.ToArray();
|
||||
}
|
||||
|
||||
private static double NiceScaleDistance(double value)
|
||||
{
|
||||
if (value <= 0) return 1;
|
||||
var power = Math.Pow(10, Math.Floor(Math.Log10(value)));
|
||||
var normalized = value / power;
|
||||
var nice = normalized >= 5 ? 5 : normalized >= 2 ? 2 : 1;
|
||||
return nice * power;
|
||||
}
|
||||
|
||||
private static IEnumerable<List<(double Lon, double Lat)>> PdfCoordinatePaths(JsonElement geometry)
|
||||
{
|
||||
if (!geometry.TryGetProperty("type", out var typeElement) || !geometry.TryGetProperty("coordinates", out var coordinates)) yield break;
|
||||
var type = typeElement.GetString();
|
||||
if (type == "Point") { yield return [PdfPoint(coordinates)]; yield break; }
|
||||
if (type == "LineString") { yield return coordinates.EnumerateArray().Select(PdfPoint).ToList(); yield break; }
|
||||
if (type == "Polygon" || type == "MultiLineString")
|
||||
{
|
||||
foreach (var path in coordinates.EnumerateArray()) yield return path.EnumerateArray().Select(PdfPoint).ToList();
|
||||
yield break;
|
||||
}
|
||||
if (type == "MultiPolygon")
|
||||
{
|
||||
foreach (var polygon in coordinates.EnumerateArray())
|
||||
foreach (var path in polygon.EnumerateArray()) yield return path.EnumerateArray().Select(PdfPoint).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
private static (double Lon, double Lat) PdfPoint(JsonElement coordinate) =>
|
||||
(coordinate[0].GetDouble(), coordinate[1].GetDouble());
|
||||
|
||||
private static string BuildKml(JsonElement features, string documentName)
|
||||
{
|
||||
var document = new XElement(Kml + "Document",
|
||||
|
||||
Reference in new issue
Block a user