Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
maxep committed Jan 17, 2017
0 parents commit 389ebe6
Show file tree
Hide file tree
Showing 547 changed files with 23,765 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
@@ -0,0 +1,2 @@
xcuserdata
Carthage
26 changes: 26 additions & 0 deletions .travis.yml
@@ -0,0 +1,26 @@
language: objective-c
osx_image: xcode8
env:
global:
- FRAMEWORK_NAME=ClusterKit

before_install:
- brew update
- brew outdated carthage || brew upgrade carthage

install:
- gem install cocoapods
- gem install xcpretty --no-rdoc --no-ri --no-document --quiet

script:
- set -o pipefail && xcodebuild -project ClusterKit.xcodeproj -scheme $FRAMEWORK_NAME -sdk iphonesimulator10.0 -configuration Release -destination "platform=iOS Simulator,name=iPhone 7" clean build test | xcpretty -c
- pod lib lint --quick

before_deploy:
- carthage build --no-skip-current
- carthage archive $FRAMEWORK_NAME

deploy:
provider: releases
on:
repo: hulab/ClusterKit
43 changes: 43 additions & 0 deletions ClusterKit.podspec
@@ -0,0 +1,43 @@

Pod::Spec.new do |s|
s.name = "ClusterKit"
s.version = "0.1.0"
s.summary = "ClusterKit is a map clustering framework targeting MapKit and Google Maps."

s.description = <<-DESC
ClusterKit is an efficient clustering framework with the following features:
- Supports MapKit AND GoogleMaps.
- Comes with 2 clustering algorithms, a Grid Based Algorithm and a Non Hierarchical Distance Based Algorithm. Other algorithms can easily be integrated.
- Annotations are stored in a QuadTree for efficient region queries.
- Cluster center can be switched to Centroid, Nearest Centroid, Bottom.
- Written in Objective-C with full Swift interop support.
DESC

s.homepage = "https://github.com/hulab/ClusterKit"
# s.screenshots = "www.example.com/screenshots_1", "www.example.com/screenshots_2"
s.license = 'MIT'
s.author = { "Hulab" => "info@mapstr.com" }
s.source = { :git => "https://github.com/hulab/ClusterKit.git", :tag => s.version.to_s }
s.social_media_url = 'https://twitter.com/mapstr_app'

s.platform = :ios, '7.0'
s.requires_arc = true
s.default_subspecs = 'Core'

s.subspec 'Core' do |ss|
ss.frameworks = 'MapKit'
ss.source_files = 'ClusterKit/ClusterKit.h', 'ClusterKit/Core/**/*.{h,m}'
end

s.subspec 'MapKit' do |ss|
ss.dependency 'ClusterKit/Core'
ss.source_files = 'ClusterKit/MapKit'
end

# s.subspec 'GoogleMaps' do |ss|
# ss.dependency 'ClusterKit/Core'
# ss.dependency 'GoogleMaps', '~> 2.1'
# ss.source_files = 'ClusterKit/GoogleMaps'
# end

end
575 changes: 575 additions & 0 deletions ClusterKit.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

99 changes: 99 additions & 0 deletions ClusterKit.xcodeproj/xcshareddata/xcschemes/ClusterKit.xcscheme
@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0820"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9CC8756E1E0295A30019AA18"
BuildableName = "ClusterKit.framework"
BlueprintName = "ClusterKit"
ReferencedContainer = "container:ClusterKit.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9CC875771E0295A30019AA18"
BuildableName = "ClusterKitTests.xctest"
BlueprintName = "ClusterKitTests"
ReferencedContainer = "container:ClusterKit.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9CC8756E1E0295A30019AA18"
BuildableName = "ClusterKit.framework"
BlueprintName = "ClusterKit"
ReferencedContainer = "container:ClusterKit.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9CC8756E1E0295A30019AA18"
BuildableName = "ClusterKit.framework"
BlueprintName = "ClusterKit"
ReferencedContainer = "container:ClusterKit.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9CC8756E1E0295A30019AA18"
BuildableName = "ClusterKit.framework"
BlueprintName = "ClusterKit"
ReferencedContainer = "container:ClusterKit.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
39 changes: 39 additions & 0 deletions ClusterKit/ClusterKit.h
@@ -0,0 +1,39 @@
// ClusterKit.h
//
// Copyright © 2017 Hulab. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#import <UIKit/UIKit.h>

//! Project version number for ClusterKit.
FOUNDATION_EXPORT double ClusterKitVersionNumber;

//! Project version string for ClusterKit.
FOUNDATION_EXPORT const unsigned char ClusterKitVersionString[];

