Repo Created

This commit is contained in:
Fr4nz D13trich 2025-11-15 17:44:12 +01:00
parent eb305e2886
commit a8c22c65db
4784 changed files with 329907 additions and 2 deletions

View file

@ -0,0 +1,79 @@
/*
* Copyright 2013-2019 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
apply plugin: "com.android.library"
dependencies {
implementation project(":play-services-maps")
implementation "org.microg:vtm-android:0.9.1-mod"
implementation "org.microg:vtm-android:0.9.1-mod:natives-armeabi"
implementation "org.microg:vtm-android:0.9.1-mod:natives-armeabi-v7a"
implementation "org.microg:vtm-android:0.9.1-mod:natives-arm64-v8a"
implementation "org.microg:vtm-android:0.9.1-mod:natives-x86"
implementation "org.microg:vtm-android:0.9.1-mod:natives-x86_64"
implementation "org.microg:vtm-extras:0.9.1-mod"
implementation "org.microg:vtm-jts:0.9.1-mod"
implementation project(":play-services-maps-core-vtm-microg-theme")
implementation "androidx.appcompat:appcompat:$appcompatVersion"
}
def execResult(...args) {
def stdout = new ByteArrayOutputStream()
exec {
commandLine args
standardOutput = stdout
}
return stdout.toString().trim()
}
android {
namespace "org.microg.gms.maps.vtm"
compileSdkVersion androidCompileSdk
buildToolsVersion "$androidBuildVersionTools"
defaultConfig {
versionName version
minSdkVersion androidMinSdk
targetSdkVersion androidTargetSdk
ndk {
abiFilters "armeabi", "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
}
}
lintOptions {
disable "MissingTranslation", "InvalidPackage", "BatteryLife", "ImpliedQuantity", "MissingQuantity"
}
buildTypes {
release {
minifyEnabled true
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
if (file("user.gradle").exists()) {
apply from: "user.gradle"
}

View file

@ -0,0 +1,16 @@
apply plugin: 'java'
dependencies {
implementation "org.microg:vtm:0.9.1-mod"
}
sourceSets {
main {
java {
srcDir 'src'
}
resources {
srcDir 'resources'
}
}
}

View file

@ -0,0 +1,546 @@
<?xml version="1.0" encoding="UTF-8"?>
<rendertheme base-text-scale="1.25" map-background="#EAEAEA"
version="1" xmlns="http://opensciencemap.org/rendertheme"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://opensciencemap.org/rendertheme https://raw.githubusercontent.com/mapsforge/vtm/master/resources/rendertheme.xsd">
<style-line cap="butt" fix="true" id="fix" width="1.0"/>
<style-text fill="#AA333333" id="road:z12" k="name" priority="2" size="16" stroke="#eeeeee"
stroke-width="5.0"/>
<style-text fill="#AA333333" id="road:z13" k="name" priority="3" size="16" stroke="#eeeeee"
stroke-width="5.0"/>
<style-text fill="#AA333333" id="road:z14" k="name" priority="4" size="16" stroke="#eeeeee"
stroke-width="5.0"/>
<style-text fill="#AA333333" id="road:z16" k="name" priority="6" size="16" stroke="#eeeeee"
stroke-width="5.0"/>
<style-text fill="#FF783B03" id="road:orange" k="name" priority="6" size="16" stroke="#eeeeee"
stroke-width="5.0"/>
<style-text style="bold" caption="true" fill="#000000" id="park" k="name" priority="0"
size="17" stroke="#eeeeee" stroke-width="5.0"/>
<style-text caption="true" dy="-14" fill="#00afff" id="transit" k="name" priority="5" size="16"
stroke="#eeeeee" stroke-width="5.0"/>
<style-text caption="true" dy="-10" fill="#00afff" id="transit-small" k="name" priority="5"
size="16" stroke="#eeeeee" stroke-width="5.0"/>
<style-area fill="#33AA0000" id="debug" stroke="#FF0000" stroke-width="1"/>
<style-line id="debug" stroke="#00FF00"/>
<style-line id="building" stroke="#dcdcdc" use="fix" width="1.0"/>
<style-line id="building-poi" stroke="#EBD5AA" use="fix" width="1.0"/>
<style-line id="sub-building" stipple="10" stipple-stroke="#00000000" stipple-width="1.0"
use="building"/>
<style-area fill="#fff2f2f2" id="building" mesh="true"/>
<style-area fill="#ffFAEDD4" id="building-poi" mesh="true"/>
<style-line cap="square" id="road-fix" use="fix"/>
<style-line id="tertiary:z12" stroke="#ffffff" use="fix" width="1.0"/>
<style-line id="secondary:z12" stroke="#ffffff" use="fix" width="1.0"/>
<style-line id="trunk:z12" stroke="#FFF1B9" use="fix" width="1.0"/>
<style-line id="primary:z12" stroke="#ffebaf" use="fix" width="1.0"/>
<style-line id="motorway_link:z12" stroke="#fde7c4" use="fix" width="1.0"/>
<style-line id="motorway:z12" stroke="#fed89d" use="fix" width="1.5"/>
<style-line id="walkway:z18" stroke="#ffffff" width="0.3"/>
<style-line id="pedestrian:z18" stroke="#ffffff" width="0.7"/>
<style-line id="residential:z18" stroke="#ffffff" width="1.0"/>
<style-line id="tertiary:z18" stroke="#ffffff" width="1.2"/>
<style-line id="secondary:z18" stroke="#ffffff" width="1.4"/>
<style-line id="trunk:z18" stroke="#FFF1B9" width="1.6"/>
<style-line id="primary:z18" stroke="#ffebaf" width="1.6"/>
<style-line id="motorway_link:z18" stroke="#fde7c4" width="1.1"/>
<style-line id="motorway:z18" stroke="#fed89d" width="2.0"/>
<style-line fix="true" id="river:z14" stroke="#A3CCFF" width="1.5"/>
<style-line fix="true" id="river:z18" stroke="#A3CCFF" width="2.5"/>
<style-line fix="true" id="waterstream:z14" stroke="#A3CCFF" width="1.0"/>
<style-line fix="true" id="waterstream:z18" stroke="#A3CCFF" width="2.0"/>
<style-area fill="#CBE6A3" id="green"/>
<style-area blend="10" blend-fill="#D6E9B9" fill="#D4E4C9" id="lightgreen"/>
<style-area blend="10" blend-fill="#DDE6D5" fill="#D4E4C9" id="graygreen"/>
<style-area blend="10" blend-fill="#DAE8D1" fill="#D4E4C9" id="sportgreen"/>
<style-area blend="17" blend-fill="#EAEAEA" fill="#EFE4D6" id="city"/>
<style-area fill="#CEE7A5" id="national_park"/>
<style-area fill="#F9EDF1" id="medical"/>
<style-area fill="#E4E4DF" id="education"/>
<style-area fill="#EAEAEA" id="residential"/>
<m closed="yes" k="boundary" v="administrative">
<m k="place" v="suburb">
<area use="residential"/>
</m>
</m>
<m closed="yes" k="landuse" v="residential|commercial">
<area use="residential"/>
</m>
<m closed="yes" k="leisure" v="playing_fields|pitch|sports_centre|stadium">
<area use="sportgreen"/>
</m>
<m closed="yes" k="landuse" v="forest">
<area use="lightgreen"/>
</m>
<m closed="yes" k="leisure" v="park|garden">
<area use="lightgreen"/>
<text use="park"/>
</m>
<m closed="yes" k="leisure" v="golf_course|miniature_golf">
<area use="graygreen"/>
</m>
<m closed="yes" k="landuse" v="cemetery">
<area use="lightgreen"/>
</m>
<m closed="yes" k="amenity" v="grave_yard">
<area use="lightgreen"/>
</m>
<m closed="yes" k="boundary" v="national_park">
<area use="national_park"/>
<text use="park"/>
</m>
<m closed="yes" k="leisure" v="nature_reserve">
<area use="national_park"/>
<text use="park"/>
</m>
<m closed="yes" k="landuse" v="retail">
<area use="city"/>
</m>
<m closed="yes" k="amenity" v="marketplace">
<area use="city"/>
</m>
<m closed="yes" k="highway" v="pedestrian">
<area use="city"/>
</m>
<m closed="yes" k="shop" v="mall">
<area use="city"/>
</m>
<m closed="yes" k="amenity" v="college|university|school|kindergarten">
<area use="education"/>
</m>
<m closed="yes" k="amenity" v="hospital|clinic">
<area use="medical"/>
</m>
<m closed="no" k="boundary" v="administrative">
<m k="admin_level" v="1|2">
<line fix="true" stroke="#555555" width="2.0"/>
</m>
<m k="admin_level" v="3|4" zoom-min="7">
<line fix="true" stipple="20" stipple-stroke="#00888888" stroke="#88888888"
width="1.5"/>
</m>
</m>
<m k="waterway">
<m k="waterway" v="stream|drain|ditch">
<m zoom-max="15">
<m k="tunnel" v="~|no">
<line use="waterstream:z14"/>
</m>
<m k="tunnel" v="yes">
<line stipple="10" stipple-stroke="#00000000" stipple-width="1.0"
use="waterstream:z14"/>
</m>
</m>
<m zoom-min="15">
<m k="tunnel" v="~|no">
<line use="waterstream:z18"/>
</m>
<m k="tunnel" v="yes">
<line stipple="10" stipple-stroke="#00000000" stipple-width="1.0"
use="waterstream:z14"/>
</m>
</m>
</m>
<m k="waterway" v="river|canal">
<m zoom-max="15" zoom-min="12">
<m k="tunnel" v="~|no">
<line use="river:z14"/>
</m>
<m k="tunnel" v="yes">
<line stipple="10" stipple-stroke="#00000000" stipple-width="1.0"
use="river:z14"/>
</m>
</m>
<m zoom-min="15">
<m k="tunnel" v="~|no">
<line use="river:z18"/>
</m>
<m k="tunnel" v="yes">
<line stipple="10" stipple-stroke="#00000000" stipple-width="1.0"
use="river:z18"/>
</m>
</m>
</m>
</m>
<m closed="yes" k="natural" v="water">
<area fill="#A3CCFF"/>
</m>
<m e="way">
<outline-layer fix="true" id="motorway:z12" stroke="#7ac87800" width="1.2"/>
<outline-layer fix="true" id="motorway_link:z12" stroke="#47fea200" width="0.8"/>
<outline-layer fix="true" id="trunk:z12" stroke="#65ca9f00" width="1.4"/>
<outline-layer fix="true" id="motorway:z18" stroke="#7ac87800" width="1.8"/>
<outline-layer fix="true" id="motorway_link:z18" stroke="#47fea200" width="1.2"/>
<outline-layer fix="true" id="trunk:z18" stroke="#65ca9f00" width="1.8"/>
<!--<outline-layer id="primary" stroke="#aa7f7700" width="0.1"/>-->
<m k="highway">
<m k="area" v="~|no|false">
<m k="tunnel" v="yes|true">
<m k="highway" v="path|cycleway|footway|track|steps">
<line stipple="1" stipple-stroke="#00000000" use="walkway:z18"/>
</m>
<m k="highway" v="trunk_link|motorway_link">
<m zoom-max="13">
<line outline="motorway_link:z12" stroke="#E0DEDA"
use="motorway_link:z12"/>
</m>
<m zoom-min="13">
<line outline="motorway_link:z18" stroke="#E0DEDA"
use="motorway_link:z18"/>
</m>
</m>
<m k="highway" v="pedestrian">
<line fade="13" stroke="#E0DEDA" use="pedestrian:z18"/>
</m>
<m k="highway" v="residential|road|living_street|unclassified">
<line fade="13" stroke="#E0DEDA" use="residential:z18"/>
</m>
<m k="highway" v="tertiary|secondary_link">
<line stroke="#E0DEDA" use="tertiary:z12"/>
<line stroke="#E0DEDA" use="tertiary:z18"/>
</m>
<m k="highway" v="secondary|primary_link">
<line stroke="#E0DEDA" use="secondary:z12"/>
<line stroke="#E0DEDA" use="secondary:z18"/>
</m>
<m k="highway" v="trunk|primary">
<m zoom-max="13">
<line outline="trunk:z12" stroke="#E0DEDA" use="trunk:z12"/>
</m>
<m zoom-min="13">
<line outline="trunk:z18" stroke="#E0DEDA" use="trunk:z18"/>
</m>
</m>
<m k="highway" v="motorway">
<m zoom-max="13">
<line outline="motorway:z12" stroke="#E0DEDA" use="motorway:z12"/>
</m>
<m zoom-min="13">
<line outline="motorway:z12" stroke="#E0DEDA" use="motorway:z18"/>
</m>
<outline outline="motorway"/>
</m>
</m>
<m k="tunnel|bridge" v="~|no">
<m k="highway" v="service">
<m k="service" v="driveway|alley">
<line use="walkway:z18"/>
<text use="road:z16"/>
</m>
</m>
<m k="highway" v="path|cycleway|footway|track|steps">
<line use="walkway:z18"/>
<text use="road:z16"/>
</m>
<m k="highway" v="trunk_link|motorway_link">
<m zoom-max="13">
<line outline="motorway_link:z12" use="motorway_link:z12"/>
</m>
<m zoom-min="13">
<line outline="motorway_link:z18" use="motorway_link:z18"/>
</m>
</m>
<m k="highway" v="residential|road|living_street|pedestrian|unclassified">
<m k="highway" v="pedestrian">
<line fade="13" use="pedestrian:z18"/>
</m>
<m k="highway" v="-|pedestrian">
<line fade="13" use="residential:z18"/>
</m>
<m zoom-min="14">
<text use="road:z14"/>
</m>
</m>
<m k="highway" v="tertiary|secondary_link">
<line use="tertiary:z12"/>
<line use="tertiary:z18"/>
<m zoom-min="13">
<text use="road:z13"/>
</m>
</m>
<m k="highway" v="secondary|primary_link">
<line use="secondary:z12"/>
<line use="secondary:z18"/>
<m zoom-min="12">
<text use="road:z12"/>
</m>
</m>
<m k="highway" v="primary">
<m zoom-max="13">
<line outline="trunk:z12" use="primary:z12"/>
</m>
<m zoom-min="13">
<line outline="trunk:z18" use="primary:z18"/>
</m>
<m zoom-min="12">
<text use="road:orange"/>
</m>
<!-- disabled for mapsforge/vtm#193
<text caption="true" fill="#111111" k="ref" priority="2" size="10"
stroke="#FFDC36" stroke-width="16.0"/>
-->
</m>
<m k="highway" v="trunk">
<m zoom-max="13">
<line outline="trunk:z12" use="trunk:z12"/>
</m>
<m zoom-min="13">
<line outline="trunk:z18" use="trunk:z18"/>
</m>
<m zoom-min="12">
<text use="road:orange"/>
</m>
<!-- disabled for mapsforge/vtm#193
<text caption="true" fill="#111111" k="ref" priority="2" size="10"
stroke="#FFDC36" stroke-width="16.0"/>
-->
</m>
<m k="highway" v="motorway">
<m zoom-max="13">
<line outline="motorway:z12" use="motorway:z12"/>
</m>
<m zoom-min="13">
<line outline="motorway:z18" use="motorway:z18"/>
</m>
<!-- disabled for mapsforge/vtm#193
<text caption="true" fill="#eeeeee" k="ref" priority="2" size="14"
stroke="#E79608" stroke-width="16.0"/>
-->
<outline outline="motorway"/>
</m>
</m>
<m k="bridge">
<outline-layer id="bridge" stroke="#88202020" width="0.08"/>
<m k="bridge" v="-|no|false">
<m k="area" v="~|no|false">
<m v="track|footway|path|cycleway|steps">
<line cap="butt" outline="bridge" use="walkway:z18"/>
</m>
<m select="first">
<m v="footway|cycleway|track|path|bridleway">
<line use="walkway:z18"/>
</m>
<!--<m v="construction">
<line cap="square" outline="bridge" use="construction" />
</m>
<m v="service">
<line cap="square" outline="bridge" use="highway-service" />
</m>-->
</m>
<m select="first">
<m v="byway|pedestrian">
<line outline="bridge" use="pedestrian:z18"/>
<text use="road:z16"/>
</m>
<m v="residential|road|unclassified|living_street">
<line outline="bridge" use="residential:z18"/>
<text use="road:z14"/>
</m>
</m>
<m select="first">
<m v="tertiary|secondary_link">
<line cap="square" outline="bridge" use="tertiary:z18"/>
<text use="road:z13"/>
</m>
<m v="trunk_link|motorway_link">
<m zoom-max="13">
<line cap="square" outline="bridge"
use="motorway_link:z12"/>
</m>
<m zoom-min="13">
<line cap="square" outline="bridge"
use="motorway_link:z18"/>
</m>
</m>
<m v="secondary|primary_link">
<line cap="square" outline="bridge" use="secondary:z18"/>
<text use="road:z12"/>
</m>
<m v="trunk|primary">
<m zoom-max="13">
<line cap="square" outline="bridge" use="trunk:z12"/>
</m>
<m zoom-min="13">
<line cap="square" outline="bridge" use="trunk:z18"/>
</m>
</m>
<m v="motorway">
<m zoom-max="13">
<line cap="square" outline="bridge" use="motorway:z12"/>
</m>
<m zoom-min="13">
<line cap="square" outline="bridge" use="motorway:z18"/>
</m>
</m>
</m>
</m>
<m k="area" select="first" v="yes|true">
<m v="footway" zoom-min="15">
<area fill="#fefefe"/>
<line cap="butt" stroke="#c0c0c0" width="0.15"/>
</m>
<m v="pedestrian|service|unclassified|residential|road|living_street"
zoom-min="13">
<area fill="#eeffffff"/>
<line cap="butt" fix="true" stroke="#c0c0c0" width="1.0"/>
</m>
</m>
</m>
</m>
</m>
</m>
</m>
<m k="railway" v="tram|light_rail|subway|narrow_gauge|rail">
<m k="tunnel" v="~|no">
<line stipple="20" stipple-stroke="#AAAAAA" stipple-width="0.1" stroke="#CCCCCC"
use="fix"
width="0.1"/>
</m>
<m k="tunnel" v="yes">
<line stipple="20" stipple-stroke="#AAAAAA" stipple-width="1.0" stroke="#00000000"
use="fix"/>
</m>
</m>
<m k="highway|railway|public_transport" v="platform">
<m k="tunnel" v="~|no">
<line use="building"/>
<area use="building"/>
</m>
<m k="tunnel" v="yes">
<line use="sub-building"/>
</m>
</m>
<m k="building">
<m k="indoor|tunnel" v="yes" zoom-min="17">
<line use="sub-building"/>
</m>
<m k="indoor|tunnel" v="~|no" zoom-min="17">
<line use="building"/>
<m k="shop" v="~">
<m closed="yes">
<area use="building"/>
</m>
<!--<extrusion line-color="#ffdcdcdc" side-color="#66dcdcdc" top-color="#f2f2f2"/>-->
</m>
<m k="shop" v="mall">
<m closed="yes">
<area use="building-poi"/>
</m>
</m>
<caption style="bold" fill="#4040ff" k="name" priority="9" size="14"
stroke="#ffffff" stroke-width="2.0"/>
<caption style="bold" fill="#606060" k="addr:housenumber" priority="10" size="10"
stroke="#ffffff" stroke-width="2.0"/>
</m>
</m>
<m e="node" select="first">
<m k="place">
<m v="suburb" zoom-max="16" zoom-min="9">
<caption fill="#8B7F5F" k="name" priority="4" size="17"
stroke="#EAEAEA" stroke-width="5.0"/>
</m>
<m v="village" zoom-max="15" zoom-min="9">
<caption fill="#8B7F5F" k="name" priority="3" size="17" stroke="#EAEAEA"
stroke-width="5.0"/>
</m>
<m v="island" zoom-min="10">
<caption style="bold" fill="#000000" k="name" priority="1" size="20"
stroke="#EAEAEA" stroke-width="5.0"/>
</m>
<m v="town">
<m zoom-max="15" zoom-min="13">
<caption fill="#8B7F5F" k="name" priority="1" size="23" stroke="#EAEAEA"
stroke-width="5.0"/>
</m>
<m zoom-max="13" zoom-min="9">
<caption fill="#615942" k="name" priority="1" size="19"
stroke="#EAEAEA" stroke-width="5.0"/>
</m>
<m zoom-max="9">
<caption fill="#000000" k="name" priority="1" size="16"
stroke="#EAEAEA" stroke-width="5.0"/>
</m>
</m>
<m v="city">
<m zoom-max="15" zoom-min="13">
<caption fill="#615942" k="name" priority="1" size="24" stroke="#EAEAEA"
stroke-width="5.0"/>
</m>
<m zoom-max="13" zoom-min="9">
<caption fill="#000000" k="name" priority="1" size="24"
stroke="#EAEAEA" stroke-width="5.0"/>
</m>
<m zoom-max="9">
<caption dy="14" fill="#000000" k="name" priority="1" size="19"
stroke="#EAEAEA" stroke-width="5.0"
symbol="assets:symbols/dot_white.svg"/>
</m>
</m>
<m v="country" zoom-max="9">
<caption style="bold" fill="#000000" k="name" priority="0" size="20"
stroke="#EAEAEA" stroke-width="5.0"/>
</m>
</m>
<m k="railway">
<m v="station">
<m zoom-max="16">
<text use="transit-small"/>
<symbol src="assets:symbols/transit/train_station_small.svg"/>
</m>
<m zoom-min="16">
<text use="transit"/>
<symbol src="assets:symbols/transit/train_station.svg"/>
</m>
</m>
</m>
<m k="addr:housenumber" zoom-min="18">
<caption style="bold" fill="#606060" k="addr:housenumber" size="10" stroke="#EAEAEA"
stroke-width="2.0"/>
</m>
</m>
</rendertheme>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.0" width="580" height="580">
<metadata id="metadata1976"/>
<defs id="defs4">
<marker viewBox="0 0 10 10" refY="5" refX="10" orient="auto" markerWidth="4" markerUnits="strokeWidth" markerHeight="3" id="ArrowStart">
<path id="path2111" d="M 10 0 L 0 5 L 10 10 z"/>
</marker>
<marker viewBox="0 0 10 10" refY="5" orient="auto" markerWidth="4" markerUnits="strokeWidth" markerHeight="3" id="ArrowEnd">
<path id="path2108" d="M 0 0 L 10 5 L 0 10 z"/>
</marker>
</defs>
<circle id="path4175" cx="290" cy="290" r="91.4" fill="#fff" stroke="#000" stroke-linejoin="bevel" stroke-linecap="square" stroke-width="36"/>
</svg>

After

Width:  |  Height:  |  Size: 867 B

View file

@ -0,0 +1,7 @@
<svg width="256" height="256" viewBox="0 0 67.733332 67.733336" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -229.27)">
<rect x="6.35" y="238.26" width="55.033" height="55.033" ry="7.4083" opacity=".4"/>
<rect x="6.35" y="235.62" width="55.033" height="55.033" ry="7.4083" fill="#00afff"/>
<path d="m25.929 243.55c-4.6905 0-8.4667 3.7762-8.4667 8.4669v19.58c0 2.3453 1.8881 4.2334 4.2333 4.2334h0.47852l-4.0235 8.1796 4.7253 0.0216 3.9688-4.7244h14.308l3.9688 4.7244 4.7253-0.0216-4.0246-8.1796h0.21497c2.3453 0 4.2333-1.8881 4.2333-4.2334v-19.58c0-4.6907-3.7761-8.4669-8.4667-8.4669zm0.52917 4.2334h14.817c2.3453 0 4.2333 1.8881 4.2333 4.2334v9.5252h-23.283v-9.5252c0-2.3453 1.8881-4.2334 4.2333-4.2334zm-4.2333 18.521h5.2917v5.2918h-5.2917zm17.992 0h5.2917v5.2918h-5.2917z" fill="#fff"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 834 B

View file

@ -0,0 +1,7 @@
<svg width="256" height="256" viewBox="-33.866666 -33.866666 135.466664 135.466664" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -229.27)">
<rect x="6.35" y="238.26" width="55.033" height="55.033" ry="7.4083" opacity=".4"/>
<rect x="6.35" y="235.62" width="55.033" height="55.033" ry="7.4083" fill="#00afff"/>
<path d="m25.929 243.55c-4.6905 0-8.4667 3.7762-8.4667 8.4669v19.58c0 2.3453 1.8881 4.2334 4.2333 4.2334h0.47852l-4.0235 8.1796 4.7253 0.0216 3.9688-4.7244h14.308l3.9688 4.7244 4.7253-0.0216-4.0246-8.1796h0.21497c2.3453 0 4.2333-1.8881 4.2333-4.2334v-19.58c0-4.6907-3.7761-8.4669-8.4667-8.4669zm0.52917 4.2334h14.817c2.3453 0 4.2333 1.8881 4.2333 4.2334v9.5252h-23.283v-9.5252c0-2.3453 1.8881-4.2334 4.2333-4.2334zm-4.2333 18.521h5.2917v5.2918h-5.2917zm17.992 0h5.2917v5.2918h-5.2917z" fill="#fff"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 854 B

View file

@ -0,0 +1,41 @@
package org.oscim.theme;
import org.oscim.backend.AssetAdapter;
import java.io.InputStream;
public enum MicrogThemes implements ThemeFile {
DEFAULT("styles/microg.xml");
// TODO: night theme
private final String mPath;
MicrogThemes(String path) {
mPath = path;
}
@Override
public XmlRenderThemeMenuCallback getMenuCallback() {
return null;
}
@Override
public String getRelativePathPrefix() {
return "";
}
@Override
public InputStream getRenderThemeAsStream() {
return AssetAdapter.readFileAsStream(mPath);
}
@Override
public void setMenuCallback(XmlRenderThemeMenuCallback menuCallback) {
}
@Override
public boolean isMapsforgeTheme() {
return false;
}
}

View file

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2013-2019 microG Project Team
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application>
<provider
android:name=".data.SharedTileProvider"
android:authorities="org.microg.gms.maps.vtm.tile"
android:enabled="true"
android:exported="true"/>
</application>
</manifest>

View file

@ -0,0 +1,102 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.gms.maps.internal;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.os.Parcel;
import android.os.RemoteException;
import android.util.Log;
import androidx.annotation.Keep;
import com.google.android.gms.dynamic.IObjectWrapper;
import com.google.android.gms.dynamic.ObjectWrapper;
import com.google.android.gms.maps.GoogleMapOptions;
import com.google.android.gms.maps.StreetViewPanoramaOptions;
import com.google.android.gms.maps.model.internal.IBitmapDescriptorFactoryDelegate;
import org.microg.gms.maps.vtm.MapFragmentImpl;
import org.microg.gms.maps.vtm.MapViewImpl;
import org.microg.gms.maps.vtm.ResourcesContainer;
import org.microg.gms.maps.vtm.StreetViewPanoramaFragmentImpl;
import org.microg.gms.maps.vtm.StreetViewPanoramaViewImpl;
import org.microg.gms.maps.vtm.bitmap.BitmapDescriptorFactoryImpl;
import org.microg.gms.maps.vtm.camera.CameraUpdateFactoryImpl;
@Keep
public class CreatorImpl extends ICreator.Stub {
private static final String TAG = "GmsMapCreator";
@Override
public void init(IObjectWrapper resources) throws RemoteException {
initV2(resources, 0);
}
@Override
public IMapFragmentDelegate newMapFragmentDelegate(IObjectWrapper activity) throws RemoteException {
return new MapFragmentImpl((Activity) ObjectWrapper.unwrap(activity));
}
@Override
public IMapViewDelegate newMapViewDelegate(IObjectWrapper context, GoogleMapOptions options) throws RemoteException {
return new MapViewImpl((Context) ObjectWrapper.unwrap(context), options);
}
@Override
public ICameraUpdateFactoryDelegate newCameraUpdateFactoryDelegate() throws RemoteException {
return CameraUpdateFactoryImpl.get();
}
@Override
public IBitmapDescriptorFactoryDelegate newBitmapDescriptorFactoryDelegate() throws RemoteException {
return new BitmapDescriptorFactoryImpl();
}
@Override
public void initV2(IObjectWrapper resources, int flags) throws RemoteException {
ResourcesContainer.set((Resources) ObjectWrapper.unwrap(resources));
}
@Override
public IStreetViewPanoramaViewDelegate newStreetViewPanoramaViewDelegate(IObjectWrapper context, StreetViewPanoramaOptions options) {
return new StreetViewPanoramaViewImpl((Activity) ObjectWrapper.unwrap(context));
}
@Override
public IStreetViewPanoramaFragmentDelegate newStreetViewPanoramaFragmentDelegate(IObjectWrapper activity) {
return new StreetViewPanoramaFragmentImpl((Activity) ObjectWrapper.unwrap(activity));
}
@Override
public int getRendererType() throws RemoteException {
return 1;
}
@Override
public void logInitialization(IObjectWrapper context, int preferredRenderer) throws RemoteException {
Log.d(TAG, "VTM-based Map initialized (preferred renderer was " + preferredRenderer + ")");
}
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
if (super.onTransact(code, data, reply, flags)) return true;
Log.d(TAG, "onTransact [unknown]: " + code + ", " + data + ", " + flags);
return false;
}
}

View file

@ -0,0 +1,50 @@
/*
* Copyright (C) 2019 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.pm.PackageManager;
import org.microg.gms.common.Constants;
public class ApplicationContextWrapper extends ContextWrapper {
private Context applicationContext;
public ApplicationContextWrapper(Context base, Context applicationContext) {
super(base);
this.applicationContext = applicationContext;
}
public static ApplicationContextWrapper gmsContextWithAttachedApplicationContext(Context applicationContext) {
try {
Context context = applicationContext.createPackageContext(Constants.GMS_PACKAGE_NAME, CONTEXT_INCLUDE_CODE & CONTEXT_IGNORE_SECURITY);
return new ApplicationContextWrapper(context, applicationContext);
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(e);
}
}
public static ApplicationContextWrapper matchingApplicationContext(Context context) {
return new ApplicationContextWrapper(context, context);
}
@Override
public Context getApplicationContext() {
return applicationContext;
}
}

View file

@ -0,0 +1,340 @@
/*
* Copyright (C) 2019 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import com.google.android.gms.maps.internal.ISnapshotReadyCallback;
import com.google.android.gms.maps.model.CameraPosition;
import org.microg.gms.maps.vtm.camera.CameraUpdate;
import org.microg.gms.maps.vtm.markup.DrawableMarkup;
import org.microg.gms.maps.vtm.markup.MarkerItemMarkup;
import org.microg.gms.maps.vtm.markup.Markup;
import org.oscim.backend.GL;
import org.oscim.backend.GLAdapter;
import org.oscim.core.MapPosition;
import org.oscim.core.Point;
import org.oscim.event.Event;
import org.oscim.event.MotionEvent;
import org.oscim.layers.marker.ItemizedLayer;
import org.oscim.layers.marker.MarkerItem;
import org.oscim.layers.vector.geometries.Drawable;
import org.oscim.map.Viewport;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.microedition.khronos.opengles.GL10;
public class BackendMap implements ItemizedLayer.OnItemGestureListener<MarkerItem>, org.oscim.map.Map.InputListener, org.oscim.map.Map.UpdateListener {
private final static String TAG = "GmsMapBackend";
private final Context context;
private final BackendMapView mapView;
private final ContainerLayout container;
private final CameraUpdateListener cameraUpdateListener;
private final Map<String, Markup> markupMap = new HashMap<String, Markup>();
private final List<DrawableMarkup> drawableMarkups = new ArrayList<DrawableMarkup>();
private MarkerItemMarkup currentlyDraggedItem;
private float dragLastX = -1;
private float dragLastY = -1;
public BackendMap(Context context, final CameraUpdateListener cameraUpdateListener) {
this.context = context;
this.cameraUpdateListener = cameraUpdateListener;
mapView = new BackendMapView(context);
mapView.items().setOnItemGestureListener(this);
mapView.map().input.bind(this);
mapView.map().events.bind(this);
container = new ContainerLayout(context);
container.addView(mapView);
}
public Viewport getViewport() {
return mapView.map().viewport();
}
public void destroy() {
mapView.map().destroy();
}
public void onResume() {
mapView.onResume();
}
public void onPause() {
mapView.onPause();
}
public MapPosition getMapPosition() {
return mapView.map().getMapPosition();
}
public View getView() {
return container;
}
public boolean hasBuilding() {
return mapView.map().layers().contains(mapView.buildings());
}
public void setBuildings(boolean buildingsEnabled) {
if (!hasBuilding() && buildingsEnabled) {
mapView.map().layers().add(mapView.buildings());
} else if (hasBuilding() && !buildingsEnabled) {
mapView.map().layers().remove(mapView.buildings());
}
redraw();
}
public void redraw() {
mapView.map().updateMap(true);
}
public void applyCameraUpdate(CameraUpdate cameraUpdate) {
cameraUpdate.apply(mapView.map());
}
public void applyCameraUpdateAnimated(CameraUpdate cameraUpdate, int durationMs) {
cameraUpdate.applyAnimated(mapView.map(), durationMs);
}
public void stopAnimation() {
mapView.map().animator().cancel();
}
public synchronized <T extends DrawableMarkup> T add(T markup) {
if (markup == null) return null;
drawableMarkups.add(markup);
Collections.sort(drawableMarkups, new Comparator<DrawableMarkup>() {
@Override
public int compare(DrawableMarkup lhs, DrawableMarkup rhs) {
return Float.compare(lhs.getZIndex(), rhs.getZIndex());
}
});
updateDrawableLayer();
redraw();
return markup;
}
private synchronized void updateDrawableLayer() {
mapView.drawables().clear();
for (DrawableMarkup markup : drawableMarkups) {
Drawable drawable = markup.getDrawable(mapView.map());
if (drawable != null) {
mapView.drawables().add(drawable);
}
}
}
public synchronized <T extends MarkerItemMarkup> T add(T markup) {
if (markup == null) return null;
markupMap.put(markup.getId(), markup);
MarkerItem item = markup.getMarkerItem(context);
mapView.items().addItem(item);
redraw();
return markup;
}
public synchronized void clear() {
markupMap.clear();
mapView.items().removeAllItems();
drawableMarkups.clear();
mapView.drawables().clear();
redraw();
}
public synchronized void remove(Markup markup) {
if (markup instanceof MarkerItemMarkup) {
markupMap.remove(markup.getId());
MarkerItem toRemove = getByUid(markup.getId());
if (toRemove != null) mapView.items().removeItem(toRemove);
} else if (markup instanceof DrawableMarkup) {
drawableMarkups.remove(markup);
updateDrawableLayer();
mapView.drawables().update();
}
redraw();
}
private MarkerItem getByUid(String uid) {
for (MarkerItem markerItem : mapView.items().getItemList()) {
if (markerItem.getUid().equals(uid)) {
return markerItem;
}
}
return null;
}
public synchronized void update(Markup markup) {
if (markup == null) return;
if (markup instanceof MarkerItemMarkup) {
MarkerItem item = getByUid(markup.getId());
if (item != null) {
mapView.items().removeItem(item);
}
item = ((MarkerItemMarkup) markup).getMarkerItem(context);
if (item != null) {
mapView.items().addItem(item);
}
} else if (markup instanceof DrawableMarkup) {
updateDrawableLayer();
mapView.drawables().update();
}
redraw();
}
@Override
public boolean onItemSingleTapUp(int index, MarkerItem item) {
Markup markup = markupMap.get(item.getUid());
if (markup != null) {
if (markup.onClick()) return true;
}
return false;
}
@Override
public boolean onItemLongPress(int index, MarkerItem item) {
Markup markup = markupMap.get(item.getUid());
if (((MarkerItemMarkup) markup).isDraggable()) {
currentlyDraggedItem = (MarkerItemMarkup) markup;
currentlyDraggedItem.onDragStart();
return false;
} else {
Log.d(TAG, "onItemLongPress: " + markup);
return false;
}
}
@Override
public void onInputEvent(Event event, MotionEvent motionEvent) {
if ((motionEvent.getAction() == MotionEvent.ACTION_CANCEL || motionEvent.getAction() == MotionEvent.ACTION_UP) && currentlyDraggedItem != null) {
currentlyDraggedItem.onDragStop();
currentlyDraggedItem = null;
}
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
dragLastX = motionEvent.getX();
dragLastY = motionEvent.getY();
}
if (motionEvent.getAction() == MotionEvent.ACTION_MOVE && currentlyDraggedItem != null) {
Point out = new Point();
mapView.map().viewport().toScreenPoint(GmsMapsTypeHelper.fromLatLng(currentlyDraggedItem.getPosition()), out);
out.x += mapView.getWidth() / 2;
out.y += mapView.getHeight() / 2;
float mx = motionEvent.getX() - dragLastX;
float my = motionEvent.getY() - dragLastY;
currentlyDraggedItem.setPosition(GmsMapsTypeHelper.toLatLng(mapView.map().viewport().fromScreenPoint((float) out.getX() + mx, (float) out.getY() + my)));
currentlyDraggedItem.onDragProgress();
dragLastX += mx;
dragLastY += my;
}
}
public void snapshot(final Bitmap bitmap, final ISnapshotReadyCallback callback) {
mapView.queueEvent(new Runnable() {
@Override
public void run() {
Bitmap surface = createBitmapFromGLSurface(0, 0, mapView.getWidth(), mapView.getHeight(), GLAdapter.gl);
final Bitmap result;
if (bitmap != null) {
Canvas c = new Canvas(bitmap);
c.drawBitmap(surface, 0, 0, new Paint());
result = bitmap;
} else {
result = surface;
}
mapView.getHandler().post(new Runnable() {
@Override
public void run() {
Log.d(TAG, "snapshot result: " + result);
try {
callback.onBitmapReady(result);
} catch (RemoteException e) {
Log.w(TAG, e);
}
}
});
}
});
}
private Bitmap createBitmapFromGLSurface(int x, int y, int w, int h, GL gl) {
int bitmapBuffer[] = new int[w * h];
int bitmapSource[] = new int[w * h];
IntBuffer intBuffer = IntBuffer.wrap(bitmapBuffer);
intBuffer.position(0);
try {
gl.readPixels(x, y, w, h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, intBuffer);
int offset1, offset2;
for (int i = 0; i < h; i++) {
offset1 = i * w;
offset2 = (h - i - 1) * w;
for (int j = 0; j < w; j++) {
int texturePixel = bitmapBuffer[offset1 + j];
int blue = (texturePixel >> 16) & 0xff;
int red = (texturePixel << 16) & 0x00ff0000;
int pixel = (texturePixel & 0xff00ff00) | red | blue;
bitmapSource[offset2 + j] = pixel;
}
}
} catch (Exception e) {
Log.e(TAG, "createBitmapFromGLSurface: " + e.getMessage(), e);
return null;
}
return Bitmap.createBitmap(bitmapSource, w, h, Bitmap.Config.ARGB_8888);
}
public void setZoomGesturesEnabled(boolean enabled) {
mapView.map().getEventLayer().enableZoom(enabled);
}
public void setScrollGesturesEnabled(boolean enabled) {
mapView.map().getEventLayer().enableMove(enabled);
}
public void setRotateGesturesEnabled(boolean enabled) {
mapView.map().getEventLayer().enableRotation(enabled);
}
public void setTiltGesturesEnabled(boolean enabled) {
mapView.map().getEventLayer().enableTilt(enabled);
}
@Override
public void onMapEvent(Event event, MapPosition mapPosition) {
if (event == org.oscim.map.Map.ANIM_END || event == org.oscim.map.Map.POSITION_EVENT || event == org.oscim.map.Map.MOVE_EVENT)
cameraUpdateListener.onCameraUpdate(GmsMapsTypeHelper.toCameraPosition(mapPosition));
}
public interface CameraUpdateListener {
void onCameraUpdate(CameraPosition cameraPosition);
}
}

View file

@ -0,0 +1,156 @@
/*
* Copyright (C) 2019 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.pm.ApplicationInfo;
import android.graphics.BitmapFactory;
import android.util.AttributeSet;
import android.util.Log;
import org.microg.gms.maps.vtm.data.SharedTileCache;
import org.microg.gms.maps.vtm.markup.ClearableVectorLayer;
import org.microg.gms.maps.vtm.R;
import org.oscim.android.AndroidAssets;
import org.oscim.android.MapView;
import org.oscim.android.canvas.AndroidBitmap;
import org.oscim.layers.marker.ItemizedLayer;
import org.oscim.layers.marker.MarkerItem;
import org.oscim.layers.marker.MarkerSymbol;
import org.oscim.layers.tile.buildings.BuildingLayer;
import org.oscim.layers.tile.vector.VectorTileLayer;
import org.oscim.layers.tile.vector.labeling.LabelLayer;
import org.oscim.map.Layers;
import org.oscim.theme.MicrogThemes;
import org.oscim.tiling.ITileCache;
import org.oscim.tiling.source.oscimap4.OSciMap4TileSource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class BackendMapView extends MapView {
private static final String TAG = "GmsMapView";
private static boolean nativeLibLoaded = false;
private LabelLayer labels;
private BuildingLayer buildings;
private ItemizedLayer<MarkerItem> items;
private ClearableVectorLayer drawables;
static synchronized Context loadNativeLib(Context context) {
try {
if (nativeLibLoaded) return context;
ApplicationInfo otherAppInfo = context.getPackageManager().getApplicationInfo(context.getApplicationContext().getPackageName(), 0);
String primaryCpuAbi = (String) ApplicationInfo.class.getField("primaryCpuAbi").get(otherAppInfo);
if (primaryCpuAbi != null) {
String path = "lib/" + primaryCpuAbi + "/libvtm-jni.so";
File cacheFile = new File(context.getApplicationContext().getCacheDir().getAbsolutePath() + "/.gmscore/" + path);
cacheFile.getParentFile().mkdirs();
File apkFile = new File(context.getPackageCodePath());
if (!cacheFile.exists() || cacheFile.lastModified() < apkFile.lastModified()) {
ZipFile zipFile = new ZipFile(apkFile);
ZipEntry entry = zipFile.getEntry(path);
if (entry != null) {
copyInputStream(zipFile.getInputStream(entry), new FileOutputStream(cacheFile));
} else {
Log.d(TAG, "Can't load native library: " + path + " does not exist in " + apkFile);
}
}
Log.d(TAG, "Loading vtm-jni from " + cacheFile.getPath());
System.load(cacheFile.getAbsolutePath());
nativeLibLoaded = true;
}
} catch (Exception e) {
Log.w(TAG, e);
}
if (!nativeLibLoaded) {
Log.d(TAG, "Loading native vtm-jni");
System.loadLibrary("vtm-jni");
nativeLibLoaded = true;
}
return context;
}
private static final void copyInputStream(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) >= 0)
out.write(buffer, 0, len);
in.close();
out.close();
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onPause() {
super.onPause();
}
public BackendMapView(Context context) {
super(loadNativeLib(context));
if (context instanceof ContextWrapper) {
AndroidAssets.init(ApplicationContextWrapper.matchingApplicationContext(((ContextWrapper) context).getBaseContext()));
}
initialize();
}
public BackendMapView(Context context, AttributeSet attributeSet) {
super(loadNativeLib(context), attributeSet);
initialize();
}
ItemizedLayer<MarkerItem> items() {
return items;
}
BuildingLayer buildings() {
return buildings;
}
ClearableVectorLayer drawables() {
return drawables;
}
private void initialize() {
ITileCache cache = new SharedTileCache(getContext());
cache.setCacheSize(512 * (1 << 10));
OSciMap4TileSource tileSource = new OSciMap4TileSource();
tileSource.setCache(cache);
VectorTileLayer baseLayer = map().setBaseMap(tileSource);
Layers layers = map().layers();
layers.add(drawables = new ClearableVectorLayer(map()));
layers.add(labels = new LabelLayer(map(), baseLayer));
layers.add(buildings = new BuildingLayer(map(), baseLayer));
layers.add(items = new ItemizedLayer<MarkerItem>(map(), new MarkerSymbol(
new AndroidBitmap(BitmapFactory.decodeResource(getContext().getResources(), R.drawable.nop)), 0.5F, 1)));
map().setTheme(MicrogThemes.DEFAULT);
}
}

View file

@ -0,0 +1,34 @@
/*
* Copyright (C) 2019 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm;
import android.content.Context;
import android.widget.FrameLayout;
import org.oscim.utils.ThreadUtils;
public class ContainerLayout extends FrameLayout {
public ContainerLayout(Context context) {
super(context);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
ThreadUtils.init();
super.onLayout(changed, left, top, right, bottom);
}
}

View file

@ -0,0 +1,90 @@
/*
* Copyright (C) 2019 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import org.oscim.core.BoundingBox;
import org.oscim.core.Box;
import org.oscim.core.GeoPoint;
import org.oscim.core.MapPosition;
import org.oscim.core.MercatorProjection;
public class GmsMapsTypeHelper {
public static android.graphics.Point toPoint(org.oscim.core.Point in) {
return new android.graphics.Point((int) in.getX(), (int) in.getY());
}
public static GeoPoint fromLatLng(LatLng latLng) {
return new GeoPoint(latLng.latitude, latLng.longitude);
}
public static LatLng toLatLng(GeoPoint geoPoint) {
return new LatLng(geoPoint.getLatitude(), geoPoint.getLongitude());
}
public static LatLngBounds toLatLngBounds(Box box) {
double minLon = MercatorProjection.toLongitude(box.xmin);
double maxLon = MercatorProjection.toLongitude(box.xmax);
double minLat = MercatorProjection.toLatitude(box.ymax);
double maxLat = MercatorProjection.toLatitude(box.ymin);
if (Double.isNaN(minLon) || Double.isNaN(maxLon) || Double.isNaN(minLat) || Double.isNaN(maxLat))
minLon = maxLon = minLat = maxLat = 0;
return new LatLngBounds(new LatLng(minLat, minLon), new LatLng(maxLat, maxLon));
}
public static org.oscim.core.Point fromPoint(android.graphics.Point point) {
return new org.oscim.core.Point(point.x, point.y);
}
public static CameraPosition toCameraPosition(MapPosition mapPosition) {
return new CameraPosition(new LatLng(mapPosition.getLatitude(), mapPosition.getLongitude()),
toZoom(mapPosition.getScale()), mapPosition.getTilt(),
toBearing(mapPosition.getBearing()));
}
public static MapPosition fromCameraPosition(CameraPosition cameraPosition) {
MapPosition mapPosition = new MapPosition(cameraPosition.target.latitude,
cameraPosition.target.longitude, fromZoom(cameraPosition.zoom));
mapPosition.setTilt(cameraPosition.tilt);
mapPosition.setBearing(fromBearing(cameraPosition.bearing));
return mapPosition;
}
public static BoundingBox fromLatLngBounds(LatLngBounds bounds) {
return new BoundingBox(bounds.southwest.latitude, bounds.southwest.longitude,
bounds.northeast.latitude, bounds.northeast.longitude);
}
public static float fromBearing(float bearing) {
return -bearing;
}
public static float toBearing(float bearing) {
return -bearing;
}
public static double fromZoom(float zoom) {
return Math.pow(2, zoom);
}
public static float toZoom(double scale) {
return (float) (Math.log(scale) / Math.log(2));
}
}

View file

@ -0,0 +1,735 @@
/*
* Copyright (C) 2019 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm;
import android.content.Context;
import android.graphics.Bitmap;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Parcel;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import androidx.core.content.ContextCompat;
import com.google.android.gms.dynamic.IObjectWrapper;
import com.google.android.gms.dynamic.ObjectWrapper;
import com.google.android.gms.maps.GoogleMapOptions;
import com.google.android.gms.maps.internal.*;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.CircleOptions;
import com.google.android.gms.maps.model.GroundOverlayOptions;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.MapStyleOptions;
import com.google.android.gms.maps.model.PolygonOptions;
import com.google.android.gms.maps.model.PolylineOptions;
import com.google.android.gms.maps.model.TileOverlayOptions;
import com.google.android.gms.maps.model.internal.ICircleDelegate;
import com.google.android.gms.maps.model.internal.IGroundOverlayDelegate;
import com.google.android.gms.maps.model.internal.IMarkerDelegate;
import com.google.android.gms.maps.model.internal.IPolygonDelegate;
import com.google.android.gms.maps.model.internal.IPolylineDelegate;
import com.google.android.gms.maps.model.internal.ITileOverlayDelegate;
import org.microg.gms.maps.vtm.camera.CameraUpdate;
import org.microg.gms.maps.vtm.camera.MapPositionCameraUpdate;
import org.microg.gms.maps.vtm.markup.CircleImpl;
import org.microg.gms.maps.vtm.markup.GroundOverlayImpl;
import org.microg.gms.maps.vtm.markup.MarkerImpl;
import org.microg.gms.maps.vtm.markup.Markup;
import org.microg.gms.maps.vtm.markup.PolygonImpl;
import org.microg.gms.maps.vtm.markup.PolylineImpl;
import org.microg.gms.maps.vtm.markup.TileOverlayImpl;
import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
public class GoogleMapImpl extends IGoogleMapDelegate.Stub
implements UiSettingsImpl.UiSettingsListener, Markup.MarkupListener, BackendMap.CameraUpdateListener {
private static final String TAG = "GmsMapImpl";
private final GoogleMapOptions options;
private final Context context;
private final BackendMap backendMap;
private final UiSettingsImpl uiSettings;
private final ProjectionImpl projection;
private int markerCounter = 0;
private int circleCounter = 0;
private int polylineCounter = 0;
private int polygonCounter = 0;
private IOnMarkerClickListener onMarkerClickListener;
private IOnMarkerDragListener onMarkerDragListener;
private IOnCameraChangeListener onCameraChangeListener;
private IOnMyLocationChangeListener onMyLocationChangeListener;
private Criteria criteria;
private Location myLocation;
private LocationListener listener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
// TODO: Actually do my location overlay
myLocation = location;
if (onMyLocationChangeListener != null && location != null) {
try {
onMyLocationChangeListener.onMyLocationChanged(ObjectWrapper.wrap(location));
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
};
private GoogleMapImpl(Context context, GoogleMapOptions options) {
this.context = context;
Context appContext = context;
if (appContext.getApplicationContext() != null)
appContext = appContext.getApplicationContext();
Context wrappedContext = ApplicationContextWrapper.gmsContextWithAttachedApplicationContext(appContext);
backendMap = new BackendMap(wrappedContext, this);
uiSettings = new UiSettingsImpl(this);
projection = new ProjectionImpl(backendMap.getViewport());
this.options = options;
criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
criteria.setPowerRequirement(Criteria.POWER_MEDIUM);
if (options != null) initFromOptions();
}
public synchronized static GoogleMapImpl create(Context context, GoogleMapOptions options) {
return new GoogleMapImpl(context, options);
}
private void initFromOptions() {
try {
uiSettings.setCompassEnabled(options.getCompassEnabled());
uiSettings.setRotateGesturesEnabled(options.isRotateGesturesEnabled());
uiSettings.setTiltGesturesEnabled(options.isTiltGesturesEnabled());
uiSettings.setScrollGesturesEnabled(options.isScrollGesturesEnabled());
uiSettings.setZoomControlsEnabled(options.isZoomControlsEnabled());
uiSettings.setZoomGesturesEnabled(options.isZoomGesturesEnabled());
if (options.getCamera() != null) {
backendMap.applyCameraUpdate(MapPositionCameraUpdate.directMapPosition(GmsMapsTypeHelper.fromCameraPosition(options.getCamera())));
}
} catch (RemoteException e) {
// Never happens: not remote
}
}
public void onDestroy() {
backendMap.destroy();
}
@Override
public void onLowMemory() throws RemoteException {
Log.d(TAG, "unimplemented Method: onLowMemory");
}
@Override
public boolean useViewLifecycleWhenInFragment() throws RemoteException {
Log.d(TAG, "unimplemented Method: useViewLifecycleWhenInFragment");
return false;
}
@Override
public void onSaveInstanceState(Bundle outState) throws RemoteException {
Log.d(TAG, "unimplemented Method: onSaveInstanceState");
}
@Override
public void setContentDescription(String desc) throws RemoteException {
Log.d(TAG, "unimplemented Method: setContentDescription");
}
@Override
public void snapshotForTest(ISnapshotReadyCallback callback) throws RemoteException {
}
@Override
public void onEnterAmbient(Bundle bundle) throws RemoteException {
Log.d(TAG, "unimplemented Method: onEnterAmbient");
}
@Override
public void onExitAmbient() throws RemoteException {
Log.d(TAG, "unimplemented Method: onExitAmbient");
}
@Override
public void setOnGroundOverlayClickListener(IOnGroundOverlayClickListener listener) throws RemoteException {
Log.d(TAG, "unimplemented Method: setOnGroundOverlayClickListener");
}
@Override
public void setOnPolygonClickListener(IOnPolygonClickListener listener) throws RemoteException {
Log.d(TAG, "unimplemented Method: setOnPolygonClickListener");
}
@Override
public void setOnPolylineClickListener(IOnPolylineClickListener listener) throws RemoteException {
Log.d(TAG, "unimplemented Method: setOnPolylineClickListener");
}
@Override
public void setOnCircleClickListener(IOnCircleClickListener listener) throws RemoteException {
Log.d(TAG, "unimplemented Method: setCircleClickListener");
}
@Override
public boolean setMapStyle(MapStyleOptions options) throws RemoteException {
Log.d(TAG, "unimplemented Method: setMapStyle");
return true;
}
@Override
public void setMinZoomPreference(float minZoom) throws RemoteException {
Log.d(TAG, "unimplemented Method: setMinZoomPreference");
}
@Override
public void setMaxZoomPreference(float maxZoom) throws RemoteException {
Log.d(TAG, "unimplemented Method: setMaxZoomPreference");
}
@Override
public void resetMinMaxZoomPreference() throws RemoteException {
Log.d(TAG, "unimplemented Method: resetMinMaxZoomPreference");
}
@Override
public void setLatLngBoundsForCameraTarget(LatLngBounds bounds) throws RemoteException {
Log.d(TAG, "unimplemented Method: setLatLngBoundsForCameraTarget");
}
public void onResume() {
backendMap.onResume();
}
public void onPause() {
backendMap.onPause();
}
public View getView() {
return backendMap.getView();
}
private String getNextMarkerId() {
return "m" + markerCounter++;
}
private String getNextCircleId() {
return "c" + circleCounter++;
}
private String getNextPolylineId() {
return "l" + polylineCounter++;
}
private String getNextPolygonId() {
return "p" + polygonCounter++;
}
/*
Camera
*/
@Override
public CameraPosition getCameraPosition() throws RemoteException {
return GmsMapsTypeHelper.toCameraPosition(backendMap.getMapPosition());
}
@Override
public float getMaxZoomLevel() throws RemoteException {
return (float) backendMap.getViewport().limitScale(Double.MIN_VALUE);
}
@Override
public float getMinZoomLevel() throws RemoteException {
return (float) backendMap.getViewport().limitScale(Double.MAX_VALUE);
}
@Override
public void moveCamera(IObjectWrapper cameraUpdate) throws RemoteException {
CameraUpdate camUpdate = (CameraUpdate) ObjectWrapper.unwrap(cameraUpdate);
backendMap.applyCameraUpdate(camUpdate);
}
@Override
public void animateCamera(IObjectWrapper cameraUpdate) throws RemoteException {
CameraUpdate camUpdate = (CameraUpdate) ObjectWrapper.unwrap(cameraUpdate);
backendMap.applyCameraUpdateAnimated(camUpdate, 1000);
}
@Override
public void animateCameraWithCallback(IObjectWrapper cameraUpdate, ICancelableCallback callback)
throws RemoteException {
CameraUpdate camUpdate = (CameraUpdate) ObjectWrapper.unwrap(cameraUpdate);
backendMap.applyCameraUpdateAnimated(camUpdate, 1000);
}
@Override
public void animateCameraWithDurationAndCallback(IObjectWrapper cameraUpdate, int duration,
ICancelableCallback callback) throws RemoteException {
CameraUpdate camUpdate = (CameraUpdate) ObjectWrapper.unwrap(cameraUpdate);
backendMap.applyCameraUpdateAnimated(camUpdate, duration);
}
@Override
public IProjectionDelegate getProjection() throws RemoteException {
return projection;
}
@Override
public void stopAnimation() throws RemoteException {
backendMap.stopAnimation();
}
@Override
public void onCameraUpdate(CameraPosition cameraPosition) {
if (onCameraChangeListener != null) {
try {
onCameraChangeListener.onCameraChange(cameraPosition);
} catch (RemoteException e) {
Log.w(TAG, e);
}
}
}
/*
Markers, polylines, polygons, overlays, etc
*/
@Override
public ICircleDelegate addCircle(CircleOptions options) throws RemoteException {
return backendMap.add(new CircleImpl(getNextCircleId(), options, this));
}
@Override
public IPolylineDelegate addPolyline(PolylineOptions options) throws RemoteException {
return backendMap.add(new PolylineImpl(getNextPolylineId(), options, this));
}
@Override
public IPolygonDelegate addPolygon(PolygonOptions options) throws RemoteException {
return backendMap.add(new PolygonImpl(getNextPolygonId(), options, this));
}
@Override
public IMarkerDelegate addMarker(MarkerOptions options) throws RemoteException {
return backendMap.add(new MarkerImpl(getNextMarkerId(), options, this));
}
@Override
public IGroundOverlayDelegate addGroundOverlay(GroundOverlayOptions options)
throws RemoteException {
Log.d(TAG, "not yet usable: addGroundOverlay");
return new GroundOverlayImpl(options); // TODO
}
@Override
public ITileOverlayDelegate addTileOverlay(TileOverlayOptions options) throws RemoteException {
Log.d(TAG, "not yet usable: addTileOverlay");
return new TileOverlayImpl(); // TODO
}
@Override
public void setInfoWindowAdapter(IInfoWindowAdapter adapter) throws RemoteException {
Log.d(TAG, "not yet usable: setInfoWindowAdapter");
}
@Override
public void clear() throws RemoteException {
backendMap.clear();
markerCounter = 0;
circleCounter = 0;
polylineCounter = 0;
polygonCounter = 0;
}
@Override
public void update(Markup markup) {
backendMap.update(markup);
}
@Override
public void remove(Markup markup) {
backendMap.remove(markup);
}
@Override
public boolean onClick(Markup markup) {
if (markup instanceof IMarkerDelegate) {
if (onMarkerClickListener != null) {
try {
if (onMarkerClickListener.onMarkerClick((IMarkerDelegate) markup))
return true;
} catch (RemoteException e) {
Log.w(TAG, e);
}
}
// TODO: open InfoWindow
}
return false;
}
@Override
public void onDragStart(Markup markup) {
backendMap.setScrollGesturesEnabled(false);
backendMap.setRotateGesturesEnabled(false);
backendMap.setTiltGesturesEnabled(false);
backendMap.setZoomGesturesEnabled(false);
if (markup instanceof IMarkerDelegate) {
if (onMarkerDragListener != null) {
try {
onMarkerDragListener.onMarkerDragStart((IMarkerDelegate) markup);
} catch (RemoteException e) {
Log.w(TAG, e);
}
}
}
}
@Override
public void onDragStop(Markup markup) {
try {
backendMap.setScrollGesturesEnabled(uiSettings.isScrollGesturesEnabled());
backendMap.setRotateGesturesEnabled(uiSettings.isRotateGesturesEnabled());
backendMap.setTiltGesturesEnabled(uiSettings.isTiltGesturesEnabled());
backendMap.setZoomGesturesEnabled(uiSettings.isZoomGesturesEnabled());
} catch (RemoteException e) {
// Never happens, is local.
}
if (markup instanceof IMarkerDelegate) {
if (onMarkerDragListener != null) {
try {
onMarkerDragListener.onMarkerDragEnd((IMarkerDelegate) markup);
} catch (RemoteException e) {
Log.w(TAG, e);
}
}
}
}
@Override
public void onDragProgress(Markup markup) {
if (markup instanceof IMarkerDelegate) {
if (onMarkerDragListener != null) {
try {
onMarkerDragListener.onMarkerDrag((IMarkerDelegate) markup);
} catch (RemoteException e) {
Log.w(TAG, e);
}
}
}
}
/*
Map options
*/
@Override
public int getMapType() throws RemoteException {
return 0;
}
@Override
public void setMapType(int type) throws RemoteException {
}
@Override
public boolean isTrafficEnabled() throws RemoteException {
return false;
}
@Override
public void setTrafficEnabled(boolean traffic) throws RemoteException {
Log.w(TAG, "Traffic not yet supported");
}
@Override
public boolean isIndoorEnabled() throws RemoteException {
return false;
}
@Override
public void setIndoorEnabled(boolean indoor) throws RemoteException {
Log.w(TAG, "Indoor not yet supported");
}
@Override
public boolean isMyLocationEnabled() throws RemoteException {
return false;
}
@Override
public void setMyLocationEnabled(boolean myLocation) throws RemoteException {
Log.w(TAG, "MyLocation not yet supported");
boolean hasPermission = ContextCompat.checkSelfPermission(context, ACCESS_COARSE_LOCATION) == PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(context, ACCESS_FINE_LOCATION) == PERMISSION_GRANTED;
if (!hasPermission) {
throw new SecurityException("Neither " + ACCESS_COARSE_LOCATION + " nor " + ACCESS_FINE_LOCATION + " granted.");
}
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
if (myLocation) {
locationManager.requestLocationUpdates(5000, 10, criteria, listener, Looper.getMainLooper());
} else {
locationManager.removeUpdates(listener);
}
}
@Override
public boolean isBuildingsEnabled() throws RemoteException {
return backendMap.hasBuilding();
}
@Override
public void setBuildingsEnabled(boolean buildingsEnabled) throws RemoteException {
backendMap.setBuildings(buildingsEnabled);
}
/*
Ui Settings
*/
@Override
public IUiSettingsDelegate getUiSettings() throws RemoteException {
Log.d(TAG, "getUiSettings: " + uiSettings);
return uiSettings;
}
@Override
public void onUiSettingsChanged(UiSettingsImpl settings) throws RemoteException {
if (settings.isCompassEnabled()) {
Log.w(TAG, "Compass not yet supported");
}
if (settings.isMyLocationButtonEnabled()) {
Log.w(TAG, "MyLocationButton not yet supported");
}
if (settings.isZoomControlsEnabled()) {
Log.w(TAG, "ZoomControls not yet supported");
}
backendMap.setScrollGesturesEnabled(settings.isScrollGesturesEnabled());
backendMap.setRotateGesturesEnabled(settings.isRotateGesturesEnabled());
backendMap.setTiltGesturesEnabled(settings.isTiltGesturesEnabled());
backendMap.setZoomGesturesEnabled(settings.isZoomGesturesEnabled());
}
/*
Listener and callback setters
*/
@Override
public void setOnCameraChangeListener(IOnCameraChangeListener listener) throws RemoteException {
Log.d(TAG, "setOnCameraChangeListener");
this.onCameraChangeListener = listener;
}
@Override
public void setOnMapClickListener(IOnMapClickListener listener) throws RemoteException {
Log.d(TAG, "setOnMapClickListener: not supported");
}
@Override
public void setOnMapLongClickListener(IOnMapLongClickListener listener) throws RemoteException {
Log.d(TAG, "setOnMapLongClickListener: not supported");
}
@Override
public void setOnMarkerClickListener(IOnMarkerClickListener listener) throws RemoteException {
Log.d(TAG, "setOnMarkerClickListener");
this.onMarkerClickListener = listener;
}
@Override
public void setOnMarkerDragListener(IOnMarkerDragListener listener) throws RemoteException {
Log.d(TAG, "setOnMarkerDragListener");
this.onMarkerDragListener = listener;
}
@Override
public void setOnInfoWindowClickListener(IOnInfoWindowClickListener listener)
throws RemoteException {
Log.d(TAG, "setOnInfoWindowClickListener: not supported");
}
@Override
public void setOnMyLocationChangeListener(IOnMyLocationChangeListener listener)
throws RemoteException {
Log.d(TAG, "setOnMyLocationChangeListener");
this.onMyLocationChangeListener = listener;
}
@Override
public void setOnMyLocationButtonClickListener(IOnMyLocationButtonClickListener listener)
throws RemoteException {
Log.d(TAG, "setOnMyLocationButtonClickListener: not supported");
}
@Override
public void setOnMapLoadedCallback(final IOnMapLoadedCallback callback) throws RemoteException {
Log.d(TAG, "setOnMapLoadedCallback");
new Handler(context.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
Log.d(TAG, "Announce map loaded");
if (callback != null) {
try {
callback.onMapLoaded();
} catch (RemoteException e) {
Log.w(TAG, e);
}
}
}
}, 5000);
}
@Override
public void setWatermarkEnabled(boolean watermark) throws RemoteException {
Log.d(TAG, "unimplemented Method: setWatermarkEnabled");
}
@Override
public void onCreate(Bundle savedInstanceState) throws RemoteException {
Log.d(TAG, "unimplemented Method: onCreate");
}
@Override
public void setCameraMoveStartedListener(IOnCameraMoveStartedListener listener) throws RemoteException {
Log.d(TAG, "unimplemented Method: setCameraMoveStartedListener");
}
@Override
public void setCameraMoveListener(IOnCameraMoveListener listener) throws RemoteException {
Log.d(TAG, "unimplemented Method: setCameraMoveListener");
}
@Override
public void setCameraMoveCanceledListener(IOnCameraMoveCanceledListener listener) throws RemoteException {
Log.d(TAG, "unimplemented Method: setCameraMoveCanceledListener");
}
@Override
public void setCameraIdleListener(IOnCameraIdleListener listener) throws RemoteException {
Log.d(TAG, "unimplemented Method: setCameraIdleListener");
}
@Override
public void setOnInfoWindowLongClickListener(IOnInfoWindowLongClickListener listener) throws RemoteException {
Log.d(TAG, "unimplemented Method: setOnInfoWindowLongClickListener");
}
@Override
public void setOnInfoWindowCloseListener(IOnInfoWindowCloseListener listener) throws RemoteException {
Log.d(TAG, "unimplemented Method: setOnInfoWindowCloseListener");
}
@Override
public void onStart() throws RemoteException {
Log.d(TAG, "unimplemented Method: onStart");
}
@Override
public void onStop() throws RemoteException {
Log.d(TAG, "unimplemented Method: onStop");
}
@Override
public void setOnMyLocationClickListener(IOnMyLocationClickListener listener) throws RemoteException {
Log.d(TAG, "unimplemented Method: setOnMyLocationClickListener");
}
/*
Misc
*/
@Override
public IObjectWrapper getTestingHelper() throws RemoteException {
return null;
}
@Override
public void snapshot(ISnapshotReadyCallback callback, IObjectWrapper bitmap)
throws RemoteException {
Bitmap b = (Bitmap) ObjectWrapper.unwrap(bitmap);
Log.d(TAG, "snapshot!: " + b);
backendMap.snapshot(b, callback);
}
@Override
public void setPadding(int left, int top, int right, int bottom) throws RemoteException {
getView().setPadding(left, top, right, bottom);
}
@Override
public Location getMyLocation() throws RemoteException {
return myLocation;
}
@Override
public void setLocationSource(ILocationSourceDelegate locationSource) throws RemoteException {
Log.d(TAG, "setLocationSource: " + locationSource);
}
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
if (super.onTransact(code, data, reply, flags)) return true;
Log.d(TAG, "onTransact [unknown]: " + code + ", " + data + ", " + flags);
return false;
}
}

