use of org.activityinfo.server.report.generator.map.cluster.Cluster in project activityinfo by bedatadriven.
the class BubbleLayerGenerator method generate.
@Override
public void generate(TiledMap map, MapContent content) {
// define our symbol scaling
RadiiCalculator radiiCalculator;
if (layer.getScaling() == ScalingType.None || layer.getMinRadius() == layer.getMaxRadius()) {
radiiCalculator = new FixedRadiiCalculator(layer.getMinRadius());
} else if (layer.getScaling() == ScalingType.Graduated) {
radiiCalculator = new GsLogCalculator(layer.getMinRadius(), layer.getMaxRadius());
} else {
radiiCalculator = new FixedRadiiCalculator(layer.getMinRadius());
}
BubbleIntersectionCalculator intersectionCalculator = new BubbleIntersectionCalculator(layer.getMaxRadius());
Clusterer clusterer = ClustererFactory.fromClustering(layer.getClustering(), radiiCalculator, intersectionCalculator);
// create the list of input point values
List<PointValue> points = new ArrayList<PointValue>();
List<PointValue> unmapped = new ArrayList<PointValue>();
generatePoints(sites, map, layer, clusterer, points, unmapped);
// Cluster points by the clustering algorithm set in the layer
List<Cluster> clusters = clusterer.cluster(map, points);
// add unmapped sites
for (PointValue pv : unmapped) {
content.getUnmappedSites().add(pv.getSite().getId());
}
BubbleLayerLegend legend = new BubbleLayerLegend();
legend.setDefinition(layer);
// create the markers
List<BubbleMapMarker> markers = new ArrayList<BubbleMapMarker>();
for (Cluster cluster : clusters) {
Point px = cluster.getPoint();
AiLatLng latlng = map.fromPixelToLatLng(px);
BubbleMapMarker marker = new BubbleMapMarker();
for (PointValue pv : cluster.getPointValues()) {
marker.getSiteIds().add(pv.getSite().getId());
}
marker.setX(px.getX());
marker.setY(px.getY());
marker.setValue(cluster.sumValues());
marker.setRadius((int) cluster.getRadius());
marker.setLat(latlng.getLat());
marker.setLng(latlng.getLng());
marker.setAlpha(layer.getAlpha());
marker.setTitle(formatTitle(cluster));
marker.setIndicatorIds(new HashSet<Integer>(layer.getIndicatorIds()));
marker.setClusterAmount(cluster.getPointValues().size());
marker.setClustering(layer.getClustering());
marker.setColor(layer.getBubbleColor());
if (marker.getValue() < legend.getMinValue()) {
legend.setMinValue(marker.getValue());
}
if (marker.getValue() > legend.getMaxValue()) {
legend.setMaxValue(marker.getValue());
}
markers.add(marker);
}
// sort order by symbol radius descending
// (this assures that smaller symbols are drawn on
// top of larger ones)
Collections.sort(markers, new Comparator<MapMarker>() {
@Override
public int compare(MapMarker o1, MapMarker o2) {
if (o1.getSize() > o2.getSize()) {
return -1;
} else if (o1.getSize() < o2.getSize()) {
return 1;
}
return 0;
}
});
// number markers if applicable
if (layer.getLabelSequence() != null) {
numberMarkers(markers);
}
content.addLegend(legend);
content.getMarkers().addAll(markers);
}
use of org.activityinfo.server.report.generator.map.cluster.Cluster in project activityinfo by bedatadriven.
the class KMeans method cluster.
public static List<Cluster> cluster(List<MarkerGraph.Node> nodes, int numClusters) {
List<Cluster> clusters = new ArrayList<Cluster>(numClusters);
// sanity check
if (numClusters > nodes.size() || nodes.size() == 0) {
throw new IllegalArgumentException();
}
// randomize
Collections.shuffle(nodes);
// choose random centers
Point[] centers = new Point[numClusters];
for (int i = 0; i != numClusters; ++i) {
centers[i] = nodes.get(i).getPoint();
}
// assign initial cluster membership
int[] membership = new int[nodes.size()];
assignClosest(nodes, centers, membership);
// execute k-means algorithm until we achieve convergence
boolean changed;
do {
computeCenters(nodes, membership, centers);
changed = assignClosest(nodes, centers, membership);
} while (changed);
// create clusters
for (int i = 0; i != numClusters; ++i) {
clusters.add(new Cluster(centers[i]));
}
for (int j = 0; j != nodes.size(); ++j) {
(clusters.get(membership[j])).addNode(nodes.get(j));
}
return clusters;
}
use of org.activityinfo.server.report.generator.map.cluster.Cluster in project activityinfo by bedatadriven.
the class IconLayerGenerator method createMarkersFrom.
private void createMarkersFrom(List<Cluster> clusters, TiledMap map, MapContent content) {
for (Cluster cluster : clusters) {
IconMapMarker marker = new IconMapMarker();
marker.setX(cluster.getPoint().getX());
marker.setY(cluster.getPoint().getY());
AiLatLng latlng = map.fromPixelToLatLng(cluster.getPoint());
marker.setLat(latlng.getLat());
marker.setLng(latlng.getLng());
marker.setTitle(formatTitle(cluster));
marker.setIcon(icon);
marker.setIndicatorId(layer.getIndicatorIds().get(0));
for (PointValue pv : cluster.getPointValues()) {
marker.getSiteIds().add(pv.getSite().getId());
}
content.getMarkers().add(marker);
}
}
use of org.activityinfo.server.report.generator.map.cluster.Cluster in project activityinfo by bedatadriven.
the class CoincidentPointsClusterTest method testRealData.
@Test
public void testRealData() throws Exception {
// Define projection for the test case
TiledMap map = new TiledMap(492, 690, new AiLatLng(2.293492496, 30.538372993), 9);
// Read data
BufferedReader in = new BufferedReader(new InputStreamReader(GraphTest.class.getResourceAsStream("/distribscolaire-points.csv")));
double originalSum = 0;
List<PointValue> points = new ArrayList<PointValue>();
while (in.ready()) {
String line = in.readLine();
String[] columns = line.split(",");
double lat = Double.parseDouble(columns[0]);
double lng = Double.parseDouble(columns[1]);
PointValue pv = new PointValue();
pv.setPx(map.fromLatLngToPixel(new AiLatLng(lat, lng)));
pv.setValue(Double.parseDouble(columns[2]));
pv.setSymbol(new MapSymbol());
pv.setSite(new SiteDTO());
originalSum += pv.getValue();
points.add(pv);
}
// Now build the graph
MarkerGraph graph = new MarkerGraph(points, new BubbleIntersectionCalculator(15));
// make sure nothing was lost in the merging of coincident points
double nodeSum = 0;
for (MarkerGraph.Node node : graph.getNodes()) {
nodeSum += node.getPointValue().getValue();
}
Assert.assertEquals("values after construction of graph", originalSum, nodeSum, 0.001);
saveGraphImage("clusterTest2", graph, 15);
GeneticSolver solver = new GeneticSolver();
List<Cluster> clusters = solver.solve(graph, new GsLogCalculator(5, 15), new BubbleFitnessFunctor(), UpperBoundsCalculator.calculate(graph, new FixedRadiiCalculator(5)));
// check to make sure all values were included
double sumAfterClustering = 0;
for (Cluster cluster : clusters) {
sumAfterClustering += cluster.sumValues();
}
Assert.assertEquals(originalSum, sumAfterClustering, 0.001);
Assert.assertEquals(15, clusters.size());
saveClusters(graph, "clusterTest-solution", clusters);
}
use of org.activityinfo.server.report.generator.map.cluster.Cluster in project activityinfo by bedatadriven.
the class IconLayerGenerator method generate.
@Override
public void generate(TiledMap map, MapContent content) {
List<PointValue> points = new ArrayList<PointValue>();
IconRectCalculator rectCalculator = new IconRectCalculator(icon);
IntersectionCalculator intersectionCalculator = new IntersectionCalculator() {
@Override
public boolean intersects(Node a, Node b) {
return a.getPointValue().getIconRect().intersects(b.getPointValue().getIconRect());
}
};
Clusterer clusterer = ClustererFactory.fromClustering(layer.getClustering(), rectCalculator, intersectionCalculator);
for (SiteDTO site : sites) {
if (meetsCriteria(site)) {
AiLatLng geoPoint = getPoint(site);
if (geoPoint != null || clusterer.isMapped(site)) {
Point point = null;
if (geoPoint != null) {
point = map.fromLatLngToPixel(geoPoint);
}
points.add(new PointValue(site, point, point == null ? null : rectCalculator.iconRect(point), getValue(site, layer.getIndicatorIds())));
} else {
content.getUnmappedSites().add(site.getId());
}
}
}
List<Cluster> clusters = clusterer.cluster(map, points);
createMarkersFrom(clusters, map, content);
IconLayerLegend legend = new IconLayerLegend();
legend.setDefinition(layer);
content.addLegend(legend);
}
Aggregations