[Git][debian-gis-team/mkgmap-splitter][master] 4 commits: New upstream version 0.0.0+svn653

Bas Couwenberg (@sebastic) gitlab at salsa.debian.org
Sun Jan 1 08:11:16 GMT 2023



Bas Couwenberg pushed to branch master at Debian GIS Project / mkgmap-splitter


Commits:
e043598a by Bas Couwenberg at 2023-01-01T09:01:32+01:00
New upstream version 0.0.0+svn653
- - - - -
61704cfa by Bas Couwenberg at 2023-01-01T09:01:34+01:00
Update upstream source from tag 'upstream/0.0.0+svn653'

Update to upstream version '0.0.0+svn653'
with Debian dir 2448d36236daa5aec4d1b4d3a5491098e79c8cbb
- - - - -
2b29e6e6 by Bas Couwenberg at 2023-01-01T09:01:49+01:00
New upstream SVN snapshot.

- - - - -
af8b5d07 by Bas Couwenberg at 2023-01-01T09:02:33+01:00
Set distribution to unstable.

- - - - -


3 changed files:

- debian/changelog
- resources/splitter-version.properties
- src/uk/me/parabola/splitter/solver/SplittableDensityArea.java


Changes:

=====================================
debian/changelog
=====================================
@@ -1,8 +1,9 @@
-mkgmap-splitter (0.0.0+svn652-2) UNRELEASED; urgency=medium
+mkgmap-splitter (0.0.0+svn653-1) unstable; urgency=medium
 
+  * New upstream SVN snapshot.
   * Add Rules-Requires-Root to control file.
 
- -- Bas Couwenberg <sebastic at debian.org>  Mon, 28 Nov 2022 13:45:41 +0100
+ -- Bas Couwenberg <sebastic at debian.org>  Sun, 01 Jan 2023 09:02:22 +0100
 
 mkgmap-splitter (0.0.0+svn652-1) unstable; urgency=medium
 


=====================================
resources/splitter-version.properties
=====================================
@@ -1,2 +1,2 @@
-svn.version: 652
-build.timestamp: 2022-06-17T08:25:16+0100
+svn.version: 653
+build.timestamp: 2022-12-27T06:20:39+0000