View file

@ -0,0 +1,180 @@
/*
* Copyright (C) 2019 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcel;
import android.os.RemoteException;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.gms.dynamic.IObjectWrapper;
import com.google.android.gms.dynamic.ObjectWrapper;
import com.google.android.gms.maps.GoogleMapOptions;
import com.google.android.gms.maps.internal.IGoogleMapDelegate;
import com.google.android.gms.maps.internal.IMapFragmentDelegate;
import com.google.android.gms.maps.internal.IOnMapReadyCallback;
public class MapFragmentImpl extends IMapFragmentDelegate.Stub {
private static final String TAG = "GmsMapFragImpl";
private GoogleMapImpl map;
private GoogleMapOptions options;
private Activity activity;
public MapFragmentImpl(Activity activity) {
this.activity = activity;
}
private GoogleMapImpl myMap() {
if (map == null) {
Log.d(TAG, "GoogleMap instance created");
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
map = GoogleMapImpl.create(inflater.getContext(), options);
}
return map;
}
@Override
public IGoogleMapDelegate getMap() throws RemoteException {
Log.d(TAG, "getMap");
return myMap();
}
@Override
public void onInflate(IObjectWrapper activity, GoogleMapOptions options,
Bundle savedInstanceState) throws RemoteException {
if (options != null) this.options = options;
Log.d(TAG, "onInflate");
}
@Override
public void onCreate(Bundle savedInstanceState) throws RemoteException {
Log.d(TAG, "onCreate");
//myMap().onCreate(savedInstanceState);
// TOOD: Certainly does not belong here and this way
Bundle mapState = savedInstanceState.getBundle("map_state");
if (mapState != null) {
mapState.setClassLoader(GoogleMapOptions.class.getClassLoader());
GoogleMapOptions options = mapState.getParcelable("MapOptions");
if (options != null) this.options = options;
}
}
@Override
public IObjectWrapper onCreateView(IObjectWrapper layoutInflater, IObjectWrapper container,
Bundle savedInstanceState) throws RemoteException {
Log.d(TAG, "onCreateView");
if (map == null) {
LayoutInflater inflater = (LayoutInflater) ObjectWrapper.unwrap(layoutInflater);
map = GoogleMapImpl.create(inflater.getContext(), options);
//map.onCreate(savedInstanceState);
} else {
View view = map.getView();
if (view.getParent() instanceof ViewGroup) {
((ViewGroup) view.getParent()).removeView(view);
}
}
return ObjectWrapper.wrap(myMap().getView());
}
@Override
public void onResume() throws RemoteException {
Log.d(TAG, "onResume");
myMap().onResume();
}
@Override
public void onPause() throws RemoteException {
Log.d(TAG, "onPause");
myMap().onPause();
}
@Override
public void onDestroyView() throws RemoteException {
Log.d(TAG, "onDestroyView");
}
@Override
public void onDestroy() throws RemoteException {
Log.d(TAG, "onDestroy");
myMap().onDestroy();
}
@Override
public void onLowMemory() throws RemoteException {
Log.d(TAG, "onLowMemory");
}
@Override
public void onEnterAmbient(Bundle bundle) throws RemoteException {
map.onEnterAmbient(bundle);
}
@Override
public void onExitAmbient() throws RemoteException {
map.onExitAmbient();
}
@Override
public void onStart() throws RemoteException {
map.onStart();
}
@Override
public void onStop() throws RemoteException {
map.onStop();
}
@Override
public void onSaveInstanceState(Bundle outState) throws RemoteException {
Log.d(TAG, "onSaveInstanceState: " + outState);
//myMap().onSaveInstanceState(outState);
}
@Override
public boolean isReady() throws RemoteException {
Log.d(TAG, "isReady");
return map != null;
}
@Override
public void getMapAsync(final IOnMapReadyCallback callback) throws RemoteException {
new Handler(activity.getMainLooper()).post(new Runnable() {
@Override
public void run() {
try {
callback.onMapReady(myMap());
} catch (RemoteException e) {
Log.w(TAG, e);
}
}
});
}
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
if (super.onTransact(code, data, reply, flags)) return true;
Log.d(TAG, "onTransact [unknown]: " + code + ", " + data + ", " + flags);
return false;
}
}

View file

@ -0,0 +1,151 @@
/*
* Copyright (C) 2019 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcel;
import android.os.RemoteException;
import android.util.Log;
import android.view.LayoutInflater;
import com.google.android.gms.dynamic.IObjectWrapper;
import com.google.android.gms.dynamic.ObjectWrapper;
import com.google.android.gms.maps.GoogleMapOptions;
import com.google.android.gms.maps.internal.IGoogleMapDelegate;
import com.google.android.gms.maps.internal.IMapViewDelegate;
import com.google.android.gms.maps.internal.IOnMapReadyCallback;
public class MapViewImpl extends IMapViewDelegate.Stub {
private static final String TAG = "GmsMapViewImpl";
private GoogleMapImpl map;
private GoogleMapOptions options;
private Context context;
private IOnMapReadyCallback readyCallback;
public MapViewImpl(Context context, GoogleMapOptions options) {
this.context = context;
this.options = options;
}
private GoogleMapImpl myMap() {
if (map == null) {
Log.d(TAG, "GoogleMap instance created");
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
map = GoogleMapImpl.create(inflater.getContext(), options);
}
return map;
}
@Override
public IGoogleMapDelegate getMap() throws RemoteException {
Log.d(TAG, "getMap");
return myMap();
}
@Override
public void onCreate(Bundle savedInstanceState) throws RemoteException {
//myMap().onCreate(savedInstanceState);
Log.d(TAG, "onCreate");
}
@Override
public void onResume() throws RemoteException {
Log.d(TAG, "onResume");
myMap().onResume();
if (readyCallback != null) {
try {
readyCallback.onMapReady(map);
readyCallback = null;
} catch (Exception e) {
Log.w(TAG, e);
}
}
}
@Override
public void onPause() throws RemoteException {
Log.d(TAG, "onPause");
myMap().onPause();
}
@Override
public void onDestroy() throws RemoteException {
Log.d(TAG, "onDestroy");
myMap().onDestroy();
}
@Override
public void onLowMemory() throws RemoteException {
Log.d(TAG, "onLowMemory");
}
@Override
public void onSaveInstanceState(Bundle outState) throws RemoteException {
Log.d(TAG, "onSaveInstanceState: " + outState);
}
@Override
public IObjectWrapper getView() throws RemoteException {
return ObjectWrapper.wrap(myMap().getView());
}
@Override
public void getMapAsync(final IOnMapReadyCallback callback) throws RemoteException {
Log.d(TAG, "getMapAsync");
new Handler(context.getMainLooper()).post(new Runnable() {
@Override
public void run() {
try {
callback.onMapReady(myMap());
} catch (RemoteException e) {
Log.w(TAG, e);
}
}
});
}
@Override
public void onEnterAmbient(Bundle bundle) throws RemoteException {
map.onEnterAmbient(bundle);
}
@Override
public void onExitAmbient() throws RemoteException {
map.onExitAmbient();
}
@Override
public void onStart() throws RemoteException {
map.onStart();
}
@Override
public void onStop() throws RemoteException {
map.onStop();
}
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
if (super.onTransact(code, data, reply, flags)) return true;
Log.d(TAG, "onTransact [unknown]: " + code + ", " + data + ", " + flags);
return false;
}
}

View file

@ -0,0 +1,59 @@
/*
* Copyright (C) 2019 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm;
import android.os.RemoteException;
import com.google.android.gms.dynamic.IObjectWrapper;
import com.google.android.gms.dynamic.ObjectWrapper;
import com.google.android.gms.maps.internal.IProjectionDelegate;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.VisibleRegion;
import org.oscim.core.Point;
import org.oscim.map.Viewport;
public class ProjectionImpl extends IProjectionDelegate.Stub {
private Viewport viewport;
private float[] extents = new float[8];
public ProjectionImpl(Viewport viewport) {
this.viewport = viewport;
}
@Override
public LatLng fromScreenLocation(IObjectWrapper obj) throws RemoteException {
Point point = GmsMapsTypeHelper
.fromPoint((android.graphics.Point) ObjectWrapper.unwrap(obj));
return GmsMapsTypeHelper
.toLatLng(viewport.fromScreenPoint((float) point.x, (float) point.y));
}
@Override
public IObjectWrapper toScreenLocation(LatLng latLng) throws RemoteException {
Point point = new Point();
viewport.toScreenPoint(GmsMapsTypeHelper.fromLatLng(latLng), point);
return ObjectWrapper.wrap(GmsMapsTypeHelper.toPoint(point));
}
@Override
public VisibleRegion getVisibleRegion() throws RemoteException {
viewport.getMapExtents(extents, 0);
// TODO: Support non-flat map extents
return new VisibleRegion(GmsMapsTypeHelper.toLatLngBounds(viewport.getBBox(null, 0)));
}
}

View file

@ -0,0 +1,35 @@
/*
* Copyright (C) 2019 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm;
import android.content.res.Resources;
public class ResourcesContainer {
private static Resources resources;
public static void set(Resources resources) {
ResourcesContainer.resources = resources;
}
public static Resources get() {
if (resources == null) {
throw new IllegalStateException("Resources have not been initialized");
} else {
return resources;
}
}
}

View file

@ -0,0 +1,97 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package org.microg.gms.maps.vtm;
import android.app.Activity;
import android.os.Bundle;
import android.os.RemoteException;
import android.widget.TextView;
import com.google.android.gms.dynamic.IObjectWrapper;
import com.google.android.gms.dynamic.ObjectWrapper;
import com.google.android.gms.maps.StreetViewPanoramaOptions;
import com.google.android.gms.maps.internal.IOnStreetViewPanoramaReadyCallback;
import com.google.android.gms.maps.internal.IStreetViewPanoramaDelegate;
import com.google.android.gms.maps.internal.IStreetViewPanoramaFragmentDelegate;
public class StreetViewPanoramaFragmentImpl extends IStreetViewPanoramaFragmentDelegate.Stub {
private Activity mActivity;
public StreetViewPanoramaFragmentImpl(Activity activity) {
this.mActivity = activity;
}
@Override
public IStreetViewPanoramaDelegate getStreetViewPanorama() throws RemoteException {
return null;
}
@Override
public void onInflate(IObjectWrapper activity, StreetViewPanoramaOptions options, Bundle savedInstanceState) throws RemoteException {
}
@Override
public void onCreate(Bundle savedInstanceState) throws RemoteException {
}
@Override
public IObjectWrapper onCreateView(IObjectWrapper layoutInflater, IObjectWrapper container, Bundle savedInstanceState) throws RemoteException {
return ObjectWrapper.wrap(new TextView(mActivity));
}
@Override
public void onResume() throws RemoteException {
}
@Override
public void onPause() throws RemoteException {
}
@Override
public void onDestroyView() throws RemoteException {
}
@Override
public void onDestroy() throws RemoteException {
}
@Override
public void onLowMemory() throws RemoteException {
}
@Override
public void onSaveInstanceState(Bundle outState) throws RemoteException {
}
@Override
public boolean isReady() throws RemoteException {
return false;
}
@Override
public void getStreetViewPanoramaAsync(IOnStreetViewPanoramaReadyCallback callback) throws RemoteException {
}
@Override
public void onStart() throws RemoteException {
}
@Override
public void onStop() throws RemoteException {
}
}

View file

@ -0,0 +1,81 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package org.microg.gms.maps.vtm;
import android.app.Activity;
import android.os.Bundle;
import android.os.RemoteException;
import android.widget.TextView;
import com.google.android.gms.dynamic.IObjectWrapper;
import com.google.android.gms.dynamic.ObjectWrapper;
import com.google.android.gms.maps.internal.IOnStreetViewPanoramaReadyCallback;
import com.google.android.gms.maps.internal.IStreetViewPanoramaDelegate;
import com.google.android.gms.maps.internal.IStreetViewPanoramaViewDelegate;
public class StreetViewPanoramaViewImpl extends IStreetViewPanoramaViewDelegate.Stub {
private Activity mActivity;
public StreetViewPanoramaViewImpl(Activity activity) {
this.mActivity = activity;
}
@Override
public IStreetViewPanoramaDelegate getStreetViewPanorama() throws RemoteException {
return null;
}
@Override
public void onCreate(Bundle savedInstanceState) throws RemoteException {
}
@Override
public void onResume() throws RemoteException {
}
@Override
public void onPause() throws RemoteException {
}
@Override
public void onDestroy() throws RemoteException {
}
@Override
public void onLowMemory() throws RemoteException {
}
@Override
public void onSaveInstanceState(Bundle outState) throws RemoteException {
}
@Override
public IObjectWrapper getView() throws RemoteException {
return ObjectWrapper.wrap(new TextView(mActivity));
}
@Override
public void getStreetViewPanoramaAsync(IOnStreetViewPanoramaReadyCallback callback) throws RemoteException {
}
@Override
public void onStart() throws RemoteException {
}
@Override
public void onStop() throws RemoteException {
}
}

View file

@ -0,0 +1,170 @@
/*
* Copyright (C) 2019 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm;
import android.os.RemoteException;
import com.google.android.gms.maps.internal.IUiSettingsDelegate;
public class UiSettingsImpl extends IUiSettingsDelegate.Stub {
private boolean zoomControlsEnabled;
private boolean compassEnabled;
private boolean myLocationButtonEnabled;
private boolean scrollGesturesEnabled = true;
private boolean zoomGesturesEnabled = true;
private boolean tiltGesturesEnabled = true;
private boolean rotateGesturesEnabled = true;
private boolean allGesturesEnabled = true;
private boolean indoorLevelPickerEnabled = false;
private boolean mapToolbarEnabled = false;
private boolean scrollGesturesEnabledDuringRotateOrZoom = true;
private UiSettingsListener listener;
public UiSettingsImpl() {
}
public UiSettingsImpl(UiSettingsListener listener) {
this.listener = listener;
}
public void setListener(UiSettingsListener listener) {
this.listener = listener;
}
@Override
public void setZoomControlsEnabled(boolean zoomControlsEnabled) throws RemoteException {
this.zoomControlsEnabled = zoomControlsEnabled;
listener.onUiSettingsChanged(this);
}
@Override
public void setCompassEnabled(boolean compassEnabled) throws RemoteException {
this.compassEnabled = compassEnabled;
listener.onUiSettingsChanged(this);
}
@Override
public void setMyLocationButtonEnabled(boolean myLocationButtonEnabled) throws RemoteException {
this.myLocationButtonEnabled = myLocationButtonEnabled;
listener.onUiSettingsChanged(this);
}
@Override
public void setScrollGesturesEnabled(boolean scrollGesturesEnabled) throws RemoteException {
this.scrollGesturesEnabled = scrollGesturesEnabled;
listener.onUiSettingsChanged(this);
}
@Override
public void setZoomGesturesEnabled(boolean zoomGestures) throws RemoteException {
this.zoomGesturesEnabled = zoomGestures;
listener.onUiSettingsChanged(this);
}
@Override
public void setTiltGesturesEnabled(boolean tiltGesturesEnabled) throws RemoteException {
this.tiltGesturesEnabled = tiltGesturesEnabled;
listener.onUiSettingsChanged(this);
}
@Override
public void setRotateGesturesEnabled(boolean rotateGesturesEnabled) throws RemoteException {
this.rotateGesturesEnabled = rotateGesturesEnabled;
listener.onUiSettingsChanged(this);
}
@Override
public void setAllGesturesEnabled(boolean gestures) throws RemoteException {
scrollGesturesEnabled = gestures;
zoomGesturesEnabled = gestures;
tiltGesturesEnabled = gestures;
rotateGesturesEnabled = gestures;
listener.onUiSettingsChanged(this);
}
@Override
public boolean isZoomControlsEnabled() throws RemoteException {
return zoomControlsEnabled;
}
@Override
public boolean isCompassEnabled() throws RemoteException {
return compassEnabled;
}
@Override
public boolean isMyLocationButtonEnabled() throws RemoteException {
return myLocationButtonEnabled;
}
@Override
public boolean isScrollGesturesEnabled() throws RemoteException {
return scrollGesturesEnabled;
}
@Override
public boolean isZoomGesturesEnabled() throws RemoteException {
return zoomGesturesEnabled;
}
@Override
public boolean isTiltGesturesEnabled() throws RemoteException {
return tiltGesturesEnabled;
}
@Override
public boolean isRotateGesturesEnabled() throws RemoteException {
return rotateGesturesEnabled;
}
@Override
public void setIndoorLevelPickerEnabled(boolean indoorLevelPicker) throws RemoteException {
this.indoorLevelPickerEnabled = indoorLevelPicker;
listener.onUiSettingsChanged(this);
}
@Override
public boolean isIndoorLevelPickerEnabled() throws RemoteException {
return indoorLevelPickerEnabled;
}
@Override
public void setMapToolbarEnabled(boolean mapToolbar) throws RemoteException {
this.mapToolbarEnabled = mapToolbar;
listener.onUiSettingsChanged(this);
}
@Override
public boolean isMapToolbarEnabled() throws RemoteException {
return mapToolbarEnabled;
}
@Override
public void setScrollGesturesEnabledDuringRotateOrZoom(boolean scrollDuringZoom) throws RemoteException {
this.scrollGesturesEnabledDuringRotateOrZoom = scrollDuringZoom;
listener.onUiSettingsChanged(this);
}
@Override
public boolean isScrollGesturesEnabledDuringRotateOrZoom() throws RemoteException {
return scrollGesturesEnabledDuringRotateOrZoom;
}
public static interface UiSettingsListener {
void onUiSettingsChanged(UiSettingsImpl settings) throws RemoteException;
}
}

View file

@ -0,0 +1,41 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm.bitmap;
import android.content.Context;
import android.graphics.Bitmap;
public abstract class AbstractBitmapDescriptor {
private Bitmap bitmap;
protected abstract Bitmap generateBitmap(Context context);
public Bitmap loadBitmap(Context context) {
if (bitmap == null) {
synchronized (this) {
if (bitmap == null)
bitmap = generateBitmap(context);
}
}
return bitmap;
}
public Bitmap getBitmap() {
return bitmap;
}
}

View file

@ -0,0 +1,41 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm.bitmap;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import java.io.IOException;
public class AssetBitmapDescriptor extends AbstractBitmapDescriptor {
private String assetName;
public AssetBitmapDescriptor(String assetName) {
this.assetName = assetName;
}
@Override
protected Bitmap generateBitmap(Context context) {
try {
return BitmapFactory.decodeStream(context.getAssets().open(assetName));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}

View file

@ -0,0 +1,38 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm.bitmap;
import android.content.Context;
import android.graphics.Bitmap;
public class BitmapBitmapDescriptor extends AbstractBitmapDescriptor {
private Bitmap bitmap;
public BitmapBitmapDescriptor(Bitmap bitmap) {
this.bitmap = bitmap;
}
@Override
public Bitmap getBitmap() {
return bitmap;
}
@Override
public Bitmap generateBitmap(Context context) {
return bitmap;
}
}

View file

@ -0,0 +1,72 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm.bitmap;
import android.graphics.Bitmap;
import android.os.Parcel;
import android.os.RemoteException;
import android.util.Log;
import com.google.android.gms.dynamic.IObjectWrapper;
import com.google.android.gms.dynamic.ObjectWrapper;
import com.google.android.gms.maps.model.internal.IBitmapDescriptorFactoryDelegate;
public class BitmapDescriptorFactoryImpl extends IBitmapDescriptorFactoryDelegate.Stub {
private static final String TAG = "GmsBitmapDescFactory";
@Override
public IObjectWrapper fromResource(int resourceId) throws RemoteException {
return ObjectWrapper.wrap(new ResourceBitmapDescriptor(resourceId));
}
@Override
public IObjectWrapper fromAsset(String assetName) throws RemoteException {
return ObjectWrapper.wrap(new AssetBitmapDescriptor(assetName));
}
@Override
public IObjectWrapper fromFile(String fileName) throws RemoteException {
return ObjectWrapper.wrap(new FileBitmapDescriptor(fileName));
}
@Override
public IObjectWrapper defaultMarker() throws RemoteException {
return ObjectWrapper.wrap(DefaultBitmapDescriptor.DEFAULT_DESCRIPTOR);
}
@Override
public IObjectWrapper defaultMarkerWithHue(float hue) throws RemoteException {
return ObjectWrapper.wrap(new DefaultBitmapDescriptor(hue));
}
@Override
public IObjectWrapper fromBitmap(Bitmap bitmap) throws RemoteException {
return ObjectWrapper.wrap(new BitmapBitmapDescriptor(bitmap));
}
@Override
public IObjectWrapper fromPath(String absolutePath) throws RemoteException {
return ObjectWrapper.wrap(new PathBitmapDescriptor(absolutePath));
}
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
if (super.onTransact(code, data, reply, flags)) return true;
Log.d(TAG, "onTransact [unknown]: " + code + ", " + data + ", " + flags);
return false;
}
}

View file

@ -0,0 +1,93 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm.bitmap;
import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;
import com.google.android.gms.dynamic.IObjectWrapper;
import com.google.android.gms.dynamic.ObjectWrapper;
import com.google.android.gms.maps.model.BitmapDescriptor;
import java.util.HashSet;
import java.util.Set;
public class BitmapDescriptorImpl {
private BitmapDescriptor descriptor;
private boolean loadStarted = false;
private Set<Runnable> waitingForLoad = new HashSet<Runnable>();
public BitmapDescriptorImpl(IObjectWrapper remoteObject) {
this(new BitmapDescriptor(remoteObject));
}
public BitmapDescriptorImpl(BitmapDescriptor descriptor) {
this.descriptor = descriptor;
}
public BitmapDescriptorImpl() {
this(new ObjectWrapper<DefaultBitmapDescriptor>(new DefaultBitmapDescriptor(0)));
}
public AbstractBitmapDescriptor getDescriptor() {
if (descriptor.getRemoteObject() == null)
return null;
Object unwrap = ObjectWrapper.unwrap(descriptor.getRemoteObject());
if (unwrap instanceof AbstractBitmapDescriptor) {
return ((AbstractBitmapDescriptor) unwrap);
} else {
return null;
}
}
public Bitmap getBitmap() {
if (getDescriptor() != null) {
return getDescriptor().getBitmap();
}
return null;
}
public synchronized boolean loadBitmapAsync(final Context context, Runnable after) {
if (getBitmap() != null) {
return false;
}
waitingForLoad.add(after);
if (loadStarted)
return true;
loadStarted = true;
if (getDescriptor() != null) {
new Thread(new Runnable() {
@Override
public void run() {
Log.d("BitmapDescriptor", "Start loading " + getDescriptor());
if (getDescriptor().loadBitmap(context) != null) {
Set<Runnable> waitingForLoad;
synchronized (BitmapDescriptorImpl.this) {
waitingForLoad = BitmapDescriptorImpl.this.waitingForLoad;
}
for (Runnable after : waitingForLoad) {
after.run();
}
}
Log.d("BitmapDescriptor", "Done loading " + getDescriptor());
}
}).start();
}
return true;
}
}

View file

@ -0,0 +1,105 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm.bitmap;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import com.google.android.gms.dynamic.ObjectWrapper;
import org.microg.gms.maps.vtm.ResourcesContainer;
import org.microg.gms.maps.vtm.R;
public class DefaultBitmapDescriptor extends AbstractBitmapDescriptor {
public static final DefaultBitmapDescriptor DEFAULT_DESCRIPTOR = new DefaultBitmapDescriptor(0);
public static final BitmapDescriptorImpl DEFAULT_DESCRIPTOR_IMPL = new BitmapDescriptorImpl(ObjectWrapper.wrap(DEFAULT_DESCRIPTOR));
public static final int DEGREES = 360;
private final float hue;
public DefaultBitmapDescriptor(float hue) {
this.hue = hue > 180 ? -DEGREES + hue : hue;
}
@Override
public Bitmap generateBitmap(Context context) {
Bitmap source;
if (this == DEFAULT_DESCRIPTOR) {
source = BitmapFactory.decodeResource(ResourcesContainer.get(), R.drawable.maps_default_marker);
} else {
source = DEFAULT_DESCRIPTOR.loadBitmap(context);
}
if (hue % DEGREES == 0) return source;
Paint paint = new Paint();
paint.setColorFilter(adjustHue(hue));
Bitmap bitmap = Bitmap.createBitmap(source.getWidth(), source.getHeight(), source.getConfig());
Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(source, 0, 0, paint);
return bitmap;
}
/**
* Creates a HUE ajustment ColorFilter
* <p/>
* see http://groups.google.com/group/android-developers/browse_thread/thread/9e215c83c3819953
* see http://gskinner.com/blog/archives/2007/12/colormatrix_cla.html
*
* @param value degrees to shift the hue.
*/
public static ColorFilter adjustHue(float value) {
ColorMatrix cm = new ColorMatrix();
adjustHue(cm, value);
return new ColorMatrixColorFilter(cm);
}
/**
* see http://groups.google.com/group/android-developers/browse_thread/thread/9e215c83c3819953
* see http://gskinner.com/blog/archives/2007/12/colormatrix_cla.html
*/
public static void adjustHue(ColorMatrix cm, float value) {
value = cleanValue(value, 180f) / 180f * (float) Math.PI;
if (value == 0) {
return;
}
float cosVal = (float) Math.cos(value);
float sinVal = (float) Math.sin(value);
float lumR = 0.213f;
float lumG = 0.715f;
float lumB = 0.072f;
float[] mat = new float[]{lumR + cosVal * (1 - lumR) + sinVal * (-lumR),
lumG + cosVal * (-lumG) + sinVal * (-lumG),
lumB + cosVal * (-lumB) + sinVal * (1 - lumB), 0, 0,
lumR + cosVal * (-lumR) + sinVal * (0.143f),
lumG + cosVal * (1 - lumG) + sinVal * (0.140f),
lumB + cosVal * (-lumB) + sinVal * (-0.283f), 0, 0,
lumR + cosVal * (-lumR) + sinVal * (-(1 - lumR)),
lumG + cosVal * (-lumG) + sinVal * (lumG),
lumB + cosVal * (1 - lumB) + sinVal * (lumB),
0, 0, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 0f, 0f, 1f};
cm.postConcat(new ColorMatrix(mat));
}
protected static float cleanValue(float p_val, float p_limit) {
return Math.min(p_limit, Math.max(-p_limit, p_val));
}
}