#import <ClusterKit/CKClusterManager.h>
#import <ClusterKit/CKAnnotationTree.h>
#import <ClusterKit/CKClusterAlgorithm.h>
#import <ClusterKit/CKNonHierarchicalDistanceBasedAlgorithm.h>
#import <ClusterKit/CKGridBasedAlgorithm.h>
#import <ClusterKit/CKMap.h>
#import <ClusterKit/CKCluster.h>


69 changes: 69 additions & 0 deletions ClusterKit/Core/Algorithm/CKClusterAlgorithm.h
@@ -0,0 +1,69 @@
// CKClusterAlgorithm.h
//
// Copyright © 2017 Hulab. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#import <Foundation/Foundation.h>
#import "CKAnnotationTree.h"

NS_ASSUME_NONNULL_BEGIN

/**
CKClusterAlgorithm represents a cluster algorithm parent class.
*/
@interface CKClusterAlgorithm : NSObject

/**
Returns an array of clusters for the given map rect at a certain zoom.
@param rect The map rect in which the clusters will be computed.
@param zoom The zoom value at which the clusters will be computed.
@param tree The tree where containing the annotations.
@return The list of cluster.
*/
- (NSArray<CKCluster *> *)clustersInRect:(MKMapRect)rect zoom:(double)zoom tree:(id<CKAnnotationTree>)tree;

@end

/**
CKClusterAlgorithm for CKCluster class registration.
The algorithm will use the registrated class to instantiate a cluster.
*/
@interface CKClusterAlgorithm (CKCluster)

/**
Registers a CKCluster class initializer.
@param clusterClass The CKCluster class initializer.
*/
- (void)registerClusterClass:(Class<CKCluster>)clusterClass;

/**
Instantiates a cluster using the registered class.
@param coordinate The cluster coordinate.
@return The newly-initialized cluster.
*/
- (__kindof CKCluster *)clusterWithCoordinate:(CLLocationCoordinate2D)coordinate;

@end

NS_ASSUME_NONNULL_END
62 changes: 62 additions & 0 deletions ClusterKit/Core/Algorithm/CKClusterAlgorithm.m
@@ -0,0 +1,62 @@
// CKClusterAlgorithm.m
//
// Copyright © 2017 Hulab. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#import "CKClusterAlgorithm.h"

@implementation CKClusterAlgorithm {
Class<CKCluster> _clusterClass;
}

- (instancetype)init {
self = [super init];
if (self) {
_clusterClass = [CKCluster class];
}
return self;
}

- (NSArray<CKCluster *> *)clustersInRect:(MKMapRect)rect zoom:(double)zoom tree:(id<CKAnnotationTree>)tree {
NSArray *annotations = [tree annotationsInRect:rect];
NSMutableArray *clusters = [NSMutableArray arrayWithCapacity:annotations.count];

for (id<CKAnnotation> annotation in annotations) {
CKCluster *cluster = [self clusterWithCoordinate:annotation.coordinate];
[cluster addAnnotation:annotation];
[clusters addObject:cluster];
}
return clusters;
}

@end

@implementation CKClusterAlgorithm (CKCluster)

- (void)registerClusterClass:(Class)clusterClass {
NSAssert([clusterClass conformsToProtocol:@protocol(CKCluster)], @"Can only register class conforming to CKCluster.");
_clusterClass = clusterClass;
}

- (CKCluster *)clusterWithCoordinate:(CLLocationCoordinate2D)coordinate {
return [_clusterClass clusterWithCoordinate:coordinate];
}

@end
43 changes: 43 additions & 0 deletions ClusterKit/Core/Algorithm/CKGridBasedAlgorithm.h
@@ -0,0 +1,43 @@
// CKGridBasedAlgorithm.h
//
// Copyright © 2017 Hulab. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#import "CKClusterAlgorithm.h"

/**
A simple grid-based clustering algorithm with O(n) performance.
The great advantage of grid-based clustering is its significant reduction of the computational complexity, especially for clustering very large data sets. The grid-based clustering approach differs from the conventional clustering algorithms in that it is concerned not with the data points but with the value space that surrounds the data points.
This grid-based implementation consists of the following the steps:
1. Iterate througth the annotations found in the given rect.
2. Associate each annotation to a grid cell. The rect is partitioned in a finite number of cells using the cell size property at the given zoom level.
3. Annotation are added to a centroid cluster {@see CKCentroidCluster} by default.
*/
@interface CKGridBasedAlgorithm : CKClusterAlgorithm

/**
The grid cell size.
*/
@property (nonatomic) CGFloat cellSize;

@end

0 comments on commit 389ebe6

Please sign in to comment.