=====================================
src/uk/me/parabola/splitter/solver/SplittableDensityArea.java
=====================================
@@ -21,10 +21,12 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -180,7 +182,7 @@ public class SplittableDensityArea {
 				if (rasteredPart.isSingular()) {
 					prepare(polygonArea);
 					Tile tile = new Tile(extraDensityInfo, rasteredPart.getBounds());
-					Solution solution = findSolutionWithSinglePolygon(0, tile, rasteredPart);
+					Solution solution = findSolutionWithSinglePolygon(0, tile, rasteredPart, new HashSet<>());
 					if (solution == null && rasteredPart.isRectangular()) 
 						solution = split();
 					if (solution != null) { 
@@ -483,9 +485,11 @@ public class SplittableDensityArea {
 	 * @param depth               recursion depth
 	 * @param tile                the tile to split
 	 * @param rasteredPolygonArea an area describing a rectilinear shape
+	 * @param knownBad collection containing rectangles which are known to be without solution 
 	 * @return a solution (maybe empty), or null if rasteredPolygon is not singular
 	 */
-	private Solution findSolutionWithSinglePolygon(int depth, final Tile tile, java.awt.geom.Area rasteredPolygonArea) {
+	private Solution findSolutionWithSinglePolygon(int depth, final Tile tile, java.awt.geom.Area rasteredPolygonArea,
+			Set<Rectangle> knownBad) {
 		if (!rasteredPolygonArea.isSingular()) {
 			return null;
 		}
@@ -512,7 +516,7 @@ public class SplittableDensityArea {
 				continue;
 			int cutX = point.x;
 			int cutY = point.y;
-			Solution part0Sol = null, part1Sol = null;
+			Solution part1Sol = null, part2Sol = null;
 			for (int axis = 0; axis < 2; axis++) {
 				Rectangle r1, r2;
 				if (axis == AXIS_HOR) {
@@ -522,26 +526,31 @@ public class SplittableDensityArea {
 					r1 = new Rectangle(pBounds.x, pBounds.y, pBounds.width, cutY - pBounds.y);
 					r2 = new Rectangle(pBounds.x, cutY, pBounds.width, (int) (pBounds.getMaxY() - cutY));
 				}
+				if (r1.isEmpty() || r2.isEmpty() || knownBad.contains(r1) || knownBad.contains(r2))
+					continue;
+//				System.out.println("depth=" + depth + ", trying point " + i + "/" + lastPoint);
 
 				if (r1.width * r1.height > r2.width * r2.height) {
 					Rectangle help = r1;
 					r1 = r2;
 					r2 = help;
 				}
-				if (!r1.isEmpty() && !r2.isEmpty()) {
-					java.awt.geom.Area area = new java.awt.geom.Area(r1);
+				java.awt.geom.Area area = new java.awt.geom.Area(r1);
+				area.intersect(rasteredPolygonArea);
+				part1Sol = findSolutionWithSinglePolygon(depth + 1, tile, area, knownBad);
+				
+				if (part1Sol != null && !part1Sol.isEmpty()) {
+					area = new java.awt.geom.Area(r2);
 					area.intersect(rasteredPolygonArea);
-
-					part0Sol = findSolutionWithSinglePolygon(depth + 1, tile, area);
-					if (part0Sol != null && !part0Sol.isEmpty()) {
-						area = new java.awt.geom.Area(r2);
-						area.intersect(rasteredPolygonArea);
-						part1Sol = findSolutionWithSinglePolygon(depth + 1, tile, area);
-						if (part1Sol != null && !part1Sol.isEmpty()) { 
-							part0Sol.merge(part1Sol);
-							return part0Sol;
-						}
+					part2Sol = findSolutionWithSinglePolygon(depth + 1, tile, area, knownBad);
+					
+					if (part2Sol != null && !part2Sol.isEmpty()) { 
+						part1Sol.merge(part2Sol);
+						return part1Sol;
 					} 
+					knownBad.add(r2);
+				} else {
+					knownBad.add(r1);
 				}
 			}
 		}
@@ -549,6 +558,8 @@ public class SplittableDensityArea {
 	}
 
 	private Solution solveRectangularArea(Tile startTile) {
+		if (startTile.getCount() <= 1)
+			return new Solution(maxNodes);
 		int bestPossible = stopNumber > 0 ? stopNumber : startTile.getMinParts(maxNodes);
 		System.out.println("Splitting tile " + startTile + ", goal is to get near " + bestPossible + " tiles");
 		return solveRectangularAreaParallel(startTile, 0);
@@ -648,9 +659,7 @@ public class SplittableDensityArea {
 			return new Solution(maxNodes);
 		
 		List<Solver> solvers = new ArrayList<>();
-		List<Future<?>> futures = new ArrayList<>();
 		int numAlgos = 2;
-		ExecutorService threadPool = Executors.newFixedThreadPool(numAlgos);
 		
 		for (int i = 0; i < numAlgos; i++) {
 			Solver solver = new Solver(++solverId, i == 1, maxNodes, startTile, shift, stopNumber, trimTiles, startSearchLimit, allowEmptyPart);
@@ -660,77 +669,85 @@ public class SplittableDensityArea {
 				continue; // too simple for SOME
 			solver.maxAspectRatio = getStartRatio(startTile);
 			solvers.add(solver);
-			futures.add(threadPool.submit(solver::solve));
 		}
-		
-		threadPool.shutdown();
-		
-		Instant t1 = null;
-		final double n75 = 0.75 * maxNodes;
-		final double n85 = 0.85 * maxNodes;
-		while (!threadPool.isTerminated()) {
-			for (int i = 0; i < solvers.size(); i++) {
-				Future<?> future = futures.get(i);
-				if (future.isDone()) {
-					try {
-						future.get();
-					} catch (InterruptedException | ExecutionException e) {
-						throw new SplitFailedException("parallel solver crashed", e.getCause());
-					}
-					Solution sol = solvers.get(i).bestSolution;
-					if (sol.isNice()) {
-						if (t1 == null)
-							t1 = Instant.now();
-						long dt = Duration.between(t1, Instant.now()).getSeconds();
-						boolean stop = false;
-						if (sol.getWorstMinNodes() >= n85 && dt > 10) {
-							stop = true; // all tiles have at least 85% of max-nodes
-						} else {
-							int num75 = 0;
-							for (Tile tile : sol.getTiles()) {
-								if (tile.getCount() < n75)
-									num75++;
+		if (solvers.size() == 1) {
+			solvers.get(0).solve();
+		} else {
+			ExecutorService threadPool = Executors.newFixedThreadPool(solvers.size());
+			List<Future<?>> futures = new ArrayList<>();
+			for (Solver solver : solvers) {
+				futures.add(threadPool.submit(solver::solve));
+			}
+			threadPool.shutdown();
+
+
+			Instant t1 = null;
+			final double n75 = 0.75 * maxNodes;
+			final double n85 = 0.85 * maxNodes;
+			while (!threadPool.isTerminated()) {
+				for (int i = 0; i < solvers.size(); i++) {
+					Future<?> future = futures.get(i);
+					if (future.isDone()) {
+						try {
+							future.get();
+						} catch (InterruptedException | ExecutionException e) {
+							throw new SplitFailedException("parallel solver crashed", e.getCause());
+						}
+						Solution sol = solvers.get(i).bestSolution;
+						if (sol.isNice()) {
+							if (t1 == null)
+								t1 = Instant.now();
+							long dt = Duration.between(t1, Instant.now()).getSeconds();
+							boolean stop = false;
+							if (sol.getWorstMinNodes() >= n85 && dt > 10) {
+								stop = true; // all tiles have at least 85% of max-nodes
+							} else {
+								int num75 = 0;
+								for (Tile tile : sol.getTiles()) {
+									if (tile.getCount() < n75)
+										num75++;
+								}
+								double below75 = 100.0 * num75 / sol.size();
+								if (below75 > 5 && dt > 30) {
+									// +5 percent of tiles are less the 75 percent but we waited +30 seconds
+									stop = true;
+								}
 							}
-							double below75 = 100.0 * num75 / sol.size();
-							if (below75 > 5 && dt > 30) {
-								// +5 percent of tiles are less the 75 percent but we waited +30 seconds
-								stop = true;
+							if (stop) {
+								// stop the other solver
+								solvers.forEach(Solver::stop);
 							}
 						}
-						if (stop) {
-							// stop the other solver
-							solvers.forEach(Solver::stop);
-						}
 					}
 				}
+				try {
+					Thread.sleep(500);
+				} catch (InterruptedException e) {
+					e.printStackTrace();
+				}
 			}
-			try {
-				Thread.sleep(500);
-			} catch (InterruptedException e) {
-				e.printStackTrace();
-			}
+			// call get() on each future to recognise possible exceptions 
+			futures.forEach(f -> {
+				try {
+					f.get();
+				} catch (InterruptedException | ExecutionException e) {
+					Thread.currentThread().interrupt();
+					throw new SplitFailedException("parallel solver crashed", e.getCause());
+				}
+			});
+			// sort by number of tiles so that the smaller number comes first
+			// can't use compareTo here as it prefers the higher worstMinNodes value
+			solvers.sort((o1, o2) -> {
+				int d = Boolean.compare(o1.bestSolution.isNice(), o2.bestSolution.isNice());
+				if (d != 0)
+					return -d; // prefer nice
+				d = Integer.compare(o1.bestSolution.size(), o2.bestSolution.size());
+				if (d != 0)
+					return d;
+				// prefer higher min-nodes
+				return Long.compare(o2.bestSolution.getWorstMinNodes(), o1.bestSolution.getWorstMinNodes()); 
+			});
 		}
-		// call get() on each future to recognise possible exceptions 
-		futures.forEach(f -> {
-			try {
-				f.get();
-			} catch (InterruptedException | ExecutionException e) {
-				Thread.currentThread().interrupt();
-				throw new SplitFailedException("parallel solver crashed", e.getCause());
-			}
-		});
-		// sort by number of tiles so that the smaller number comes first
-		// can't use compareTo here as it prefers the higher worstMinNodes value
-		solvers.sort((o1, o2) -> {
-			int d = Boolean.compare(o1.bestSolution.isNice(), o2.bestSolution.isNice());
-			if (d != 0)
-				return -d; // prefer nice
-			d = Integer.compare(o1.bestSolution.size(), o2.bestSolution.size());
-			if (d != 0)
-				return d;
-			// prefer higher min-nodes
-			return Long.compare(o2.bestSolution.getWorstMinNodes(), o1.bestSolution.getWorstMinNodes()); 
-		});
 		Solver best = solvers.get(0);
 		if (best.bestSolution.isEmpty()) {
 			int highestCount = extraDensityInfo.getMaxNodesInDensityMapGridElement();



View it on GitLab: https://salsa.debian.org/debian-gis-team/mkgmap-splitter/-/compare/c89d09d68264a39ab38c711e2738c2bcf9d90a72...af8b5d07e78d38b43b0167f2d5edb99f3f8ed69f

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/mkgmap-splitter/-/compare/c89d09d68264a39ab38c711e2738c2bcf9d90a72...af8b5d07e78d38b43b0167f2d5edb99f3f8ed69f
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20230101/4a894fed/attachment-0001.htm>


More information about the Pkg-grass-devel mailing list