View file

@ -0,0 +1,34 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm.bitmap;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
public class FileBitmapDescriptor extends AbstractBitmapDescriptor {
private String fileName;
public FileBitmapDescriptor(String fileName) {
this.fileName = fileName;
}
@Override
public Bitmap generateBitmap(Context context) {
return BitmapFactory.decodeFile(fileName);
}
}

View file

@ -0,0 +1,22 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm.bitmap;
public class PathBitmapDescriptor {
public PathBitmapDescriptor(String absolutePath) {
}
}

View file

@ -0,0 +1,55 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm.bitmap;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import androidx.core.content.ContextCompat;
public class ResourceBitmapDescriptor extends AbstractBitmapDescriptor {
private int resourceId;
public ResourceBitmapDescriptor(int resourceId) {
this.resourceId = resourceId;
}
@Override
public Bitmap generateBitmap(Context context) {
return drawableToBitmap(context, ContextCompat.getDrawable(context.getApplicationContext(), resourceId));
}
public static Bitmap drawableToBitmap(Context context, Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
return DefaultBitmapDescriptor.DEFAULT_DESCRIPTOR.loadBitmap(context);
}
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
}

View file

@ -0,0 +1,24 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm.camera;
import org.oscim.map.Map;
public interface CameraUpdate {
void apply(Map map);
void applyAnimated(Map map, int duration);
}

