Skip to content

Commit

Permalink
Merge pull request #14 from djordon/better-plotting
Browse files Browse the repository at this point in the history
Better plotting
  • Loading branch information
djordon committed Jul 8, 2017
2 parents 0fddedf + 803d780 commit 380d183
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 19 deletions.
25 changes: 21 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,38 @@ Polygon-partitioner
For partitioning polygons into disjoint rectangles. Because you never know when you need to partition some polygons.


Documentation
-------------


Features
--------

This package implements two main methods:

1. A method that approximates a polygon by a rectilinear polygon.

This is guaranteed to cover the input with the default settings. You can change the coarseness of the approximation, leading to an output with far fewer points than the input (but without a guarantee of if covering the input).

2. A method that partitions a rectilinear polygon into non-overlapping rectangles.


Documentation
-------------


Installation
------------

.. code-block:: scala
lazy val partitioner = RootProject(uri("git://github.com/djordon/polygon-partitioner.git"))
lazy val root = Project("root", file("."))
.dependsOn(partitioner)
Bugs and issues
---------------

File bugs/issues/requests at https://github.com/djordon/polygon-partitioner/issues.


Copyright and license
---------------------
Expand Down
4 changes: 2 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ lazy val core = (project in file("core"))
.settings(
Seq(
name := "polygon-partitioner-core",
version := "0.1.1-SNAPSHOT",
version := "0.1.0-SNAPSHOT",
coverageEnabled := true
),
libraryDependencies ++= coreDependencies
Expand All @@ -45,4 +45,4 @@ lazy val db = (project in file("db"))
coverageEnabled := false
),
libraryDependencies ++= dbDependencies)
.dependsOn(core % "test->test;compile->compile")
.dependsOn(core % "test->test;compile->compile")
4 changes: 2 additions & 2 deletions core/src/main/scala/org/partitioner/partition/partition.scala
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ object RectangleEndpointExtractor {

object OrthogonalPolygonPartitioner {
import CornerExtractor.extractCorners
import GeometryUtils.normalizePolygon
import PolygonApproximator.removeAxisAlignedCollinearity
import RectangleEndpointExtractor.extractRectangleEndpoints
import OrthogonalPolygonCornerExtender.extendCorners
import scala.language.implicitConversions
Expand Down Expand Up @@ -175,7 +175,7 @@ object OrthogonalPolygonPartitioner {
}
}

def partition: Polygon => List[Rectangle] = (normalizePolygon _)
def partition: Polygon => List[Rectangle] = (removeAxisAlignedCollinearity _)
.andThen(extractCorners _)
.andThen(makeRectangleCorners _)
.andThen(extractRectangles _)
Expand Down
25 changes: 17 additions & 8 deletions plot/src/main/scala/org/partitioner/plot.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ package org.partitioner.plot
import java.io.File

import com.vividsolutions.jts.geom.Polygon

import org.partitioner._

import plotly.element._
import plotly.layout.{Axis, Layout, HoverMode, Margin}
import plotly.layout.{Axis, HoverMode, Layout, Margin}
import plotly.{Plotly, Scatter}


Expand All @@ -16,6 +14,11 @@ trait PlotDefaults {
lazy val boundaryMarkerColor = Color.RGBA(194, 33, 10, 0.9)
lazy val boundaryMarker = Marker(color = boundaryMarkerColor, line = boundaryLine)

lazy val backgroundMarker: Marker = Marker(
color = Color.RGB(0, 0, 0),
line = Line(color = Color.RGB(0, 0, 0), width = 0.0)
)

val defaultLayout = Layout(
title = "",
xaxis = Axis(showgrid = true, showticklabels = false, zeroline = false),
Expand All @@ -41,7 +44,7 @@ trait PlotDefaults {
)

def defaultRectangleColor(rec: Rectangle): Color = {
Color.RGBA(0, 15, (Math.random() * 200).toInt + 55, 0.7)
Color.RGB(0, 15, (Math.random() * 200).toInt + 55)
}
}

Expand Down Expand Up @@ -113,15 +116,17 @@ object PolygonPlotter extends PlotDefaults {

def polygonPlotter(
polygon: Polygon,
marker: Marker = boundaryMarker): List[Scatter] = {
marker: Marker = boundaryMarker,
fill: Option[Fill] = None): List[Scatter] = {

val interior: List[List[Point]] = polygon.getHolesCoordinates.map(_.map(Point.apply))
val exterior: List[Point] = polygon.toList.map(Point.apply)

val partialScatter = pointScatter(
_: List[Point],
marker,
mode = Some(ScatterMode(ScatterMode.Markers, ScatterMode.Lines))
mode = Some(ScatterMode(ScatterMode.Markers, ScatterMode.Lines)),
fill = fill
)

(exterior :: interior).map(partialScatter)
Expand All @@ -136,14 +141,18 @@ object PolygonPlotter extends PlotDefaults {
layout: Layout = defaultLayout,
rectangleColor: Rectangle => Color = defaultRectangleColor _,
polygonMarker: Marker = boundaryMarker,
interiorMarker: Marker = interiorLineMarker): File = {
interiorMarker: Marker = interiorLineMarker,
backgroundMarker: Marker = backgroundMarker,
openInBrowser: Boolean = true): File = {

val fill: Option[Fill] = Some(Fill.ToNextY)
val scatters: List[Scatter] = {
polygons.flatMap(polygonPlotter(_: Polygon, backgroundMarker, fill)) ++
rectangles.flatMap(rectanglePlotter(_: Rectangle, rectangleColor)) ++
innerLines.flatMap(cornerLinePlotter(_: CornerLine, interiorMarker)) ++
polygons.flatMap(polygonPlotter(_: Polygon, polygonMarker))
}

Plotly.plot(fileName, scatters, layout.copy(title = Some(title)))
Plotly.plot(fileName, scatters, layout.copy(title = Some(title)), openInBrowser = openInBrowser)
}
}
28 changes: 25 additions & 3 deletions plot/src/test/scala/org/partitioner/plotSpec.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
package org.partitioner
package org.partitioner.plot

import org.partitioner._

import org.scalatest.{Matchers, WordSpec}

Expand All @@ -8,8 +10,28 @@ import scala.language.reflectiveCalls

class PolygonPlotterSpec extends WordSpec with Matchers with PolygonFixtures {
"PolygonPlotter" can {
"quickPlot" should {
"do something" in {
"polygonPlotter" should {
"return a Scatter for the exterior and holes of the polygon" in {
for (pg <- fixtures.values) {
val numGeometries: Int = 1 + pg.getNumInteriorRing
val scatters = PolygonPlotter.polygonPlotter(pg)

scatters.length shouldEqual numGeometries
}
}
}

"rectanglePlotter" should {
"return a Scatter for the top and bottom lines of a rectangle" in {
val rectangle: Rectangle = Rectangle(Point(0, 1), Point(1, 0))
PolygonPlotter.rectanglePlotter(rectangle).length shouldEqual 2
}
}

"cornerLinePlotter" should {
"return one Scatter for the line" in {
val line: CornerLine = CornerLine(Point(0, 0), Point(0, 1), 90)
PolygonPlotter.cornerLinePlotter(line).length shouldEqual 1
}
}
}
Expand Down

0 comments on commit 380d183

Please sign in to comment.