View file

@ -0,0 +1,203 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm.camera;
import android.os.RemoteException;
import android.util.Log;
import com.google.android.gms.dynamic.IObjectWrapper;
import com.google.android.gms.dynamic.ObjectWrapper;
import com.google.android.gms.maps.internal.ICameraUpdateFactoryDelegate;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import org.microg.gms.maps.vtm.GmsMapsTypeHelper;
import org.oscim.core.MapPosition;
import org.oscim.map.Map;
public class CameraUpdateFactoryImpl extends ICameraUpdateFactoryDelegate.Stub {
private static final String TAG = "GmsMapCamUpdateFactory";
private CameraUpdateFactoryImpl() {
}
private static CameraUpdateFactoryImpl instance;
public static CameraUpdateFactoryImpl get() {
if (instance == null) {
instance = new CameraUpdateFactoryImpl();
}
return instance;
}
@Override
public IObjectWrapper zoomIn() throws RemoteException {
Log.d(TAG, "zoomIn");
return new ObjectWrapper<CameraUpdate>(new MapPositionCameraUpdate() {
@Override
MapPosition getMapPosition(Map map) {
MapPosition mapPosition = map.getMapPosition();
mapPosition.setScale(GmsMapsTypeHelper.fromZoom(
GmsMapsTypeHelper.toZoom(mapPosition.getScale()) + 1));
return mapPosition;
}
});
}
@Override
public IObjectWrapper zoomOut() throws RemoteException {
Log.d(TAG, "zoomOut");
return new ObjectWrapper<CameraUpdate>(new MapPositionCameraUpdate() {
@Override
MapPosition getMapPosition(Map map) {
MapPosition mapPosition = map.getMapPosition();
mapPosition.setScale(GmsMapsTypeHelper.fromZoom(
GmsMapsTypeHelper.toZoom(mapPosition.getScale()) - 1));
return mapPosition;
}
});
}
@Override
public IObjectWrapper scrollBy(final float x, final float y) throws RemoteException {
Log.d(TAG, "scrollBy");
return new ObjectWrapper<CameraUpdate>(new MapPositionCameraUpdate() {
@Override
MapPosition getMapPosition(Map map) {
MapPosition mapPosition = map.getMapPosition();
mapPosition.setPosition(map.viewport()
.fromScreenPoint((float) (map.getWidth() / 2.0 + x),
(float) (map.getHeight() / 2.0 + y)));
return mapPosition;
}
});
}
@Override
public IObjectWrapper zoomTo(final float zoom) throws RemoteException {
Log.d(TAG, "zoomTo");
return new ObjectWrapper<CameraUpdate>(new MapPositionCameraUpdate() {
@Override
MapPosition getMapPosition(Map map) {
MapPosition mapPosition = map.getMapPosition();
mapPosition.setScale(GmsMapsTypeHelper.fromZoom(zoom));
return mapPosition;
}
});
}
@Override
public IObjectWrapper zoomBy(final float zoomDelta) throws RemoteException {
Log.d(TAG, "zoomBy");
return new ObjectWrapper<CameraUpdate>(new MapPositionCameraUpdate() {
@Override
MapPosition getMapPosition(Map map) {
MapPosition mapPosition = map.getMapPosition();
mapPosition.setScale(GmsMapsTypeHelper.fromZoom(
GmsMapsTypeHelper.toZoom(mapPosition.getScale()) + zoomDelta));
return mapPosition;
}
});
}
@Override
public IObjectWrapper zoomByWithFocus(final float zoomDelta, int x, int y)
throws RemoteException {
Log.d(TAG, "zoomByWithFocus");
return new ObjectWrapper<CameraUpdate>(new MapPositionCameraUpdate() {
@Override
MapPosition getMapPosition(Map map) {
MapPosition mapPosition = map.getMapPosition();
mapPosition.setScale(GmsMapsTypeHelper.fromZoom(
GmsMapsTypeHelper.toZoom(mapPosition.getScale()) + zoomDelta));
Log.w(TAG, "zoomBy with focus not yet supported"); // TODO
return mapPosition;
}
});
}
@Override
public IObjectWrapper newCameraPosition(final CameraPosition cameraPosition)
throws RemoteException {
Log.d(TAG, "newCameraPosition");
return new ObjectWrapper<CameraUpdate>(new MapPositionCameraUpdate() {
@Override
MapPosition getMapPosition(Map map) {
return GmsMapsTypeHelper.fromCameraPosition(cameraPosition);
}
});
}
@Override
public IObjectWrapper newLatLng(final LatLng latLng) throws RemoteException {
Log.d(TAG, "newLatLng");
return new ObjectWrapper<CameraUpdate>(new MapPositionCameraUpdate() {
@Override
MapPosition getMapPosition(Map map) {
MapPosition mapPosition = map.getMapPosition();
mapPosition.setPosition(GmsMapsTypeHelper.fromLatLng(latLng));
return mapPosition;
}
});
}
@Override
public IObjectWrapper newLatLngZoom(final LatLng latLng, final float zoom)
throws RemoteException {
Log.d(TAG, "newLatLngZoom");
return new ObjectWrapper<CameraUpdate>(new MapPositionCameraUpdate() {
@Override
MapPosition getMapPosition(Map map) {
MapPosition mapPosition = map.getMapPosition();
mapPosition.setPosition(GmsMapsTypeHelper.fromLatLng(latLng));
mapPosition.setScale(GmsMapsTypeHelper.fromZoom(zoom));
return mapPosition;
}
});
}
@Override
public IObjectWrapper newLatLngBounds(final LatLngBounds bounds, int padding) throws RemoteException {
Log.d(TAG, "newLatLngBounds");
return new ObjectWrapper<CameraUpdate>(new MapPositionCameraUpdate() {
@Override
MapPosition getMapPosition(Map map) {
MapPosition mapPosition = map.getMapPosition();
mapPosition.setByBoundingBox(GmsMapsTypeHelper.fromLatLngBounds(bounds),
map.getWidth(), map.getHeight());
return mapPosition;
}
});
}
@Override
public IObjectWrapper newLatLngBoundsWithSize(final LatLngBounds bounds, final int width, final int height, int padding)
throws RemoteException {
Log.d(TAG, "newLatLngBoundsWithSize");
return new ObjectWrapper<CameraUpdate>(new MapPositionCameraUpdate() {
@Override
MapPosition getMapPosition(Map map) {
MapPosition mapPosition = map.getMapPosition();
mapPosition.setByBoundingBox(GmsMapsTypeHelper.fromLatLngBounds(bounds),
width, height);
return mapPosition;
}
});
}
}

View file

@ -0,0 +1,44 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm.camera;
import org.oscim.core.MapPosition;
import org.oscim.map.Map;
public abstract class MapPositionCameraUpdate implements CameraUpdate {
abstract MapPosition getMapPosition(Map map);
@Override
public void apply(Map map) {
map.setMapPosition(getMapPosition(map));
}
@Override
public void applyAnimated(Map map, int duration) {
map.animator().animateTo(duration, getMapPosition(map));
}
public static CameraUpdate directMapPosition(final MapPosition position) {
return new MapPositionCameraUpdate() {
@Override
MapPosition getMapPosition(Map map) {
return position;
}
};
}
}

View file

@ -0,0 +1,31 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm.camera;
import org.oscim.map.Map;
public class NoCameraUpdate implements CameraUpdate {
@Override
public void apply(Map map) {
}
@Override
public void applyAnimated(Map map, int duration) {
}
}

View file

@ -0,0 +1,138 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm.data;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import org.oscim.core.Tile;
import org.oscim.tiling.ITileCache;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
public class SharedTileCache implements ITileCache {
private final ArrayList<ByteArrayOutputStream> cacheBuffers;
private final Context context;
public SharedTileCache(Context context) {
this.context = context;
this.cacheBuffers = new ArrayList<ByteArrayOutputStream>();
}
@Override
public TileWriter writeTile(Tile tile) {
ByteArrayOutputStream os;
synchronized (this.cacheBuffers) {
if (this.cacheBuffers.isEmpty()) {
os = new ByteArrayOutputStream('耀');
} else {
os = this.cacheBuffers.remove(this.cacheBuffers.size() - 1);
}
}
return new CacheTileWriter(tile, os);
}
public void saveTile(Tile tile, ByteArrayOutputStream data, boolean success) {
byte[] bytes = null;
if (success) {
bytes = data.toByteArray();
}
synchronized (this.cacheBuffers) {
data.reset();
this.cacheBuffers.add(data);
}
if (success) {
ContentValues values = new ContentValues();
values.put("x", tile.tileX);
values.put("y", tile.tileY);
values.put("z", tile.zoomLevel);
values.put("time", 0);
values.put("last_access", 0);
values.put("data", bytes);
context.getContentResolver().insert(SharedTileProvider.PROVIDER_URI, values);
}
}
@Override
public TileReader getTile(Tile tile) {
Cursor cursor = context.getContentResolver().query(SharedTileProvider.PROVIDER_URI, new String[]{"data"}, "z=? AND x=? AND y=?", new String[]{String.valueOf(tile.zoomLevel), String.valueOf(tile.tileX), String.valueOf(tile.tileY)}, null);
if (cursor != null) {
if (!cursor.moveToFirst()) {
cursor.close();
return null;
} else {
ByteArrayInputStream in = new ByteArrayInputStream(cursor.getBlob(0));
cursor.close();
return new CacheTileReader(tile, in);
}
}
return null;
}
@Override
public void setCacheSize(long l) {
}
class CacheTileWriter implements TileWriter {
final ByteArrayOutputStream os;
final Tile tile;
CacheTileWriter(Tile tile, ByteArrayOutputStream os) {
this.tile = tile;
this.os = os;
}
public Tile getTile() {
return tile;
}
public OutputStream getOutputStream() {
return os;
}
public void complete(boolean success) {
saveTile(tile, os, success);
}
}
class CacheTileReader implements TileReader {
final InputStream is;
final Tile tile;
public CacheTileReader(Tile tile, InputStream is) {
this.tile = tile;
this.is = is;
}
public Tile getTile() {
return tile;
}
public InputStream getInputStream() {
return is;
}
}
}

View file

@ -0,0 +1,94 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm.data;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
/*
* TODO: Writing to cache should be protected, tiles should be downloaded by service instead of client app.
*/
public class SharedTileProvider extends ContentProvider {
private static final String DB_NAME = "tilecache.db";
public static final String PROVIDER_NAME = "org.microg.gms.maps.vtm.tile";
public static final Uri PROVIDER_URI = Uri.parse("content://" + PROVIDER_NAME);
private SQLiteHelper sqLiteHelper;
public SharedTileProvider() {
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// Implement this to handle requests to delete one or more rows.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public String getType(Uri uri) {
return "vnd.android.cursor.item/org.microg.gms.map.tile";
}
@Override
public Uri insert(Uri uri, ContentValues values) {
sqLiteHelper.getWritableDatabase().insert("tiles", null, values);
return PROVIDER_URI;
}
@Override
public boolean onCreate() {
sqLiteHelper = new SQLiteHelper(getContext(), DB_NAME);
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
return sqLiteHelper.getReadableDatabase().query("tiles", projection, selection, selectionArgs, null, null, sortOrder);
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
return sqLiteHelper.getWritableDatabase().update("tiles", values, selection, selectionArgs);
}
class SQLiteHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String TILE_SCHEMA = "CREATE TABLE tiles(x INTEGER NOT NULL,y INTEGER NOT NULL,z INTEGER NOT NULL,time LONG NOT NULL,last_access LONG NOT NULL,data BLOB,PRIMARY KEY(x,y,z));";
public SQLiteHelper(Context context, String dbName) {
super(context, dbName, null, DATABASE_VERSION);
}
public void onCreate(SQLiteDatabase db) {
db.execSQL(TILE_SCHEMA);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS tiles");
this.onCreate(db);
}
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
this.onUpgrade(db, oldVersion, newVersion);
}
}
}

View file

@ -0,0 +1,214 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm.markup;
import android.os.RemoteException;
import android.util.Log;
import com.google.android.gms.dynamic.IObjectWrapper;
import com.google.android.gms.dynamic.ObjectWrapper;
import com.google.android.gms.maps.model.CircleOptions;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.PatternItem;
import com.google.android.gms.maps.model.internal.ICircleDelegate;
import org.microg.gms.maps.vtm.GmsMapsTypeHelper;
import org.oscim.layers.vector.geometries.CircleDrawable;
import org.oscim.layers.vector.geometries.Drawable;
import org.oscim.layers.vector.geometries.Style;
import org.oscim.map.Map;
import java.util.List;
public class CircleImpl extends ICircleDelegate.Stub implements DrawableMarkup {
private static final String TAG = "GmsMapCircle";
private final String id;
private final CircleOptions options;
private final MarkupListener listener;
private boolean removed = false;
public CircleImpl(String id, CircleOptions options, MarkupListener listener) {
this.id = id;
this.listener = listener;
this.options = options == null ? new CircleOptions() : options;
}
@Override
public void remove() throws RemoteException {
listener.remove(this);
removed = true;
}
@Override
public String getId() {
return id;
}
@Override
public void setCenter(LatLng center) throws RemoteException {
options.center(center);
listener.update(this);
}
@Override
public LatLng getCenter() throws RemoteException {
return options.getCenter();
}
@Override
public void setRadius(double radius) throws RemoteException {
options.radius(radius);
listener.update(this);
}
@Override
public double getRadius() throws RemoteException {
return options.getRadius();
}
@Override
public void setStrokeWidth(float width) throws RemoteException {
options.strokeWidth(width);
listener.update(this);
}
@Override
public float getStrokeWidth() throws RemoteException {
return options.getStrokeWidth();
}
@Override
public void setStrokeColor(int color) throws RemoteException {
options.strokeColor(color);
listener.update(this);
}
@Override
public int getStrokeColor() throws RemoteException {
return options.getStrokeColor();
}
@Override
public void setFillColor(int color) throws RemoteException {
options.fillColor(color);
listener.update(this);
}
@Override
public int getFillColor() throws RemoteException {
return options.getFillColor();
}
@Override
public void setZIndex(float zIndex) throws RemoteException {
options.zIndex(zIndex);
listener.update(this);
}
@Override
public float getZIndex() {
return options.getZIndex();
}
@Override
public void setVisible(boolean visible) throws RemoteException {
options.visible(visible);
listener.update(this);
}
@Override
public boolean isVisible() {
return options.isVisible();
}
@Override
public boolean equalsRemote(ICircleDelegate other) throws RemoteException {
return other != null && other.getId().equals(getId());
}
@Override
public int hashCodeRemote() throws RemoteException {
return id.hashCode();
}
@Override
public void setClickable(boolean clickable) throws RemoteException {
Log.d(TAG, "unimplemented method: setClickable");
}
@Override
public boolean isClickable() throws RemoteException {
return false;
}
@Override
public void setStrokePattern(List<PatternItem> object) throws RemoteException {
Log.d(TAG, "unimplemented method: setStrokePattern");
}
@Override
public List<PatternItem> getStrokePattern() throws RemoteException {
Log.d(TAG, "unimplemented method: getStrokePattern");
return null;
}
@Override
public void setTag(IObjectWrapper object) throws RemoteException {
Log.d(TAG, "unimplemented method: setTag");
}
@Override
public IObjectWrapper getTag() throws RemoteException {
Log.d(TAG, "unimplemented method: getTag");
return ObjectWrapper.wrap(null);
}
@Override
public boolean onClick() {
return listener.onClick(this);
}
@Override
public void onDragStart() {
listener.onDragStart(this);
}
@Override
public void onDragStop() {
listener.onDragStop(this);
}
@Override
public void onDragProgress() {
listener.onDragProgress(this);
}
@Override
public Drawable getDrawable(Map map) {
if (!isVisible() || removed) return null;
return new CircleDrawable(
GmsMapsTypeHelper.fromLatLng(options.getCenter()),
options.getRadius() / 1000.0,
Style.builder()
.strokeColor(options.getStrokeColor())
.fillAlpha(1)
.fillColor(options.getFillColor())
.strokeWidth(options.getStrokeWidth()).build());
}
}

View file

@ -0,0 +1,30 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm.markup;
import org.oscim.layers.vector.VectorLayer;
import org.oscim.map.Map;
public class ClearableVectorLayer extends VectorLayer {
public ClearableVectorLayer(Map map) {
super(map);
}
public void clear() {
mDrawables.clear();
}
}

View file

@ -0,0 +1,26 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm.markup;
import org.oscim.layers.vector.geometries.Drawable;
import org.oscim.map.Map;
public interface DrawableMarkup extends Markup {
float getZIndex();
Drawable getDrawable(Map map);
}

View file

@ -0,0 +1,165 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm.markup;
import android.os.RemoteException;
import com.google.android.gms.dynamic.IObjectWrapper;
import com.google.android.gms.maps.model.GroundOverlayOptions;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.internal.IGroundOverlayDelegate;
public class GroundOverlayImpl extends IGroundOverlayDelegate.Stub {
private LatLng position;
private float transparency;
private float zIndex;
private boolean visible;
private String id;
private float width;
private float height;
private float bearing;
public GroundOverlayImpl(GroundOverlayOptions options) {
}
@Override
public void remove() throws RemoteException {
}
@Override
public String getId() throws RemoteException {
return id;
}
@Override
public void setPosition(LatLng pos) throws RemoteException {
this.position = pos;
}
@Override
public LatLng getPosition() throws RemoteException {
return position;
}
@Override
public void setDimension(float dimension) throws RemoteException {
setDimensions(dimension, dimension);
}
@Override
public void setDimensions(float width, float height) throws RemoteException {
this.width = width;
this.height = height;
}
@Override
public float getWidth() throws RemoteException {
return width;
}
@Override
public float getHeight() throws RemoteException {
return height;
}
@Override
public void setPositionFromBounds(LatLngBounds bounds) throws RemoteException {
}
@Override
public LatLngBounds getBounds() throws RemoteException {
return null;
}
@Override
public void setBearing(float bearing) throws RemoteException {
this.bearing = bearing;
}
@Override
public float getBearing() throws RemoteException {
return bearing;
}
@Override
public void setZIndex(float zIndex) throws RemoteException {
this.zIndex = zIndex;
}
@Override
public float getZIndex() throws RemoteException {
return zIndex;
}
@Override
public void setVisible(boolean visible) throws RemoteException {
this.visible = visible;
}
@Override
public boolean isVisible() throws RemoteException {
return visible;
}
@Override
public void setTransparency(float transparency) throws RemoteException {
this.transparency = transparency;
}
@Override
public float getTransparency() throws RemoteException {
return transparency;
}
@Override
public boolean equalsRemote(IGroundOverlayDelegate other) throws RemoteException {
return other != null && other.getId().equals(getId());
}
@Override
public int hashCodeRemote() throws RemoteException {
return id.hashCode();
}
@Override
public void setImage(IObjectWrapper img) throws RemoteException {
}
@Override
public void setClickable(boolean clickable) throws RemoteException {
}
@Override
public boolean isClickable() throws RemoteException {
return false;
}
@Override
public void setTag(IObjectWrapper obj) throws RemoteException {
}
@Override
public IObjectWrapper getTag() throws RemoteException {
return null;
}
}

View file

@ -0,0 +1,165 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm.markup;
import android.content.Context;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.google.android.gms.maps.model.internal.IMarkerDelegate;
import org.microg.gms.maps.vtm.GoogleMapImpl;
import org.microg.gms.maps.vtm.ResourcesContainer;
import org.microg.gms.maps.vtm.R;
import static android.os.Build.VERSION.SDK_INT;
import static android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1;
public class InfoWindow {
private static final String TAG = InfoWindow.class.getName();
private Context context;
private View window;
private GoogleMapImpl map;
private MarkerImpl marker;
public InfoWindow(Context context, final GoogleMapImpl map, final MarkerImpl marker) {
super();
this.context = context;
this.map = map;
this.marker = marker;
}
public void setWindow(View view) {
window = view;
if (window != null) {
window.measure(0, 0);
}
}
public boolean isComplete() {
return window != null;
}
public void setContent(View view) {
if (view == null)
return;
setWindow(new DefaultWindow(view));
}
public void buildDefault() {
if (marker.getTitle() != null)
setContent(new DefaultContent());
}
public void destroy() {
if (window instanceof DefaultWindow) {
((DefaultWindow) window).removeAllViews();
}
}
public IMarkerDelegate getMarker() {
return marker;
}
/*
@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
if (window != null && marker.getHeight() != -1 && !shadow) {
try {
Log.d(TAG, "draw InfoWindow");
window.measure(0, 0);
window.layout(0, 0, window.getMeasuredWidth(), window.getMeasuredHeight());
//Point point = mapView.getProjection().toPixels(marker.getPosition().toGeoPoint(), null);
// osmdroid 4.1 bugfix
Point zero = mapView.getProjection().toPixels(new GeoPoint(0, 0), null);
point.offset(-zero.x, -zero.y);
point.offset(-window.getMeasuredWidth() / 2, -window.getMeasuredHeight() - marker.getHeight());
Log.d(TAG, point.toString());
canvas.save();
canvas.translate(point.x, point.y);
window.draw(canvas);
canvas.restore();
} catch (Exception e) {
// This is not remote...
}
}
}
@Override
public boolean onTap(GeoPoint p, MapView mapView) {
try {
IOnInfoWindowClickListener listener = null; //map.getInfoWindowClickListener();
if (listener != null) {
Point clickPoint = mapView.getProjection().toPixels(p, null);
Point markerPoint = mapView.getProjection().toPixels(marker.getPosition().toGeoPoint(), null);
Rect rect = new Rect(markerPoint.x - (window.getMeasuredWidth() / 2),
markerPoint.y - marker.getHeight() - window.getMeasuredHeight(),
markerPoint.x + (window.getMeasuredWidth() / 2),
markerPoint.y - marker.getHeight());
if (rect.contains(clickPoint.x, clickPoint.y)) {
try {
listener.onInfoWindowClick(marker);
} catch (RemoteException e) {
Log.w(TAG, e);
}
return true;
}
}
} catch (Exception e) {
// This is not remote...
}
return false;
}
*/
private class DefaultWindow extends FrameLayout {
@SuppressWarnings("deprecation")
public DefaultWindow(View view) {
super(context);
addView(view);
if (SDK_INT > ICE_CREAM_SANDWICH_MR1) {
setBackground(ResourcesContainer.get().getDrawable(R.drawable.maps_default_window));
} else {
setBackgroundDrawable(ResourcesContainer.get().getDrawable(R.drawable.maps_default_window));
}
}
}
private class DefaultContent extends LinearLayout {
public DefaultContent() {
super(context);
setOrientation(LinearLayout.VERTICAL);
TextView title = new TextView(context);
title.setTextAppearance(context,
android.R.style.TextAppearance_DeviceDefault_Medium_Inverse);
title.setText(marker.getTitle());
addView(title);
if (marker.getSnippet() != null) {
TextView snippet = new TextView(context);
snippet.setTextAppearance(context,
android.R.style.TextAppearance_DeviceDefault_Inverse);
snippet.setText(marker.getSnippet());
addView(snippet);
}
}
}
}

View file

@ -0,0 +1,289 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm.markup;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.RemoteException;
import android.util.Log;
import com.google.android.gms.dynamic.IObjectWrapper;
import com.google.android.gms.dynamic.ObjectWrapper;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.internal.IMarkerDelegate;
import org.microg.gms.maps.vtm.GmsMapsTypeHelper;
import org.microg.gms.maps.vtm.bitmap.BitmapDescriptorImpl;
import org.microg.gms.maps.vtm.bitmap.DefaultBitmapDescriptor;
import org.oscim.android.canvas.AndroidBitmap;
import org.oscim.layers.marker.MarkerItem;
import org.oscim.layers.marker.MarkerSymbol;
public class MarkerImpl extends IMarkerDelegate.Stub implements MarkerItemMarkup {
private static final String TAG = "GmsMapMarkerImpl";
private final String id;
private final MarkerOptions options;
private final MarkupListener listener;
private BitmapDescriptorImpl icon;
private AndroidBitmap oldBitmap;
private boolean removed = false;
private IObjectWrapper tag = null;
public MarkerImpl(String id, MarkerOptions options, MarkupListener listener) {
this.id = id;
this.listener = listener;
this.options = options == null ? new MarkerOptions() : options;
if (options.getPosition() == null) {
options.position(new LatLng(0, 0));
}
icon = options.getIcon() == null ? null : new BitmapDescriptorImpl(options.getIcon());
Log.d(TAG, "New marker " + id + " with title " + options.getTitle() + " @ " +
options.getPosition());
}
@Override
public void remove() {
listener.remove(this);
removed = true;
icon = null;
oldBitmap = null;
}
@Override
public String getId() {
return id;
}
@Override
public void setPosition(LatLng pos) {
options.position(pos);
listener.update(this);
}
@Override
public LatLng getPosition() {
return options.getPosition();
}
@Override
public void setTitle(String title) {
options.title(title);
listener.update(this);
}
@Override
public String getTitle() {
return options.getTitle();
}
@Override
public void setSnippet(String snippet) {
options.snippet(snippet);
}
@Override
public String getSnippet() {
return options.getSnippet();
}
@Override
public void setDraggable(boolean drag) {
options.draggable(drag);
}
@Override
public boolean isDraggable() {
return options.isDraggable();
}
@Override
public void showInfoWindow() {
}
@Override
public void hideInfoWindow() {
}
@Override
public boolean isInfoWindowShown() {
return false;
}
@Override
public void setVisible(boolean visible) {
options.visible(visible);
}
@Override
public boolean isVisible() {
return options.isVisible();
}
@Override
public boolean equalsRemote(IMarkerDelegate other) throws RemoteException {
return other != null && other.getId().equals(getId());
}
@Override
public int hashCodeRemote() {
return hashCode();
}
@Override
public int hashCode() {
return super.hashCode();
}
@Override
public void setIcon(IObjectWrapper obj) {
if (obj == null) {
icon = new BitmapDescriptorImpl();
} else {
icon = new BitmapDescriptorImpl(obj);
}
listener.update(this);
}
@Override
public void setAnchor(float x, float y) {
options.anchor(x, y);
listener.update(this);
}
@Override
public void setFlat(boolean flat) {
options.flat(flat);
listener.update(this);
}
@Override
public boolean isFlat() {
return options.isFlat();
}
@Override
public void setRotation(float rotation) {
options.rotation(rotation);
listener.update(this);
}
@Override
public float getRotation() {
return options.getRotation();
}
@Override
public void setInfoWindowAnchor(float x, float y) {
options.infoWindowAnchor(x, y);
}
@Override
public void setAlpha(float alpha) {
options.alpha(alpha);
listener.update(this);
}
@Override
public float getAlpha() {
return options.getAlpha();
}
public int getHeight() {
Bitmap bitmap = icon.getBitmap();
if (bitmap == null)
return -1;
return bitmap.getHeight();
}
@Override
public boolean onClick() {
return listener.onClick(this);
}
@Override
public void onDragStart() {
listener.onDragStart(this);
}
@Override
public void onDragStop() {
listener.onDragStop(this);
}
@Override
public void onDragProgress() {
listener.onDragProgress(this);
}
@Override
public MarkerItem getMarkerItem(Context context) {
if (removed) return null;
MarkerItem item = new MarkerItem(getId(), getTitle(), getSnippet(),
GmsMapsTypeHelper.fromLatLng(getPosition()));
BitmapDescriptorImpl icon = this.icon;
if (icon == null)
icon = DefaultBitmapDescriptor.DEFAULT_DESCRIPTOR_IMPL;
if (icon.getBitmap() != null) {
oldBitmap = new AndroidBitmap(icon.getBitmap());
prepareMarkerIcon(item);
} else {
if (!icon.loadBitmapAsync(context, new Runnable() {
@Override
public void run() {
listener.update(MarkerImpl.this);
}
})) {
// Was loaded since last check...
oldBitmap = new AndroidBitmap(icon.getBitmap());
prepareMarkerIcon(item);
}
// Keep old icon while loading new
if (oldBitmap != null) {
prepareMarkerIcon(item);
}
}
return item;
}
private void prepareMarkerIcon(MarkerItem item) {
item.setMarker(new MarkerSymbol(oldBitmap, options.getAnchorU(), options.getAnchorV(), !options.isFlat()));
}
@Override
public void setZIndex(float zIndex) {
options.zIndex(zIndex);
}
@Override
public float getZIndex() {
return options.getZIndex();
}
@Override
public void setTag(IObjectWrapper obj) {
this.tag = obj;
}
@Override
public IObjectWrapper getTag() {
return this.tag == null ? ObjectWrapper.wrap(null) : this.tag;
}
}

View file

@ -0,0 +1,33 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm.markup;
import android.content.Context;
import com.google.android.gms.maps.model.LatLng;
import org.oscim.layers.marker.MarkerItem;
public interface MarkerItemMarkup extends Markup {
MarkerItem getMarkerItem(Context context);
boolean isDraggable();
LatLng getPosition();
void setPosition(LatLng latLng);
}

View file

@ -0,0 +1,41 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm.markup;
public interface Markup {
String getId();
boolean onClick();
void onDragStart();
void onDragStop();
void onDragProgress();
interface MarkupListener {
void update(Markup markup);
void remove(Markup markup);
boolean onClick(Markup markup);
void onDragStart(Markup markup);
void onDragStop(Markup markup);
void onDragProgress(Markup markup);
}
}

View file

@ -0,0 +1,242 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm.markup;
import android.os.RemoteException;
import com.google.android.gms.dynamic.IObjectWrapper;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.PatternItem;
import com.google.android.gms.maps.model.PolygonOptions;
import com.google.android.gms.maps.model.internal.IPolygonDelegate;
import org.microg.gms.maps.vtm.GmsMapsTypeHelper;
import org.oscim.core.GeoPoint;
import org.oscim.layers.vector.geometries.Drawable;
import org.oscim.layers.vector.geometries.PolygonDrawable;
import org.oscim.layers.vector.geometries.Style;
import org.oscim.map.Map;
import java.util.ArrayList;
import java.util.List;
public class PolygonImpl extends IPolygonDelegate.Stub implements DrawableMarkup {
private static final String TAG = "GmsMapsPolygonImpl";
private final String id;
private final PolygonOptions options;
private final MarkupListener listener;
private boolean removed = false;
public PolygonImpl(String id, PolygonOptions options, MarkupListener listener) {
this.id = id;
this.options = options;
this.listener = listener;
}
@Override
public void remove() throws RemoteException {
listener.remove(this);
removed = true;
}
@Override
public String getId() {
return id;
}
@Override
public boolean onClick() {
return listener.onClick(this);
}
@Override
public void onDragStart() {
listener.onDragStart(this);
}
@Override
public void onDragStop() {
listener.onDragStop(this);
}
@Override
public void onDragProgress() {
listener.onDragProgress(this);
}
@Override
public void setPoints(List<LatLng> points) throws RemoteException {
options.getPoints().clear();
options.getPoints().addAll(points);
listener.update(this);
}
@Override
public List<LatLng> getPoints() throws RemoteException {
return options.getPoints();
}
@Override
public void setHoles(List holes) throws RemoteException {
options.getHoles().clear();
options.getHoles().addAll(holes);
listener.update(this);
}
@Override
public List getHoles() throws RemoteException {
return options.getHoles();
}
@Override
public void setStrokeWidth(float width) throws RemoteException {
options.strokeWidth(width);
listener.update(this);
}
@Override
public float getStrokeWidth() {
return options.getStrokeWidth();
}
@Override
public void setStrokeColor(int color) throws RemoteException {
options.strokeColor(color);
listener.update(this);
}
@Override
public int getStrokeColor() {
return options.getStrokeColor();
}
@Override
public void setFillColor(int color) throws RemoteException {
options.fillColor(color);
listener.update(this);
}
@Override
public int getFillColor() {
return options.getFillColor();
}
@Override
public void setZIndex(float zIndex) throws RemoteException {
options.zIndex(zIndex);
listener.update(this);
}
@Override
public float getZIndex() {
return options.getZIndex();
}
@Override
public Drawable getDrawable(Map map) {
if (!isVisible() || removed) return null;
List<GeoPoint> points = new ArrayList<GeoPoint>();
for (LatLng point : options.getPoints()) {
points.add(GmsMapsTypeHelper.fromLatLng(point));
}
if (points.size() < 3 || (points.size() == 3 && points.get(2).equals(points.get(0)))) {
// Need at least 3 distinguished points to draw a polygon
return null;
}
// TODO: holes
return new PolygonDrawable(points, Style.builder()
.fillAlpha(1)
.strokeColor(getStrokeColor())
.strokeWidth(getStrokeWidth())
.fillColor(getFillColor())
.build());
}
@Override
public void setVisible(boolean visible) throws RemoteException {
options.visible(visible);
listener.update(this);
}
@Override
public boolean isVisible() {
return options.isVisible();
}
@Override
public void setGeodesic(boolean geod) throws RemoteException {
options.geodesic(geod);
listener.update(this);
}
@Override
public boolean isGeodesic() throws RemoteException {
return options.isGeodesic();
}
@Override
public boolean equalsRemote(IPolygonDelegate other) throws RemoteException {
return other != null && other.getId().equals(getId());
}
@Override
public int hashCodeRemote() throws RemoteException {
return id.hashCode();
}
// Not implemented
@Override
public void setClickable(boolean click) throws RemoteException {
}
@Override
public boolean isClickable() throws RemoteException {
return false;
}
@Override
public void setStrokeJointType(int type) throws RemoteException {
}
@Override
public int getStrokeJointType() throws RemoteException {
return 0;
}
@Override
public void setStrokePattern(List<PatternItem> items) throws RemoteException {
}
@Override
public List<PatternItem> getStrokePattern() throws RemoteException {
return null;
}
@Override
public void setTag(IObjectWrapper obj) throws RemoteException {
}
@Override
public IObjectWrapper getTag() throws RemoteException {
return null;
}
}

View file

@ -0,0 +1,237 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm.markup;
import android.os.RemoteException;
import android.util.Log;
import com.google.android.gms.dynamic.IObjectWrapper;
import com.google.android.gms.maps.model.Cap;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.PatternItem;
import com.google.android.gms.maps.model.PolylineOptions;
import com.google.android.gms.maps.model.internal.IPolylineDelegate;
import org.microg.gms.maps.vtm.GmsMapsTypeHelper;
import org.oscim.core.GeoPoint;
import org.oscim.layers.vector.geometries.Drawable;
import org.oscim.layers.vector.geometries.LineDrawable;
import org.oscim.layers.vector.geometries.Style;
import org.oscim.map.Map;
import java.util.ArrayList;
import java.util.List;
public class PolylineImpl extends IPolylineDelegate.Stub implements DrawableMarkup {
private static final String TAG = "GmsMapsPolylineImpl";
private final String id;
private final PolylineOptions options;
private final MarkupListener listener;
private boolean removed = false;
public PolylineImpl(String id, PolylineOptions options, MarkupListener listener) {
this.id = id;
this.options = options == null ? new PolylineOptions() : options;
this.listener = listener;
}
@Override
public void remove() {
listener.remove(this);
removed = true;
}
@Override
public String getId() {
return id;
}
@Override
public boolean onClick() {
return listener.onClick(this);
}
@Override
public void onDragStart() {
listener.onDragStart(this);
}
@Override
public void onDragStop() {
listener.onDragStop(this);
}
@Override
public void onDragProgress() {
listener.onDragProgress(this);
}
@Override
public void setPoints(List<LatLng> points) {
options.getPoints().clear();
options.getPoints().addAll(points);
listener.update(this);
}
@Override
public List<LatLng> getPoints() {
return options.getPoints();
}
@Override
public void setWidth(float width) {
options.width(width);
listener.update(this);
}
@Override
public float getWidth() {
return options.getWidth();
}
@Override
public void setColor(int color) {
this.options.color(color);
listener.update(this);
}
@Override
public int getColor() {
return options.getColor();
}
@Override
public void setZIndex(float zIndex) {
options.zIndex(zIndex);
listener.update(this);
}
@Override
public float getZIndex() {
return options.getZIndex();
}
@Override
public void setVisible(boolean visible) {
options.visible(visible);
listener.update(this);
}
@Override
public boolean isVisible() {
return options.isVisible();
}
@Override
public void setGeodesic(boolean geod) {
options.geodesic(geod);
listener.update(this);
}
@Override
public boolean isGeodesic() {
return options.isGeodesic();
}
@Override
public boolean equalsRemote(IPolylineDelegate other) throws RemoteException {
Log.d(TAG, "equalsRemote");
return other != null && other.getId().equals(getId());
}
@Override
public int hashCodeRemote() {
Log.d(TAG, "hashcodeRemote");
return id.hashCode();
}
// Not implemented
@Override
public void setClickable(boolean clickable) throws RemoteException {
}
@Override
public boolean isClickable() throws RemoteException {
return false;
}
@Override
public void setStartCap(Cap startCap) throws RemoteException {
}
@Override
public Cap getStartCap() throws RemoteException {
return null;
}
@Override
public void setEndCap(Cap endCap) throws RemoteException {
}
@Override
public Cap getEndCap() throws RemoteException {
return null;
}
@Override
public void setJointType(int jointType) throws RemoteException {
}
@Override
public int getJointType() throws RemoteException {
return 0;
}
@Override
public void setPattern(List<PatternItem> pattern) throws RemoteException {
}
@Override
public List<PatternItem> getPattern() throws RemoteException {
return null;
}
@Override
public void setTag(IObjectWrapper tag) throws RemoteException {
}
@Override
public IObjectWrapper getTag() throws RemoteException {
return null;
}
@Override
public Drawable getDrawable(Map map) {
if (!isVisible() || removed) return null;
if (options.getPoints().size() < 2) {
// You hardly draw a line with less than two points
return null;
}
List<GeoPoint> points = new ArrayList<GeoPoint>();
for (LatLng point : options.getPoints()) {
points.add(GmsMapsTypeHelper.fromLatLng(point));
}
return new LineDrawable(points, Style.builder().strokeColor(getColor()).strokeWidth(getWidth()).build());
}
}

View file

@ -0,0 +1,87 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.vtm.markup;
import android.os.RemoteException;
import com.google.android.gms.maps.model.internal.ITileOverlayDelegate;
public class TileOverlayImpl extends ITileOverlayDelegate.Stub {
@Override
public void remove() throws RemoteException {
}
@Override
public void clearTileCache() throws RemoteException {
}
@Override
public String getId() throws RemoteException {
return null;
}
@Override
public void setZIndex(float zIndex) throws RemoteException {
}
@Override
public float getZIndex() throws RemoteException {
return 0;
}
@Override
public void setVisible(boolean visible) throws RemoteException {
}
@Override
public boolean isVisible() throws RemoteException {
return false;
}
@Override
public boolean equalsRemote(ITileOverlayDelegate other) throws RemoteException {
return false;
}
@Override
public int hashCodeRemote() throws RemoteException {
return 0;
}
@Override
public void setFadeIn(boolean fadeIn) throws RemoteException {
}
@Override
public boolean getFadeIn() throws RemoteException {
return false;
}
@Override
public void setTransparency(float transparency) throws RemoteException {
}
@Override
public float getTransparency() throws RemoteException {
return 0;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 B