pax_global_header00006660000000000000000000000064125340452140014512gustar00rootroot0000000000000052 comment=0ae17d4999f712685088b44587c83df93a945294 osmosis-0.44.1/000077500000000000000000000000001253404521400132745ustar00rootroot00000000000000osmosis-0.44.1/.gitignore000066400000000000000000000000521253404521400152610ustar00rootroot00000000000000.gradle *.javaEe *.javae *.iml *.ipr *.iwsosmosis-0.44.1/README000066400000000000000000000041371253404521400141610ustar00rootroot00000000000000Osmosis is a command line Java application for processing Open Street Map (http://www.openstreetmap.org) data. The tool consists of a series of pluggable components that can be chained together to perform a larger operation. For example, it has components for reading from database and from file, components for writing to database and to file, components for deriving and applying change sets to data sources, components for sorting data, etc. It has been written so that it is easy to add new features without re-writing common tasks such as file or database handling. Some brief build, running and installation notes are provided below, however most documentation may be found on the project wiki page. http://wiki.openstreetmap.org/wiki/Osmosis **** BUILD **** Osmosis is built using the Gradle (http://gradle.org) built tool, however Gradle does not need to be installed. The only requirements are a 1.6 JDK, and an Internet connection. Below are several commands useful to build the software. All commands must be run from the root of the source tree. Build the software without running unit tests: ./gradlew assemble Perform a complete build including unit tests: ./gradlew build Clean the build tree: ./gradlew clean Verify checkstyle compliance: ./gradlew checkstyleMain checkstyleTest **** RUNNING **** After completing the build process, a working Osmosis installation is contained in the package sub-directory. The Osmosis launcher scripts reside in the bin sub-directory of package. On a UNIX-like environment use the "osmosis" script, on a Windows environment use the "osmosis.bat" script. However, for installing the software it is recommended to use a distribution archive described below. **** INSTALLATION **** After completing the build process, distribution archives in zip and tar gzipped formats are contained in the package/build/distribution directory. These archives may be extracted to a location of your choice. The bin sub-directory should either be added to your PATH, or in the case of UNIX-like environments the "osmosis" script may be symlinked into an existing directory already on the PATH. osmosis-0.44.1/build-support/000077500000000000000000000000001253404521400161055ustar00rootroot00000000000000osmosis-0.44.1/build-support/.gitignore000066400000000000000000000000171253404521400200730ustar00rootroot00000000000000.project /ivy osmosis-0.44.1/build-support/checkstyle.xml000066400000000000000000000145051253404521400207720ustar00rootroot00000000000000 osmosis-0.44.1/build-support/osmosis_formatting.xml000066400000000000000000000675501253404521400225720ustar00rootroot00000000000000 osmosis-0.44.1/build.gradle000066400000000000000000000076161253404521400155650ustar00rootroot00000000000000task wrapper(type: Wrapper) { gradleVersion = '2.4' } apply plugin: 'idea' /* Build collections containing each type of project. These collections will * be used to apply common configurations to projects of the same type. */ def packageProjects = allprojects.findAll { project -> project.path.equals(':package') } def buildProjects = allprojects.findAll { project -> project.path.equals(':build-support') } def dockerProjects = allprojects.findAll { project -> project.path.equals(':db-server') } // Java projects are all those that aren't in the previous collections. def javaProjects = subprojects.findAll { project -> !packageProjects.contains(project) && !buildProjects.contains(project) && !dockerProjects.contains(project) } // Apply common project configuration subprojects { apply plugin: 'eclipse-wtp' apply plugin: 'idea' // All projects use a common group id. group = 'org.openstreetmap.osmosis' // Load the project version dynamically from Git. For release builds, don't add a suffix. def versionSuffix = "RELEASE".equals(osmosisBuildType) ? '' : '-' + osmosisBuildType version = 'git describe --always --dirty'.execute().in.text.trim() + versionSuffix // Enable access to artefact dependency repositories. repositories { // Standard Maven repository. mavenCentral() } } // Apply common configurations to all projects supporting Java. configure(javaProjects) { apply plugin: 'checkstyle' apply plugin: 'java' apply plugin: 'jdepend' apply plugin: 'maven' apply plugin: 'signing' sourceCompatibility = 1.6 test { /* * Pass on each of our custom properties to the unit tests if they have * been provided. */ ['db.apidb.authfile', 'db.pgsql.authfile'].each { propName -> if (System.getProperties().containsKey(propName)) { jvmArgs '-D' + propName + '=' + System.getProperty(propName) } } //testLogging.showStandardStreams = true } dependencies { testCompile group: 'junit', name: 'junit', version: dependencyVersionJunit } checkstyle { configFile = new File(rootDir, 'build-support/checkstyle.xml') configProperties.samedir = configFile.parentFile } // Build javadoc and source jars and include in published artifacts. task javadocJar(type: Jar, dependsOn: javadoc) { classifier = 'javadoc' from 'build/docs/javadoc' } task sourcesJar(type: Jar) { from sourceSets.main.allSource classifier = 'sources' } artifacts { archives jar archives javadocJar archives sourcesJar } // Sign all published artifacts if signing is enabled. signing { sign configurations.archives required = Boolean.valueOf(osmosisSigningEnabled) } // Configure the maven plugin to upload artefacts to the Sonatype repository. uploadArchives { repositories { mavenDeployer { beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } // We upload to the Sonatype SNAPSHOT repository unless it is a release build in // which case we upload to the staging repository. def sonatypeRepoUrl = "RELEASE".equals(osmosisBuildType) ? 'https://oss.sonatype.org/service/local/staging/deploy/maven2/' : 'https://oss.sonatype.org/content/repositories/snapshots/' repository(url: sonatypeRepoUrl) { authentication(userName: sonatypeUsername, password: sonatypePassword) } pom.project { name project.name packaging 'jar' description 'Osmosis is a Java application and library for processing OSM data.' url 'http://wiki.openstreetmap.org/wiki/Osmosis' scm { url 'https://github.com/openstreetmap/osmosis' connection 'scm:git:git://github.com/openstreetmap/osmosis.git' developerConnection 'scm:git:ssh://git@github.com/openstreetmap/osmosis.git' } licenses { license { name 'Public Domain' } } developers { developer { id 'brett' name 'Brett Henderson' email 'brett@bretth.com' } } } } } } } osmosis-0.44.1/db-server/000077500000000000000000000000001253404521400151655ustar00rootroot00000000000000osmosis-0.44.1/db-server/.gitignore000066400000000000000000000000371253404521400171550ustar00rootroot00000000000000.classpath .project .settings osmosis-0.44.1/db-server/Dockerfile000066400000000000000000000003471253404521400171630ustar00rootroot00000000000000FROM fedora:21 # Install PostgreSQL RUN yum install -y postgresql-server postgresql-contrib # Install PostGIS RUN yum install -y postgis EXPOSE 5432 COPY docker-start.sh /start.sh COPY script /install/script CMD ["/start.sh"] osmosis-0.44.1/db-server/build.sh000077500000000000000000000004301253404521400166200ustar00rootroot00000000000000#!/bin/sh # Build the docker image. # The use of tar is a workaround for the docker restriction of not following symlinks. This # tar command dereferences symlinks and then passes the resultant archive to the docker build. tar -czh . | docker build -t="bretth/osmosis-build" - osmosis-0.44.1/db-server/docker-start.sh000077500000000000000000000041031253404521400201240ustar00rootroot00000000000000#!/bin/bash DATADIR="/var/lib/pgsql/data" # test if DATADIR has content if [ ! "$(ls -A $DATADIR)" ]; then # Create the en_US.UTF-8 locale. We need UTF-8 support in the database. localedef -v -c -i en_US -f UTF-8 en_US.UTF-8 echo "Initializing Postgres Database at $DATADIR" su postgres sh -lc "initdb --encoding=UTF-8 --locale=en_US.UTF-8" su postgres sh -lc "postgres --single -jE" <<-EOSQL CREATE USER osm WITH SUPERUSER PASSWORD 'password'; EOSQL # Allow the osm user to connect remotely with a password. echo "listen_addresses = '*'" >> "${DATADIR}/postgresql.conf" echo "host all osm 0.0.0.0/0 md5" >> "${DATADIR}/pg_hba.conf" # Create the pgsnapshot database owned by osm. su postgres sh -lc "postgres --single -jE" <<-EOSQL CREATE DATABASE pgosmsnap06_test OWNER osm; EOSQL # Create the apidb database owned by osm. su postgres sh -lc "postgres --single -jE" <<-EOSQL CREATE DATABASE api06_test OWNER osm; EOSQL # Start the database server temporarily while we configure the databases. su postgres sh -lc "pg_ctl -w start" # Configure the pgosmsnap06_test database as the OSM user. su postgres sh -lc "psql -U osm pgosmsnap06_test" <<-EOSQL CREATE EXTENSION hstore; CREATE EXTENSION postgis; \i /install/script/pgsnapshot_schema_0.6.sql \i /install/script/pgsnapshot_schema_0.6_action.sql \i /install/script/pgsnapshot_schema_0.6_bbox.sql \i /install/script/pgsnapshot_schema_0.6_linestring.sql EOSQL # Configure the api06_test database as the OSM user. su postgres sh -lc "psql -U osm api06_test" <<-EOSQL \i /install/script/contrib/apidb_0.6.sql \i /install/script/contrib/apidb_0.6_osmosis_xid_indexing.sql EOSQL # Stop the database. su postgres sh -lc "pg_ctl -w stop" fi SHUTDOWN_COMMAND="echo \"Shutting down postgres\"; su postgres sh -lc \"pg_ctl -w stop\"" trap "${SHUTDOWN_COMMAND}" SIGTERM trap "${SHUTDOWN_COMMAND}" SIGINT # Start the database server. su postgres sh -lc "pg_ctl -w start" echo "Docker container startup complete" # Wait for the server to exit. while test -e "/var/lib/pgsql/data/postmaster.pid"; do sleep 0.5 done osmosis-0.44.1/db-server/readme.txt000066400000000000000000000012301253404521400171570ustar00rootroot00000000000000This directory contains the scripts to create a docker-based database server to be used for unit testing. In order to use this server, docker must be installed on the local workstation. Beyond that, no additional configuration should be required. To build the docker image, run the following script. ./build.sh To run the docker image, run the following command. To stop the server, press Ctrl-C. docker run -ti --rm=true --name osmosis-build -p 5432:5432 bretth/osmosis-build If you wish to troubleshoot a running server, you may run the following command to get a bash prompt inside the docker container. docker exec -ti osmosis-build /bin/bash osmosis-0.44.1/db-server/script000077700000000000000000000000001253404521400214442../package/scriptustar00rootroot00000000000000osmosis-0.44.1/gradle.properties000066400000000000000000000040051253404521400166470ustar00rootroot00000000000000# Enable the gradle build daemon. The daemon is a gradle process that # remains running between builds. This significantly speeds up build # times. org.gradle.daemon=true # 3rd Party Library Versions dependencyVersionClassworlds=2.5.2 dependencyVersionCommonsCodec=1.10 dependencyVersionCommonsCompress=1.9 dependencyVersionCommonsDbcp=1.4 dependencyVersionJpf=1.5 dependencyVersionJunit=4.12 dependencyVersionMySql=5.1.35 dependencyVersionNetty=3.2.10.Final dependencyVersionPostGis=1.3.3 dependencyVersionPostgreSql=9.4-1201-jdbc4 dependencyVersionProtobuf=2.6.1 dependencyVersionSpring=4.1.6.RELEASE dependencyVersionWoodstoxCore=4.4.1 dependencyVersionWoodstoxStax2=3.1.4 # Remaining on 2.9.1 instead of 2.10.0 for now because the newer version # depends on org.w3c.dom.ElementTraversal which is not being transitively # included. This could be possibly be fixed by including a newer version # of xml-apis but this hasn't been verified. dependencyVersionXerces=2.9.1 # Builds are signed if the osmosisSigningEnabled property is set to true. # To enable signing, it is recommended to leave this file untouched and to # create a gradle.properties in your /.gradle/ directory and override # the setting there. It is also necessary to set the following properties: # * signing.keyId - Something like ABCDEFGH (see gpg --list-keys) # * signing.secretKeyRingFile - Something like /home//.gnupg/secring.gpg # * signing.password - The password to unlock the secret key. osmosisSigningEnabled=false # If uploading to the Sonatype repositories, a username/password must be # provided. To do this, create a gradle.properties in your /.gradle/ # directory and override the below property values there. sonatypeUsername=DO NOT EDIT ME. Read the above comments. sonatypePassword=DO NOT EDIT ME. Read the above comments. # By default, all builds are SNAPSHOT builds. To create a release build, this # property should be overridden to be RELEASE. Note that this variable should # not be updated. osmosisBuildType=SNAPSHOT osmosis-0.44.1/gradle/000077500000000000000000000000001253404521400145325ustar00rootroot00000000000000osmosis-0.44.1/gradle/wrapper/000077500000000000000000000000001253404521400162125ustar00rootroot00000000000000osmosis-0.44.1/gradle/wrapper/gradle-wrapper.jar000066400000000000000000001460521253404521400216340ustar00rootroot00000000000000PK `QF META-INF/PK `QFr+?TMETA-INF/MANIFEST.MFMLK-. K-*ϳR03-IM+I, dZ)%bµrrPK ]QForg/PK ]QF org/gradle/PK ]QForg/gradle/wrapper/PK ]QFhdf#org/gradle/wrapper/Download$1.class}M 0h5Z+v/ ׆p!.H3SK;a(Id0®lWO*i)2Xsd1,:"! G5=R+ȃɹws??~XªQx)I)`^F\F ṂzQFRhMK K [A*_ɮoANϖvӟtp854˰ZsM0ݍ+e錞K{zahӱa{jr⿅ >4fڦ?(06 %L7k}8e*)v0 DqZ5*>F]m4xqNuj}g'-mZ0Zjw䜦[b!ڋ3)UD0A\>yIA$Rf MxfFӴ*e]ӫxwԯ x wuH𘗽P`{!!}%nx/ q}Jhͮ0,މ=q@{,Qzii“G7 !8CH3 `_[(`+8$U)<$4OZd4}/z@:CYׅ"D "Vv I (&%꿮)[|SW/9s ,n%BrUv/PK ]QF] 3org/gradle/wrapper/ExclusiveFileAccessManager.classVKpem&im!@!PlP(ӂbhZ 6]ݍMK} >u蝣2#-XGGǃ://߷6?  Gw^D>tIq WiA9% NߏQ#583x6HSq0(3dD-*pWb~~֤':u$SzOut$%R1%+F.k[kP0vU 6E AJJΛ4lStAjfPM&$xf5)PVuU33ާX^{XXʴrdu56n)j/dbAS;4]mdBK1jOqڢnr-hkz,ceK(.<4̋y5cӘ![vnfF$Թ gPaL13 aД 5R96YK,Ap/]l \ak:rAC}ѫ .ZjMǗf}uUQebPMfA=YT[ {[K8Lb<sHi"3+/a2FXY22֯u{(2NS)G//T> 3h ڸ7B(^:Ga*{Pl6\;#4͠v )l y&ͳ`sua$&&s"\^&x3^9O&39qߝ}~9z(sL7R <7o :ǐG3ăVL=W_ߠ(~׉_hy?;Cr|1C_JV,9fx6'2!Ƽ!09'($)^RV-=wj$\7ud/j-'I%4۵ 2ۤG*1 <PK ]QFc`-org/gradle/wrapper/WrapperConfiguration.classn@g8N7Ρ--@[QU6@QB[I*ؑSDC!fN, ?y~:9w(w7͋fzusY.xCCF4Ĩ75%c0.w*&UVVqF IJrN kxB \»'/;'k00#IR,TkA i CeG4G۳B1p3r중2SL6 zl'K9lF#N,wEc"Ұ(v 6[+U32vٸfL;6bfDt,f&6nh4# T;j nID5/G'"皶EY(sJhfZ)Ԭ&Yv숔XH`8BVXnə"Rd`KQW8kKtedTgȄejrm)3.oer$K.uڡz9Gp]LY[pcxb٧ NRzFKKSA7sȧy+:2`ligh鰑qUܠt~`fVT;j:V03v; glcJusyI\\+ؘ_b?ڭbA">qHǸY|u*qSr*-=~PqKǏIAtK.XڮG&`ۊ5K 2c3EݾH}tױHk/u5kXlH"5 "M;|L^x|I;Y%79R, [rng}zlj2 t᳼w2iIa%EVFi.OoΔu9mX<VM{ 7J/Q7و 70_C<.ȿ&(r>)U>'K۱T/) nEh<AXBC4E%/ADo_݃>蓛='O/6.6my">FA_ ,b` ("TCj;'JT|p3Q}4}gx[C8AP"AB;&ꇈ.JziE\"&?nqAKO8:aN>GbF'-&=eh=q /ӋONOp 7gBC8\QJ Xzc^sw PK ]QFy0Vorg/gradle/wrapper/Logger.classoPǿ*1pL EWo1&d  f&Ki Xs9* OHfp+ۨ&Q,D];Bܕp A`w 32 I^m{]⯧>wީ}N6Ǫc;8ƄԵ]u`r壣FQs5mP힩TT-]鹎a-PDս +TYb|Tuz|<[(N$&cbXC3RWu:+mf=mdϞ:?2RlDLBZB3{/AQHGB< 2og\+j/>M\> {JQV \ZWHcHXŠ\_)Gt } РF If:B~@R &~ 6H#J2b&J9򼉖ekY4|3}(4y0 TРJ =-u/g5ېur Bwek++ܥ~FLMvo 3zgF{(lMtwoIlquu 9&ilb\cEx{q֩|d/k%З˺h}(莫WrŒmkS? ;(PmVW ?suS^uu2(̆c΂9 s.nxSWXvq`w*CRPJ.d pQy<ŏT *5sxZSEnYO,Jע(żn ?gF*~! _k̻gMU1YN$K\E1pC_tCFGŸUU_xG.;`rkp Ⲃu;Y2]cYgU*擦&HܤaܤO>]aF(TdžKF Irfח7(In 3%I$K u`obM%Tw-5ִp-UhWf^A;]Tp!joCb1 Cݾ۫S(#-S:^p>if~y"c<{Fw12~C %FJ+yͥpD"s( 6]eL/-yk63u1Y;)-lé\}j_,iEfӚ~'lpv2:oFx *W p}nۺ?vV1r WpV8(z t ~J rC')q1μ}$i8ӳt,$0m6KOQηә2+{*{3D΅6b@|&2&qh q(c›v&vzROPdҭH-[!1PiaуUfWB 6.q\Kȱ [Fͅ=$Oq|}t]s,v玬s@14:,v-21)hbf1C,]gM>|C _kdqB]32Rռ$hbFhy'[ZpU<ћ!/b机A==HW=fd`TaF2fƓ jUڶaGy\Qy}ĿT8yN22IAүa=VBD=d+xﺔ%|4#j>K>GXy B:|P;XLJ|PK ]QF=Ym! org/gradle/wrapper/Install.classY |y>1 `AH9@m [fI` <Ҏ%a'vq$4=p&u&n#ȘrLn։ۦMJZ {x5"7dsBobKJ>:HazSo{ w-&HK ?)D$пѿҿ)3Hu_A  6қApΘ#;^} 8 A eAVyAj73 yVB5Y;*H{9 |GRxC:y‘ uo o r5הV6u2 n an[y ;A&v n(7H'6wʅD vlݼ_>U2{t =8z$9x4zᎣBgGm-#9iYLZ>%2z; stT5іQK' KKt9@ܜH&L-δ`;{.TR=֑NC ؅Å0VNdƣ#w tZaItmz{Inv1&oיI?3>[G5a-qL nz1#ʹ(eM"Öz**qwAGьنW0[D'bsF oCL.n deBD.S۽ h2  ʃvRՋ"T:G2I)ܑºVz:4^f$#Zr `>l#=)|mFF #6l'"pS(s Ŷ|TTg:uS& aF*?19,mJ\XyO*i>Dk!#UR*<Ԁ<<6njxޭCeX84#* 1Fto$5W}##Qy 1?C 'Tgtk`4E2{rM/%#t/*[I$łB-`޾2wDq-DE<е4Č[=G4)f9pFGyBIʏ8p?*.(HR5~P8C9/*?%zZ0[hC pUaQ}X__VY? Tc*?0y[&#!X=gnǦGѨn `QT[܊O3KQ_Z3;W˷(w\@ײŎ>)3^vK(H$*vA8"Hl<#N;oE{Vi T%Ѣ,IMK=InQSfsyHx|xnlu7.W.-i& ڢr-PwB& (+mJ Vl Gvm5EOCi3umQKy(y*RWe> <4wKE-X+Si[e8R!R&7&$H:8@6{ T90Ei(3䡑DHӮmnW cg~UQ1LKIp>ig?:y>iL%k)TƼvf.y=%L"('9';Eo (*D(Na"aiFUBc;!y;3Ό8},i|= ^3X(:CeWHoB+oB.;lkɏqnnմE??4݉t)X <@? +/g+ocU prޑs'6'%fm+"kꝦϒ|94"c f`V"^rRnd"C3>@j\5C= t#CsLlB &UjB Јp⌓|Wa/Xl/ ޼ˎJ7P 0KcH\uD׀/T4T)4q2MK1K1ؼ:9C^:iq3hgK7>)D̀ _DP1,pgA+2>gvuIFA Ik4); SBK&4da~y`z:'jdz=vd y=^ 5z mC[|9ln}{"5+jM~<}ҍg۫_hHDsykWWk $::X,GɧyW7kY/R߀ʪTpC0of *[Y(Rmww([0˙Tnq "C$/컽˿^nˆߩoweoS.ne?_%"z{ZO1q߄IgܒKEFwPK ]QFL -org/gradle/wrapper/BootstrapMainStarter.classVY[V=²l1pNSJ4 `:/FD,.iڗ6/|M/vd7w;s̽co/eqWF/f$/aVF+dü,aI1XzwMڴYV5#nͬI,_ m5F:-HO͌i:tV"0 ! a\~X@]T-B4 3L5HpO̎JTpP;"%5)%YҎ:l/O~1yn$۷5JьTL]f9dzByd.hNuT'[UzifJ9TV"܃ )xt\:JFvhؓDA| KAt'zEܪE=gϱ()xCM{T G >Ed4Ѕ׵m _+5rÏÏFyK7 wT92`fg̜ ԩ6 ڻ,R}5(Nimm;==荜+AU*tS(\z&+PUYȲ"Z?,S*O8TTp#]p7ZLgw)⾵,+̞;CנӺBͧ`Z%ܮqfLUE:jښq`>;|4{Dj6R\a(\K$"\&T)3զ@j1-2 X#5E|@-봋,:u;O`L!&;͡cԭ“?G1&1_҄7_&ƄM<'|@3LZ p0b CyJ&_1@$CҊC4}xWnM+vuon$"I&/OP1EѼtİyt,mbiory\ ˿+Z$|cqVv (Aq=:Mawxq1):L%>=ZYJDvPK ]QFE C (org/gradle/wrapper/WrapperExecutor.classXw`#Grqlg;e3KHBh<^XNRYd82H[hX-mInh @Kҽ.{M}wg\߻7xO~p 0^k¸-ZBkeua>7(nQ(`ob֑2E6KCwλP=27~>e ø'ΏQtX5-_3u_1+4ɝ0|!c|E/ Jŗe1+Q|_FT/5:׵eohpǖ#Cý#c bZgVMtlMWl-goղE] ]R> K HVT o<$̼nن^Pĵh>m/Sm64ޥ4NY{4+GvhD9n\FwNcB~Ӛ蜰LVci$:sCS40sdjiZ4h{ iSpEk*Ow.RU [oԸn Lk٭e9G-=YzQ` EPpJWAN;I fJ]> (-ҵ#beJӚgi \l[JN9HlۦLYX}2þDm9)4cTIyrQw{}f'tۏNE*hk}:)ȉUW[Adg]i>-?G%(!͚ " :hT|" FMaFdSy"xzqkU>oP)kNVRFߩsMv;71M0 ҕ-Dwh:DUן Ze[v۪4CA,gߕ!{>H1gSz{6;iLBKEuWr7r[9h蘄,f3 Y{)w*Lq"?ן#SH́D.NԮHVvu/+}gn=(Izު[ǣ%iPQ7<>FeU 󅷵2/3sTExK{-q-<)[ z|O`pVgłg6^2g$_?T"/K8_wQ_}Ɠ*@((l4Nנ9dj}bnfv,SIG(Ұt vrek TP"!e~,%v#2F {|ĉ/ISzQL*=KE.{2n*IM"iKOAnIePp6碼iVcгS9~ݓү)깴^aV~qU:/|% 8 @)a[q Ø&,z1cڤ|j! Wܹ;1z^DѧDmGАHAcCS^`4:e2Mc VLTw[ŝ3ܽUޙCh^r IFK3گXJ-g?랪{1܏xI.)^%:Fi%T@ϟ ‰6Mڅ|.) '5Nq `ih1p`(j9N0{p;&[ЀW0J OM4 :Rfػ_5űS-ޭPm>K= W>PK ]QF B*org/gradle/wrapper/GradleWrapperMain.classXxNjU8 Ô Ԑ΀Y fmVQb؉H8=N8'يM'Nwz;gwu:-B_yy O>֋*.2\.PJ\W)8ǫxܽVpzoPQ&Fyx7 ޢUM|\!wRn~ zxXX PQ#܇*ŇU1!&\cʏT9c*T|PIb3T|֏I__O/KFO~|Mץ-w~.ǷT|Q]?'\~g ~ypoǁûz;+:1=>635R@(=çEї.#*Gm |m0uE#ѧRI3DT]&vHB }|HwAg׭G47_%uM8P]λ@5;1 VHJ0M=Jq=4:[H,n34vCFE3~$e1/#*A4y(e<u1{':bWrM<4A^`ܰ:{O-TFacL[IU3`$6F崌xApUII3InIIEc2h6l-7]8M>/rBp˒ ,jj-nM&V ]$ tU;5;M)b62)4 V s\x*jg+?O /+jBғjH l T/ zSX<0ksrRq36MOF[Ic5!˅.@UiI^KB,`eu(gʢdP>MBM(S5QXFa5$BŒNcOWD&JE"5HQJXK4Q%9+=/Rq+:fdAE,ER_Qeb6=7аAw1BLӳf"bMc=ij$kgiϑcF RJ ib 7)\Y>Z-.fh!%䢄UHŇ)ҫkFZQ+q5KcѨuQmX6E:DRo!3OoL74Br`=ut2/ՓԘ.Z FGR ^5ye7 cxYdvc+1X=ݱŝcGʸ>g/*^.Ʈ(Aeys;Sv{NďyӻO,zE)]7'cV1͇yVƒ#e4̝j;Þ7<ƘlTB3r0 pwzv qơ`Va! rD(~(kr0k_}))|p0 4L@<`ZhWzG[Ebq {| 'o &P PGZ(4f%\*S(#eyKA@. NE *N(XFU'-iAYR.X4ZԠ0eC),X1MaP?x 5&3F:z-mQ,G#.:B3mWc= b3nG ^8+Zm;"Q;|99J!D%C XH9Ĉ18~=nK!9\Kh eq(6і"3N2"l9 t𷖾BPCn\Pch!T hG:QKVJ:f+27ɮw6': VV8uk 4i\2캳Uez46qii}( \q2Z[z%0plZ;x9W \u֖UN\j2^C%:LyfWɐ݊琾I\whJl}:%v0uwv5R]4vw#1QWys{쳽=}%m/c*%,ULLs#}`Է0mw3a0Y HKoJx!+ }Xx$pg.(Jcݨti>DL(!L Xa_..)i %L?7nRrjPK ]QFpd "org/gradle/wrapper/Install$1.classVWW=2$1q+Vچ` hE@FTPC2a&L@mbkko}-zJzӯ~_HМ޻{{߿W2cC<8xeJ UraV$*qV΂f-m-̙JLfĕh5KEJUKMՇj9 U%C78Dl3QUj@D2M[`YO%r.0iɇQt i҃6/]1=(Gף NYu´8Qӈ,K5pe cl^淞ըFT7߭ڃf̃ge#3 oϷбjWuf',F:E^㴖H\m$=QOq>fkXjb Zkd;*oF-Uvj2MEu31-S@^g"WjU!Zw)Cja:+}tpBV Cm:,ՁbwL#V%s֒΅u i)[ݫ؃%Ut+6н}WdSrǸԩ k9HFxKcPIv'Ʌdd 34ٔg{9;bfj~AQhώ4dFz1EF' 4kG Ji ֍C׌$+X!C ^C`#Q7ـOT+_ty,'nb(Isރ0Y(+1}8וQK?et&P>X/#]\5_<+ƒ~9Ye$&rJG^uTrٟC3.h*X)̳UTZbT( ?h *qW;KW98hjqID&p/ i,Sp.^m@`5BuJyJx8ЄT̛T na+B(6Q6 b:Q6v3g+ ~lPùȪ!j?CUTనE[o*:.;H*agY'}8qv[ ci7jni`Yz4 ` .Ɍ{/#F%V-2PK ]QFj jV8org/gradle/wrapper/PathAssembler$LocalDistribution.classR[KAftq[yk[KA!|(L!N MJP?U<3Ҩ|ؙs.s˿ū9`OM}Q&m5ȏT0芟"VY~ܪ+Mc56-ډiK` {DjyT򏄽Ilֲ$,4T*? {M Fɡkmjs M%ydw-~[ؑ%Ru<[5'_n$6E<`=fAxwZIDډ?7 U46?S@h=W-ĝPK ]QFcJK!org/gradle/wrapper/Download.classWg~f3; 9X( l" $v4, ]Pq;,lgf TmnU^[l(UT#bσ*Ge|LU4*ISb Q|V4Sy|A%<|YW𸌯*zDoxT-TSL-S TU=WOe<# Aafu1 k,췭a;on&-qS#wNO-AIX=j "J FMh[`J Z8n遴q`[yV8X愾`HՏYL];c-\mưvtqk̸{$DZsJf$G7gLc"0k٬Գ3gMͬ I˜ˤ2 ³*)H-gTjd /LYOláڭD!e8n,nՕ;4rbё nckئe1^?ً}l8s~}uECwY) vl7qfhF+E;.ﭺ/y#8Ǯbph%!-!tj{#w|roרQ+23wavb#v&J2pÄގy  S(a8IfUVe`->Cx d~M"ɾ|X,HיHxT'v"v] /`x@trfelO4P!H F 7h!mʩLA-^8LB-JAPK ]QFVOO#gradle-wrapper-classpath.propertiesSO)IUHIM,R)MUMT00U04"SKg#CSbĔTLҼT[.PK JQF)build-receipt.properties5O1n0 "$;q4hVҢkAS I6MBNwǻO)2;aZ,n6@)_ߝ='- BLOm3(N9h2mCpKF lJ"|8[v0qoŧhR Fh!0r L> 1X JW#ゅ ? PK JQForg/gradle/cli/PK JQF<S1org/gradle/cli/AbstractCommandLineConverter.classT]oA= +mt>BHhBem` Cߢ/42YPa9{s?p# 5ϕBy9yEx\Ye ZpՆaEjw I7|ZU c:tiw]HaٲzQdu;BrQfظ&DV\%6# ǹƙun]s̷X3ػe9H%ҲIk.=,ȍ-1ak^1蔕)9(id0^}y_7бp:%`i6t*㰊jBL F vUWm_ImuוD I8H7Լ&%DDՄ3qONB :ACvsπb0\8y 3CEw&T*kY+$@B!K͡5IYF6VANwh`+&XEKH,έQFV# J#hRq +dAy ~#TN*)oްOOSxΑ 86'??'k<ų@zV`PK JQF2_e(org/gradle/cli/CommandLineParser$1.classA 0EhZ v庈kCPEv-iIp.<S\p>?fxCDlnmMJ]k'iu#0BWՔ!f,By@wZ͕t!BI]#HI9|g|{ -|PK JQFRB <org/gradle/cli/CommandLineParser$MissingOptionArgState.class]O`6d 2 c&/1N4`W5S/ ^H#2-sKƖ&9O״ 1UQ4%ի*gE)D15u KD10ؓp :@^3\ٲŪ+^1UqQ)B&@)ʊ! B@n!fU(AiW|ۤᲵMnR# yd8!>] ZEGO*%UoulGQ/\TMn˹-02#/hAlu@t%-q*2Nw e&BgsQ\gݧ-F͌& nX{~ϐ2zfZC R6A Ӱἆ%GAa3@Lv0Lc8~csC7]Saf=/b !i!WiXN$!9!:">i!z&|'d&w`8Ig9NOXFiХ uD5x Rl( 38qhKCO p:mO.6p'%0o %rC?7o@Ӹ<=@QO b쫇|CMa"!˰߰d^7Uܰ^t^EY3G5Dh8%h+aVE3D*PK JQFM2=org/gradle/cli/CommandLineParser$OptionStringComparator.classTOAfeam`ZPd) HJ  ަ Yvɛ{&ƳvBkj8tޛyo/ jѱcр%:UlQNJU-`!?`nbHzT(gHuO:{|"<Cbq,l ߷YqDݶ̚-M oyޕJ z-Qӹ|H Nl#Kݑ]:Պ}^!C ެ\kW=jA;W{D9!ŒeAS/@%ئRƾj n5nIJ dOcy_e[o9 =}&fH]ͰqiR-x/ rahf2=BF=Y \ KaڙdiZ_L*SHhpPsED?!Fq`pZl{ݺ=1#[s!B{./zi|CG1ǐIVy&$nR$B;C'r."{i"Llr".03m`Y(N͒V055QM<3t Ʃ`1< mcd3B= `OPK JQF# GK1org/gradle/cli/CommandLineArgumentException.classJ1O3Zm+Uו0tD23k*|(1IK-Y  2aEE9炧=OQzTqvK9fU v#tiˀFCb!ė*BE{2ȅ 9`)K,Ihh\x &J>p1YITةQcBW~ͿDcD y f@]tӻLA^%6uV18(c]3 2gy=ݴoa̝̩ kqv>PK JQF?h=org/gradle/cli/CommandLineParser$KnownOptionParserState.classXkx~dY&Vdsд!@LawL73ۙJ[^6V{zJB^֢Oy<}ߟ=gfvݰ?ܾs@;ޕw%!cL!XIy^l^^\OIcB w10X/LtL{$|Uz|={el}2oɷd|a=_P8? cu 'yy(agL K%yT¯$PkXk戄ٗmivOBsh['Xh43g~vt&@A˰qlŀ1bjn&5 wfbqԴ]L0 KB}qeF;zylXqLҟ;C Dl2XwiMU9^܀¬[2ԘnհT ky|qG\R-VlFtw[^ZpwL&tJ%Fڬuu[s-ά }A*I/m^E> @YK#m^:y}` b(`Vʎ7hZ8h W '̇۶g vGVlWpv(؉)BA 4.nS:vA :WV:ujմ\UTBq>:ȲI6)Oݦ%ݣ6uBsԤmq=ajl-N+8*7+xC bH”.k8e9tTij$ *9 cNsxF ^ ~ڛJjFN趾d/?BQ2xEE*~!Ů656ד#f"zHxS[,mUbj%pAMi /}2h4i-lӨo/F[Xulxz o,<#^Z<;^=F݉5y豖 g7eÿ%8#^+XLw6j=K֕ xr^ i/=Tqܼ42b6vc&>ܰh0g|,eŨCgm}C~Rqᦊl>hAdf^]2gbV% %jO2!ǃL&~spfc9OvtYSr\w 7V*9dpŮ[ [3Gҩ7~vOrDx (Sl}izKg:$D)ahJb9gP6hhVD +$D땐h<Y<*6JBx M'X>bAlwĶ%Y9!e} n/*XO߯i;BPK JQFk7org/gradle/cli/CommandLineParser$OptionComparator.classUmOP~nQ:oSD oe b0!c,Zvğ_Hb"6sJC{=9Ϲ~P4dW%,(c ^JX^IXu E ^3tmm2$r}d }w5C}5\ޱgVnkR,)XN];ڡ5P ЬC渺3y  ,#e}0Ђ/]i'jjV]zaՋ S6^~ u- TtY+y&duK< Y$jj7cv 2W[VAۛ+mS*(uB1lņ,i^\r 8;c =x\8npﹸvr CQo *]] 4|[Tuޒ%`anot.AAiU WGŵ S/co4<}u!TZi>Jv!a<@*QȒ̜!q ;G'.!v {nD<|ڊ֋1(Н0Q I9b|b$m:ݳtBHO\g3(W`iL9I k aXtβE$i,:AyLS)""J?QAX_PK JQFb'n?org/gradle/cli/CommandLineParser$UnknownOptionParserState.classURA==$a2@(""UZ`$SdL__\H*~7= B%q}q[A :0A0iDq5k rCw˺& ezabq [vJ%nWL[F ! ɕgY6rkk X>O 6E=}9A{gN)Ҧ>曖.^]S`{jHO~噎-pe}^^rJI=R7٠cSޒ{2iOcinی1^#r޲t1b7?4yvo=)L^)aFZ֜[c9*z'̼n$T BAa F&00 mGd6a4j3 C'/n{._VƵձ+1DX UR%H}4+.L_c=:"L32}F7>L`g%.dJ\)+QLgq.:K^dI׵{""¾j4e8 ț#u`@Ts䥓?|pP{fr mEhQr!"XOٯUVH/.\ 鋘6?9R?SͩUÕ@FcH:U1-NcjXc4Uy<blfq=PK JQF"zZ &org/gradle/cli/CommandLineOption.classV[sV˱E  cP@HICEUGT\Y S¤tCg'C~GVdٲKΞ՞ow=m;0%c:6Lu`; fx%p -xK ܆*cAF>ꩂ4!#x,ƠpG(ߍ%qKFI{dY5~G*n4gXBǔ^4Ubkֿn ,[7'yBQbeI3%5r&u#q2Qy[wHHSYJWɬjJf@H7h[Ҭ,J8ڲ -7ܨq&nԝR1GC (ONT4{Zj̨.2jyi~\PSDz5,žcKBO}p,̮V!^ԜUmH(Q"lbQ-#a("Zrw6 ivΝ=w _|dŦmTҜ1d{mC);BNDfQkikɄaXq2ЯܵRB7"$(XAy/A7A#>;:|(F ͹=U&KcEZP|yq- S+·\U|HQS$dú݄31TMZ@wťK) sAChU0^]<. uʓGa(M"%z.업cg"W=d1fIٔd}F6,O).a9Ţ,se,~Bٿŋ#Hp+o(8Y:nY XGQWwe|W}?%d735V?6FeTs q83x[S/W&SwE>F)L+5VeF'1Gy݌`RͫW5OޞJo0LA E.ȸ:V61'!unQúwTK7rXr̐[1E0w$DϞCόm  kV%8py'ЃZT1жO~0͢˚QX|l%>ow l (t((TyN,x0^*QpKWj'DG \! ׇ6!$>!À40d)w[@bbu1NbkP$LװMUWlV Gn"{$ G^FHbp,>"]vqvοVw΄1(|v3A?w2{10]/~ ^&IC9$Egd$}uvNrg5&<gSF2#SӤXLBi ,A|;"AmȜ2BXiL8 G:m$x0$aOI(>*A[Ue/3n3̎Hm ߗzck쉡-,N3U?ϗ^i e;^{*΅e gl͑HC9Y\Y,X f.Ggab@HFSϢ/@tOL]u(#_k#ܩ7onaܾN25h8)Jeb[11_b7İ#j1lFד>^I>7ʢ0uI;, W/pdiM O: 䡟 I%'/;Lق)<$O#30VQ+qvC#B7>8^C~,rPK JQFg*&org/gradle/cli/CommandLineParser.classY xTյ^+8$<"cB2DT0xHNLQ*Q`}WVEIQbm}>l[{o{zk[L&={wD4OE>-NS:`ҩYti]:^4i:TNDOnvsS\stZ5^qNxNHkD KuPft0\s|\'V9OfhH9_>|!E_Gx5n*kDK|(j|NWu\ ⊀_&Zy6xXr:͢ Ѣŭ>nvLdh]ȌŬӘU`$muN3j#Q1M3c֊p ǂN+)^n;ӸKÑ]a{rYƸ4Aŧ`*p3c1gkmj {m[Q{4qi9?B3ˬH׸3e]fʐ<~tk1j4/߲v40Wn3wU]`*jYVqh^4*b+;cTu `[،wE噳!3Ve3X2mj-!9Jme0l.\f(Um$5/XQT(ڲ*5>0X1MB)[C,] K\%uK6 :ZѵBQ+#fh Ġ;S>aogD|IJJ"/?{)KlllQK@pk lw7[ɀ旤Q&3 1exp 2^Њ$W,fHB9iȰTA/L gnqי1:m^W y^937=&3; Y9lays@ 㴒A^WV![Nlf4 wCVMAs6l|r%%,X2ѭъc9#_z`Υ1 N{ng߈d HŊ&oɑ4Vck i cQn2yU@C8dq~r4#3rafmA𝖵Ӑ-tچ1zǓ:H$m}]$ǝB<8&Hj60S+e1+UxvO L͈V)2dcKw$ԧT*fsM;s&A@+srPђd@X%~R,>AŅoBBotEQ ĢRtmAӠ/mAw2O^æa8nˠüzP>6xk&q;( winҠ1⡎A_e+ ?#<ZY} x ˎ-o ?71U )4Y7x `mEo;h%Kc ŕe.Cm5/2Kiy͕eH48MVˣHâY HB3u{>COicOYS}q1y)V\, >!i85~Q迁"%Fڶ!]8S8j/{3fcf]܂" lT/i$jp8/6[Z#ikM 'GmX܌Ƌw3*fTt ݪ¯jdLɱ8u7Gq3fۉfX )TeF'|_7 QdBɦ{6u^U߽S-J ~S%\hC8KpiG OF1wxp:bp4}GR/ŭA qp:UY?z-g= hະtp?"@4t44Ə(J}T0qefl/*_8xnqV?F:fVGdQCYA'vtXA] X1jM4XX"JV8#$Ӷa fdBYs@ֳ X]-pޚ J%+2'|Zy3+vܚ]yZ?IKUfQ S4p[])  7DI+6~6v=N Uҹp#ڢA[ !q7cODh$J5煰PcC`Ff"mXs4|'6ۭneX# kA:ŋ>+ Az /)2{ <dMÌOkfP;#\2fVZwE}Q*Fn2ld/-t\7*błQ%u„֌pUOHzYKxF/GnEտqW-{>Q8+(ڎk1hY?y^=܋h)s> 6GN,\ӛz)5ݽ4BH&Z t0f !Gӗ1gkrʏTW*UnU.=Bb w?7SASٳB^:FSQSY{iLCyw8C|Rz~oOCg' =4Ӥ&Y:ߋ:)=44tEP/6e(fB- T-:KѺ= R{)G0ԇ)TŋXlDMHTѻ 5* fB<Αvj9Kn-U?D+}ͨ3Y z܆|Gh)tIW71e|<$\*Rߍ46Tx-]NZKWi+uS3]M-tYHVDY=K黴~(DR0NH;\JqG]H;y#m͝t%參Gi/?h?O񫴟ߦO7V+9=HndWkIqzGl2A3Þ.6iS$C?jAnnWJӠӠևzk9z=;1Iw2{EnGN_Q='1FQ=6Ľ z1:s1"!llJJ.-\Y bq/Xb%MDU)BJyfxܪv/}[ł0Zre19& D[ /7w5 q`{EG$\hT@'5x^b@̥8$sӇ IyyCMm*[|V5z鼆r·.qW(k8)A6 QH(b0Yl.uK@. R~}NG`v&LO<}Q8ZؾJya `}tKg" h=v^ $%ӊB|L'Y|zw\].J?W:OKb8)`E%ds!1z 5HCo#<ߧi'1;Ԋ(K5dC ~ORiq >5$i\~~D?FY 4plFnJ3I9hm=U[/0fx#=./ˉh]OWf{Ik-\&4=Qx&9ZRV&"s$Яy@( oh9}Pn+G?8*uzö?#܅ϝ頯ֆG med''EѮ@{vG!'Q-KAT8ے۳RH,C H6~7~Z$g/uT*^@ /4?h3 COm>o("N{0w-r 3=81EIBhG1 hAv|v7*8 D O$Wr"'߇LXV<#v?UgWaKwX.ҝQr$a1C2ԭZ?vPX>Bn3TV;Ng(!j<$}E]bݍ;[7+.C{=hg^uuv?ϢEh?7sσ&7no?PK JQF_>ң)3org/gradle/cli/CommandLineParser$AfterOptions.classmOP( @ 1Q|Dt1wkծ5wE#]|!Je<1Mz99s۟PƊ'IW1!y &TU,2~=x6x !fu'\lkug!s6tL![/Hvfe׹[‘zdL[N!e`oyXuyej&!&)bA02]yr^5Vf6R\4dr] C0ԖQi26{{J.-ߏ޺&Ww{Ֆ/IU0ᘓ*3Le o13/#|]ˣ%D3zaS2u7XMc qaA78yWN*%1|avť-N x!*JB)>#iIShln|AjTDVИF(J9DRR; %܊1C!˩1(|GFJfKmt$F5kj|EFߧjr dY+!kmrQ>э=ep2n&0ft9\9E'tN* iϤK49hPK JQFGf3org/gradle/cli/CommandLineParser$OptionString.classSNA=]ʗ(U-e)'#  XlwD w+Bs;s=??~ &cAYs)TҘa! ei,pW]p_8 =[wfnsak璳bv0[=כ)m1$j^C0dlWv8Bv-(wAP ;e(|¯9<Zkߴ>o8ª;UZ-6d7_8'_AyKBkxy>Eӂ4Ui 1 z]A@Z Moz~]{*Ka:r摎, b^hxc+ ݥNC:`U L1r) ;{2̜?3zE9nB;;esy-w'i< MI^NN֤ʍЛh8Yq|9wvc 91Ȩ(` (OaʓbmDm>X1#Ka ~B>FJg!6l|;4 kaCԍx0r/iA';`CG G¡c#'30@ÌnmaF⺙igM1*[Ĥ=\E7i PK JQFx&T` ;org/gradle/cli/AbstractPropertiesCommandLineConverter.classV[wU L2悡5&I  i-4J`Ei+v fpfD{_ m\KWu dY\go}_p?H8"%ެHO%"ͧ= IX6@7=q|';y !H"r k7b0tuVɫ}%_&I cbj| f1\f)^2bYZ ڦbZ:c듶r*&2 M n8&M2jV)DĜ2W5( ,MIzn)嚺Re9hst4%D  Tmgv֭ttKzAm" e7tv٧) ٹW v"Qys;]^W/ypF,w5h}ے6&FOڕ.e`ZcCQ@Q,_Q+WDh2DDYFCF0-6j qdqțt+#y:*[0JZEf~]r~N WScXD\/ô.'Ƕk_4ЫTS!Wn[0( 5R%պ<a՝ISؾꢦ.Ci$h{wfЪCMx(t'9%f9o=,N=M柃B&; ﭣ/ N?gyO:aeJ^/F}o b b4kt"tZ3 яU0fx'ySr 6 aadB3 /)LF}Atc^l?$ͼA_ !7Vkg렾@ ‡CGGDoЅph.` (rroYJ]kKIrIn#)`,r|4 mYYBY-B1>q?PK JQF ,org/gradle/cli/ParsedCommandLineOption.classS[OA-"\A(-ʊP1!iĤoC;Ylw- &JD}G.I|9|93|`+)dPPQL!B0冊I,-,&q[~器+䲤⾊ {lqWAW-+ b^ f~,Cz2$J^YA4_T[Wjls6)5fn2Gsy;+c&k_2U`V]Rm4=a[T.ipoSP0/DND=t=Z+jpS0? KOrbjrjd0ajWKp &N&7YָE4Wl/xY92,BS*jx<Iy2=4yt Zce[ZҚE̙swy' :iB&1!CŴ3*f5$0b^E!YsMKc2\(4ff[\xf}f!?\t]($zr,.épx| luj6%;fOxզPɭq…% v2^l"P+ܧ8ش癄[2۟kVMa*W`sQ(r Q.$uv\ y;>ަVv[fnYx2=Y#X13:ncTŢ%,Xѱ5Pg),V5H3 K; 3'<<JڵSΐ!/g&W;;^ݸ v,ly/x-/TQZ]܉\E/˕=lk<RwgrŁtZ.=EPhh+"J6mL+"F~OA-, f1B 娆E$5"y  3@AU'2P*= QE3D5@}C2Pw'3y=RHI8[-vtn5@ $}_+:)+C EoPK JQF'H g)org/gradle/cli/CommandLineConverter.classQMK@}ԯ'"4 FM)HQ ޷lI7ݔ6MBya=t$S l)8A {Oyb :˄3I5' JXdT"qx{a/4OR1=Q615 ڹ6ƇEWbRh{'qj1M8zta,gZTRwZ\SYVSݜnhUYB/n/1Oz_G86\fjAʚajJuG-UʙeZ7^[u(5}2(Y٪Zk$N(@yA(تeٺip|0Xh5UUJ`[QtZw&~ժ:ѷ3<MSn9j*ߌq\6 G J*yN;{2#hfc f*SL Èaq!y" Ǘ axIbtxh.x%0&X}?:Ui4^}R֚Be*"nE& ̗he;*J"b68pÕ7rC.?V-0fO~^y뱉6{*B^*Y-z=:7CRyʍհjHC*dfN͔W{M ^pCMPzkt_gBR,]x;^Vw+eM+" ;zf7i^/O3}xb]C[B]d5c|Q%G7GO=m~} ҈'ҮOC.i^yb;30rؑ^!yڢ{f U5$:2lދ9eX Lm1 }IbR$Yy|M7PK JQF;|9org/gradle/cli/SystemPropertiesCommandLineConverter.classJ@ثmjE5BDąR/P~ӑ$&BJW 'iAY3͜l "lYlE <& d@HgL{:rRs:C*X4NĬQ ۴;hZ3a ѽG!]Gv7S"5eb o}ɸGtFMz9y~X{()spL`7e.KV, TXxɢfDTEGPWJmh~49AjxѰ sh gԙn85].FԒs9Q΢*s/@Ug J*ce+s+1 $p6/t-,;h-.Z >kZPK JQF-h2org/gradle/cli/CommandLineParser$ParserState.classSoPN) sT4706|3M$m f{@ú[s-?&>GmdiҞ|~pF62΢jv,-4WׄTqB0;%v=^(>{J` aŴ9,D!PK JQFF= ;org/gradle/cli/CommandLineParser$AfterFirstSubCommand.classVRPN[J;be-x)U.R(XE_( |gtPq猏C8I K0㟳{v|gw9| E͈4тHA/pK\3*B;ExqOH0ԛoB Нҍ\$gȫy%ͫ!k)USdqW5ռ0l%^--1x[+T^ɓğҳr~I6T/ =]kS1&U`fV Ҍ)F2/ Y88f-IMy$ M1eLo H2ڼ})MzٛZʑ"P\\y6O\}9ݲ'JBKeվm gËYzK/ Z1}**2 ~CG&1%`Z 3t9eaёgںokǔ@g%Ku`|G%E5e uS閻5ϗ4ڪ۲b}B\EU6:YPFJjh>3L578")&COH)YslH#?nA;ΙZwQW+S ^ͼ8W'AE[=|>>Јs6MMT > wH{im::^A:HG8d"Fx&O+\AX!vѸq HW69Z e+˝}с; \G7Ĺ(( ]LSh`cB p.9Bj1 D'($U<"z@'bj']GZ f<_PK JQF 3EEgradle-cli-classpath.propertiesSO)IUHIM,R)MUMT00U04"#Cg#CSb[ҼT[.PK `QF AMETA-INF/PK `QFr+?T)META-INF/MANIFEST.MFPK ]QFAorg/PK ]QF Aorg/gradle/PK ]QFAorg/gradle/wrapper/PK ]QFhdf#org/gradle/wrapper/Download$1.classPK ]QFޅpDorg/gradle/wrapper/Download$SystemPropertiesProxyAuthenticator.classPK ]QFXs"vorg/gradle/wrapper/IDownload.classPK ]QFz\Q-`org/gradle/wrapper/GradleUserHomeLookup.classPK ]QF] 3org/gradle/wrapper/ExclusiveFileAccessManager.classPK ]QFc`-org/gradle/wrapper/WrapperConfiguration.classPK ]QFQ}i 0org/gradle/wrapper/SystemPropertiesHandler.classPK ]QFy0Vorg/gradle/wrapper/Logger.classPK ]QFrn&org/gradle/wrapper/PathAssembler.classPK ]QF=Ym! org/gradle/wrapper/Install.classPK ]QFL -org/gradle/wrapper/GradleWrapperMain.classPK ]QFpd "Iorg/gradle/wrapper/Install$1.classPK ]QFj jV8Porg/gradle/wrapper/PathAssembler$LocalDistribution.classPK ]QFcJK!'Rorg/gradle/wrapper/Download.classPK ]QFVOO#Zgradle-wrapper-classpath.propertiesPK JQF)[build-receipt.propertiesPK JQFA\org/gradle/cli/PK JQF<S1@\org/gradle/cli/AbstractCommandLineConverter.classPK JQF2_e(^org/gradle/cli/CommandLineParser$1.classPK JQFRB <_org/gradle/cli/CommandLineParser$MissingOptionArgState.classPK JQFM2=borg/gradle/cli/CommandLineParser$OptionStringComparator.classPK JQF# GK1eorg/gradle/cli/CommandLineArgumentException.classPK JQF?h=;gorg/gradle/cli/CommandLineParser$KnownOptionParserState.classPK JQFk7]oorg/gradle/cli/CommandLineParser$OptionComparator.classPK JQFb'n?rorg/gradle/cli/CommandLineParser$UnknownOptionParserState.classPK JQF"zZ &uorg/gradle/cli/CommandLineOption.classPK JQFl\ϧ8{org/gradle/cli/CommandLineParser$OptionParserState.classPK JQF[xn&}org/gradle/cli/ParsedCommandLine.classPK JQFA5l| :horg/gradle/cli/ProjectPropertiesCommandLineConverter.classPK JQF2lWJF<org/gradle/cli/CommandLineParser$CaseInsensitiveStringComparator.classPK JQFg*&org/gradle/cli/CommandLineParser.classPK JQF_>ң)3org/gradle/cli/CommandLineParser$AfterOptions.classPK JQFGf3org/gradle/cli/CommandLineParser$OptionString.classPK JQFx&T` ;lorg/gradle/cli/AbstractPropertiesCommandLineConverter.classPK JQF ,%org/gradle/cli/ParsedCommandLineOption.classPK JQFs=+org/gradle/cli/CommandLineParser$OptionAwareParserState.classPK JQF'H g)org/gradle/cli/CommandLineConverter.classPK JQFC| <~org/gradle/cli/CommandLineParser$BeforeFirstSubCommand.classPK JQF;|9²org/gradle/cli/SystemPropertiesCommandLineConverter.classPK JQF-h2org/gradle/cli/CommandLineParser$ParserState.classPK JQFF= ;org/gradle/cli/CommandLineParser$AfterFirstSubCommand.classPK JQF 3EEgradle-cli-classpath.propertiesPK11osmosis-0.44.1/gradle/wrapper/gradle-wrapper.properties000066400000000000000000000003461253404521400232470ustar00rootroot00000000000000#Wed Jun 03 22:25:15 EST 2015 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-bin.zip osmosis-0.44.1/gradlew000077500000000000000000000117301253404521400146510ustar00rootroot00000000000000#!/usr/bin/env bash ############################################################################## ## ## Gradle start up script for UN*X ## ############################################################################## # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS="" APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" warn ( ) { echo "$*" } die ( ) { echo echo "$*" echo exit 1 } # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false case "`uname`" in CYGWIN* ) cygwin=true ;; Darwin* ) darwin=true ;; MINGW* ) msys=true ;; esac # For Cygwin, ensure paths are in UNIX format before anything is touched. if $cygwin ; then [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` fi # Attempt to set APP_HOME # Resolve links: $0 may be a link PRG="$0" # Need this for relative symlinks. while [ -h "$PRG" ] ; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG=`dirname "$PRG"`"/$link" fi done SAVED="`pwd`" cd "`dirname \"$PRG\"`/" >&- APP_HOME="`pwd -P`" cd "$SAVED" >&- CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD="$JAVA_HOME/jre/sh/java" else JAVACMD="$JAVA_HOME/bin/java" fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else JAVACMD="java" which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi # Increase the maximum file descriptors if we can. if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then MAX_FD="$MAX_FD_LIMIT" fi ulimit -n $MAX_FD if [ $? -ne 0 ] ; then warn "Could not set maximum file descriptor limit: $MAX_FD" fi else warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" fi fi # For Darwin, add options to specify how the application appears in the dock if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi # For Cygwin, switch paths to Windows format before running java if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` SEP="" for dir in $ROOTDIRSRAW ; do ROOTDIRS="$ROOTDIRS$SEP$dir" SEP="|" done OURCYGPATTERN="(^($ROOTDIRS))" # Add a user-defined pattern to the cygpath arguments if [ "$GRADLE_CYGPATTERN" != "" ] ; then OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" fi # Now convert the arguments - kludge to limit ourselves to /bin/sh i=0 for arg in "$@" ; do CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` else eval `echo args$i`="\"$arg\"" fi i=$((i+1)) done case $i in (0) set -- ;; (1) set -- "$args0" ;; (2) set -- "$args0" "$args1" ;; (3) set -- "$args0" "$args1" "$args2" ;; (4) set -- "$args0" "$args1" "$args2" "$args3" ;; (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules function splitJvmOpts() { JVM_OPTS=("$@") } eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" osmosis-0.44.1/gradlew.bat000066400000000000000000000045441253404521400154200ustar00rootroot00000000000000@if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @rem @rem ########################################################################## @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS= set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if "%ERRORLEVEL%" == "0" goto init echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto init echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :init @rem Get command-line arguments, handling Windowz variants if not "%OS%" == "Windows_NT" goto win9xME_args if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. set CMD_LINE_ARGS= set _SKIP=2 :win9xME_args_slurp if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* goto execute :4NT_args @rem Get arguments from the 4NT Shell from JP Software set CMD_LINE_ARGS=%$ :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% :end @rem End local scope for the variables with windows NT shell if "%ERRORLEVEL%"=="0" goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 exit /b 1 :mainEnd if "%OS%"=="Windows_NT" endlocal :omega osmosis-0.44.1/osmosis-apidb/000077500000000000000000000000001253404521400160455ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/.checkstyle000066400000000000000000000010051253404521400202000ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-apidb/.gitignore000066400000000000000000000000531253404521400200330ustar00rootroot00000000000000.classpath .project .settings /bin /build osmosis-0.44.1/osmosis-apidb/build.gradle000066400000000000000000000010521253404521400203220ustar00rootroot00000000000000dependencies { compile project(':osmosis-core') compile project(':osmosis-replication') compile project(':osmosis-xml') compile group: 'commons-dbcp', name: 'commons-dbcp', version: dependencyVersionCommonsDbcp compile group: 'org.springframework', name: 'spring-jdbc', version: dependencyVersionSpring runtime group: 'org.postgresql', name: 'postgresql', version: dependencyVersionPostgreSql runtime group: 'mysql', name: 'mysql-connector-java', version: dependencyVersionMySql testCompile project(':osmosis-testutil') } osmosis-0.44.1/osmosis-apidb/src/000077500000000000000000000000001253404521400166345ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/000077500000000000000000000000001253404521400175605ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/000077500000000000000000000000001253404521400205015ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/000077500000000000000000000000001253404521400212705ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/000077500000000000000000000000001253404521400241565ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400256525ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/000077500000000000000000000000001253404521400267315ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/ApidbPluginLoader.java000066400000000000000000000047371253404521400331340ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.apidb.v0_6.ApidbChangeReaderFactory; import org.openstreetmap.osmosis.apidb.v0_6.ApidbChangeWriterFactory; import org.openstreetmap.osmosis.apidb.v0_6.ApidbCurrentReaderFactory; import org.openstreetmap.osmosis.apidb.v0_6.ApidbFileReplicatorFactory; import org.openstreetmap.osmosis.apidb.v0_6.ApidbReaderFactory; import org.openstreetmap.osmosis.apidb.v0_6.ApidbTruncatorFactory; import org.openstreetmap.osmosis.apidb.v0_6.ApidbWriterFactory; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.plugin.PluginLoader; /** * The plugin loader for the API Schema tasks. * * @author Brett Henderson */ public class ApidbPluginLoader implements PluginLoader { /** * {@inheritDoc} */ @Override public Map loadTaskFactories() { Map factoryMap; factoryMap = new HashMap(); factoryMap.put("read-apidb", new ApidbReaderFactory()); factoryMap.put("rd", new ApidbReaderFactory()); factoryMap.put("read-apidb-change", new ApidbChangeReaderFactory()); factoryMap.put("rdc", new ApidbChangeReaderFactory()); factoryMap.put("read-apidb-current", new ApidbCurrentReaderFactory()); factoryMap.put("rdcur", new ApidbCurrentReaderFactory()); factoryMap.put("write-apidb", new ApidbWriterFactory()); factoryMap.put("wd", new ApidbWriterFactory()); factoryMap.put("write-apidb-change", new ApidbChangeWriterFactory()); factoryMap.put("wdc", new ApidbChangeWriterFactory()); factoryMap.put("truncate-apidb", new ApidbTruncatorFactory()); factoryMap.put("td", new ApidbTruncatorFactory()); factoryMap.put("replicate-apidb", new ApidbFileReplicatorFactory()); factoryMap.put("repa", new ApidbFileReplicatorFactory()); factoryMap.put("read-apidb-0.6", new ApidbReaderFactory()); factoryMap.put("read-apidb-change-0.6", new ApidbChangeReaderFactory()); factoryMap.put("read-apidb-current-0.6", new ApidbCurrentReaderFactory()); factoryMap.put("write-apidb-0.6", new ApidbWriterFactory()); factoryMap.put("write-apidb-change-0.6", new ApidbChangeWriterFactory()); factoryMap.put("truncate-apidb-0.6", new ApidbTruncatorFactory()); factoryMap.put("replicate-apidb-0.6", new ApidbFileReplicatorFactory()); return factoryMap; } } osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/common/000077500000000000000000000000001253404521400302215ustar00rootroot00000000000000BaseTableReader.java000066400000000000000000000102561253404521400337560ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.common; import java.sql.ResultSet; import java.sql.SQLException; import java.util.NoSuchElementException; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; /** * Provides the base implementation of all database table readers. * * @author Brett Henderson * * @param * The type of entity to retrieved. */ public abstract class BaseTableReader implements ReleasableIterator { private DatabaseContext dbCtx; private ResultSet resultSet; private T nextValue; /** * Creates a new instance. * * @param loginCredentials * Contains all information required to connect to the database. */ public BaseTableReader(DatabaseLoginCredentials loginCredentials) { dbCtx = new DatabaseContext(loginCredentials); } /** * Builds the result set that the reader will iterate over. * * @param queryDbCtx * The database context to query against. * @return A result set positioned before the first record. */ protected abstract ResultSet createResultSet(DatabaseContext queryDbCtx); /** * Builds an entity object from the current recordset row. * * @param activeResultSet * The record set to retrieve the data from. * @return The result of the read. */ protected abstract ReadResult createNextValue(ResultSet activeResultSet); /** * If the implementation requires multiple rows to build an entity object, * this method allows the implementation to return an entity based on the * fact that no more rows are available. This default implementation returns * a blank result. * * @return The last result record. */ protected ReadResult createLastValue() { return new ReadResult(true, null); } /** * Reads the next entity from the database and stores it in the internal * nextValue variable. This will be set to null if no more data is * available. */ private void readNextValue() { if (resultSet == null) { resultSet = createResultSet(dbCtx); } try { ReadResult readResult; // Loop until a valid result is determined. Typically a loop is // required when a record on the result set is skipped over by the // reader implementation. do { if (resultSet.next()) { readResult = createNextValue(resultSet); } else { readResult = createLastValue(); } } while (!readResult.isUsableResult()); nextValue = readResult.getEntity(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to move to next record.", e); } } /** * {@inheritDoc} */ public boolean hasNext() { if (resultSet == null) { readNextValue(); } return (nextValue != null); } /** * {@inheritDoc} */ public T next() { T result; if (!hasNext()) { throw new NoSuchElementException(); } result = nextValue; readNextValue(); return result; } /** * {@inheritDoc} */ public void release() { nextValue = null; resultSet = null; dbCtx.release(); } /** * {@inheritDoc} */ public void remove() { throw new UnsupportedOperationException(); } /** * Represents the result of an entity read from the result set at the current position. * * @param * The type of entity to retrieved. */ protected static class ReadResult { private boolean usableResult; private T entity; /** * Creates a new instance. * * @param usableResult * Indicates if this result should be used. * @param entity * The entity that was read. */ public ReadResult(boolean usableResult, T entity) { this.usableResult = usableResult; this.entity = entity; } /** * Returns the usable result flag. * * @return The usable result flag. */ public boolean isUsableResult() { return usableResult; } /** * Returns the entity. * * @return The entity. */ public T getEntity() { return entity; } } } DataSourceFactory.java000066400000000000000000000031631253404521400343720ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.common; import org.apache.commons.dbcp.BasicDataSource; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; /** * Produces data sources based on a set of database credentials. */ public final class DataSourceFactory { /** * This class cannot be instantiated. */ private DataSourceFactory() { } /** * Creates a new data source based on the specified credentials. * * @param credentials * The database credentials. * * @return The data source. */ public static BasicDataSource createDataSource(DatabaseLoginCredentials credentials) { BasicDataSource dataSource; dataSource = new BasicDataSource(); switch (credentials.getDbType()) { case POSTGRESQL: dataSource.setDriverClassName("org.postgresql.Driver"); dataSource.setUrl("jdbc:postgresql://" + credentials.getHost() + "/" + credentials.getDatabase() /*+ "?loglevel=2"*/); break; case MYSQL: dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://" + credentials.getHost() + "/" + credentials.getDatabase()); break; default: throw new OsmosisRuntimeException("Unknown database type " + credentials.getDbType() + "."); } dataSource.setUsername(credentials.getUser()); dataSource.setPassword(credentials.getPassword()); return dataSource; } } DatabaseContext.java000066400000000000000000000420551253404521400340640ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.common; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabaseType; /** * This class manages the lifecycle of JDBC objects to minimise the risk of connection leaks and to * support a consistent approach to database access. * * @author Brett Henderson */ public class DatabaseContext { private static final Logger LOG = Logger.getLogger(DatabaseContext.class.getName()); private final DatabaseLoginCredentials loginCredentials; private Connection connection; /** * This statement is used in cases where the statement isn't exposed to the client. It is stored * globally here to allow it to remain open after a method return and to simplify resource * cleanup. It will be closed during release or if a new statement is created. */ private Statement statement; private IdentityValueLoader identityValueLoader; private boolean autoCommit; /** * Creates a new instance. * * @param loginCredentials Contains all information required to connect to the database. */ public DatabaseContext(DatabaseLoginCredentials loginCredentials) { this.loginCredentials = loginCredentials; autoCommit = false; try { switch (loginCredentials.getDbType()) { case POSTGRESQL: Class.forName("org.postgresql.Driver"); identityValueLoader = new PostgresqlIdentityValueLoader(this); break; case MYSQL: Class.forName("com.mysql.jdbc.Driver"); identityValueLoader = new MysqlIdentityValueLoader(this); break; default: throw new OsmosisRuntimeException("Unknown database type " + loginCredentials.getDbType() + "."); } } catch (ClassNotFoundException e) { throw new OsmosisRuntimeException("Unable to find database driver.", e); } } /** * If no database connection is open, a new connection is opened. The database connection is * then returned. * * @return The database connection. */ private Connection getConnection() { if (connection == null) { switch (loginCredentials.getDbType()) { case POSTGRESQL: connection = getPostgresConnection(); break; case MYSQL: connection = getMysqlConnection(); break; default: throw new OsmosisRuntimeException("Unknown database type " + loginCredentials.getDbType() + "."); } } return connection; } /** * @return postgres connection */ private Connection getPostgresConnection() { Connection newConnection = null; try { LOG.finer("Creating a new database connection."); newConnection = DriverManager.getConnection( "jdbc:postgresql://" + loginCredentials.getHost() + "/" + loginCredentials.getDatabase(), // + "?logLevel=2" loginCredentials.getUser(), loginCredentials.getPassword() ); newConnection.setAutoCommit(autoCommit); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to establish a database connection.", e); } return newConnection; } /** * @return The mysql database connection. */ private Connection getMysqlConnection() { Connection newConnection = null; try { String url; url = "jdbc:mysql://" + loginCredentials.getHost() + "/" + loginCredentials.getDatabase() + "?user=" + loginCredentials.getUser() + "&password=" + loginCredentials.getPassword(); if (loginCredentials.getForceUtf8()) { url += "&useUnicode=true&characterEncoding=UTF-8"; } if (loginCredentials.getProfileSql()) { url += "&profileSql=true"; } newConnection = DriverManager.getConnection(url); newConnection.setAutoCommit(autoCommit); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to establish a database connection.", e); } return newConnection; } /** * Returns the database type currently in use. This should only be used when it is not possible * to write database agnostic statements. * * @return The database type. */ public DatabaseType getDatabaseType() { return loginCredentials.getDbType(); } /** * Truncates the contents of the specified tables. * * @param tables * The tables to be truncated. */ public void truncateTables(List tables) { switch (loginCredentials.getDbType()) { case POSTGRESQL: StringBuilder statementBuilder = new StringBuilder(); for (String table : tables) { if (statementBuilder.length() == 0) { statementBuilder.append("TRUNCATE "); } else { statementBuilder.append(", "); } statementBuilder.append(table); } statementBuilder.append(" CASCADE"); executeStatement(statementBuilder.toString()); break; case MYSQL: for (String table : tables) { executeStatement("TRUNCATE " + table); } break; default: throw new OsmosisRuntimeException("Unknown database type " + loginCredentials.getDbType() + "."); } } /** * Disables the indexes of the specified tables. * * @param tables * The tables to disable indexes on. */ public void disableIndexes(List tables) { switch (loginCredentials.getDbType()) { case POSTGRESQL: // There is no way to automatically disable all indexes for a table. break; case MYSQL: for (String table : tables) { executeStatement("ALTER TABLE " + table + " DISABLE KEYS"); } break; default: throw new OsmosisRuntimeException("Unknown database type " + loginCredentials.getDbType() + "."); } } /** * Enables the indexes of the specified tables. * * @param tables * The tables to enable indexes on. */ public void enableIndexes(List tables) { switch (loginCredentials.getDbType()) { case POSTGRESQL: // There is no way to automatically disable all indexes for a table. break; case MYSQL: for (String table : tables) { executeStatement("ALTER TABLE " + table + " ENABLE KEYS"); } break; default: throw new OsmosisRuntimeException("Unknown database type " + loginCredentials.getDbType() + "."); } } /** * Locks the specified tables for exclusive access. * * @param tables * The tables to lock. */ public void lockTables(List tables) { switch (loginCredentials.getDbType()) { case POSTGRESQL: // Locking tables is not supported. break; case MYSQL: StringBuilder statementBuilder = new StringBuilder(); for (String table : tables) { if (statementBuilder.length() == 0) { statementBuilder.append("LOCK TABLES "); } else { statementBuilder.append(", "); } statementBuilder.append(table); statementBuilder.append(" WRITE"); } executeStatement(statementBuilder.toString()); break; default: throw new OsmosisRuntimeException("Unknown database type " + loginCredentials.getDbType() + "."); } } /** * Unlocks the specified tables. * * @param tables * The tables to unlock. */ public void unlockTables(List tables) { switch (loginCredentials.getDbType()) { case POSTGRESQL: // Locking tables is not supported. break; case MYSQL: executeStatement("UNLOCK TABLES"); break; default: throw new OsmosisRuntimeException("Unknown database type " + loginCredentials.getDbType() + "."); } } /** * Gets the last inserted identity column value. This is a global value and may not work * correctly if the database uses triggers. * * @return The last inserted identity column value. */ public long getLastInsertId() { return identityValueLoader.getLastInsertId(); } /** * Gets the last retrieved sequence value. This is specific to the current connection only. * * @param sequenceName * The name of the sequence. * @return The last inserted identity column value. */ public long getLastSequenceId(String sequenceName) { return identityValueLoader.getLastSequenceId(sequenceName); } /** * Executes a sql statement against the database. * * @param sql The sql statement to be invoked. */ public void executeStatement(String sql) { try { if (statement != null) { statement.close(); } statement = getConnection().createStatement(); statement.execute(sql); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to execute statement.", e); } } /** * Creates a new database prepared statement. * * @param sql * The statement to be created. * @return The newly created statement. */ public PreparedStatement prepareStatement(String sql) { try { PreparedStatement preparedStatement; preparedStatement = getConnection().prepareStatement(sql); return preparedStatement; } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to create database prepared statement.", e); } } private void setStatementFetchSizeForStreaming(Statement streamingStatement) { try { switch (loginCredentials.getDbType()) { case POSTGRESQL: streamingStatement.setFetchSize(10000); break; case MYSQL: streamingStatement.setFetchSize(Integer.MIN_VALUE); break; default: throw new OsmosisRuntimeException("Unknown database type " + loginCredentials.getDbType() + "."); } } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to update statement fetch size.", e); } } /** * Creates a new database statement that is configured so that any result sets created using it * will stream data from the database instead of returning all records at once and storing in * memory. *

* If no input parameters need to be set on the statement, use the executeStreamingQuery method * instead. * * @param sql * The statement to be created. This must be a select statement. * @return The newly created statement. */ public PreparedStatement prepareStatementForStreaming(String sql) { try { PreparedStatement newStatement; // Create a statement for returning streaming results. newStatement = getConnection().prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); setStatementFetchSizeForStreaming(newStatement); return newStatement; } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to create streaming resultset statement.", e); } } /** * Executes a query and returns a result set. The returned result set must be closed by the * caller. * * @param sql The query to execute. * @return The newly created result set. */ public ResultSet executeQuery(String sql) { try { ResultSet resultSet; LOG.finest("Executing query {" + sql + "}"); if (statement != null) { statement.close(); } statement = getConnection().createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); setStatementFetchSizeForStreaming(statement); resultSet = statement.executeQuery(sql); return resultSet; } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to create resultset.", e); } } /** * Commits any outstanding transaction. */ public void commit() { if (connection != null) { try { connection.commit(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to commit changes.", e); } } } /** * Releases all database resources. This method is guaranteed not to throw transactions and * should always be called in a finally block whenever this class is used. */ public void release() { identityValueLoader.release(); if (statement != null) { try { statement.close(); } catch (SQLException e) { // We cannot throw an exception within a release statement. LOG.log(Level.WARNING, "Unable to close existing statement.", e); } statement = null; } if (connection != null) { try { connection.close(); } catch (SQLException e) { // We cannot throw an exception within a release statement. LOG.log(Level.WARNING, "Unable to close database connection.", e); } connection = null; } } /** * Sets the auto-commit property on the underlying connection. * * @param autoCommit The new auto commit value. */ public void setAutoCommit(boolean autoCommit) { if (connection != null) { try { LOG.finest("Setting auto commit to " + autoCommit + "."); connection.setAutoCommit(autoCommit); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to commit changes.", e); } } this.autoCommit = autoCommit; } /** * Indicates if the specified column exists in the database. * * @param tableName The table to check for. * @param columnName The column to check for. * @return True if the column exists, false otherwise. */ public boolean doesColumnExist(String tableName, String columnName) { ResultSet resultSet = null; boolean result; try { LOG.finest("Checking if column {" + columnName + "} in table {" + tableName + "} exists."); resultSet = getConnection().getMetaData().getColumns(null, null, tableName, columnName); result = resultSet.next(); resultSet.close(); resultSet = null; return result; } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to check for the existence of column " + tableName + "." + columnName + ".", e); } finally { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to close column existence result set.", e); } } } } /** * Indicates if the specified table exists in the database. * * @param tableName The table to check for. * @return True if the table exists, false otherwise. */ public boolean doesTableExist(String tableName) { ResultSet resultSet = null; boolean result; try { LOG.finest("Checking if table {" + tableName + "} exists."); resultSet = getConnection().getMetaData().getTables(null, null, tableName, new String[] {"TABLE"}); result = resultSet.next(); resultSet.close(); resultSet = null; return result; } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to check for the existence of table " + tableName + ".", e); } finally { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to close table existence result set.", e); } } } } /** * Enforces cleanup of any remaining resources during garbage collection. This is a safeguard * and should not be required if release is called appropriately. * * @throws Throwable If a problem occurs during finalization. */ @Override protected void finalize() throws Throwable { release(); super.finalize(); } } DatabaseContext2.java000066400000000000000000000264161253404521400341510ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.common; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.dbcp.BasicDataSource; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabaseType; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.jdbc.datasource.DataSourceUtils; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionTemplate; /** * This class manages the lifecycle of JDBC objects to minimise the risk of connection leaks and to * support a consistent approach to database access. * * @author Brett Henderson */ public class DatabaseContext2 { private static final Logger LOG = Logger.getLogger(DatabaseContext.class.getName()); private BasicDataSource dataSource; private PlatformTransactionManager txnManager; private TransactionTemplate txnTemplate; private JdbcTemplate jdbcTemplate; private DatabaseType dbType; private IdentityValueLoader identityValueLoader; /** * Creates a new instance. * * @param loginCredentials Contains all information required to connect to the database. */ public DatabaseContext2(DatabaseLoginCredentials loginCredentials) { dataSource = DataSourceFactory.createDataSource(loginCredentials); txnManager = new DataSourceTransactionManager(dataSource); txnTemplate = new TransactionTemplate(txnManager); jdbcTemplate = new JdbcTemplate(dataSource); this.dbType = loginCredentials.getDbType(); setStatementFetchSizeForStreaming(); switch (loginCredentials.getDbType()) { case POSTGRESQL: identityValueLoader = new PostgresqlIdentityValueLoader2(this); break; case MYSQL: identityValueLoader = new MysqlIdentityValueLoader2(this); break; default: throw new OsmosisRuntimeException("Unknown database type " + loginCredentials.getDbType() + "."); } } /** * Gets the jdbc template which provides access to database functions. * * @return The jdbc template. */ public JdbcTemplate getJdbcTemplate() { return jdbcTemplate; } /** * Invokes the provided callback code within a transaction. * * @param txnCallback * The logic to be invoked within a transaction. * @param * The return type of the transaction callback. * * @return The result. */ public Object executeWithinTransaction(TransactionCallback txnCallback) { return txnTemplate.execute(txnCallback); } /** * Returns the database type currently in use. This should only be used when it is not possible * to write database agnostic statements. * * @return The database type. */ public DatabaseType getDatabaseType() { return dbType; } private void setStatementFetchSizeForStreaming() { switch (dbType) { case POSTGRESQL: jdbcTemplate.setFetchSize(10000); break; case MYSQL: jdbcTemplate.setFetchSize(Integer.MIN_VALUE); break; default: throw new OsmosisRuntimeException("Unknown database type " + dbType + "."); } } /** * Truncates the contents of the specified tables. * * @param tables * The tables to be truncated. */ public void truncateTables(List tables) { switch (dbType) { case POSTGRESQL: StringBuilder statementBuilder = new StringBuilder(); for (String table : tables) { if (statementBuilder.length() == 0) { statementBuilder.append("TRUNCATE "); } else { statementBuilder.append(", "); } statementBuilder.append(table); } jdbcTemplate.update(statementBuilder.toString()); break; case MYSQL: for (String table : tables) { jdbcTemplate.update("TRUNCATE " + table); } break; default: throw new OsmosisRuntimeException("Unknown database type " + dbType + "."); } } /** * Disables the indexes of the specified tables. * * @param tables * The tables to disable indexes on. */ public void disableIndexes(List tables) { switch (dbType) { case POSTGRESQL: // There is no way to automatically disable all indexes for a table. break; case MYSQL: for (String table : tables) { jdbcTemplate.update("ALTER TABLE " + table + " DISABLE KEYS"); } break; default: throw new OsmosisRuntimeException("Unknown database type " + dbType + "."); } } /** * Enables the indexes of the specified tables. * * @param tables * The tables to enable indexes on. */ public void enableIndexes(List tables) { switch (dbType) { case POSTGRESQL: // There is no way to automatically disable all indexes for a table. break; case MYSQL: for (String table : tables) { jdbcTemplate.update("ALTER TABLE " + table + " ENABLE KEYS"); } break; default: throw new OsmosisRuntimeException("Unknown database type " + dbType + "."); } } /** * Locks the specified tables for exclusive access. * * @param tables * The tables to lock. */ public void lockTables(List tables) { switch (dbType) { case POSTGRESQL: // Locking tables is not supported. break; case MYSQL: StringBuilder statementBuilder = new StringBuilder(); for (String table : tables) { if (statementBuilder.length() == 0) { statementBuilder.append("LOCK TABLES "); } else { statementBuilder.append(", "); } statementBuilder.append(table); statementBuilder.append(" WRITE"); } jdbcTemplate.update(statementBuilder.toString()); break; default: throw new OsmosisRuntimeException("Unknown database type " + dbType + "."); } } /** * Unlocks the specified tables. * * @param tables * The tables to unlock. */ public void unlockTables(List tables) { switch (dbType) { case POSTGRESQL: // Locking tables is not supported. break; case MYSQL: jdbcTemplate.update("UNLOCK TABLES"); break; default: throw new OsmosisRuntimeException("Unknown database type " + dbType + "."); } } /** * Gets the last inserted identity column value. This is a global value and may not work * correctly if the database uses triggers. * * @return The last inserted identity column value. */ public long getLastInsertId() { return identityValueLoader.getLastInsertId(); } /** * Gets the last retrieved sequence value. This is specific to the current connection only. * * @param sequenceName * The name of the sequence. * @return The last inserted identity column value. */ public long getLastSequenceId(String sequenceName) { return identityValueLoader.getLastSequenceId(sequenceName); } /** * Releases all database resources. This method is guaranteed not to throw transactions and * should always be called in a finally block whenever this class is used. */ public void release() { identityValueLoader.release(); try { dataSource.close(); } catch (SQLException e) { LOG.log(Level.WARNING, "Unable to cleanup the database connection pool.", e); } } /** * Indicates if the specified column exists in the database. * * @param tableName The table to check for. * @param columnName The column to check for. * @return True if the column exists, false otherwise. */ public boolean doesColumnExist(String tableName, String columnName) { ResultSet resultSet = null; boolean result; try { Connection connection; LOG.finest("Checking if column {" + columnName + "} in table {" + tableName + "} exists."); // This connection may not be freed if an exception occurs. It's a small chance and the // additional code to avoid it is cumbersome. connection = DataSourceUtils.getConnection(dataSource); resultSet = connection.getMetaData().getColumns(null, null, tableName, columnName); result = resultSet.next(); resultSet.close(); resultSet = null; DataSourceUtils.releaseConnection(connection, dataSource); return result; } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to check for the existence of column " + tableName + "." + columnName + ".", e); } finally { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to close column existence result set.", e); } } } } /** * Indicates if the specified table exists in the database. * * @param tableName The table to check for. * @return True if the table exists, false otherwise. */ public boolean doesTableExist(String tableName) { ResultSet resultSet = null; boolean result; try { Connection connection; LOG.finest("Checking if table {" + tableName + "} exists."); // This connection may not be freed if an exception occurs. It's a small chance and the // additional code to avoid it is cumbersome. connection = DataSourceUtils.getConnection(dataSource); resultSet = connection.getMetaData().getTables(null, null, tableName, new String[] {"TABLE"}); result = resultSet.next(); resultSet.close(); resultSet = null; DataSourceUtils.releaseConnection(connection, dataSource); return result; } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to check for the existence of table " + tableName + ".", e); } finally { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to close table existence result set.", e); } } } } /** * Enforces cleanup of any remaining resources during garbage collection. This is a safeguard * and should not be required if release is called appropriately. * * @throws Throwable If a problem occurs during finalization. */ @Override protected void finalize() throws Throwable { release(); super.finalize(); } } IdentityValueLoader.java000066400000000000000000000016631253404521400347300ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.common; import org.openstreetmap.osmosis.core.lifecycle.Releasable; /** * Retrieves last inserted identity columns. This examines global connection values and may not work * correctly if the database uses triggers. It will however work correctly in a multi-threaded * environment. * * @author Brett Henderson */ public interface IdentityValueLoader extends Releasable { /** * Returns the id of the most recently inserted row on the current * connection. * * @return The newly inserted id. */ long getLastInsertId(); /** * Returns the most recently returned value from the specified sequence on the current * connection. * * @param sequenceName * The name of the sequence to query. * @return The most recent sequence id. */ long getLastSequenceId(String sequenceName); } MysqlIdentityValueLoader.java000066400000000000000000000047771253404521400357670ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.common; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.database.ReleasableStatementContainer; /** * Mysql implementation of an identity value loader. * * @author Brett Henderson */ public class MysqlIdentityValueLoader implements IdentityValueLoader { private static final Logger LOG = Logger.getLogger(MysqlIdentityValueLoader.class.getName()); private static final String SQL_SELECT_LAST_INSERT_ID = "SELECT LAST_INSERT_ID() AS lastInsertId FROM DUAL"; private DatabaseContext dbCtx; private ReleasableStatementContainer statementContainer; private PreparedStatement selectInsertIdStatement; /** * Creates a new instance. * * @param dbCtx * The database context to use for all database access. */ public MysqlIdentityValueLoader(DatabaseContext dbCtx) { this.dbCtx = dbCtx; statementContainer = new ReleasableStatementContainer(); } /** * Returns the id of the most recently inserted row on the current * connection. * * @return The newly inserted id. */ public long getLastInsertId() { ResultSet lastInsertQuery; if (selectInsertIdStatement == null) { selectInsertIdStatement = statementContainer.add(dbCtx.prepareStatementForStreaming(SQL_SELECT_LAST_INSERT_ID)); } lastInsertQuery = null; try { long lastInsertId; lastInsertQuery = selectInsertIdStatement.executeQuery(); lastInsertQuery.next(); lastInsertId = lastInsertQuery.getLong("lastInsertId"); lastInsertQuery.close(); lastInsertQuery = null; return lastInsertId; } catch (SQLException e) { throw new OsmosisRuntimeException( "Unable to retrieve the id of the newly inserted record.", e ); } finally { if (lastInsertQuery != null) { try { lastInsertQuery.close(); } catch (SQLException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to close last insert query.", e); } } } } /** * {@inheritDoc} */ @Override public long getLastSequenceId(String sequenceName) { throw new UnsupportedOperationException(); } /** * {@inheritDoc} */ @Override public void release() { statementContainer.release(); } } MysqlIdentityValueLoader2.java000066400000000000000000000022041253404521400360300ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.common; /** * Mysql implementation of an identity value loader. * * @author Brett Henderson */ public class MysqlIdentityValueLoader2 implements IdentityValueLoader { private static final String SQL_SELECT_LAST_INSERT_ID = "SELECT LAST_INSERT_ID() AS lastInsertId FROM DUAL"; private DatabaseContext2 dbCtx; /** * Creates a new instance. * * @param dbCtx * The database context to use for all database access. */ public MysqlIdentityValueLoader2(DatabaseContext2 dbCtx) { this.dbCtx = dbCtx; } /** * Returns the id of the most recently inserted row on the current * connection. * * @return The newly inserted id. */ public long getLastInsertId() { return dbCtx.getJdbcTemplate().queryForObject(SQL_SELECT_LAST_INSERT_ID, Long.class); } /** * {@inheritDoc} */ @Override public long getLastSequenceId(String sequenceName) { throw new UnsupportedOperationException(); } /** * {@inheritDoc} */ @Override public void release() { // Do nothing. } } PostgresqlIdentityValueLoader.java000066400000000000000000000071171253404521400370140ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.common; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.database.ReleasableStatementContainer; /** * Postgresql implementation of an identity value loader. * * @author Brett Henderson */ public class PostgresqlIdentityValueLoader implements IdentityValueLoader { private static final Logger LOG = Logger.getLogger(PostgresqlIdentityValueLoader.class.getName()); private static final String SQL_SELECT_LAST_INSERT_ID = "SELECT lastval() AS lastInsertId"; private static final String SQL_SELECT_LAST_SEQUENCE_ID = "SELECT currval(?) AS lastSequenceId"; private DatabaseContext dbCtx; private ReleasableStatementContainer statementContainer; private PreparedStatement selectInsertIdStatement; private PreparedStatement selectSequenceIdStatement; /** * Creates a new instance. * * @param dbCtx * The database context to use for all database access. */ public PostgresqlIdentityValueLoader(DatabaseContext dbCtx) { this.dbCtx = dbCtx; statementContainer = new ReleasableStatementContainer(); } /** * Returns the id of the most recently inserted row on the current * connection. * * @return The newly inserted id. */ public long getLastInsertId() { ResultSet lastInsertQuery; if (selectInsertIdStatement == null) { selectInsertIdStatement = statementContainer.add(dbCtx.prepareStatementForStreaming(SQL_SELECT_LAST_INSERT_ID)); } lastInsertQuery = null; try { long lastInsertId; lastInsertQuery = selectInsertIdStatement.executeQuery(); lastInsertQuery.next(); lastInsertId = lastInsertQuery.getLong("lastInsertId"); lastInsertQuery.close(); lastInsertQuery = null; return lastInsertId; } catch (SQLException e) { throw new OsmosisRuntimeException( "Unable to retrieve the id of the newly inserted record.", e ); } finally { if (lastInsertQuery != null) { try { lastInsertQuery.close(); } catch (SQLException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to close last insert query.", e); } } } } /** * {@inheritDoc} */ @Override public long getLastSequenceId(String sequenceName) { ResultSet lastSequenceQuery; if (selectSequenceIdStatement == null) { selectSequenceIdStatement = statementContainer.add(dbCtx.prepareStatementForStreaming(SQL_SELECT_LAST_SEQUENCE_ID)); } lastSequenceQuery = null; try { long lastSequenceId; selectSequenceIdStatement.setString(1, sequenceName); lastSequenceQuery = selectSequenceIdStatement.executeQuery(); lastSequenceQuery.next(); lastSequenceId = lastSequenceQuery.getLong("lastSequenceId"); lastSequenceQuery.close(); lastSequenceQuery = null; return lastSequenceId; } catch (SQLException e) { throw new OsmosisRuntimeException( "Unable to retrieve the last sequence id.", e ); } finally { if (lastSequenceQuery != null) { try { lastSequenceQuery.close(); } catch (SQLException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to close last sequence query.", e); } } } } /** * {@inheritDoc} */ @Override public void release() { statementContainer.release(); } } PostgresqlIdentityValueLoader2.java000066400000000000000000000024411253404521400370710ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.common; /** * Postgresql implementation of an identity value loader. * * @author Brett Henderson */ public class PostgresqlIdentityValueLoader2 implements IdentityValueLoader { private static final String SQL_SELECT_LAST_INSERT_ID = "SELECT lastval() AS lastInsertId"; private static final String SQL_SELECT_LAST_SEQUENCE_ID = "SELECT currval(?) AS lastSequenceId"; private DatabaseContext2 dbCtx; /** * Creates a new instance. * * @param dbCtx * The database context to use for all database access. */ public PostgresqlIdentityValueLoader2(DatabaseContext2 dbCtx) { this.dbCtx = dbCtx; } /** * Returns the id of the most recently inserted row on the current * connection. * * @return The newly inserted id. */ public long getLastInsertId() { return dbCtx.getJdbcTemplate().queryForObject(SQL_SELECT_LAST_INSERT_ID, Long.class); } /** * {@inheritDoc} */ @Override public long getLastSequenceId(String sequenceName) { return dbCtx.getJdbcTemplate().queryForObject(SQL_SELECT_LAST_SEQUENCE_ID, Long.class, sequenceName); } /** * {@inheritDoc} */ @Override public void release() { // Do nothing. } } osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/000077500000000000000000000000001253404521400275035ustar00rootroot00000000000000ApidbChangeReader.java000066400000000000000000000102521253404521400335370ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6; import java.util.Collections; import java.util.Date; import org.openstreetmap.osmosis.apidb.common.DatabaseContext2; import org.openstreetmap.osmosis.apidb.v0_6.impl.AllEntityDao; import org.openstreetmap.osmosis.apidb.v0_6.impl.DeltaToDiffReader; import org.openstreetmap.osmosis.apidb.v0_6.impl.SchemaVersionValidator; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.RunnableChangeSource; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallbackWithoutResult; /** * A change source reading from database history tables. This aims to be suitable for running at * regular intervals with database overhead proportional to changeset size. * * @author Brett Henderson */ public class ApidbChangeReader implements RunnableChangeSource { private ChangeSink changeSink; private DatabaseLoginCredentials loginCredentials; private DatabasePreferences preferences; private Date intervalBegin; private Date intervalEnd; private boolean fullHistory; /** * Creates a new instance. * * @param loginCredentials * Contains all information required to connect to the database. * @param preferences * Contains preferences configuring database behaviour. * @param intervalBegin * Marks the beginning (inclusive) of the time interval to be checked. * @param intervalEnd * Marks the end (exclusive) of the time interval to be checked. * @param fullHistory * Specifies if full version history should be returned, or just a single change per * entity for the interval. */ public ApidbChangeReader(DatabaseLoginCredentials loginCredentials, DatabasePreferences preferences, Date intervalBegin, Date intervalEnd, boolean fullHistory) { this.loginCredentials = loginCredentials; this.preferences = preferences; this.intervalBegin = intervalBegin; this.intervalEnd = intervalEnd; this.fullHistory = fullHistory; } /** * {@inheritDoc} */ public void setChangeSink(ChangeSink changeSink) { this.changeSink = changeSink; } /** * Runs the task implementation. This is called by the run method within a transaction. * * @param dbCtx * Used to access the database. */ protected void runImpl(DatabaseContext2 dbCtx) { try { AllEntityDao entityDao; ReleasableIterator reader; changeSink.initialize(Collections.emptyMap()); new SchemaVersionValidator(loginCredentials, preferences) .validateVersion(ApidbVersionConstants.SCHEMA_MIGRATIONS); entityDao = new AllEntityDao(dbCtx.getJdbcTemplate()); reader = entityDao.getHistory(intervalBegin, intervalEnd); if (!fullHistory) { reader = new DeltaToDiffReader(reader); } try { while (reader.hasNext()) { changeSink.process(reader.next()); } } finally { reader.release(); } changeSink.complete(); } finally { changeSink.release(); } } /** * Reads all data from the database and send it to the sink. */ public void run() { final DatabaseContext2 dbCtx = new DatabaseContext2(loginCredentials); try { dbCtx.executeWithinTransaction(new TransactionCallbackWithoutResult() { private DatabaseContext2 dbCtxInner = dbCtx; @Override protected void doInTransactionWithoutResult(TransactionStatus arg0) { runImpl(dbCtxInner); } }); } finally { dbCtx.release(); } } } ApidbChangeReaderFactory.java000066400000000000000000000035541253404521400350760ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6; import java.util.Date; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.database.DatabaseTaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.v0_6.RunnableChangeSourceManager; /** * The task manager factory for a database change reader. * * @author Brett Henderson */ public class ApidbChangeReaderFactory extends DatabaseTaskManagerFactory { private static final String ARG_INTERVAL_BEGIN = "intervalBegin"; private static final String ARG_INTERVAL_END = "intervalEnd"; private static final String ARG_READ_FULL_HISTORY = "readFullHistory"; private static final boolean DEFAULT_READ_FULL_HISTORY = false; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { DatabaseLoginCredentials loginCredentials; DatabasePreferences preferences; Date intervalBegin; Date intervalEnd; boolean fullHistory; // Get the task arguments. loginCredentials = getDatabaseLoginCredentials(taskConfig); preferences = getDatabasePreferences(taskConfig); intervalBegin = getDateArgument(taskConfig, ARG_INTERVAL_BEGIN, new Date(0)); intervalEnd = getDateArgument(taskConfig, ARG_INTERVAL_END, new Date()); fullHistory = getBooleanArgument(taskConfig, ARG_READ_FULL_HISTORY, DEFAULT_READ_FULL_HISTORY); return new RunnableChangeSourceManager( taskConfig.getId(), new ApidbChangeReader(loginCredentials, preferences, intervalBegin, intervalEnd, fullHistory), taskConfig.getPipeArgs() ); } } ApidbChangeWriter.java000066400000000000000000000063131253404521400336140ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.apidb.v0_6.impl.ActionChangeWriter; import org.openstreetmap.osmosis.apidb.v0_6.impl.ChangeWriter; import org.openstreetmap.osmosis.apidb.v0_6.impl.SchemaVersionValidator; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.task.common.ChangeAction; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; /** * A change sink writing to database tables. This aims to be suitable for running at regular * intervals with database overhead proportional to changeset size. * * @author Brett Henderson */ public class ApidbChangeWriter implements ChangeSink { private final ChangeWriter changeWriter; private final Map actionWriterMap; private final SchemaVersionValidator schemaVersionValidator; /** * Creates a new instance. * * @param loginCredentials Contains all information required to connect to the database. * @param preferences Contains preferences configuring database behaviour. * @param populateCurrentTables If true, the current tables will be populated as well as history * tables. */ public ApidbChangeWriter(DatabaseLoginCredentials loginCredentials, DatabasePreferences preferences, boolean populateCurrentTables) { changeWriter = new ChangeWriter(loginCredentials, populateCurrentTables); actionWriterMap = new HashMap(); actionWriterMap.put(ChangeAction.Create, new ActionChangeWriter(changeWriter, ChangeAction.Create)); actionWriterMap.put(ChangeAction.Modify, new ActionChangeWriter(changeWriter, ChangeAction.Modify)); actionWriterMap.put(ChangeAction.Delete, new ActionChangeWriter(changeWriter, ChangeAction.Delete)); schemaVersionValidator = new SchemaVersionValidator(loginCredentials, preferences); } /** * {@inheritDoc} */ public void initialize(Map metaData) { // Do nothing. } /** * {@inheritDoc} */ public void process(ChangeContainer change) { ChangeAction action; // Verify that the schema version is supported. schemaVersionValidator.validateVersion(ApidbVersionConstants.SCHEMA_MIGRATIONS); action = change.getAction(); if (!actionWriterMap.containsKey(action)) { throw new OsmosisRuntimeException("The action " + action + " is unrecognized."); } // Process the entity using the action writer appropriate for the change // action. change.getEntityContainer().process(actionWriterMap.get(action)); } /** * {@inheritDoc} */ public void complete() { changeWriter.complete(); } /** * {@inheritDoc} */ public void release() { changeWriter.release(); } } ApidbChangeWriterFactory.java000066400000000000000000000030561253404521400351450ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.database.DatabaseTaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.v0_6.ChangeSinkManager; /** * The task manager factory for a database change writer. * * @author Brett Henderson */ public class ApidbChangeWriterFactory extends DatabaseTaskManagerFactory { private static final String ARG_POPULATE_CURRENT_TABLES = "populateCurrentTables"; private static final boolean DEFAULT_POPULATE_CURRENT_TABLES = true; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { DatabaseLoginCredentials loginCredentials; DatabasePreferences preferences; boolean populateCurrentTables; // Get the task arguments. loginCredentials = getDatabaseLoginCredentials(taskConfig); preferences = getDatabasePreferences(taskConfig); populateCurrentTables = getBooleanArgument( taskConfig, ARG_POPULATE_CURRENT_TABLES, DEFAULT_POPULATE_CURRENT_TABLES); return new ChangeSinkManager( taskConfig.getId(), new ApidbChangeWriter( loginCredentials, preferences, populateCurrentTables ), taskConfig.getPipeArgs() ); } } ApidbCurrentReader.java000066400000000000000000000067211253404521400340020ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6; import java.util.Collections; import org.openstreetmap.osmosis.core.OsmosisConstants; import org.openstreetmap.osmosis.apidb.common.DatabaseContext2; import org.openstreetmap.osmosis.apidb.v0_6.impl.AllEntityDao; import org.openstreetmap.osmosis.apidb.v0_6.impl.SchemaVersionValidator; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.task.v0_6.RunnableSource; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallbackWithoutResult; /** * An OSM data source reading from a databases current tables. The entire contents of the database * are read. * * @author Brett Henderson */ public class ApidbCurrentReader implements RunnableSource { private Sink sink; private DatabaseLoginCredentials loginCredentials; private DatabasePreferences preferences; /** * Creates a new instance. * * @param loginCredentials * Contains all information required to connect to the database. * @param preferences * Contains preferences configuring database behaviour. */ public ApidbCurrentReader(DatabaseLoginCredentials loginCredentials, DatabasePreferences preferences) { this.loginCredentials = loginCredentials; this.preferences = preferences; } /** * {@inheritDoc} */ public void setSink(Sink sink) { this.sink = sink; } /** * Runs the task implementation. This is called by the run method within a transaction. * * @param dbCtx * Used to access the database. */ protected void runImpl(DatabaseContext2 dbCtx) { try { AllEntityDao entityDao; ReleasableIterator reader; sink.initialize(Collections.emptyMap()); new SchemaVersionValidator(loginCredentials, preferences) .validateVersion(ApidbVersionConstants.SCHEMA_MIGRATIONS); entityDao = new AllEntityDao(dbCtx.getJdbcTemplate()); sink.process(new BoundContainer(new Bound("Osmosis " + OsmosisConstants.VERSION))); reader = entityDao.getCurrent(); try { while (reader.hasNext()) { sink.process(reader.next()); } } finally { reader.release(); } sink.complete(); } finally { sink.release(); } } /** * Reads all data from the database and send it to the sink. */ public void run() { final DatabaseContext2 dbCtx = new DatabaseContext2(loginCredentials); try { dbCtx.executeWithinTransaction(new TransactionCallbackWithoutResult() { private DatabaseContext2 dbCtxInner = dbCtx; @Override protected void doInTransactionWithoutResult(TransactionStatus arg0) { runImpl(dbCtxInner); } }); } finally { dbCtx.release(); } } } ApidbCurrentReaderFactory.java000066400000000000000000000023171253404521400353270ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.database.DatabaseTaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.v0_6.RunnableSourceManager; /** * The task manager factory for a database reader. * * @author Brett Henderson */ public class ApidbCurrentReaderFactory extends DatabaseTaskManagerFactory { /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { DatabaseLoginCredentials loginCredentials; DatabasePreferences preferences; // Get the task arguments. loginCredentials = getDatabaseLoginCredentials(taskConfig); preferences = getDatabasePreferences(taskConfig); return new RunnableSourceManager( taskConfig.getId(), new ApidbCurrentReader(loginCredentials, preferences), taskConfig.getPipeArgs() ); } } ApidbFileReplicator.java000066400000000000000000000067161253404521400341450ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6; import org.openstreetmap.osmosis.apidb.common.DatabaseContext2; import org.openstreetmap.osmosis.apidb.v0_6.impl.AllEntityDao; import org.openstreetmap.osmosis.apidb.v0_6.impl.ReplicationSource; import org.openstreetmap.osmosis.apidb.v0_6.impl.Replicator; import org.openstreetmap.osmosis.apidb.v0_6.impl.SchemaVersionValidator; import org.openstreetmap.osmosis.apidb.v0_6.impl.SystemTimeLoader; import org.openstreetmap.osmosis.apidb.v0_6.impl.TimeDao; import org.openstreetmap.osmosis.apidb.v0_6.impl.TransactionDao; import org.openstreetmap.osmosis.apidb.v0_6.impl.TransactionManager; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.RunnableChangeSource; /** * Performs replication from an API database into change files. */ public class ApidbFileReplicator implements RunnableChangeSource { private DatabaseLoginCredentials loginCredentials; private DatabasePreferences preferences; private int iterations; private int minInterval; private int maxInterval; private ChangeSink changeSink; /** * Creates a new instance. * * @param loginCredentials * Contains all information required to connect to the database. * @param preferences * Contains preferences configuring database behaviour. * @param iterations * The number of replication intervals to execute. 0 means * infinite. * @param minInterval * The minimum number of milliseconds between intervals. * @param maxInterval * The maximum number of milliseconds between intervals if no new * data is available. This isn't a hard limit because proces */ public ApidbFileReplicator(DatabaseLoginCredentials loginCredentials, DatabasePreferences preferences, int iterations, int minInterval, int maxInterval) { this.loginCredentials = loginCredentials; this.preferences = preferences; this.iterations = iterations; this.minInterval = minInterval; this.maxInterval = maxInterval; } /** * {@inheritDoc} */ @Override public void setChangeSink(ChangeSink changeSink) { this.changeSink = changeSink; } /** * Runs the task implementation. This is called by the run method within a transaction. * * @param dbCtx * Used to access the database. */ protected void runImpl(DatabaseContext2 dbCtx) { Replicator replicator; ReplicationSource source; TransactionManager txnSnapshotLoader; SystemTimeLoader systemTimeLoader; new SchemaVersionValidator(loginCredentials, preferences) .validateVersion(ApidbVersionConstants.SCHEMA_MIGRATIONS); source = new AllEntityDao(dbCtx.getJdbcTemplate()); txnSnapshotLoader = new TransactionDao(dbCtx); systemTimeLoader = new TimeDao(dbCtx.getJdbcTemplate()); replicator = new Replicator(source, changeSink, txnSnapshotLoader, systemTimeLoader, iterations, minInterval, maxInterval); replicator.replicate(); } /** * {@inheritDoc} */ @Override public void run() { final DatabaseContext2 dbCtx = new DatabaseContext2(loginCredentials); try { runImpl(dbCtx); } finally { dbCtx.release(); } } } ApidbFileReplicatorFactory.java000066400000000000000000000035741253404521400354740ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.database.DatabaseTaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.v0_6.RunnableChangeSourceManager; /** * The task factory for a file-based database replicator. */ public class ApidbFileReplicatorFactory extends DatabaseTaskManagerFactory { private static final String ARG_ITERATIONS = "iterations"; private static final String ARG_MIN_INTERVAL = "minInterval"; private static final String ARG_MAX_INTERVAL = "maxInterval"; private static final int DEFAULT_ITERATIONS = 1; private static final int DEFAULT_MIN_INTERVAL = 0; private static final int DEFAULT_MAX_INTERVAL = 0; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { DatabaseLoginCredentials loginCredentials; DatabasePreferences preferences; int iterations; int minInterval; int maxInterval; // Get the task arguments. loginCredentials = getDatabaseLoginCredentials(taskConfig); preferences = getDatabasePreferences(taskConfig); iterations = getIntegerArgument(taskConfig, ARG_ITERATIONS, DEFAULT_ITERATIONS); minInterval = getIntegerArgument(taskConfig, ARG_MIN_INTERVAL, DEFAULT_MIN_INTERVAL); maxInterval = getIntegerArgument(taskConfig, ARG_MAX_INTERVAL, DEFAULT_MAX_INTERVAL); return new RunnableChangeSourceManager( taskConfig.getId(), new ApidbFileReplicator(loginCredentials, preferences, iterations, minInterval, maxInterval), taskConfig.getPipeArgs() ); } } osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/ApidbReader.java000066400000000000000000000074571253404521400325250ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6; import java.util.Collections; import java.util.Date; import org.openstreetmap.osmosis.core.OsmosisConstants; import org.openstreetmap.osmosis.apidb.common.DatabaseContext2; import org.openstreetmap.osmosis.apidb.v0_6.impl.AllEntityDao; import org.openstreetmap.osmosis.apidb.v0_6.impl.EntitySnapshotReader; import org.openstreetmap.osmosis.apidb.v0_6.impl.SchemaVersionValidator; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.task.v0_6.RunnableSource; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallbackWithoutResult; /** * An OSM data source reading from a database. The entire contents of the database are read. * * @author Brett Henderson */ public class ApidbReader implements RunnableSource { private Sink sink; private DatabaseLoginCredentials loginCredentials; private DatabasePreferences preferences; private Date snapshotInstant; /** * Creates a new instance. * * @param loginCredentials Contains all information required to connect to the database. * @param preferences Contains preferences configuring database behaviour. * @param snapshotInstant The state of the node table at this point in time will be dumped. This * ensures a consistent snapshot. */ public ApidbReader(DatabaseLoginCredentials loginCredentials, DatabasePreferences preferences, Date snapshotInstant) { this.loginCredentials = loginCredentials; this.preferences = preferences; this.snapshotInstant = snapshotInstant; } /** * {@inheritDoc} */ public void setSink(Sink sink) { this.sink = sink; } /** * Runs the task implementation. This is called by the run method within a transaction. * * @param dbCtx * Used to access the database. */ protected void runImpl(DatabaseContext2 dbCtx) { try { AllEntityDao entityDao; ReleasableIterator reader; sink.initialize(Collections.emptyMap()); new SchemaVersionValidator(loginCredentials, preferences) .validateVersion(ApidbVersionConstants.SCHEMA_MIGRATIONS); entityDao = new AllEntityDao(dbCtx.getJdbcTemplate()); sink.process(new BoundContainer(new Bound("Osmosis " + OsmosisConstants.VERSION))); reader = new EntitySnapshotReader(entityDao.getHistory(), snapshotInstant); try { while (reader.hasNext()) { sink.process(reader.next()); } } finally { reader.release(); } sink.complete(); } finally { sink.release(); } } /** * Reads all data from the database and send it to the sink. */ public void run() { final DatabaseContext2 dbCtx = new DatabaseContext2(loginCredentials); try { dbCtx.executeWithinTransaction(new TransactionCallbackWithoutResult() { private DatabaseContext2 dbCtxInner = dbCtx; @Override protected void doInTransactionWithoutResult(TransactionStatus arg0) { runImpl(dbCtxInner); } }); } finally { dbCtx.release(); } } } ApidbReaderFactory.java000066400000000000000000000026361253404521400337700ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6; import java.util.Date; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.database.DatabaseTaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.v0_6.RunnableSourceManager; /** * The task manager factory for a database reader. * * @author Brett Henderson */ public class ApidbReaderFactory extends DatabaseTaskManagerFactory { private static final String ARG_SNAPSHOT_INSTANT = "snapshotInstant"; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { DatabaseLoginCredentials loginCredentials; DatabasePreferences preferences; Date snapshotInstant; // Get the task arguments. loginCredentials = getDatabaseLoginCredentials(taskConfig); preferences = getDatabasePreferences(taskConfig); snapshotInstant = getDateArgument(taskConfig, ARG_SNAPSHOT_INSTANT, new Date()); return new RunnableSourceManager( taskConfig.getId(), new ApidbReader(loginCredentials, preferences, snapshotInstant), taskConfig.getPipeArgs() ); } } osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/ApidbTruncator.java000066400000000000000000000040631253404521400332720ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6; import java.util.Arrays; import java.util.List; import org.openstreetmap.osmosis.apidb.common.DatabaseContext; import org.openstreetmap.osmosis.apidb.v0_6.impl.SchemaVersionValidator; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.task.common.RunnableTask; /** * A standalone OSM task with no inputs or outputs that truncates tables in a apidb database. This * is used for removing all existing data from tables. * * @author Brett Henderson */ public class ApidbTruncator implements RunnableTask { // These tables will be truncated by the sql query. private static final List TRUNCATE_TABLES = Arrays.asList(new String[] { "current_relation_members", "current_relation_tags", "current_relations", "current_way_nodes", "current_way_tags", "current_ways", "current_node_tags", "current_nodes", "relation_members", "relation_tags", "relations", "way_nodes", "way_tags", "ways", "node_tags", "nodes", "changeset_tags", "changesets", "users"}); private final DatabaseContext dbCtx; private final SchemaVersionValidator schemaVersionValidator; /** * Creates a new instance. * * @param loginCredentials * Contains all information required to connect to the database. * @param preferences * Contains preferences configuring database behaviour. */ public ApidbTruncator(DatabaseLoginCredentials loginCredentials, DatabasePreferences preferences) { dbCtx = new DatabaseContext(loginCredentials); schemaVersionValidator = new SchemaVersionValidator(loginCredentials, preferences); } /** * Truncates all data from the database. */ public void run() { try { schemaVersionValidator.validateVersion(ApidbVersionConstants.SCHEMA_MIGRATIONS); dbCtx.truncateTables(TRUNCATE_TABLES); dbCtx.commit(); } finally { dbCtx.release(); } } } ApidbTruncatorFactory.java000066400000000000000000000016271253404521400345460ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6; import org.openstreetmap.osmosis.core.database.DatabaseTaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.common.RunnableTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; /** * The task manager factory for a database table truncator. * * @author Brett Henderson */ public class ApidbTruncatorFactory extends DatabaseTaskManagerFactory { /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { return new RunnableTaskManager( taskConfig.getId(), new ApidbTruncator( getDatabaseLoginCredentials(taskConfig), getDatabasePreferences(taskConfig) ), taskConfig.getPipeArgs() ); } } ApidbVersionConstants.java000066400000000000000000000024401253404521400345510ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6; /** * Defines constants specific to the specific schema version. * * @author Brett Henderson */ public final class ApidbVersionConstants { /** * This class cannot be instantiated. */ private ApidbVersionConstants() { } /** * Defines the schema migrations expected to be in the database. */ public static final String[] SCHEMA_MIGRATIONS = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "20100513171259", "20100516124737", "20100910084426", "20101114011429", "20110322001319", "20110508145337", "20110521142405", "20110925112722", "20111116184519", "20111212183945", "20120123184321", "20120208122334", "20120208194454", "20120214210114", "20120219161649", "20120318201948", "20120328090602", "20120404205604", "20120808231205", "20121005195010", "20121012044047", "20121119165817", "20121202155309", "20121203124841", "20130328184137" }; } osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/ApidbWriter.java000066400000000000000000001424311253404521400325670ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import org.openstreetmap.osmosis.apidb.common.DatabaseContext; import org.openstreetmap.osmosis.apidb.v0_6.impl.ChangesetManager; import org.openstreetmap.osmosis.apidb.v0_6.impl.MemberTypeRenderer; import org.openstreetmap.osmosis.apidb.v0_6.impl.SchemaVersionValidator; import org.openstreetmap.osmosis.apidb.v0_6.impl.UserManager; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityProcessor; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.database.DbFeature; import org.openstreetmap.osmosis.core.database.DbFeatureHistory; import org.openstreetmap.osmosis.core.database.DbOrderedFeature; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.util.FixedPrecisionCoordinateConvertor; import org.openstreetmap.osmosis.core.util.TileCalculator; /** * An OSM data sink for storing all data to a database. This task is intended for writing to an * empty database. * * @author Brett Henderson */ public class ApidbWriter implements Sink, EntityProcessor { // These SQL strings are the prefix to statements that will be built based // on how many rows of data are to be inserted at a time. private static final String INSERT_SQL_NODE_COLUMNS = "INSERT INTO nodes(node_id, timestamp, version, visible, changeset_id, latitude, longitude, tile)"; private static final String INSERT_SQL_NODE_PARAMS = "?, ?, ?, ?, ?, ?, ?, ?"; private static final int INSERT_PRM_COUNT_NODE = 8; private static final String INSERT_SQL_NODE_TAG_COLUMNS = "INSERT INTO node_tags (node_id, k, v, version)"; private static final String INSERT_SQL_NODE_TAG_PARAMS = "?, ?, ?, ?"; private static final int INSERT_PRM_COUNT_NODE_TAG = 4; private static final String INSERT_SQL_WAY_COLUMNS = "INSERT INTO ways (way_id, timestamp, version, visible, changeset_id)"; private static final String INSERT_SQL_WAY_PARAMS = "?, ?, ?, ?, ?"; private static final int INSERT_PRM_COUNT_WAY = 5; private static final String INSERT_SQL_WAY_TAG_COLUMNS = "INSERT INTO way_tags (way_id, k, v, version)"; private static final String INSERT_SQL_WAY_TAG_PARAMS = "?, ?, ?, ?"; private static final int INSERT_PRM_COUNT_WAY_TAG = 4; private static final String INSERT_SQL_WAY_NODE_COLUMNS = "INSERT INTO way_nodes (way_id, node_id, sequence_id, version)"; private static final String INSERT_SQL_WAY_NODE_PARAMS = "?, ?, ?, ?"; private static final int INSERT_PRM_COUNT_WAY_NODE = 4; private static final String INSERT_SQL_RELATION_COLUMNS = "INSERT INTO relations (relation_id, timestamp, version, visible, changeset_id)"; private static final String INSERT_SQL_RELATION_PARAMS = "?, ?, ?, ?, ?"; private static final int INSERT_PRM_COUNT_RELATION = 5; private static final String INSERT_SQL_RELATION_TAG_COLUMNS = "INSERT INTO relation_tags (relation_id, k, v, version)"; private static final String INSERT_SQL_RELATION_TAG_PARAMS = "?, ?, ?, ?"; private static final int INSERT_PRM_COUNT_RELATION_TAG = 4; private static final String INSERT_SQL_RELATION_MEMBER_COLUMNS = "INSERT INTO relation_members (relation_id, member_type, member_id, sequence_id, member_role, version)"; private static final String INSERT_SQL_RELATION_MEMBER_PARAMS_MYSQL = "?, ?, ?, ?, ?, ?"; private static final String INSERT_SQL_RELATION_MEMBER_PARAMS_PGSQL = "?, ?::nwr_enum, ?, ?, ?, ?"; private static final int INSERT_PRM_COUNT_RELATION_MEMBER = 6; // These tables will have indexes disabled during loading data. private static final List DISABLE_KEY_TABLES = Arrays.asList(new String[] {"nodes", "node_tags", "ways", "way_tags", "way_nodes", "relations", "relation_tags", "relation_members"}); // These SQL statements will be invoked after loading history tables to // populate the current tables. private static final int LOAD_CURRENT_NODE_ROW_COUNT = 1000000; private static final int LOAD_CURRENT_WAY_ROW_COUNT = 100000; private static final int LOAD_CURRENT_RELATION_ROW_COUNT = 100000; private static final String LOAD_CURRENT_NODES = "INSERT INTO current_nodes SELECT node_id, latitude, longitude, changeset_id, visible, timestamp, tile, version" + " FROM nodes WHERE node_id >= ? AND node_id < ?"; private static final String LOAD_CURRENT_NODE_TAGS = "INSERT INTO current_node_tags SELECT node_id, k, v FROM node_tags WHERE node_id >= ? AND node_id < ?"; private static final String LOAD_CURRENT_WAYS = "INSERT INTO current_ways SELECT way_id, changeset_id, timestamp, visible, version FROM ways" + " WHERE way_id >= ? AND way_id < ?"; private static final String LOAD_CURRENT_WAY_TAGS = "INSERT INTO current_way_tags SELECT way_id, k, v FROM way_tags" + " WHERE way_id >= ? AND way_id < ?"; private static final String LOAD_CURRENT_WAY_NODES = "INSERT INTO current_way_nodes SELECT way_id, node_id, sequence_id FROM way_nodes" + " WHERE way_id >= ? AND way_id < ?"; private static final String LOAD_CURRENT_RELATIONS = "INSERT INTO current_relations SELECT relation_id, changeset_id, timestamp, visible, version" + " FROM relations WHERE relation_id >= ? AND relation_id < ?"; private static final String LOAD_CURRENT_RELATION_TAGS = "INSERT INTO current_relation_tags SELECT relation_id, k, v FROM relation_tags" + " WHERE relation_id >= ? AND relation_id < ?"; private static final String LOAD_CURRENT_RELATION_MEMBERS = "INSERT INTO current_relation_members (relation_id, member_id, member_role, member_type, sequence_id)" + " SELECT relation_id, member_id, member_role, member_type, sequence_id" + " FROM relation_members WHERE relation_id >= ? AND relation_id < ?"; // These tables will be locked for exclusive access while loading data. private static final List LOCK_TABLES = Arrays.asList(new String[] {"nodes", "node_tags", "ways", "way_tags", "way_nodes", "relations", "relation_tags", "relation_members", "current_nodes", "current_node_tags", "current_ways", "current_way_tags", "current_way_nodes", "current_relations", "current_relation_tags", "current_relation_members", "users", "changesets", "changeset_tags" }); // These constants define how many rows of each data type will be inserted // with single insert statements. private static final int INSERT_BULK_ROW_COUNT_NODE = 100; private static final int INSERT_BULK_ROW_COUNT_NODE_TAG = 100; private static final int INSERT_BULK_ROW_COUNT_WAY = 100; private static final int INSERT_BULK_ROW_COUNT_WAY_TAG = 100; private static final int INSERT_BULK_ROW_COUNT_WAY_NODE = 100; private static final int INSERT_BULK_ROW_COUNT_RELATION = 100; private static final int INSERT_BULK_ROW_COUNT_RELATION_TAG = 100; private static final int INSERT_BULK_ROW_COUNT_RELATION_MEMBER = 100; /** * Builds a multi-row SQL insert statement. * * @param columnSql * The basic query without value bind variables. * @param parametersSql * The SQL parameters portion of the query. * @param rowCount * The number of rows to insert in a single query. * @return The generated SQL statement. */ private static String buildSqlInsertStatement(String columnSql, String parametersSql, int rowCount) { StringBuilder buffer; buffer = new StringBuilder(); buffer.append(columnSql).append(" VALUES "); for (int i = 0; i < rowCount; i++) { if (i > 0) { buffer.append(", "); } buffer.append("("); buffer.append(parametersSql); buffer.append(")"); } return buffer.toString(); } private String insertSqlSingleNode; private String insertSqlBulkNode; private String insertSqlSingleNodeTag; private String insertSqlBulkNodeTag; private String insertSqlSingleWay; private String insertSqlBulkWay; private String insertSqlSingleWayTag; private String insertSqlBulkWayTag; private String insertSqlSingleWayNode; private String insertSqlBulkWayNode; private String insertSqlSingleRelation; private String insertSqlBulkRelation; private String insertSqlSingleRelationTag; private String insertSqlBulkRelationTag; private String insertSqlSingleRelationMember; private String insertSqlBulkRelationMember; private final DatabaseContext dbCtx; private final UserManager userManager; private final ChangesetManager changesetManager; private final SchemaVersionValidator schemaVersionValidator; private final boolean lockTables; private final boolean populateCurrentTables; private final List nodeBuffer; private final List>> nodeTagBuffer; private final List wayBuffer; private final List>> wayTagBuffer; private final List>> wayNodeBuffer; private final List relationBuffer; private final List>> relationTagBuffer; private final List>> relationMemberBuffer; private long maxNodeId; private long minNodeId; private long maxWayId; private long minWayId; private long maxRelationId; private long minRelationId; private final TileCalculator tileCalculator; private final MemberTypeRenderer memberTypeRenderer; private boolean initialized; private PreparedStatement singleNodeStatement; private PreparedStatement bulkNodeStatement; private PreparedStatement singleNodeTagStatement; private PreparedStatement bulkNodeTagStatement; private PreparedStatement singleWayStatement; private PreparedStatement bulkWayStatement; private PreparedStatement singleWayTagStatement; private PreparedStatement bulkWayTagStatement; private PreparedStatement singleWayNodeStatement; private PreparedStatement bulkWayNodeStatement; private PreparedStatement singleRelationStatement; private PreparedStatement bulkRelationStatement; private PreparedStatement singleRelationTagStatement; private PreparedStatement bulkRelationTagStatement; private PreparedStatement singleRelationMemberStatement; private PreparedStatement bulkRelationMemberStatement; private PreparedStatement loadCurrentNodesStatement; private PreparedStatement loadCurrentNodeTagsStatement; private PreparedStatement loadCurrentWaysStatement; private PreparedStatement loadCurrentWayTagsStatement; private PreparedStatement loadCurrentWayNodesStatement; private PreparedStatement loadCurrentRelationsStatement; private PreparedStatement loadCurrentRelationTagsStatement; private PreparedStatement loadCurrentRelationMembersStatement; /** * Creates a new instance. * * @param loginCredentials Contains all information required to connect to the database. * @param preferences Contains preferences configuring database behaviour. * @param lockTables If true, all tables will be locked during loading. * @param populateCurrentTables If true, the current tables will be populated as well as history * tables. */ public ApidbWriter(DatabaseLoginCredentials loginCredentials, DatabasePreferences preferences, boolean lockTables, boolean populateCurrentTables) { dbCtx = new DatabaseContext(loginCredentials); userManager = new UserManager(dbCtx); changesetManager = new ChangesetManager(dbCtx); schemaVersionValidator = new SchemaVersionValidator(loginCredentials, preferences); this.lockTables = lockTables; this.populateCurrentTables = populateCurrentTables; nodeBuffer = new ArrayList(); nodeTagBuffer = new ArrayList>>(); wayBuffer = new ArrayList(); wayTagBuffer = new ArrayList>>(); wayNodeBuffer = new ArrayList>>(); relationBuffer = new ArrayList(); relationTagBuffer = new ArrayList>>(); relationMemberBuffer = new ArrayList>>(); maxNodeId = Long.MIN_VALUE; minNodeId = Long.MAX_VALUE; maxWayId = Long.MIN_VALUE; minWayId = Long.MAX_VALUE; maxRelationId = Long.MIN_VALUE; minRelationId = Long.MAX_VALUE; tileCalculator = new TileCalculator(); memberTypeRenderer = new MemberTypeRenderer(); initialized = false; } private void buildSqlStatements() { insertSqlSingleNode = buildSqlInsertStatement(INSERT_SQL_NODE_COLUMNS, INSERT_SQL_NODE_PARAMS, 1); insertSqlBulkNode = buildSqlInsertStatement(INSERT_SQL_NODE_COLUMNS, INSERT_SQL_NODE_PARAMS, INSERT_BULK_ROW_COUNT_NODE); insertSqlSingleNodeTag = buildSqlInsertStatement( INSERT_SQL_NODE_TAG_COLUMNS, INSERT_SQL_NODE_TAG_PARAMS, 1); insertSqlBulkNodeTag = buildSqlInsertStatement(INSERT_SQL_NODE_TAG_COLUMNS, INSERT_SQL_NODE_TAG_PARAMS, INSERT_BULK_ROW_COUNT_NODE_TAG); insertSqlSingleWay = buildSqlInsertStatement(INSERT_SQL_WAY_COLUMNS, INSERT_SQL_WAY_PARAMS, 1); insertSqlBulkWay = buildSqlInsertStatement(INSERT_SQL_WAY_COLUMNS, INSERT_SQL_WAY_PARAMS, INSERT_BULK_ROW_COUNT_WAY); insertSqlSingleWayTag = buildSqlInsertStatement(INSERT_SQL_WAY_TAG_COLUMNS, INSERT_SQL_WAY_TAG_PARAMS, 1); insertSqlBulkWayTag = buildSqlInsertStatement(INSERT_SQL_WAY_TAG_COLUMNS, INSERT_SQL_WAY_TAG_PARAMS, INSERT_BULK_ROW_COUNT_WAY_TAG); insertSqlSingleWayNode = buildSqlInsertStatement( INSERT_SQL_WAY_NODE_COLUMNS, INSERT_SQL_WAY_NODE_PARAMS, 1); insertSqlBulkWayNode = buildSqlInsertStatement(INSERT_SQL_WAY_NODE_COLUMNS, INSERT_SQL_WAY_NODE_PARAMS, INSERT_BULK_ROW_COUNT_WAY_NODE); insertSqlSingleRelation = buildSqlInsertStatement(INSERT_SQL_RELATION_COLUMNS, INSERT_SQL_RELATION_PARAMS, 1); insertSqlBulkRelation = buildSqlInsertStatement(INSERT_SQL_RELATION_COLUMNS, INSERT_SQL_RELATION_PARAMS, INSERT_BULK_ROW_COUNT_RELATION); insertSqlSingleRelationTag = buildSqlInsertStatement(INSERT_SQL_RELATION_TAG_COLUMNS, INSERT_SQL_RELATION_TAG_PARAMS, 1); insertSqlBulkRelationTag = buildSqlInsertStatement(INSERT_SQL_RELATION_TAG_COLUMNS, INSERT_SQL_RELATION_TAG_PARAMS, INSERT_BULK_ROW_COUNT_RELATION_TAG); } /** * Initialises prepared statements and obtains database locks. Can be called multiple times. */ private void initialize() { if (!initialized) { schemaVersionValidator.validateVersion(ApidbVersionConstants.SCHEMA_MIGRATIONS); buildSqlStatements(); switch (dbCtx.getDatabaseType()) { case POSTGRESQL: insertSqlSingleRelationMember = buildSqlInsertStatement(INSERT_SQL_RELATION_MEMBER_COLUMNS, INSERT_SQL_RELATION_MEMBER_PARAMS_PGSQL, 1); insertSqlBulkRelationMember = buildSqlInsertStatement(INSERT_SQL_RELATION_MEMBER_COLUMNS, INSERT_SQL_RELATION_MEMBER_PARAMS_PGSQL, INSERT_BULK_ROW_COUNT_RELATION_MEMBER); break; case MYSQL: insertSqlSingleRelationMember = buildSqlInsertStatement(INSERT_SQL_RELATION_MEMBER_COLUMNS, INSERT_SQL_RELATION_MEMBER_PARAMS_MYSQL, 1); insertSqlBulkRelationMember = buildSqlInsertStatement(INSERT_SQL_RELATION_MEMBER_COLUMNS, INSERT_SQL_RELATION_MEMBER_PARAMS_MYSQL, INSERT_BULK_ROW_COUNT_RELATION_MEMBER); break; default: throw new OsmosisRuntimeException("Unknown database type " + dbCtx.getDatabaseType() + "."); } bulkNodeStatement = dbCtx.prepareStatement(insertSqlBulkNode); singleNodeStatement = dbCtx.prepareStatement(insertSqlSingleNode); bulkNodeTagStatement = dbCtx.prepareStatement(insertSqlBulkNodeTag); singleNodeTagStatement = dbCtx.prepareStatement(insertSqlSingleNodeTag); bulkWayStatement = dbCtx.prepareStatement(insertSqlBulkWay); singleWayStatement = dbCtx.prepareStatement(insertSqlSingleWay); bulkWayTagStatement = dbCtx.prepareStatement(insertSqlBulkWayTag); singleWayTagStatement = dbCtx.prepareStatement(insertSqlSingleWayTag); bulkWayNodeStatement = dbCtx.prepareStatement(insertSqlBulkWayNode); singleWayNodeStatement = dbCtx.prepareStatement(insertSqlSingleWayNode); bulkRelationStatement = dbCtx.prepareStatement(insertSqlBulkRelation); singleRelationStatement = dbCtx.prepareStatement(insertSqlSingleRelation); bulkRelationTagStatement = dbCtx.prepareStatement(insertSqlBulkRelationTag); singleRelationTagStatement = dbCtx.prepareStatement(insertSqlSingleRelationTag); bulkRelationMemberStatement = dbCtx.prepareStatement(insertSqlBulkRelationMember); singleRelationMemberStatement = dbCtx.prepareStatement(insertSqlSingleRelationMember); loadCurrentNodesStatement = dbCtx.prepareStatement(LOAD_CURRENT_NODES); loadCurrentNodeTagsStatement = dbCtx.prepareStatement(LOAD_CURRENT_NODE_TAGS); loadCurrentWaysStatement = dbCtx.prepareStatement(LOAD_CURRENT_WAYS); loadCurrentWayTagsStatement = dbCtx.prepareStatement(LOAD_CURRENT_WAY_TAGS); loadCurrentWayNodesStatement = dbCtx.prepareStatement(LOAD_CURRENT_WAY_NODES); loadCurrentRelationsStatement = dbCtx.prepareStatement(LOAD_CURRENT_RELATIONS); loadCurrentRelationTagsStatement = dbCtx.prepareStatement(LOAD_CURRENT_RELATION_TAGS); loadCurrentRelationMembersStatement = dbCtx.prepareStatement(LOAD_CURRENT_RELATION_MEMBERS); // Disable indexes to improve load performance. dbCtx.disableIndexes(DISABLE_KEY_TABLES); // Lock tables if required to improve load performance. if (lockTables) { dbCtx.lockTables(LOCK_TABLES); } initialized = true; } } /** * Sets node values as bind variable parameters to a node insert query. * * @param statement The prepared statement to add the values to. * @param initialIndex The offset index of the first variable to set. * @param node The node containing the data to be inserted. */ private void populateNodeParameters(PreparedStatement statement, int initialIndex, Node node) { int prmIndex; prmIndex = initialIndex; // We can't write an entity with a null timestamp. if (node.getTimestamp() == null) { throw new OsmosisRuntimeException("Node " + node.getId() + " does not have a timestamp set."); } try { statement.setLong(prmIndex++, node.getId()); statement.setTimestamp(prmIndex++, new Timestamp(node.getTimestamp().getTime())); statement.setInt(prmIndex++, node.getVersion()); statement.setBoolean(prmIndex++, true); statement.setLong(prmIndex++, node.getChangesetId()); statement.setInt(prmIndex++, FixedPrecisionCoordinateConvertor.convertToFixed(node.getLatitude())); statement.setInt(prmIndex++, FixedPrecisionCoordinateConvertor.convertToFixed(node.getLongitude())); statement.setLong(prmIndex++, tileCalculator.calculateTile(node.getLatitude(), node.getLongitude())); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to set a prepared statement parameter for a node.", e); } } /** * Sets way values as bind variable parameters to a way insert query. * * @param statement The prepared statement to add the values to. * @param initialIndex The offset index of the first variable to set. * @param way The way containing the data to be inserted. */ private void populateWayParameters(PreparedStatement statement, int initialIndex, Way way) { int prmIndex; prmIndex = initialIndex; // We can't write an entity with a null timestamp. if (way.getTimestamp() == null) { throw new OsmosisRuntimeException("Way " + way.getId() + " does not have a timestamp set."); } try { statement.setLong(prmIndex++, way.getId()); statement.setTimestamp(prmIndex++, new Timestamp(way.getTimestamp().getTime())); statement.setInt(prmIndex++, way.getVersion()); statement.setBoolean(prmIndex++, true); statement.setLong(prmIndex++, way.getChangesetId()); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to set a prepared statement parameter for a way.", e); } } /** * Sets tag values as bind variable parameters to a tag insert query. * * @param statement The prepared statement to add the values to. * @param initialIndex The offset index of the first variable to set. * @param dbEntityTag The entity tag containing the data to be inserted. */ private void populateEntityTagParameters(PreparedStatement statement, int initialIndex, DbFeatureHistory> dbEntityTag) { int prmIndex; Tag tag; prmIndex = initialIndex; tag = dbEntityTag.getFeature().getFeature(); try { statement.setLong(prmIndex++, dbEntityTag.getFeature().getEntityId()); statement.setString(prmIndex++, tag.getKey()); statement.setString(prmIndex++, tag.getValue()); statement.setInt(prmIndex++, dbEntityTag.getVersion()); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to set a prepared statement parameter for an entity tag.", e); } } /** * Sets node reference values as bind variable parameters to a way node insert query. * * @param statement The prepared statement to add the values to. * @param initialIndex The offset index of the first variable to set. * @param dbWayNode The way node containing the data to be inserted. */ private void populateWayNodeParameters(PreparedStatement statement, int initialIndex, DbFeatureHistory> dbWayNode) { int prmIndex; prmIndex = initialIndex; try { statement.setLong(prmIndex++, dbWayNode.getFeature().getEntityId()); statement.setLong(prmIndex++, dbWayNode.getFeature().getFeature().getNodeId()); statement.setInt(prmIndex++, dbWayNode.getFeature().getSequenceId()); statement.setInt(prmIndex++, dbWayNode.getVersion()); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to set a prepared statement parameter for a way node.", e); } } /** * Sets relation values as bind variable parameters to a relation insert query. * * @param statement The prepared statement to add the values to. * @param initialIndex The offset index of the first variable to set. * @param relation The way containing the data to be inserted. */ private void populateRelationParameters(PreparedStatement statement, int initialIndex, Relation relation) { int prmIndex; prmIndex = initialIndex; // We can't write an entity with a null timestamp. if (relation.getTimestamp() == null) { throw new OsmosisRuntimeException("Relation " + relation.getId() + " does not have a timestamp set."); } try { statement.setLong(prmIndex++, relation.getId()); statement.setTimestamp(prmIndex++, new Timestamp(relation.getTimestamp().getTime())); statement.setInt(prmIndex++, relation.getVersion()); statement.setBoolean(prmIndex++, true); statement.setLong(prmIndex++, relation.getChangesetId()); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to set a prepared statement parameter for a relation.", e); } } /** * Sets member reference values as bind variable parameters to a relation member insert query. * * @param statement The prepared statement to add the values to. * @param initialIndex The offset index of the first variable to set. * @param dbRelationMember The relation member containing the data to be inserted. */ private void populateRelationMemberParameters(PreparedStatement statement, int initialIndex, DbFeatureHistory> dbRelationMember) { int prmIndex; RelationMember relationMember; prmIndex = initialIndex; relationMember = dbRelationMember.getFeature().getFeature(); try { statement.setLong(prmIndex++, dbRelationMember.getFeature().getEntityId()); statement.setString(prmIndex++, memberTypeRenderer.render(relationMember.getMemberType())); statement.setLong(prmIndex++, relationMember.getMemberId()); statement.setInt(prmIndex++, dbRelationMember.getFeature().getSequenceId()); statement.setString(prmIndex++, relationMember.getMemberRole()); statement.setInt(prmIndex++, dbRelationMember.getVersion()); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to set a prepared statement parameter for a relation member.", e); } } /** * Flushes nodes to the database. If complete is false, this will only write nodes until the * remaining node count is less than the multi-row insert statement row count. If complete is * true, all remaining rows will be written using single row insert statements. * * @param complete If true, all data will be written to the database. If false, some data may be * left until more data is available. */ private void flushNodes(boolean complete) { while (nodeBuffer.size() >= INSERT_BULK_ROW_COUNT_NODE) { int prmIndex; List processedNodes; processedNodes = new ArrayList(INSERT_BULK_ROW_COUNT_NODE); prmIndex = 1; for (int i = 0; i < INSERT_BULK_ROW_COUNT_NODE; i++) { Node node; node = nodeBuffer.remove(0); processedNodes.add(node); populateNodeParameters(bulkNodeStatement, prmIndex, node); prmIndex += INSERT_PRM_COUNT_NODE; } try { bulkNodeStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to bulk insert nodes into the database.", e); } for (Node node : processedNodes) { addNodeTags(node); } } if (complete) { while (nodeBuffer.size() > 0) { Node node; node = nodeBuffer.remove(0); populateNodeParameters(singleNodeStatement, 1, node); try { singleNodeStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert a node into the database.", e); } addNodeTags(node); } } } /** * Flushes node tags to the database. If complete is false, this will only write node tags until * the remaining node tag count is less than the multi-row insert statement row count. If * complete is true, all remaining rows will be written using single row insert statements. * * @param complete If true, all data will be written to the database. If false, some data may be * left until more data is available. */ private void flushNodeTags(boolean complete) { while (nodeTagBuffer.size() >= INSERT_BULK_ROW_COUNT_NODE_TAG) { int prmIndex; prmIndex = 1; for (int i = 0; i < INSERT_BULK_ROW_COUNT_NODE_TAG; i++) { populateEntityTagParameters(bulkNodeTagStatement, prmIndex, nodeTagBuffer.remove(0)); prmIndex += INSERT_PRM_COUNT_NODE_TAG; } try { bulkNodeTagStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to bulk insert node tags into the database.", e); } } if (complete) { while (nodeTagBuffer.size() > 0) { populateEntityTagParameters(singleNodeTagStatement, 1, nodeTagBuffer.remove(0)); try { singleNodeTagStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert a node tag into the database.", e); } } } } /** * Flushes ways to the database. If complete is false, this will only write ways until the * remaining way count is less than the multi-row insert statement row count. If complete is * true, all remaining rows will be written using single row insert statements. * * @param complete If true, all data will be written to the database. If false, some data may be * left until more data is available. */ private void flushWays(boolean complete) { while (wayBuffer.size() >= INSERT_BULK_ROW_COUNT_WAY) { List processedWays; int prmIndex; processedWays = new ArrayList(INSERT_BULK_ROW_COUNT_WAY); prmIndex = 1; for (int i = 0; i < INSERT_BULK_ROW_COUNT_WAY; i++) { Way way; way = wayBuffer.remove(0); processedWays.add(way); populateWayParameters(bulkWayStatement, prmIndex, way); prmIndex += INSERT_PRM_COUNT_WAY; } try { bulkWayStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to bulk insert ways into the database.", e); } for (Way way : processedWays) { addWayTags(way); addWayNodes(way); } } if (complete) { while (wayBuffer.size() > 0) { Way way; way = wayBuffer.remove(0); populateWayParameters(singleWayStatement, 1, way); try { singleWayStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert a way into the database.", e); } addWayTags(way); addWayNodes(way); } } } /** * Flushes way tags to the database. If complete is false, this will only write way tags until * the remaining way tag count is less than the multi-row insert statement row count. If * complete is true, all remaining rows will be written using single row insert statements. * * @param complete If true, all data will be written to the database. If false, some data may be * left until more data is available. */ private void flushWayTags(boolean complete) { while (wayTagBuffer.size() >= INSERT_BULK_ROW_COUNT_WAY_TAG) { int prmIndex; prmIndex = 1; for (int i = 0; i < INSERT_BULK_ROW_COUNT_WAY_TAG; i++) { populateEntityTagParameters(bulkWayTagStatement, prmIndex, wayTagBuffer.remove(0)); prmIndex += INSERT_PRM_COUNT_WAY_TAG; } try { bulkWayTagStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to bulk insert way tags into the database.", e); } } if (complete) { while (wayTagBuffer.size() > 0) { populateEntityTagParameters(singleWayTagStatement, 1, wayTagBuffer.remove(0)); try { singleWayTagStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert a way tag into the database.", e); } } } } /** * Flushes way nodes to the database. If complete is false, this will only write way nodes until * the remaining way node count is less than the multi-row insert statement row count. If * complete is true, all remaining rows will be written using single row insert statements. * * @param complete If true, all data will be written to the database. If false, some data may be * left until more data is available. */ private void flushWayNodes(boolean complete) { while (wayNodeBuffer.size() >= INSERT_BULK_ROW_COUNT_WAY_NODE) { int prmIndex; prmIndex = 1; for (int i = 0; i < INSERT_BULK_ROW_COUNT_WAY_NODE; i++) { populateWayNodeParameters(bulkWayNodeStatement, prmIndex, wayNodeBuffer.remove(0)); prmIndex += INSERT_PRM_COUNT_WAY_NODE; } try { bulkWayNodeStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to bulk insert way nodes into the database.", e); } } if (complete) { while (wayNodeBuffer.size() > 0) { populateWayNodeParameters(singleWayNodeStatement, 1, wayNodeBuffer.remove(0)); try { singleWayNodeStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert a way node into the database.", e); } } } } /** * Flushes relations to the database. If complete is false, this will only write relations until * the remaining way count is less than the multi-row insert statement row count. If complete is * true, all remaining rows will be written using single row insert statements. * * @param complete If true, all data will be written to the database. If false, some data may be * left until more data is available. */ private void flushRelations(boolean complete) { while (relationBuffer.size() >= INSERT_BULK_ROW_COUNT_RELATION) { List processedRelations; int prmIndex; processedRelations = new ArrayList(INSERT_BULK_ROW_COUNT_RELATION); prmIndex = 1; for (int i = 0; i < INSERT_BULK_ROW_COUNT_RELATION; i++) { Relation relation; relation = relationBuffer.remove(0); processedRelations.add(relation); populateRelationParameters(bulkRelationStatement, prmIndex, relation); prmIndex += INSERT_PRM_COUNT_RELATION; } try { bulkRelationStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to bulk insert relations into the database.", e); } for (Relation relation : processedRelations) { addRelationTags(relation); addRelationMembers(relation); } } if (complete) { while (relationBuffer.size() > 0) { Relation relation; relation = relationBuffer.remove(0); populateRelationParameters(singleRelationStatement, 1, relation); try { singleRelationStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert a relation into the database.", e); } addRelationTags(relation); addRelationMembers(relation); } } } /** * Flushes relation tags to the database. If complete is false, this will only write relation * tags until the remaining relation tag count is less than the multi-row insert statement row * count. If complete is true, all remaining rows will be written using single row insert * statements. * * @param complete If true, all data will be written to the database. If false, some data may be * left until more data is available. */ private void flushRelationTags(boolean complete) { while (relationTagBuffer.size() >= INSERT_BULK_ROW_COUNT_RELATION_TAG) { int prmIndex; prmIndex = 1; for (int i = 0; i < INSERT_BULK_ROW_COUNT_RELATION_TAG; i++) { populateEntityTagParameters(bulkRelationTagStatement, prmIndex, relationTagBuffer.remove(0)); prmIndex += INSERT_PRM_COUNT_RELATION_TAG; } try { bulkRelationTagStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to bulk insert relation tags into the database.", e); } } if (complete) { while (relationTagBuffer.size() > 0) { populateEntityTagParameters(singleRelationTagStatement, 1, relationTagBuffer.remove(0)); try { singleRelationTagStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert a relation tag into the database.", e); } } } } /** * Flushes relation members to the database. If complete is false, this will only write relation * members until the remaining relation member count is less than the multi-row insert statement * row count. If complete is true, all remaining rows will be written using single row insert * statements. * * @param complete If true, all data will be written to the database. If false, some data may be * left until more data is available. */ private void flushRelationMembers(boolean complete) { while (relationMemberBuffer.size() >= INSERT_BULK_ROW_COUNT_RELATION_MEMBER) { int prmIndex; prmIndex = 1; for (int i = 0; i < INSERT_BULK_ROW_COUNT_RELATION_MEMBER; i++) { populateRelationMemberParameters(bulkRelationMemberStatement, prmIndex, relationMemberBuffer.remove(0)); prmIndex += INSERT_PRM_COUNT_RELATION_MEMBER; } try { bulkRelationMemberStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to bulk insert relation members into the database.", e); } } if (complete) { while (relationMemberBuffer.size() > 0) { populateRelationMemberParameters(singleRelationMemberStatement, 1, relationMemberBuffer.remove(0)); try { singleRelationMemberStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert a relation member into the database.", e); } } } } private void populateCurrentNodes() { // Copy data into the current node tables. for (long i = minNodeId; i < maxNodeId; i += LOAD_CURRENT_NODE_ROW_COUNT) { // Node try { loadCurrentNodesStatement.setLong(1, i); loadCurrentNodesStatement.setLong(2, i + LOAD_CURRENT_NODE_ROW_COUNT); loadCurrentNodesStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to load current nodes.", e); } // Node tags try { loadCurrentNodeTagsStatement.setLong(1, i); loadCurrentNodeTagsStatement.setLong(2, i + LOAD_CURRENT_NODE_ROW_COUNT); loadCurrentNodeTagsStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to load current node tags.", e); } dbCtx.commit(); } } private void populateCurrentWays() { for (long i = minWayId; i < maxWayId; i += LOAD_CURRENT_WAY_ROW_COUNT) { // Way try { loadCurrentWaysStatement.setLong(1, i); loadCurrentWaysStatement.setLong(2, i + LOAD_CURRENT_WAY_ROW_COUNT); loadCurrentWaysStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to load current ways.", e); } // Way tags try { loadCurrentWayTagsStatement.setLong(1, i); loadCurrentWayTagsStatement.setLong(2, i + LOAD_CURRENT_WAY_ROW_COUNT); loadCurrentWayTagsStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to load current way tags.", e); } // Way nodes try { loadCurrentWayNodesStatement.setLong(1, i); loadCurrentWayNodesStatement.setLong(2, i + LOAD_CURRENT_WAY_ROW_COUNT); loadCurrentWayNodesStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to load current way nodes.", e); } dbCtx.commit(); } } private void populateCurrentRelations() { for (long i = minRelationId; i < maxRelationId; i += LOAD_CURRENT_RELATION_ROW_COUNT) { // Way try { loadCurrentRelationsStatement.setLong(1, i); loadCurrentRelationsStatement.setLong(2, i + LOAD_CURRENT_RELATION_ROW_COUNT); loadCurrentRelationsStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to load current relations.", e); } // Relation tags try { loadCurrentRelationTagsStatement.setLong(1, i); loadCurrentRelationTagsStatement.setLong(2, i + LOAD_CURRENT_RELATION_ROW_COUNT); loadCurrentRelationTagsStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to load current relation tags.", e); } // Relation members try { loadCurrentRelationMembersStatement.setLong(1, i); loadCurrentRelationMembersStatement.setLong(2, i + LOAD_CURRENT_RELATION_ROW_COUNT); loadCurrentRelationMembersStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to load current relation members.", e); } dbCtx.commit(); } } private void populateCurrentTables() { if (populateCurrentTables) { populateCurrentNodes(); populateCurrentWays(); populateCurrentRelations(); } } /** * {@inheritDoc} */ public void initialize(Map metaData) { // Do nothing. } /** * Writes any buffered data to the database and commits. */ @Override public void complete() { initialize(); flushNodes(true); flushNodeTags(true); flushWays(true); flushWayTags(true); flushWayNodes(true); flushRelations(true); flushRelationTags(true); flushRelationMembers(true); // Re-enable indexes now that the load has completed. dbCtx.enableIndexes(DISABLE_KEY_TABLES); populateCurrentTables(); // Unlock tables (if they were locked) now that we have completed. if (lockTables) { dbCtx.unlockTables(LOCK_TABLES); } dbCtx.commit(); } /** * Releases all database resources. */ public void release() { userManager.release(); dbCtx.release(); } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { Entity entity; initialize(); entity = entityContainer.getEntity(); userManager.addOrUpdateUser(entityContainer.getEntity().getUser()); changesetManager.addChangesetIfRequired(entity.getChangesetId(), entity.getUser()); entityContainer.process(this); } /** * {@inheritDoc} */ public void process(BoundContainer boundContainer) { // Do nothing. } /** * {@inheritDoc} */ public void process(NodeContainer nodeContainer) { Node node; long nodeId; node = nodeContainer.getEntity(); nodeId = node.getId(); if (nodeId >= maxNodeId) { maxNodeId = nodeId + 1; } if (nodeId < minNodeId) { minNodeId = nodeId; } nodeBuffer.add(node); flushNodes(false); } /** * Process the node tags. * * @param node The node to be processed. */ private void addNodeTags(Node node) { for (Tag tag : node.getTags()) { nodeTagBuffer.add(new DbFeatureHistory>(new DbFeature(node.getId(), tag), node .getVersion())); } flushNodeTags(false); } /** * {@inheritDoc} */ public void process(WayContainer wayContainer) { Way way; long wayId; flushNodes(true); way = wayContainer.getEntity(); wayId = way.getId(); if (wayId >= maxWayId) { maxWayId = wayId + 1; } if (wayId < minWayId) { minWayId = wayId; } wayBuffer.add(way); flushWays(false); } /** * Process the way tags. * * @param way The way to be processed. */ private void addWayTags(Way way) { for (Tag tag : way.getTags()) { wayTagBuffer.add(new DbFeatureHistory>(new DbFeature(way.getId(), tag), way .getVersion())); } flushWayTags(false); } /** * Process the way nodes. * * @param way The way to be processed. */ private void addWayNodes(Way way) { List nodeReferenceList; nodeReferenceList = way.getWayNodes(); for (int i = 0; i < nodeReferenceList.size(); i++) { wayNodeBuffer.add(new DbFeatureHistory>(new DbOrderedFeature( way.getId(), nodeReferenceList.get(i), i + 1), way.getVersion())); } flushWayNodes(false); } /** * {@inheritDoc} */ public void process(RelationContainer relationContainer) { Relation relation; long relationId; flushWays(true); relation = relationContainer.getEntity(); relationId = relation.getId(); if (relationId >= maxRelationId) { maxRelationId = relationId + 1; } if (relationId < minRelationId) { minRelationId = relationId; } relationBuffer.add(relation); flushRelations(false); } /** * Process the relation tags. * * @param relation The relation to be processed. */ private void addRelationTags(Relation relation) { for (Tag tag : relation.getTags()) { relationTagBuffer.add(new DbFeatureHistory>(new DbFeature(relation.getId(), tag), relation.getVersion())); } flushRelationTags(false); } /** * Process the relation members. * * @param relation The relation to be processed. */ private void addRelationMembers(Relation relation) { List memberReferenceList; memberReferenceList = relation.getMembers(); for (int i = 0; i < memberReferenceList.size(); i++) { relationMemberBuffer.add(new DbFeatureHistory>( new DbOrderedFeature(relation.getId(), memberReferenceList.get(i), i + 1), relation .getVersion())); } flushRelationMembers(false); } } ApidbWriterFactory.java000066400000000000000000000033541253404521400340400ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.database.DatabaseTaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkManager; /** * The task manager factory for a database writer. * * @author Brett Henderson */ public class ApidbWriterFactory extends DatabaseTaskManagerFactory { private static final String ARG_LOCK_TABLES = "lockTables"; private static final String ARG_POPULATE_CURRENT_TABLES = "populateCurrentTables"; private static final boolean DEFAULT_LOCK_TABLES = true; private static final boolean DEFAULT_POPULATE_CURRENT_TABLES = true; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { DatabaseLoginCredentials loginCredentials; DatabasePreferences preferences; boolean lockTables; boolean populateCurrentTables; // Get the task arguments. loginCredentials = getDatabaseLoginCredentials(taskConfig); preferences = getDatabasePreferences(taskConfig); lockTables = getBooleanArgument(taskConfig, ARG_LOCK_TABLES, DEFAULT_LOCK_TABLES); populateCurrentTables = getBooleanArgument( taskConfig, ARG_POPULATE_CURRENT_TABLES, DEFAULT_POPULATE_CURRENT_TABLES); return new SinkManager( taskConfig.getId(), new ApidbWriter(loginCredentials, preferences, lockTables, populateCurrentTables), taskConfig.getPipeArgs() ); } } osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl/000077500000000000000000000000001253404521400304445ustar00rootroot00000000000000ActionChangeWriter.java000066400000000000000000000032021253404521400347450ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityProcessor; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.task.common.ChangeAction; /** * Writes entities to a database according to a specific action. * * @author Brett Henderson */ public class ActionChangeWriter implements EntityProcessor { private ChangeWriter changeWriter; private ChangeAction action; /** * Creates a new instance. * * @param changeWriter * The underlying change writer. * @param action * The action to apply to all writes. */ public ActionChangeWriter(ChangeWriter changeWriter, ChangeAction action) { this.changeWriter = changeWriter; this.action = action; } /** * {@inheritDoc} */ public void process(BoundContainer bound) { // Do nothing. } /** * {@inheritDoc} */ public void process(NodeContainer nodeContainer) { changeWriter.write(nodeContainer.getEntity(), action); } /** * {@inheritDoc} */ public void process(WayContainer wayContainer) { changeWriter.write(wayContainer.getEntity(), action); } /** * {@inheritDoc} */ public void process(RelationContainer relationContainer) { changeWriter.write(relationContainer.getEntity(), action); } } AllEntityDao.java000066400000000000000000000121021253404521400335550ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.lifecycle.ReleasableContainer; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.store.MultipleSourceIterator; import org.springframework.jdbc.core.JdbcTemplate; /** * Provides operations that act on on all entity types by combining operations from the underlying * DAO implementations. */ public class AllEntityDao implements ReplicationSource { private NodeDao nodeDao; private WayDao wayDao; private RelationDao relationDao; /** * Creates a new instance. * * @param jdbcTemplate * Used to access the database. */ public AllEntityDao(JdbcTemplate jdbcTemplate) { nodeDao = new NodeDao(jdbcTemplate); wayDao = new WayDao(jdbcTemplate); relationDao = new RelationDao(jdbcTemplate); } /** * Retrieves the changes that have were made by a set of transactions. * * @param predicates * Contains the predicates defining the transactions to be queried. * @return An iterator pointing at the identified records. */ public ReleasableIterator getHistory(ReplicationQueryPredicates predicates) { ReleasableContainer releasableContainer; releasableContainer = new ReleasableContainer(); try { List> sources; MultipleSourceIterator resultIterator; sources = new ArrayList>(); sources.add(releasableContainer.add(nodeDao.getHistory(predicates))); sources.add(releasableContainer.add(wayDao.getHistory(predicates))); sources.add(releasableContainer.add(relationDao.getHistory(predicates))); resultIterator = new MultipleSourceIterator(sources); releasableContainer.clear(); return resultIterator; } finally { releasableContainer.release(); } } /** * Retrieves the changes that have were made between two points in time. * * @param intervalBegin * Marks the beginning (inclusive) of the time interval to be checked. * @param intervalEnd * Marks the end (exclusive) of the time interval to be checked. * @return An iterator pointing at the identified records. */ public ReleasableIterator getHistory(Date intervalBegin, Date intervalEnd) { ReleasableContainer releasableContainer; releasableContainer = new ReleasableContainer(); try { List> sources; MultipleSourceIterator resultIterator; sources = new ArrayList>(); sources.add(releasableContainer.add(nodeDao.getHistory(intervalBegin, intervalEnd))); sources.add(releasableContainer.add(wayDao.getHistory(intervalBegin, intervalEnd))); sources.add(releasableContainer.add(relationDao.getHistory(intervalBegin, intervalEnd))); resultIterator = new MultipleSourceIterator(sources); releasableContainer.clear(); return resultIterator; } finally { releasableContainer.release(); } } /** * Retrieves all changes in the database. * * @return An iterator pointing at the identified records. */ public ReleasableIterator getHistory() { ReleasableContainer releasableContainer; releasableContainer = new ReleasableContainer(); try { List> sources; MultipleSourceIterator resultIterator; sources = new ArrayList>(); sources.add(releasableContainer.add(nodeDao.getHistory())); sources.add(releasableContainer.add(wayDao.getHistory())); sources.add(releasableContainer.add(relationDao.getHistory())); resultIterator = new MultipleSourceIterator(sources); releasableContainer.clear(); return resultIterator; } finally { releasableContainer.release(); } } /** * Retrieves all current data in the database. * * @return An iterator pointing at the current records. */ public ReleasableIterator getCurrent() { ReleasableContainer releasableContainer; releasableContainer = new ReleasableContainer(); try { List> sources; MultipleSourceIterator resultIterator; sources = new ArrayList>(); sources.add(releasableContainer.add(nodeDao.getCurrent())); sources.add(releasableContainer.add(wayDao.getCurrent())); sources.add(releasableContainer.add(relationDao.getCurrent())); resultIterator = new MultipleSourceIterator(sources); releasableContainer.clear(); return resultIterator; } finally { releasableContainer.release(); } } } ChangeReader.java000066400000000000000000000061031253404521400335400ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainerFactory; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.task.common.ChangeAction; /** * Creates change records based on the data provided by an underlying entity history iterator. * * @param * The type of entity provided by this iterator. */ public class ChangeReader implements ReleasableIterator { private ReleasableIterator> source; private EntityContainerFactory containerFactory; /** * Creates a new instance. * * @param source * The entity history source. * @param containerFactory * The factory for wrapping entity objects into containers. */ public ChangeReader(ReleasableIterator> source, EntityContainerFactory containerFactory) { this.source = source; this.containerFactory = containerFactory; } /** * {@inheritDoc} */ @Override public boolean hasNext() { return source.hasNext(); } /** * {@inheritDoc} */ @Override public ChangeContainer next() { EntityHistory entityHistory; T entity; EntityContainer entityContainer; boolean createdPreviously; // Get the entity from the underlying source. entityHistory = source.next(); entity = entityHistory.getEntity(); // Wrap the entity in a container. entityContainer = containerFactory.createContainer(entity); // This is only a create if the version is 1. createdPreviously = (entityHistory.getEntity().getVersion() > 1); // The entity has been modified if it is visible and was created previously. // It is a create if it is visible and was NOT created previously. // It is a delete if it is NOT visible and was created previously. // No action if it is NOT visible and was NOT created previously. if (entityHistory.isVisible() && createdPreviously) { return new ChangeContainer(entityContainer, ChangeAction.Modify); } else if (entityHistory.isVisible() && !createdPreviously) { return new ChangeContainer(entityContainer, ChangeAction.Create); } else if (!entityHistory.isVisible() && createdPreviously) { return new ChangeContainer(entityContainer, ChangeAction.Delete); } else { // This is an unusual case in that an initial version has been marked as not visible. // The production database contains many examples of this, presumably due to the original // TIGER import not being deleted properly. return new ChangeContainer(entityContainer, ChangeAction.Delete); } } /** * {@inheritDoc} */ @Override public void remove() { throw new UnsupportedOperationException(); } /** * {@inheritDoc} */ @Override public void release() { source.release(); } } ChangeWriter.java000066400000000000000000001430171253404521400336200ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.apidb.common.DatabaseContext; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.ReleasableStatementContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.openstreetmap.osmosis.core.task.common.ChangeAction; import org.openstreetmap.osmosis.core.util.FixedPrecisionCoordinateConvertor; import org.openstreetmap.osmosis.core.util.TileCalculator; /** * Writes changes to a database. * * @author Brett Henderson */ public class ChangeWriter { private static final Logger LOG = Logger.getLogger(ChangeWriter.class.getName()); private static final String INSERT_SQL_NODE = "INSERT INTO nodes (node_id, version, timestamp, visible, changeset_id, latitude, longitude, tile)" + " VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; private static final String UPDATE_SQL_NODE = "UPDATE nodes SET timestamp = ?, visible = ?, changeset_id = ?, latitude = ?, longitude = ?, tile = ?" + " WHERE node_id = ? AND version = ?"; private static final String SELECT_SQL_NODE_COUNT = "SELECT Count(node_id) AS rowCount FROM nodes WHERE node_id = ? AND version = ?"; private static final String INSERT_SQL_NODE_CURRENT = "INSERT INTO current_nodes (id, version, timestamp, visible, changeset_id, latitude, longitude, tile)" + " VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; private static final String UPDATE_SQL_NODE_CURRENT = "UPDATE current_nodes SET version = ?, timestamp = ?, visible = ?, changeset_id = ?, latitude = ?," + " longitude = ?, tile = ? WHERE id = ?"; private static final String SELECT_SQL_NODE_CURRENT_COUNT = "SELECT Count(id) AS rowCount FROM current_nodes WHERE id = ?"; private static final String INSERT_SQL_NODE_TAG = "INSERT INTO node_tags (node_id, version, k, v) VALUES (?, ?, ?, ?)"; private static final String DELETE_SQL_NODE_TAG = "DELETE FROM node_tags WHERE node_id = ? AND version = ?"; private static final String INSERT_SQL_NODE_TAG_CURRENT = "INSERT INTO current_node_tags (node_id, k, v) VALUES (?, ?, ?)"; private static final String DELETE_SQL_NODE_TAG_CURRENT = "DELETE FROM current_node_tags WHERE node_id = ?"; private static final String INSERT_SQL_WAY = "INSERT INTO ways (way_id, version, timestamp, visible, changeset_id) VALUES (?, ?, ?, ?, ?)"; private static final String UPDATE_SQL_WAY = "UPDATE current_ways SET timestamp = ?, visible = ?, changeset_id = ? WHERE id = ? AND version = ?"; private static final String SELECT_SQL_WAY_COUNT = "SELECT Count(way_id) AS rowCount FROM ways WHERE way_id = ? AND version = ?"; private static final String INSERT_SQL_WAY_CURRENT = "INSERT INTO current_ways (id, version, timestamp, visible, changeset_id) VALUES (?, ?, ?, ?, ?)"; private static final String UPDATE_SQL_WAY_CURRENT = "UPDATE current_ways SET version = ?, timestamp = ?, visible = ?, changeset_id = ? WHERE id = ?"; private static final String SELECT_SQL_WAY_CURRENT_COUNT = "SELECT Count(id) AS rowCount FROM current_ways WHERE id = ?"; private static final String INSERT_SQL_WAY_TAG = "INSERT INTO way_tags (way_id, version, k, v) VALUES (?, ?, ?, ?)"; private static final String DELETE_SQL_WAY_TAG = "DELETE FROM way_tags WHERE way_id = ? AND version = ?"; private static final String INSERT_SQL_WAY_TAG_CURRENT = "INSERT INTO current_way_tags (way_id, k, v) VALUES (?, ?, ?)"; private static final String DELETE_SQL_WAY_TAG_CURRENT = "DELETE FROM current_way_tags WHERE way_id = ?"; private static final String INSERT_SQL_WAY_NODE = "INSERT INTO way_nodes (way_id, version, node_id, sequence_id) VALUES (?, ?, ?, ?)"; private static final String DELETE_SQL_WAY_NODE = "DELETE FROM way_nodes WHERE way_id = ? AND version = ?"; private static final String INSERT_SQL_WAY_NODE_CURRENT = "INSERT INTO current_way_nodes (way_id, node_id, sequence_id) VALUES (?, ?, ?)"; private static final String DELETE_SQL_WAY_NODE_CURRENT = "DELETE FROM current_way_nodes WHERE way_id = ?"; private static final String INSERT_SQL_RELATION = "INSERT INTO relations (relation_id, version, timestamp, visible, changeset_id) VALUES (?, ?, ?, ?, ?)"; private static final String UPDATE_SQL_RELATION = "UPDATE relations SET timestamp = ?, visible = ?, changeset_id = ? WHERE relation_id = ? AND version = ?"; private static final String SELECT_SQL_RELATION_COUNT = "SELECT Count(id) AS rowCount FROM current_relations WHERE id = ? AND version = ?"; private static final String INSERT_SQL_RELATION_CURRENT = "INSERT INTO current_relations (id, version, timestamp, visible, changeset_id) VALUES (?, ?, ?, ?, ?)"; private static final String UPDATE_SQL_RELATION_CURRENT = "UPDATE current_relations SET version = ?, timestamp = ?, visible = ?, changeset_id = ? WHERE id = ?"; private static final String SELECT_SQL_RELATION_CURRENT_COUNT = "SELECT Count(id) AS rowCount FROM current_relations WHERE id = ?"; private static final String INSERT_SQL_RELATION_TAG = "INSERT INTO relation_tags (relation_id, version, k, v) VALUES (?, ?, ?, ?)"; private static final String DELETE_SQL_RELATION_TAG = "DELETE FROM relation_tags WHERE relation_id = ? AND version = ?"; private static final String INSERT_SQL_RELATION_TAG_CURRENT = "INSERT INTO current_relation_tags (relation_id, k, v) VALUES (?, ?, ?)"; private static final String DELETE_SQL_RELATION_TAG_CURRENT = "DELETE FROM current_relation_tags WHERE relation_id = ?"; private static final String INSERT_SQL_RELATION_MEMBER_MYSQL = "INSERT INTO relation_members (relation_id, version, member_type, member_id, member_role, sequence_id)" + " VALUES (?, ?, ?, ?, ?, ?)"; private static final String INSERT_SQL_RELATION_MEMBER_PGSQL = "INSERT INTO relation_members (relation_id, version, member_type, member_id, member_role, sequence_id)" + " VALUES (?, ?, ?::nwr_enum, ?, ?, ?)"; private static final String DELETE_SQL_RELATION_MEMBER = "DELETE FROM relation_members WHERE relation_id = ? AND version = ?"; private static final String INSERT_SQL_RELATION_MEMBER_CURRENT_MYSQL = "INSERT INTO current_relation_members (relation_id, member_type, member_id, member_role, sequence_id)" + " VALUES (?, ?, ?, ?, ?)"; private static final String INSERT_SQL_RELATION_MEMBER_CURRENT_PGSQL = "INSERT INTO current_relation_members (relation_id, member_type, member_id, member_role, sequence_id)" + " VALUES (?, ?::nwr_enum, ?, ?, ?)"; private static final String DELETE_SQL_RELATION_MEMBER_CURRENT = "DELETE FROM current_relation_members WHERE relation_id = ?"; private final DatabaseContext dbCtx; private final UserManager userManager; private final ChangesetManager changesetManager; private final boolean populateCurrentTables; private final ReleasableStatementContainer statementContainer; private PreparedStatement insertNodeStatement; private PreparedStatement updateNodeStatement; private PreparedStatement selectNodeCountStatement; private PreparedStatement insertNodeCurrentStatement; private PreparedStatement updateNodeCurrentStatement; private PreparedStatement selectNodeCurrentCountStatement; private PreparedStatement insertNodeTagStatement; private PreparedStatement deleteNodeTagStatement; private PreparedStatement insertNodeTagCurrentStatement; private PreparedStatement deleteNodeTagCurrentStatement; private PreparedStatement insertWayStatement; private PreparedStatement updateWayStatement; private PreparedStatement selectWayCountStatement; private PreparedStatement insertWayCurrentStatement; private PreparedStatement updateWayCurrentStatement; private PreparedStatement selectWayCurrentCountStatement; private PreparedStatement insertWayTagStatement; private PreparedStatement deleteWayTagStatement; private PreparedStatement insertWayTagCurrentStatement; private PreparedStatement deleteWayTagCurrentStatement; private PreparedStatement insertWayNodeStatement; private PreparedStatement deleteWayNodeStatement; private PreparedStatement insertWayNodeCurrentStatement; private PreparedStatement deleteWayNodeCurrentStatement; private PreparedStatement insertRelationStatement; private PreparedStatement updateRelationStatement; private PreparedStatement selectRelationCountStatement; private PreparedStatement insertRelationCurrentStatement; private PreparedStatement updateRelationCurrentStatement; private PreparedStatement selectRelationCurrentCountStatement; private PreparedStatement insertRelationTagStatement; private PreparedStatement deleteRelationTagStatement; private PreparedStatement insertRelationTagCurrentStatement; private PreparedStatement deleteRelationTagCurrentStatement; private PreparedStatement insertRelationMemberStatement; private PreparedStatement deleteRelationMemberStatement; private PreparedStatement insertRelationMemberCurrentStatement; private PreparedStatement deleteRelationMemberCurrentStatement; private final MemberTypeRenderer memberTypeRenderer; private final TileCalculator tileCalculator; /** * Creates a new instance. * * @param loginCredentials Contains all information required to connect to the database. * @param populateCurrentTables If true, the current tables will be populated as well as history * tables. */ public ChangeWriter(DatabaseLoginCredentials loginCredentials, boolean populateCurrentTables) { dbCtx = new DatabaseContext(loginCredentials); statementContainer = new ReleasableStatementContainer(); userManager = new UserManager(dbCtx); changesetManager = new ChangesetManager(dbCtx); this.populateCurrentTables = populateCurrentTables; tileCalculator = new TileCalculator(); memberTypeRenderer = new MemberTypeRenderer(); } /** * Checks to see if the specified entity exists. * * @param statement The statement used to perform the check. * @param id The entity identifier. * @return True if the entity exists, false otherwise. * @throws SQLException if an error occurs accessing the database. */ private boolean checkIfEntityExists(PreparedStatement statement, long id) throws SQLException { boolean exists; ResultSet resultSet; resultSet = null; try { statement.setLong(1, id); resultSet = statement.executeQuery(); resultSet.next(); if (resultSet.getInt("rowCount") == 0) { exists = false; } else { exists = true; } resultSet.close(); resultSet = null; return exists; } finally { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to close entity existence check result set.", e); } } } } /** * Checks to see if the specified entity history item exists. * * @param statement The statement used to perform the check. * @param id The entity identifier. * @param version The entity version. * @return True if the entity exists, false otherwise. * @throws SQLException if an error occurs accessing the database. */ private boolean checkIfEntityHistoryExists(PreparedStatement statement, long id, int version) throws SQLException { boolean exists; ResultSet resultSet; int prmIndex; resultSet = null; try { prmIndex = 1; statement.setLong(prmIndex++, id); statement.setInt(prmIndex++, version); resultSet = statement.executeQuery(); resultSet.next(); if (resultSet.getInt("rowCount") == 0) { exists = false; } else { exists = true; } resultSet.close(); resultSet = null; return exists; } finally { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to close entity history existence result set.", e); } } } } /** * Writes the specified node change to the database. * * @param node The node to be written. * @param action The change to be applied. */ public void write(Node node, ChangeAction action) { boolean visible; boolean exists; int prmIndex; // We can't write an entity with a null timestamp. if (node.getTimestamp() == null) { throw new OsmosisRuntimeException("Node " + node.getId() + " does not have a timestamp set."); } // Add or update the user in the database. userManager.addOrUpdateUser(node.getUser()); // Create the changeset in the database. changesetManager.addChangesetIfRequired(node.getChangesetId(), node.getUser()); // If this is a deletion, the entity is not visible. visible = !action.equals(ChangeAction.Delete); // Create the prepared statements for node creation if necessary. if (insertNodeStatement == null) { insertNodeStatement = statementContainer.add(dbCtx.prepareStatement(INSERT_SQL_NODE)); updateNodeStatement = statementContainer.add(dbCtx.prepareStatement(UPDATE_SQL_NODE)); selectNodeCountStatement = statementContainer.add(dbCtx.prepareStatement(SELECT_SQL_NODE_COUNT)); insertNodeCurrentStatement = statementContainer.add(dbCtx.prepareStatement(INSERT_SQL_NODE_CURRENT)); updateNodeCurrentStatement = statementContainer.add(dbCtx.prepareStatement(UPDATE_SQL_NODE_CURRENT)); selectNodeCurrentCountStatement = statementContainer.add(dbCtx .prepareStatement(SELECT_SQL_NODE_CURRENT_COUNT)); insertNodeTagStatement = statementContainer.add(dbCtx.prepareStatement(INSERT_SQL_NODE_TAG)); deleteNodeTagStatement = statementContainer.add(dbCtx.prepareStatement(DELETE_SQL_NODE_TAG)); insertNodeTagCurrentStatement = statementContainer.add(dbCtx.prepareStatement(INSERT_SQL_NODE_TAG_CURRENT)); deleteNodeTagCurrentStatement = statementContainer.add(dbCtx.prepareStatement(DELETE_SQL_NODE_TAG_CURRENT)); } // Remove the existing tags of the node history item. try { prmIndex = 1; deleteNodeTagStatement.setLong(prmIndex++, node.getId()); deleteNodeTagStatement.setInt(prmIndex++, node.getVersion()); deleteNodeTagStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to delete node history tags for node with id=" + node.getId() + ".", e); } // Update the node if it already exists in the history table, otherwise insert it. try { exists = checkIfEntityHistoryExists(selectNodeCountStatement, node.getId(), node.getVersion()); } catch (SQLException e) { throw new OsmosisRuntimeException( "Unable to check if current node with id=" + node.getId() + " exists.", e); } if (exists) { // Update the node in the history table. try { prmIndex = 1; updateNodeStatement.setTimestamp(prmIndex++, new Timestamp(node.getTimestamp().getTime())); updateNodeStatement.setBoolean(prmIndex++, visible); updateNodeStatement.setLong(prmIndex++, node.getChangesetId()); updateNodeStatement.setInt(prmIndex++, FixedPrecisionCoordinateConvertor.convertToFixed(node .getLatitude())); updateNodeStatement.setInt(prmIndex++, FixedPrecisionCoordinateConvertor.convertToFixed(node .getLongitude())); updateNodeStatement.setLong(prmIndex++, tileCalculator.calculateTile(node.getLatitude(), node .getLongitude())); updateNodeStatement.setLong(prmIndex++, node.getId()); updateNodeStatement.setInt(prmIndex++, node.getVersion()); updateNodeStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to update history node with id=" + node.getId() + ".", e); } } else { // Insert the new node into the history table. try { prmIndex = 1; insertNodeStatement.setLong(prmIndex++, node.getId()); insertNodeStatement.setInt(prmIndex++, node.getVersion()); insertNodeStatement.setTimestamp(prmIndex++, new Timestamp(node.getTimestamp().getTime())); insertNodeStatement.setBoolean(prmIndex++, visible); insertNodeStatement.setLong(prmIndex++, node.getChangesetId()); insertNodeStatement.setInt(prmIndex++, FixedPrecisionCoordinateConvertor.convertToFixed(node .getLatitude())); insertNodeStatement.setInt(prmIndex++, FixedPrecisionCoordinateConvertor.convertToFixed(node .getLongitude())); insertNodeStatement.setLong(prmIndex++, tileCalculator.calculateTile(node.getLatitude(), node .getLongitude())); insertNodeStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert history node with id=" + node.getId() + ".", e); } } // Insert the tags of the new node into the history table. for (Tag tag : node.getTags()) { try { prmIndex = 1; insertNodeTagStatement.setLong(prmIndex++, node.getId()); insertNodeTagStatement.setInt(prmIndex++, node.getVersion()); insertNodeTagStatement.setString(prmIndex++, tag.getKey()); insertNodeTagStatement.setString(prmIndex++, tag.getValue()); insertNodeTagStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert history node tag with id=" + node.getId() + " and key=(" + tag.getKey() + ").", e); } } if (populateCurrentTables) { // Delete the existing node tags from the current table. try { deleteNodeTagCurrentStatement.setLong(1, node.getId()); deleteNodeTagCurrentStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException( "Unable to delete current node tags with id=" + node.getId() + ".", e); } // Update the node if it already exists in the current table, otherwise insert it. try { exists = checkIfEntityExists(selectNodeCurrentCountStatement, node.getId()); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to check if current node with id=" + node.getId() + " exists.", e); } if (exists) { // Update the node in the current table. try { prmIndex = 1; updateNodeCurrentStatement.setInt(prmIndex++, node.getVersion()); updateNodeCurrentStatement.setTimestamp(prmIndex++, new Timestamp(node.getTimestamp().getTime())); updateNodeCurrentStatement.setBoolean(prmIndex++, visible); updateNodeCurrentStatement.setLong(prmIndex++, node.getChangesetId()); updateNodeCurrentStatement.setInt(prmIndex++, FixedPrecisionCoordinateConvertor.convertToFixed(node .getLatitude())); updateNodeCurrentStatement.setInt(prmIndex++, FixedPrecisionCoordinateConvertor.convertToFixed(node .getLongitude())); updateNodeCurrentStatement.setLong(prmIndex++, tileCalculator.calculateTile(node.getLatitude(), node.getLongitude())); updateNodeCurrentStatement.setLong(prmIndex++, node.getId()); updateNodeCurrentStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to update current node with id=" + node.getId() + ".", e); } } else { // Insert the new node into the current table. try { prmIndex = 1; insertNodeCurrentStatement.setLong(prmIndex++, node.getId()); insertNodeCurrentStatement.setInt(prmIndex++, node.getVersion()); insertNodeCurrentStatement.setTimestamp(prmIndex++, new Timestamp(node.getTimestamp().getTime())); insertNodeCurrentStatement.setBoolean(prmIndex++, visible); insertNodeCurrentStatement.setLong(prmIndex++, node.getChangesetId()); insertNodeCurrentStatement.setInt(prmIndex++, FixedPrecisionCoordinateConvertor.convertToFixed(node .getLatitude())); insertNodeCurrentStatement.setInt(prmIndex++, FixedPrecisionCoordinateConvertor.convertToFixed(node .getLongitude())); insertNodeCurrentStatement.setLong(prmIndex++, tileCalculator.calculateTile(node.getLatitude(), node.getLongitude())); insertNodeCurrentStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert current node with id=" + node.getId() + ".", e); } } // Insert the tags of the new node into the current table. for (Tag tag : node.getTags()) { try { prmIndex = 1; insertNodeTagCurrentStatement.setLong(prmIndex++, node.getId()); insertNodeTagCurrentStatement.setString(prmIndex++, tag.getKey()); insertNodeTagCurrentStatement.setString(prmIndex++, tag.getValue()); insertNodeTagCurrentStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert current node tag with id=" + node.getId() + " and key=(" + tag.getKey() + ").", e); } } } } /** * Writes the specified way change to the database. * * @param way The way to be written. * @param action The change to be applied. */ public void write(Way way, ChangeAction action) { boolean visible; boolean exists; int prmIndex; List nodeReferenceList; // We can't write an entity with a null timestamp. if (way.getTimestamp() == null) { throw new OsmosisRuntimeException("Way " + way.getId() + " does not have a timestamp set."); } // Add or update the user in the database. userManager.addOrUpdateUser(way.getUser()); // Create the changeset in the database. changesetManager.addChangesetIfRequired(way.getChangesetId(), way.getUser()); nodeReferenceList = way.getWayNodes(); // If this is a deletion, the entity is not visible. visible = !action.equals(ChangeAction.Delete); // Create the prepared statements for way creation if necessary. if (insertWayStatement == null) { insertWayStatement = statementContainer.add(dbCtx.prepareStatement(INSERT_SQL_WAY)); updateWayStatement = statementContainer.add(dbCtx.prepareStatement(UPDATE_SQL_WAY)); selectWayCountStatement = statementContainer.add(dbCtx.prepareStatement(SELECT_SQL_WAY_COUNT)); insertWayCurrentStatement = statementContainer.add(dbCtx.prepareStatement(INSERT_SQL_WAY_CURRENT)); updateWayCurrentStatement = statementContainer.add(dbCtx.prepareStatement(UPDATE_SQL_WAY_CURRENT)); selectWayCurrentCountStatement = statementContainer.add(dbCtx .prepareStatement(SELECT_SQL_WAY_CURRENT_COUNT)); insertWayTagStatement = statementContainer.add(dbCtx.prepareStatement(INSERT_SQL_WAY_TAG)); deleteWayTagStatement = statementContainer.add(dbCtx.prepareStatement(DELETE_SQL_WAY_TAG)); insertWayTagCurrentStatement = statementContainer.add(dbCtx.prepareStatement(INSERT_SQL_WAY_TAG_CURRENT)); deleteWayTagCurrentStatement = statementContainer.add(dbCtx.prepareStatement(DELETE_SQL_WAY_TAG_CURRENT)); insertWayNodeStatement = statementContainer.add(dbCtx.prepareStatement(INSERT_SQL_WAY_NODE)); deleteWayNodeStatement = statementContainer.add(dbCtx.prepareStatement(DELETE_SQL_WAY_NODE)); insertWayNodeCurrentStatement = statementContainer.add(dbCtx.prepareStatement(INSERT_SQL_WAY_NODE_CURRENT)); deleteWayNodeCurrentStatement = statementContainer.add(dbCtx.prepareStatement(DELETE_SQL_WAY_NODE_CURRENT)); } // Remove the existing tags of the way history item. try { prmIndex = 1; deleteWayTagStatement.setLong(prmIndex++, way.getId()); deleteWayTagStatement.setInt(prmIndex++, way.getVersion()); deleteWayTagStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to delete way history tags for way with id=" + way.getId() + ".", e); } // Remove the existing way nodes of the way history item. try { prmIndex = 1; deleteWayNodeStatement.setLong(prmIndex++, way.getId()); deleteWayNodeStatement.setInt(prmIndex++, way.getVersion()); deleteWayNodeStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException( "Unable to delete way history nodes for way with id=" + way.getId() + ".", e); } // Update the way if it already exists in the history table, otherwise insert it. try { exists = checkIfEntityHistoryExists(selectWayCountStatement, way.getId(), way.getVersion()); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to check if current way with id=" + way.getId() + " exists.", e); } if (exists) { // Update the way in the history table. try { prmIndex = 1; updateWayStatement.setTimestamp(prmIndex++, new Timestamp(way.getTimestamp().getTime())); updateWayStatement.setBoolean(prmIndex++, visible); updateWayStatement.setLong(prmIndex++, way.getChangesetId()); updateWayStatement.setLong(prmIndex++, way.getId()); updateWayStatement.setInt(prmIndex++, way.getVersion()); updateWayStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to update history way with id=" + way.getId() + ".", e); } } else { // Insert the new way into the history table. try { prmIndex = 1; insertWayStatement.setLong(prmIndex++, way.getId()); insertWayStatement.setInt(prmIndex++, way.getVersion()); insertWayStatement.setTimestamp(prmIndex++, new Timestamp(way.getTimestamp().getTime())); insertWayStatement.setBoolean(prmIndex++, visible); insertWayStatement.setLong(prmIndex++, way.getChangesetId()); insertWayStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert history way with id=" + way.getId() + ".", e); } } // Insert the tags of the new way into the history table. for (Tag tag : way.getTags()) { try { prmIndex = 1; insertWayTagStatement.setLong(prmIndex++, way.getId()); insertWayTagStatement.setInt(prmIndex++, way.getVersion()); insertWayTagStatement.setString(prmIndex++, tag.getKey()); insertWayTagStatement.setString(prmIndex++, tag.getValue()); insertWayTagStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert history way tag with id=" + way.getId() + " and key=(" + tag.getKey() + ").", e); } } // Insert the nodes of the new way into the history table. for (int i = 0; i < nodeReferenceList.size(); i++) { WayNode nodeReference; nodeReference = nodeReferenceList.get(i); try { prmIndex = 1; insertWayNodeStatement.setLong(prmIndex++, way.getId()); insertWayNodeStatement.setInt(prmIndex++, way.getVersion()); insertWayNodeStatement.setLong(prmIndex++, nodeReference.getNodeId()); insertWayNodeStatement.setLong(prmIndex++, i + 1); insertWayNodeStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert history way node with way id=" + way.getId() + " and node id=" + nodeReference.getNodeId() + ".", e); } } if (populateCurrentTables) { // Delete the existing way tags from the current table. try { deleteWayTagCurrentStatement.setLong(1, way.getId()); deleteWayTagCurrentStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to delete current way tags with id=" + way.getId() + ".", e); } // Delete the existing way nodes from the current table. try { deleteWayNodeCurrentStatement.setLong(1, way.getId()); deleteWayNodeCurrentStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to delete current way nodes with id=" + way.getId() + ".", e); } // Update the node if it already exists in the current table, otherwise insert it. try { exists = checkIfEntityExists(selectWayCurrentCountStatement, way.getId()); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to check if current way with id=" + way.getId() + " exists.", e); } if (exists) { // Update the way in the current table. try { prmIndex = 1; updateWayCurrentStatement.setInt(prmIndex++, way.getVersion()); updateWayCurrentStatement.setTimestamp(prmIndex++, new Timestamp(way.getTimestamp().getTime())); updateWayCurrentStatement.setBoolean(prmIndex++, visible); updateWayCurrentStatement.setLong(prmIndex++, way.getChangesetId()); updateWayCurrentStatement.setLong(prmIndex++, way.getId()); updateWayCurrentStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to update current way with id=" + way.getId() + ".", e); } } else { // Insert the new way into the current table. try { prmIndex = 1; insertWayCurrentStatement.setLong(prmIndex++, way.getId()); insertWayCurrentStatement.setInt(prmIndex++, way.getVersion()); insertWayCurrentStatement.setTimestamp(prmIndex++, new Timestamp(way.getTimestamp().getTime())); insertWayCurrentStatement.setBoolean(prmIndex++, visible); insertWayCurrentStatement.setLong(prmIndex++, way.getChangesetId()); insertWayCurrentStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert current way with id=" + way.getId() + ".", e); } } // Insert the tags of the new way into the current table. for (Tag tag : way.getTags()) { try { prmIndex = 1; insertWayTagCurrentStatement.setLong(prmIndex++, way.getId()); insertWayTagCurrentStatement.setString(prmIndex++, tag.getKey()); insertWayTagCurrentStatement.setString(prmIndex++, tag.getValue()); insertWayTagCurrentStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert current way tag with id=" + way.getId() + " and key=(" + tag.getKey() + ").", e); } } // Insert the nodes of the new way into the current table. for (int i = 0; i < nodeReferenceList.size(); i++) { WayNode nodeReference; nodeReference = nodeReferenceList.get(i); try { prmIndex = 1; insertWayNodeCurrentStatement.setLong(prmIndex++, way.getId()); insertWayNodeCurrentStatement.setLong(prmIndex++, nodeReference.getNodeId()); insertWayNodeCurrentStatement.setLong(prmIndex++, i); insertWayNodeCurrentStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert current way node with way id=" + way.getId() + " and node id=" + nodeReference.getNodeId() + ".", e); } } } } /** * Writes the specified relation change to the database. * * @param relation The relation to be written. * @param action The change to be applied. */ public void write(Relation relation, ChangeAction action) { boolean visible; boolean exists; int prmIndex; List relationMemberList; // We can't write an entity with a null timestamp. if (relation.getTimestamp() == null) { throw new OsmosisRuntimeException("Relation " + relation.getId() + " does not have a timestamp set."); } // Add or update the user in the database. userManager.addOrUpdateUser(relation.getUser()); // Create the changeset in the database. changesetManager.addChangesetIfRequired(relation.getChangesetId(), relation.getUser()); relationMemberList = relation.getMembers(); // If this is a deletion, the entity is not visible. visible = !action.equals(ChangeAction.Delete); // Create the prepared statements for relation creation if necessary. if (insertRelationStatement == null) { insertRelationStatement = statementContainer.add(dbCtx.prepareStatement(INSERT_SQL_RELATION)); updateRelationStatement = statementContainer.add(dbCtx.prepareStatement(UPDATE_SQL_RELATION)); selectRelationCountStatement = statementContainer.add(dbCtx.prepareStatement(SELECT_SQL_RELATION_COUNT)); insertRelationCurrentStatement = statementContainer .add(dbCtx.prepareStatement(INSERT_SQL_RELATION_CURRENT)); updateRelationCurrentStatement = statementContainer .add(dbCtx.prepareStatement(UPDATE_SQL_RELATION_CURRENT)); selectRelationCurrentCountStatement = statementContainer.add(dbCtx .prepareStatement(SELECT_SQL_RELATION_CURRENT_COUNT)); insertRelationTagStatement = statementContainer.add(dbCtx.prepareStatement(INSERT_SQL_RELATION_TAG)); deleteRelationTagStatement = statementContainer.add(dbCtx.prepareStatement(DELETE_SQL_RELATION_TAG)); insertRelationTagCurrentStatement = statementContainer.add(dbCtx .prepareStatement(INSERT_SQL_RELATION_TAG_CURRENT)); deleteRelationTagCurrentStatement = statementContainer.add(dbCtx .prepareStatement(DELETE_SQL_RELATION_TAG_CURRENT)); switch (dbCtx.getDatabaseType()) { case POSTGRESQL: insertRelationMemberStatement = statementContainer.add(dbCtx.prepareStatement(INSERT_SQL_RELATION_MEMBER_PGSQL)); break; case MYSQL: insertRelationMemberStatement = statementContainer.add(dbCtx.prepareStatement(INSERT_SQL_RELATION_MEMBER_MYSQL)); break; default: throw new OsmosisRuntimeException("Unknown database type " + dbCtx.getDatabaseType() + "."); } deleteRelationMemberStatement = statementContainer.add(dbCtx.prepareStatement(DELETE_SQL_RELATION_MEMBER)); switch (dbCtx.getDatabaseType()) { case POSTGRESQL: insertRelationMemberCurrentStatement = statementContainer.add(dbCtx.prepareStatement(INSERT_SQL_RELATION_MEMBER_CURRENT_PGSQL)); break; case MYSQL: insertRelationMemberCurrentStatement = statementContainer.add(dbCtx.prepareStatement(INSERT_SQL_RELATION_MEMBER_CURRENT_MYSQL)); break; default: throw new OsmosisRuntimeException("Unknown database type " + dbCtx.getDatabaseType() + "."); } deleteRelationMemberCurrentStatement = statementContainer.add(dbCtx .prepareStatement(DELETE_SQL_RELATION_MEMBER_CURRENT)); } // Remove the existing tags of the relation history item. try { prmIndex = 1; deleteRelationTagStatement.setLong(prmIndex++, relation.getId()); deleteRelationTagStatement.setInt(prmIndex++, relation.getVersion()); deleteRelationTagStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to delete relation history tags for relation with id=" + relation.getId() + ".", e); } // Remove the existing relation members of the relation history item. try { prmIndex = 1; deleteRelationMemberStatement.setLong(prmIndex++, relation.getId()); deleteRelationMemberStatement.setInt(prmIndex++, relation.getVersion()); deleteRelationMemberStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to delete relation history members for relation with id=" + relation.getId() + ".", e); } // Update the relation if it already exists in the history table, otherwise insert it. try { exists = checkIfEntityHistoryExists(selectRelationCountStatement, relation.getId(), relation.getVersion()); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to check if current relation with id=" + relation.getId() + " exists.", e); } if (exists) { // Update the relation in the history table. try { prmIndex = 1; updateRelationStatement.setTimestamp(prmIndex++, new Timestamp(relation.getTimestamp().getTime())); updateRelationStatement.setBoolean(prmIndex++, visible); updateRelationStatement.setLong(prmIndex++, relation.getChangesetId()); updateRelationStatement.setLong(prmIndex++, relation.getId()); updateRelationStatement.setInt(prmIndex++, relation.getVersion()); updateRelationStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException( "Unable to update history relation with id=" + relation.getId() + ".", e); } } else { // Insert the new relation into the history table. try { prmIndex = 1; insertRelationStatement.setLong(prmIndex++, relation.getId()); insertRelationStatement.setInt(prmIndex++, relation.getVersion()); insertRelationStatement.setTimestamp(prmIndex++, new Timestamp(relation.getTimestamp().getTime())); insertRelationStatement.setBoolean(prmIndex++, visible); insertRelationStatement.setLong(prmIndex++, relation.getChangesetId()); insertRelationStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException( "Unable to insert history relation with id=" + relation.getId() + ".", e); } } // Insert the tags of the new relation into the history table. for (Tag tag : relation.getTags()) { try { prmIndex = 1; insertRelationTagStatement.setLong(prmIndex++, relation.getId()); insertRelationTagStatement.setInt(prmIndex++, relation.getVersion()); insertRelationTagStatement.setString(prmIndex++, tag.getKey()); insertRelationTagStatement.setString(prmIndex++, tag.getValue()); insertRelationTagStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert history relation tag with id=" + relation.getId() + " and key=(" + tag.getKey() + ").", e); } } // Insert the members of the new relation into the history table. for (int i = 0; i < relationMemberList.size(); i++) { RelationMember relationMember; relationMember = relationMemberList.get(i); try { prmIndex = 1; insertRelationMemberStatement.setLong(prmIndex++, relation.getId()); insertRelationMemberStatement.setInt(prmIndex++, relation.getVersion()); insertRelationMemberStatement.setString(prmIndex++, memberTypeRenderer.render(relationMember .getMemberType())); insertRelationMemberStatement.setLong(prmIndex++, relationMember.getMemberId()); insertRelationMemberStatement.setString(prmIndex++, relationMember.getMemberRole()); insertRelationMemberStatement.setInt(prmIndex++, i + 1); insertRelationMemberStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert history relation member with relation id=" + relation.getId() + ", member type=" + relationMember.getMemberId() + " and member id=" + relationMember.getMemberId() + ".", e); } } if (populateCurrentTables) { // Delete the existing relation tags from the current table. try { deleteRelationTagCurrentStatement.setLong(1, relation.getId()); deleteRelationTagCurrentStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to delete current relation tags with id=" + relation.getId() + ".", e); } // Delete the existing relation members from the current table. try { deleteRelationMemberCurrentStatement.setLong(1, relation.getId()); deleteRelationMemberCurrentStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to delete current relation members with id=" + relation.getId() + ".", e); } // Update the relation if it already exists in the current table, otherwise insert it. try { exists = checkIfEntityExists(selectRelationCurrentCountStatement, relation.getId()); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to check if current relation with id=" + relation.getId() + " exists.", e); } if (exists) { // Update the relation in the current table. try { prmIndex = 1; updateRelationCurrentStatement.setInt(prmIndex++, relation.getVersion()); updateRelationCurrentStatement.setTimestamp(prmIndex++, new Timestamp(relation.getTimestamp() .getTime())); updateRelationCurrentStatement.setBoolean(prmIndex++, visible); updateRelationCurrentStatement.setLong(prmIndex++, relation.getChangesetId()); updateRelationCurrentStatement.setLong(prmIndex++, relation.getId()); updateRelationCurrentStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to update current relation with id=" + relation.getId() + ".", e); } } else { // Insert the new node into the current table. try { prmIndex = 1; insertRelationCurrentStatement.setLong(prmIndex++, relation.getId()); insertRelationCurrentStatement.setInt(prmIndex++, relation.getVersion()); insertRelationCurrentStatement.setTimestamp(prmIndex++, new Timestamp(relation.getTimestamp() .getTime())); insertRelationCurrentStatement.setBoolean(prmIndex++, visible); insertRelationCurrentStatement.setLong(prmIndex++, relation.getChangesetId()); insertRelationCurrentStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert current relation with id=" + relation.getId() + ".", e); } } // Insert the tags of the new relation into the current table. for (Tag tag : relation.getTags()) { try { prmIndex = 1; insertRelationTagCurrentStatement.setLong(prmIndex++, relation.getId()); insertRelationTagCurrentStatement.setString(prmIndex++, tag.getKey()); insertRelationTagCurrentStatement.setString(prmIndex++, tag.getValue()); insertRelationTagCurrentStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert current relation tag with id=" + relation.getId() + " and key=(" + tag.getKey() + ").", e); } } // Insert the members of the new relation into the current table. for (int i = 0; i < relationMemberList.size(); i++) { RelationMember relationMember; relationMember = relationMemberList.get(i); try { prmIndex = 1; insertRelationMemberCurrentStatement.setLong(prmIndex++, relation.getId()); insertRelationMemberCurrentStatement.setString(prmIndex++, memberTypeRenderer.render(relationMember .getMemberType())); insertRelationMemberCurrentStatement.setLong(prmIndex++, relationMember.getMemberId()); insertRelationMemberCurrentStatement.setString(prmIndex++, relationMember.getMemberRole()); insertRelationMemberCurrentStatement.setInt(prmIndex++, i + 1); insertRelationMemberCurrentStatement.execute(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert current relation member with relation id=" + relation.getId() + ", member type=" + relationMember.getMemberId() + " and member id=" + relationMember.getMemberId() + ".", e); } } } } /** * Flushes all changes to the database. */ public void complete() { dbCtx.commit(); } /** * Releases all database resources. */ public void release() { statementContainer.release(); userManager.release(); changesetManager.release(); dbCtx.release(); } } ChangesetManager.java000066400000000000000000000145131253404521400344300ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisConstants; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.apidb.common.DatabaseContext; import org.openstreetmap.osmosis.core.database.ReleasableStatementContainer; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.lifecycle.Releasable; import org.openstreetmap.osmosis.core.lifecycle.ReleasableContainer; import org.openstreetmap.osmosis.core.util.FixedPrecisionCoordinateConvertor; /** * Creates and maintains changesets for a database conversation. This will create a separate * changeset for each user id making changes. * * @author Brett Henderson */ public class ChangesetManager implements Releasable { private static final Logger LOG = Logger.getLogger(ChangesetManager.class.getName()); private static final int MAX_CHANGESET_ID_CACHE_SIZE = 32768; private static final String SQL_INSERT_CHANGESET = "INSERT INTO changesets" + " (id, user_id, created_at, min_lat, max_lat, min_lon, max_lon, closed_at, num_changes)" + " VALUES" + " (?, ?, NOW(), " + FixedPrecisionCoordinateConvertor.convertToFixed(-90) + ", " + FixedPrecisionCoordinateConvertor.convertToFixed(90) + ", " + FixedPrecisionCoordinateConvertor.convertToFixed(-180) + ", " + FixedPrecisionCoordinateConvertor.convertToFixed(180) + ", NOW(), 0)"; private static final String SQL_INSERT_CHANGESET_TAG = "INSERT INTO changeset_tags (changeset_id, k, v)" + " VALUES (?, 'created_by', 'Osmosis " + OsmosisConstants.VERSION + "'), (?, 'replication', 'true')"; private static final String SQL_SELECT_CHANGESET_COUNT = "SELECT Count(*) AS changesetCount FROM changesets WHERE id = ?"; private final DatabaseContext dbCtx; private final ReleasableContainer releasableContainer; private final ReleasableStatementContainer statementContainer; private PreparedStatement insertStatement; private PreparedStatement insertTagStatement; private PreparedStatement selectCountStatement; private Set knownChangesetIds; /** * Creates a new instance. * * @param dbCtx The database context to use for all database access. */ public ChangesetManager(DatabaseContext dbCtx) { this.dbCtx = dbCtx; releasableContainer = new ReleasableContainer(); statementContainer = new ReleasableStatementContainer(); releasableContainer.add(statementContainer); knownChangesetIds = new LinkedHashSet(32768); } private int readChangesetCount(ResultSet countSet) { ResultSet resultSet = countSet; try { int changesetCount; resultSet.next(); changesetCount = resultSet.getInt("changesetCount"); resultSet.close(); resultSet = null; return changesetCount; } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to read the changeset count.", e); } finally { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { LOG.log(Level.WARNING, "Unable to close result set.", e); } } } } private boolean doesChangesetExist(long changesetId) { if (knownChangesetIds.contains(changesetId)) { return true; } if (selectCountStatement == null) { selectCountStatement = statementContainer.add(dbCtx .prepareStatementForStreaming(SQL_SELECT_CHANGESET_COUNT)); } try { int prmIndex; boolean changesetExists; // Check if the changeset exists. prmIndex = 1; selectCountStatement.setLong(prmIndex++, changesetId); changesetExists = readChangesetCount(selectCountStatement.executeQuery()) > 0; return changesetExists; } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to check if a changeset " + changesetId + " exists.", e); } } private void addChangeset(long changesetId, long userId) { if (insertStatement == null) { insertStatement = statementContainer.add(dbCtx.prepareStatement(SQL_INSERT_CHANGESET)); insertTagStatement = statementContainer.add(dbCtx.prepareStatement(SQL_INSERT_CHANGESET_TAG)); } try { int prmIndex; // Insert the new changeset record. prmIndex = 1; insertStatement.setLong(prmIndex++, changesetId); insertStatement.setLong(prmIndex++, userId); insertStatement.executeUpdate(); // Insert the changeset tags. prmIndex = 1; insertTagStatement.setLong(prmIndex++, changesetId); insertTagStatement.setLong(prmIndex++, changesetId); insertTagStatement.executeUpdate(); // Add the changeset to the cache, and trim the cache if required. knownChangesetIds.add(changesetId); if (knownChangesetIds.size() > MAX_CHANGESET_ID_CACHE_SIZE) { Iterator i = knownChangesetIds.iterator(); i.next(); i.remove(); } } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert a new changeset for user with id " + userId + ".", e); } } /** * Checks to see if the changeset already exists and adds it if it doesn't. * * @param changesetId * The changeset identifier. * @param user * The user who created the changeset. */ public void addChangesetIfRequired(long changesetId, OsmUser user) { if (!doesChangesetExist(changesetId)) { addChangeset(changesetId, user.getId()); } } /** * {@inheritDoc} */ @Override public void release() { releasableContainer.release(); } } DeltaToDiffReader.java000066400000000000000000000065141253404521400345060ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.util.List; import java.util.NoSuchElementException; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.store.PeekableIterator; import org.openstreetmap.osmosis.core.task.common.ChangeAction; /** * Takes an underlying full history delta stream and converts it into a diff stream. The difference * between the two is that a delta stream may contain multiple changes for a single entity, a diff * stream will contain a single change for the entity to get from the beginning to end point. */ public class DeltaToDiffReader implements ReleasableIterator { private PeekableIterator> sourceIterator; private ChangeContainer nextValue; private boolean nextValueLoaded; /** * Creates a new instance. * * @param sourceIterator * An iterator containing the full history for entities. */ public DeltaToDiffReader( ReleasableIterator sourceIterator) { this.sourceIterator = new PeekableIterator>(new EntityHistoryListReader(sourceIterator)); nextValueLoaded = false; } /** * {@inheritDoc} */ public boolean hasNext() { while (!nextValueLoaded && sourceIterator.hasNext()) { List changeList; ChangeContainer changeContainer; boolean createdPreviously; // Get the next change list from the underlying stream. changeList = sourceIterator.next(); // Check the first node, if it has a version greater than 1 the node // existed prior to the interval beginning and therefore cannot be a // create. createdPreviously = (changeList.get(0).getEntityContainer().getEntity().getVersion() > 1); // Get the most current change. changeContainer = changeList.get(changeList.size() - 1); // The entity has been modified if it is a create/modify and was created previously. // It is a create if it is create/modify and was NOT created previously. // It is a delete if it is a delete and was created previously. // No action if it is a delete and was NOT created previously. if (!ChangeAction.Delete.equals(changeContainer.getAction()) && createdPreviously) { nextValue = new ChangeContainer(changeContainer.getEntityContainer(), ChangeAction.Modify); nextValueLoaded = true; } else if (!ChangeAction.Delete.equals(changeContainer.getAction()) && !createdPreviously) { nextValue = new ChangeContainer(changeContainer.getEntityContainer(), ChangeAction.Create); nextValueLoaded = true; } else if (ChangeAction.Delete.equals(changeContainer.getAction()) && createdPreviously) { nextValue = new ChangeContainer(changeContainer.getEntityContainer(), ChangeAction.Delete); nextValueLoaded = true; } } return nextValueLoaded; } /** * {@inheritDoc} */ public ChangeContainer next() { if (!hasNext()) { throw new NoSuchElementException(); } nextValueLoaded = false; return nextValue; } /** * {@inheritDoc} */ public void remove() { throw new UnsupportedOperationException(); } /** * {@inheritDoc} */ public void release() { sourceIterator.release(); } } EntityContainerReader.java000066400000000000000000000040761253404521400355010ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.util.NoSuchElementException; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainerFactory; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; /** * Wraps a stream of entity history objects into entity containers. Only visible items will be returned. * * @param * The type of entity provided by this iterator. */ public class EntityContainerReader implements ReleasableIterator { private ReleasableIterator> source; private EntityContainerFactory containerFactory; private EntityContainer nextValue; private boolean nextValueLoaded; /** * Creates a new instance. * * @param source * The entity history source. * @param containerFactory * The factory for wrapping entity objects into containers. */ public EntityContainerReader( ReleasableIterator> source, EntityContainerFactory containerFactory) { this.source = source; this.containerFactory = containerFactory; } /** * {@inheritDoc} */ @Override public boolean hasNext() { while (!nextValueLoaded && source.hasNext()) { T entity; // Get the entity from the underlying source. entity = source.next().getEntity(); // Wrap the entity in a container. nextValue = containerFactory.createContainer(entity); nextValueLoaded = true; } return nextValueLoaded; } /** * {@inheritDoc} */ @Override public EntityContainer next() { if (!hasNext()) { throw new NoSuchElementException(); } nextValueLoaded = false; return nextValue; } /** * {@inheritDoc} */ @Override public void remove() { throw new UnsupportedOperationException(); } /** * {@inheritDoc} */ @Override public void release() { source.release(); } } osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl/EntityDao.java000066400000000000000000000501351253404521400332130ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.sql.Types; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainerFactory; import org.openstreetmap.osmosis.core.database.DbFeature; import org.openstreetmap.osmosis.core.database.DbFeatureHistory; import org.openstreetmap.osmosis.core.database.DbFeatureHistoryComparator; import org.openstreetmap.osmosis.core.database.DbFeatureHistoryRowMapper; import org.openstreetmap.osmosis.core.database.DbFeatureRowMapper; import org.openstreetmap.osmosis.core.database.RowMapperListener; import org.openstreetmap.osmosis.core.database.SortingStoreRowMapperListener; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.lifecycle.ReleasableContainer; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.sort.common.FileBasedSort; import org.openstreetmap.osmosis.core.store.SingleClassObjectSerializationFactory; import org.openstreetmap.osmosis.core.store.StoreReleasingIterator; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; /** * Provides functionality common to all top level entity daos. * * @param * The entity type to be supported. */ public abstract class EntityDao { private static final Logger LOG = Logger.getLogger(EntityDao.class.getName()); private JdbcTemplate jdbcTemplate; private NamedParameterJdbcTemplate namedParamJdbcTemplate; private String entityName; /** * Creates a new instance. * * @param jdbcTemplate * Used to access the database. * @param entityName * The name of the entity. Used for building dynamic sql queries. */ protected EntityDao(JdbcTemplate jdbcTemplate, String entityName) { this.jdbcTemplate = jdbcTemplate; this.namedParamJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate); this.entityName = entityName; } /** * Provides access to the named parameter jdbc template. * * @return The jdbc template. */ protected NamedParameterJdbcTemplate getNamedParamJdbcTemplate() { return namedParamJdbcTemplate; } /** * Produces an array of additional column names specific to this entity type to be returned by * entity queries. * * @return The column names. */ protected abstract String[] getTypeSpecificFieldNames(); /** * Creates a row mapper that receives common entity data objects and produces full entity * objects. * * @param entityListener * The full entity object listener. * @return The full entity row mapper. */ protected abstract RowMapperListener getEntityRowMapper(RowMapperListener entityListener); /** * Gets the entity container factory for the entity type. * * @return The factory. */ protected abstract EntityContainerFactory getContainerFactory(); /** * Gets the history feature populators for the entity type. * * @param selectedEntityStatement * The statement for obtaining the id and version pairs of entity records selected. * @param parameterSource * The parameters required to execute the selected entity statement. * @return The history feature populators. */ protected abstract List> getFeatureHistoryPopulators( String selectedEntityStatement, MapSqlParameterSource parameterSource); private String buildFeaturelessEntityHistoryQuery(String selectedEntityStatement) { StringBuilder sql; sql = new StringBuilder(); sql.append("SELECT e."); sql.append(entityName); sql.append("_id AS id, e.version, e.timestamp, e.visible, u.data_public,"); sql.append(" u.id AS user_id, u.display_name, e.changeset_id"); for (String fieldName : getTypeSpecificFieldNames()) { sql.append(", e."); sql.append(fieldName); } sql.append(" FROM "); sql.append(entityName); sql.append("s e"); sql.append(" INNER JOIN "); sql.append(selectedEntityStatement); sql.append(" t ON e."); sql.append(entityName); sql.append("_id = t."); sql.append(entityName); sql.append("_id AND e.version = t.version"); sql.append(" INNER JOIN changesets c ON e.changeset_id = c.id INNER JOIN users u ON c.user_id = u.id"); LOG.log(Level.FINER, "Entity history query: " + sql); return sql.toString(); } private ReleasableIterator> getFeaturelessEntityHistory( String selectedEntityStatement, MapSqlParameterSource parameterSource) { FileBasedSort> sortingStore = new FileBasedSort>( new SingleClassObjectSerializationFactory(EntityHistory.class), new EntityHistoryComparator(), true); try { String sql; SortingStoreRowMapperListener> storeListener; EntityHistoryRowMapper entityHistoryRowMapper; RowMapperListener entityRowMapper; EntityDataRowMapper entityDataRowMapper; ReleasableIterator> resultIterator; sql = buildFeaturelessEntityHistoryQuery(selectedEntityStatement); // Sends all received data into the object store. storeListener = new SortingStoreRowMapperListener>(sortingStore); // Retrieves the visible attribute allowing modifies to be distinguished // from deletes. entityHistoryRowMapper = new EntityHistoryRowMapper(storeListener); // Retrieves the entity type specific columns and builds the entity objects. entityRowMapper = getEntityRowMapper(entityHistoryRowMapper); // Retrieves the common entity information. entityDataRowMapper = new EntityDataRowMapper(entityRowMapper, false); // Perform the query passing the row mapper chain to process rows in a streamy fashion. namedParamJdbcTemplate.query(sql, parameterSource, entityDataRowMapper); // Open a iterator on the store that will release the store upon completion. resultIterator = new StoreReleasingIterator>(sortingStore.iterate(), sortingStore); // The store itself shouldn't be released now that it has been attached to the iterator. sortingStore = null; return resultIterator; } finally { if (sortingStore != null) { sortingStore.release(); } } } private ReleasableIterator>> getTagHistory(String selectedEntityStatement, MapSqlParameterSource parameterSource) { FileBasedSort>> sortingStore = new FileBasedSort>>( new SingleClassObjectSerializationFactory(DbFeatureHistory.class), new DbFeatureHistoryComparator(), true); try { String sql; SortingStoreRowMapperListener>> storeListener; DbFeatureHistoryRowMapper> dbFeatureHistoryRowMapper; DbFeatureRowMapper dbFeatureRowMapper; TagRowMapper tagRowMapper; ReleasableIterator>> resultIterator; sql = "SELECT et." + entityName + "_id AS id, et.k, et.v, et.version" + " FROM " + entityName + "_tags et" + " INNER JOIN " + selectedEntityStatement + " t ON et." + entityName + "_id = t." + entityName + "_id AND et.version = t.version"; LOG.log(Level.FINER, "Tag history query: " + sql); // Sends all received data into the object store. storeListener = new SortingStoreRowMapperListener>>(sortingStore); // Retrieves the version information associated with the tag. dbFeatureHistoryRowMapper = new DbFeatureHistoryRowMapper>(storeListener); // Retrieves the entity information associated with the tag. dbFeatureRowMapper = new DbFeatureRowMapper(dbFeatureHistoryRowMapper); // Retrieves the basic tag information. tagRowMapper = new TagRowMapper(dbFeatureRowMapper); // Perform the query passing the row mapper chain to process rows in a streamy fashion. namedParamJdbcTemplate.query(sql, parameterSource, tagRowMapper); // Open a iterator on the store that will release the store upon completion. resultIterator = new StoreReleasingIterator>>(sortingStore.iterate(), sortingStore); // The store itself shouldn't be released now that it has been attached to the iterator. sortingStore = null; return resultIterator; } finally { if (sortingStore != null) { sortingStore.release(); } } } private ReleasableIterator> getEntityHistory( String selectedEntityStatement, MapSqlParameterSource parameterSource) { ReleasableContainer releasableContainer; releasableContainer = new ReleasableContainer(); try { ReleasableIterator> entityIterator; ReleasableIterator>> tagIterator; List> featurePopulators; EntityHistoryReader entityHistoryReader; entityIterator = releasableContainer.add( getFeaturelessEntityHistory(selectedEntityStatement, parameterSource)); tagIterator = releasableContainer.add( getTagHistory(selectedEntityStatement, parameterSource)); featurePopulators = getFeatureHistoryPopulators(selectedEntityStatement, parameterSource); for (FeatureHistoryPopulator featurePopulator : featurePopulators) { releasableContainer.add(featurePopulator); } entityHistoryReader = new EntityHistoryReader(entityIterator, tagIterator, featurePopulators); // The sources are now all attached to the history reader so we don't want to release // them in the finally block. releasableContainer.clear(); return entityHistoryReader; } finally { releasableContainer.release(); } } private ReleasableIterator getChangeHistory( String selectedEntityStatement, MapSqlParameterSource parameterSource) { return new ChangeReader(getEntityHistory(selectedEntityStatement, parameterSource), getContainerFactory()); } private List buildTransactionRanges(long bottomTransactionId, long topTransactionId) { List rangeValues; int currentXid; int finishXid; // Begin building the values to use in the WHERE clause transaction ranges. Each pair of ids // in this list will become a range selection. rangeValues = new ArrayList(); // If the bottom and top values are identical then no ranges are required. If we don't add // this check here we could end up querying for all 4 billion transaction ids or all data in // the database. if (bottomTransactionId == topTransactionId) { return rangeValues; } // We must now convert the top and bottom long representations of xids into their integer // format because that is how they are indexed in the database. // The bottom id is the first transaction id that has not been read yet, so we begin reading from it. currentXid = (int) bottomTransactionId; rangeValues.add(currentXid); // The top transaction id is the first unassigned transaction id, so we must stop reading one short of that. finishXid = ((int) topTransactionId) - 1; // Process until we have enough ranges to reach the finish xid. do { // Determine how to terminate the current transaction range. if (currentXid <= 2 && finishXid >= 0) { // The range overlaps special ids 0-2 which should never be queried on. // Terminate the current range before the special values. rangeValues.add(-1); // Begin the new range after the special values. rangeValues.add(3); currentXid = 3; } else if (finishXid < currentXid) { // The range crosses the integer overflow point. Only do this check once we are // past 2 because the xid special values 0-2 may need to be crossed first. // Terminate the current range at the maximum int value. rangeValues.add(Integer.MAX_VALUE); // Begin a new range at the minimum int value. rangeValues.add(Integer.MIN_VALUE); currentXid = Integer.MIN_VALUE; } else { // There are no problematic transaction id values between the current value and // the top transaction id so terminate the current range at the top transaction // id. rangeValues.add(finishXid); currentXid = finishXid; } } while (currentXid != finishXid); return rangeValues; } private void buildTransactionRangeWhereClause(StringBuilder sql, MapSqlParameterSource parameters, long bottomTransactionId, long topTransactionId) { List rangeValues; // Determine the transaction ranges required to select all transactions between the bottom // and top values. This takes into account transaction id wrapping issues and reserved ids. rangeValues = buildTransactionRanges(bottomTransactionId, topTransactionId); // Create a range clause for each range pair. for (int i = 0; i < rangeValues.size(); i = i + 2) { if (i > 0) { sql.append(" OR "); } sql.append("("); sql.append("xid_to_int4(xmin) >= :rangeValue").append(i); sql.append(" AND "); sql.append("xid_to_int4(xmin) <= :rangeValue").append(i + 1); sql.append(")"); parameters.addValue("rangeValue" + i, rangeValues.get(i), Types.INTEGER); parameters.addValue("rangeValue" + (i + 1), rangeValues.get(i + 1), Types.INTEGER); } } private void buildTransactionIdListWhereClause(StringBuilder sql, List transactionIdList) { for (int i = 0; i < transactionIdList.size(); i++) { if (i > 0) { sql.append(","); } // Must cast to int to allow the integer based xmin index to be used correctly. sql.append((int) transactionIdList.get(i).longValue()); } } /** * Retrieves the changes that have were made by a set of transactions. * * @param predicates * Contains the predicates defining the transactions to be queried. * @return An iterator pointing at the identified records. */ public ReleasableIterator getHistory(ReplicationQueryPredicates predicates) { String selectedEntityTableName; StringBuilder sql; MapSqlParameterSource parameterSource; ReleasableIterator historyIterator; // PostgreSQL sometimes incorrectly chooses to perform full table scans, these options // prevent this. Note that this is not recommended practice according to documentation // but fixing this would require modifying the table statistics gathering // configuration on the production database to produce better plans. jdbcTemplate.execute( "set local enable_seqscan = false;" + "set local enable_mergejoin = false;" + "set local enable_hashjoin = false"); parameterSource = new MapSqlParameterSource(); selectedEntityTableName = "tmp_" + entityName + "s"; sql = new StringBuilder(); sql.append("CREATE TEMPORARY TABLE "); sql.append(selectedEntityTableName); sql.append(" ON COMMIT DROP"); sql.append(" AS SELECT "); sql.append(entityName); sql.append("_id, version FROM "); sql.append(entityName); sql.append("s WHERE (("); // Add the main transaction ranges to the where clause. buildTransactionRangeWhereClause(sql, parameterSource, predicates.getBottomTransactionId(), predicates .getTopTransactionId()); sql.append(")"); // If previously active transactions have become ready since the last invocation we include those as well. if (predicates.getReadyList().size() > 0) { sql.append(" OR xid_to_int4(xmin) IN ("); buildTransactionIdListWhereClause(sql, predicates.getReadyList()); sql.append(")"); } sql.append(")"); // Any active transactions must be explicitly excluded. if (predicates.getActiveList().size() > 0) { sql.append(" AND xid_to_int4(xmin) NOT IN ("); buildTransactionIdListWhereClause(sql, predicates.getActiveList()); sql.append(")"); } sql.append(" AND redaction_id IS NULL"); LOG.log(Level.FINER, "Entity identification query: " + sql); namedParamJdbcTemplate.update(sql.toString(), parameterSource); jdbcTemplate.update("ALTER TABLE ONLY " + selectedEntityTableName + " ADD CONSTRAINT pk_" + selectedEntityTableName + " PRIMARY KEY (" + entityName + "_id, version)"); jdbcTemplate.update("ANALYZE " + selectedEntityTableName); if (LOG.isLoggable(Level.FINER)) { LOG.log(Level.FINER, jdbcTemplate.queryForObject("SELECT Count(" + entityName + "_id) FROM " + selectedEntityTableName, Integer.class) + " " + entityName + " records located."); } // Extract the data and obtain an iterator for the results. historyIterator = getChangeHistory(selectedEntityTableName, new MapSqlParameterSource()); // The temp table is no longer required and can be deleted. jdbcTemplate.execute("DROP TABLE " + selectedEntityTableName); return historyIterator; } /** * Retrieves the changes that have were made between two points in time. * * @param intervalBegin * Marks the beginning (inclusive) of the time interval to be checked. * @param intervalEnd * Marks the end (exclusive) of the time interval to be checked. * @return An iterator pointing at the identified records. */ public ReleasableIterator getHistory(Date intervalBegin, Date intervalEnd) { String selectedEntityTableName; StringBuilder sql; MapSqlParameterSource parameterSource; ReleasableIterator historyIterator; // PostgreSQL sometimes incorrectly chooses to perform full table scans, these options // prevent this. Note that this is not recommended practice according to documentation // but fixing this would require modifying the table statistics gathering // configuration on the production database to produce better plans. jdbcTemplate.execute( "set local enable_seqscan = false;" + "set local enable_mergejoin = false;" + "set local enable_hashjoin = false"); selectedEntityTableName = "tmp_" + entityName + "s"; sql = new StringBuilder(); sql.append("CREATE TEMPORARY TABLE "); sql.append(selectedEntityTableName); sql.append(" ON COMMIT DROP"); sql.append(" AS SELECT "); sql.append(entityName); sql.append("_id, version FROM "); sql.append(entityName); sql.append("s WHERE timestamp > :intervalBegin AND timestamp <= :intervalEnd"); LOG.log(Level.FINER, "Entity identification query: " + sql); parameterSource = new MapSqlParameterSource(); parameterSource.addValue("intervalBegin", intervalBegin, Types.TIMESTAMP); parameterSource.addValue("intervalEnd", intervalEnd, Types.TIMESTAMP); namedParamJdbcTemplate.update(sql.toString(), parameterSource); jdbcTemplate.update("ANALYZE " + selectedEntityTableName); // Extract the data and obtain an iterator for the results. historyIterator = getChangeHistory(selectedEntityTableName, new MapSqlParameterSource()); // The temp table is no longer required and can be deleted. jdbcTemplate.execute("DROP TABLE " + selectedEntityTableName); return historyIterator; } /** * Retrieves all changes in the database. * * @return An iterator pointing at the identified records. */ public ReleasableIterator getHistory() { // Join the entity table to itself which will return all records. return getChangeHistory(entityName + "s", new MapSqlParameterSource()); } /** * Retrieves all current data in the database. * * @return An iterator pointing at the current records. */ public ReleasableIterator getCurrent() { // Join the entity table to the current version of itself which will return all current // records. return new EntityContainerReader( getEntityHistory("(SELECT id AS " + entityName + "_id, version FROM current_" + entityName + "s WHERE visible = TRUE)", new MapSqlParameterSource()), getContainerFactory()); } } EntityDataRowMapper.java000066400000000000000000000055161253404521400351420ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Date; import org.openstreetmap.osmosis.core.database.RowMapperListener; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.springframework.jdbc.core.RowCallbackHandler; /** * Maps entity result set rows into common entity data objects. */ public class EntityDataRowMapper implements RowCallbackHandler { private RowMapperListener listener; private boolean readAllUsers; /** * Creates a new instance. * * @param listener * The destination for result objects. * @param readAllUsers * If true, even anonymous users will be returned. Should be false in most cases. */ public EntityDataRowMapper(RowMapperListener listener, boolean readAllUsers) { this.listener = listener; this.readAllUsers = readAllUsers; } /** * Determines the appropriate user name to add to an entity based upon the user details * provided. * * @param dataPublic * The value of the public edit flag for the user. * @param userId * The unique id of the user. * @param userName * The display name of the user. * @return The appropriate user to add to the entity. */ private OsmUser readUserField(boolean dataPublic, int userId, String userName) { if (userId == OsmUser.NONE.getId()) { return OsmUser.NONE; } else if (dataPublic || readAllUsers) { String correctedUserName; if (userName == null) { correctedUserName = ""; } else { correctedUserName = userName; } return new OsmUser(userId, correctedUserName); } else { return OsmUser.NONE; } } /** * {@inheritDoc} */ @Override public void processRow(ResultSet resultSet) throws SQLException { long id; int version; Date timestamp; OsmUser user; long changesetId; CommonEntityData entityData; id = resultSet.getLong("id"); version = resultSet.getInt("version"); timestamp = new Date(resultSet.getTimestamp("timestamp").getTime()); user = readUserField(resultSet.getBoolean("data_public"), resultSet.getInt("user_id"), resultSet .getString("display_name")); changesetId = resultSet.getLong("changeset_id"); //node = new Node(id, version, timestamp, user, changesetId, latitude, longitude); entityData = new CommonEntityData(id, version, timestamp, user, changesetId); listener.process(entityData, resultSet); } } EntityHistory.java000066400000000000000000000035501253404521400340710ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import org.openstreetmap.osmosis.core.store.GenericObjectReader; import org.openstreetmap.osmosis.core.store.GenericObjectWriter; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; import org.openstreetmap.osmosis.core.store.Storeable; /** * A data class representing a history record. * * @author Brett Henderson * @param * The type of entity that this class stores history for. */ public class EntityHistory implements Storeable { private T entity; private boolean visible; /** * Creates a new instance. * * @param entity * The contained entity. * @param visible * The visible field. */ public EntityHistory(T entity, boolean visible) { this.entity = entity; this.visible = visible; } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers * within the store. */ @SuppressWarnings("unchecked") public EntityHistory(StoreReader sr, StoreClassRegister scr) { entity = (T) new GenericObjectReader(sr, scr).readObject(); visible = sr.readBoolean(); } /** * {@inheritDoc} */ public void store(StoreWriter sw, StoreClassRegister scr) { new GenericObjectWriter(sw, scr).writeObject(entity); sw.writeBoolean(visible); } /** * Gets the contained entity. * * @return The entity. */ public T getEntity() { return entity; } /** * Gets the visible flag. * * @return The visible flag. */ public boolean isVisible() { return visible; } } EntityHistoryComparator.java000066400000000000000000000016771253404521400361310ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.util.Comparator; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; /** * A comparator for sorting entity history objects by entity id then entity version. * * @param * The type of entity being sorted. */ public class EntityHistoryComparator implements Comparator> { /** * {@inheritDoc} */ @Override public int compare(EntityHistory o1, EntityHistory o2) { long idDelta; int versionDelta; idDelta = o1.getEntity().getId() - o2.getEntity().getId(); if (idDelta < 0) { return -1; } else if (idDelta > 0) { return 1; } versionDelta = o1.getEntity().getVersion() - o2.getEntity().getVersion(); if (versionDelta < 0) { return -1; } else if (versionDelta > 0) { return 1; } return 0; } } EntityHistoryListReader.java000066400000000000000000000050071253404521400360470ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.util.ArrayList; import java.util.List; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.store.PeekableIterator; /** * Reads a history stream and groups all changes for a single entity into lists. */ public class EntityHistoryListReader implements ReleasableIterator> { private PeekableIterator sourceIterator; /** * Creates a new instance. * * @param sourceIterator * An iterator containing full entity history ordered by type, identifier and * version. */ public EntityHistoryListReader(ReleasableIterator sourceIterator) { this.sourceIterator = new PeekableIterator(sourceIterator); } /** * {@inheritDoc} */ @Override public boolean hasNext() { return sourceIterator.hasNext(); } /** * {@inheritDoc} */ @Override public List next() { List changeList; Entity peekEntity; long currentId; EntityType currentEntityType; // Get the next change from the underlying stream. peekEntity = sourceIterator.peekNext().getEntityContainer().getEntity(); currentId = peekEntity.getId(); currentEntityType = peekEntity.getType(); // Loop until all history values for the current element are exhausted. changeList = new ArrayList(); while (sourceIterator.hasNext()) { ChangeContainer tmpChangeContainer = sourceIterator.peekNext(); // Break out of the loop when we reach the next entity in the stream. if (currentId != tmpChangeContainer.getEntityContainer().getEntity().getId() || !currentEntityType.equals(tmpChangeContainer.getEntityContainer().getEntity().getType())) { break; } // We want the value that we have already peeked from the iterator, so remove it from the iterator. sourceIterator.next(); // Add the change to the result list. changeList.add(tmpChangeContainer); } return changeList; } /** * {@inheritDoc} */ @Override public void remove() { throw new UnsupportedOperationException(); } /** * {@inheritDoc} */ @Override public void release() { sourceIterator.release(); } } EntityHistoryReader.java000066400000000000000000000067551253404521400352260ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.util.List; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.database.DbFeature; import org.openstreetmap.osmosis.core.database.DbFeatureHistory; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.lifecycle.ReleasableContainer; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; /** * Provides a single iterator based on data provided by underlying iterators from each of the * underlying entity and feature iterators. Each underlying iterator provides one component of the * overall entity. * * @param * The type of entity provided by this iterator. */ public class EntityHistoryReader implements ReleasableIterator> { private ReleasableContainer releasableContainer; private ReleasableIterator> entityIterator; private FeatureHistoryPopulator tagPopulator; private List> featurePopulators; private EntityHistory nextValue; /** * Creates a new instance. * * @param entityIterator * The entity source. * @param tagIterator * The tag source. * @param featurePopulators * Populators to add entity specific features to the generated entities. */ public EntityHistoryReader(ReleasableIterator> entityIterator, ReleasableIterator>> tagIterator, List> featurePopulators) { releasableContainer = new ReleasableContainer(); this.entityIterator = releasableContainer.add(entityIterator); tagPopulator = releasableContainer.add(new FeatureHistoryPopulator>(tagIterator, new TagCollectionLoader())); for (FeatureHistoryPopulator featurePopulator : featurePopulators) { releasableContainer.add(featurePopulator); } this.featurePopulators = featurePopulators; } /** * Consolidates the output of all history readers so that entities are fully * populated. * * @return An entity history record where the entity is fully populated. */ private EntityHistory readNextEntityHistory() { EntityHistory entityHistory; T entity; entityHistory = entityIterator.next(); entity = entityHistory.getEntity(); // Add all applicable tags to the entity. tagPopulator.populateFeatures(entity); // Add entity type specific features to the entity. for (FeatureHistoryPopulator populator : featurePopulators) { populator.populateFeatures(entity); } return entityHistory; } /** * {@inheritDoc} */ @Override public boolean hasNext() { while (nextValue == null && entityIterator.hasNext()) { nextValue = readNextEntityHistory(); } return (nextValue != null); } /** * {@inheritDoc} */ @Override public EntityHistory next() { EntityHistory result; if (!hasNext()) { throw new OsmosisRuntimeException("No records are available, call hasNext first."); } result = nextValue; nextValue = null; return result; } /** * {@inheritDoc} */ @Override public void remove() { throw new UnsupportedOperationException(); } /** * {@inheritDoc} */ @Override public void release() { releasableContainer.release(); } } EntityHistoryRowMapper.java000066400000000000000000000022131253404521400357210ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.sql.ResultSet; import java.sql.SQLException; import org.openstreetmap.osmosis.core.database.RowMapperListener; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; /** * Maps entity history result set rows into entity history objects. * * @param * The type of entity to be processed. */ public class EntityHistoryRowMapper implements RowMapperListener { private RowMapperListener> listener; /** * Creates a new instance. * * @param listener * The destination for result objects. */ public EntityHistoryRowMapper(RowMapperListener> listener) { this.listener = listener; } /** * {@inheritDoc} */ @Override public void process(T data, ResultSet resultSet) throws SQLException { boolean visible; EntityHistory entityHistory; visible = resultSet.getBoolean("visible"); entityHistory = new EntityHistory(data, visible); listener.process(entityHistory, resultSet); } } EntitySnapshotReader.java000066400000000000000000000060201253404521400353450ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.util.Date; import java.util.List; import java.util.NoSuchElementException; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.store.PeekableIterator; import org.openstreetmap.osmosis.core.task.common.ChangeAction; /** * Produces a snapshot at a point in time from a complete history stream. * * @author Brett Henderson */ public class EntitySnapshotReader implements ReleasableIterator { private PeekableIterator> sourceIterator; private Date snapshotInstant; private EntityContainer nextValue; private boolean nextValueLoaded; /** * Creates a new instance. * * @param sourceIterator * An iterator containing the full history for entities. * @param snapshotInstant * The state of the entity at this point in time will be dumped. * This ensures a consistent snapshot. */ public EntitySnapshotReader( ReleasableIterator sourceIterator, Date snapshotInstant) { this.sourceIterator = new PeekableIterator>(new EntityHistoryListReader(sourceIterator)); this.snapshotInstant = snapshotInstant; nextValueLoaded = false; } /** * {@inheritDoc} */ public boolean hasNext() { while (!nextValueLoaded && sourceIterator.hasNext()) { List changeList; ChangeContainer changeContainer; // Get the next change list from the underlying stream. changeList = sourceIterator.next(); // Loop until all history values for the current element are exhausted and get the // latest version of the entity that fits within the snapshot timestamp. changeContainer = null; for (ChangeContainer tmpChangeContainer : changeList) { // We're only interested in elements prior or equal to the snapshot point. if (tmpChangeContainer.getEntityContainer().getEntity() .getTimestamp().compareTo(snapshotInstant) <= 0) { // Replace the current change container with the later version. changeContainer = tmpChangeContainer; } } // We are not interested in items created after the snapshot timestamp (ie. null) or deleted items. if (changeContainer != null && !ChangeAction.Delete.equals(changeContainer.getAction())) { nextValue = changeContainer.getEntityContainer(); nextValueLoaded = true; } } return nextValueLoaded; } /** * {@inheritDoc} */ public EntityContainer next() { if (!hasNext()) { throw new NoSuchElementException(); } nextValueLoaded = false; return nextValue; } /** * {@inheritDoc} */ public void remove() { throw new UnsupportedOperationException(); } /** * {@inheritDoc} */ public void release() { sourceIterator.release(); } } FeatureHistoryPopulator.java000066400000000000000000000042361253404521400361200ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import org.openstreetmap.osmosis.core.database.DbFeature; import org.openstreetmap.osmosis.core.database.DbFeatureHistory; import org.openstreetmap.osmosis.core.database.FeatureCollectionLoader; import org.openstreetmap.osmosis.core.database.FeaturePopulator; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.store.PeekableIterator; import org.openstreetmap.osmosis.core.store.Storeable; /** * Populates entities with their features using a sorted data source. * * @param * The type of entity to be populated. * @param * The type of feature to be added. * @param * The database feature class type. This is extensible to allow other attributes to be * added to features such as a sequence number. */ public class FeatureHistoryPopulator> implements FeaturePopulator { private PeekableIterator> source; private FeatureCollectionLoader featureLoader; /** * Creates a new instance. * * @param source * The feature source. * @param featureLoader * Provides access to the feature collection within the entity. */ public FeatureHistoryPopulator(ReleasableIterator> source, FeatureCollectionLoader featureLoader) { this.source = new PeekableIterator>(source); this.featureLoader = featureLoader; } /** * {@inheritDoc} */ @Override public void populateFeatures(Te entity) { // Add all applicable tags to the entity. while (source.hasNext() && source.peekNext().getFeature().getEntityId() == entity.getId() && source.peekNext().getVersion() == entity.getVersion()) { featureLoader.getFeatureCollection(entity).add(source.next().getFeature().getFeature()); } } /** * {@inheritDoc} */ @Override public void release() { source.release(); } } MemberTypeParser.java000066400000000000000000000023121253404521400344540ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; /** * Parses the database representation of a relation member type into an entity * type object. * * @author Brett Henderson */ public class MemberTypeParser { private static final Map MEMBER_TYPE_MAP = new HashMap(); static { MEMBER_TYPE_MAP.put("Node", EntityType.Node); MEMBER_TYPE_MAP.put("Way", EntityType.Way); MEMBER_TYPE_MAP.put("Relation", EntityType.Relation); } /** * Parses the database representation of a relation member type into an * entity type object. * * @param memberType * The database value of member type. * @return A strongly typed entity type. */ public EntityType parse(String memberType) { if (MEMBER_TYPE_MAP.containsKey(memberType)) { return MEMBER_TYPE_MAP.get(memberType); } else { throw new OsmosisRuntimeException("The member type " + memberType + " is not recognised."); } } } MemberTypeRenderer.java000066400000000000000000000021561253404521400347740ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; /** * Renders a member type object into its database representation. * * @author Brett Henderson */ public class MemberTypeRenderer { private static final Map MEMBER_TYPE_MAP = new HashMap(); static { MEMBER_TYPE_MAP.put(EntityType.Node, "Node"); MEMBER_TYPE_MAP.put(EntityType.Way, "Way"); MEMBER_TYPE_MAP.put(EntityType.Relation, "Relation"); } /** * Renders a member type into its xml representation. * * @param memberType * The member type. * @return A rendered member type. */ public String render(EntityType memberType) { if (MEMBER_TYPE_MAP.containsKey(memberType)) { return MEMBER_TYPE_MAP.get(memberType); } else { throw new OsmosisRuntimeException("The member type " + memberType + " is not recognised."); } } } osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl/NodeDao.java000066400000000000000000000033401253404521400326200ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.util.Collections; import java.util.List; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainerFactory; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainerFactory; import org.openstreetmap.osmosis.core.database.RowMapperListener; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; /** * Provides access to nodes in the database. */ public class NodeDao extends EntityDao { private static final String[] TYPE_SPECIFIC_FIELD_NAMES = new String[] {"latitude", "longitude"}; /** * Creates a new instance. * * @param jdbcTemplate * Used to access the database. */ public NodeDao(JdbcTemplate jdbcTemplate) { super(jdbcTemplate, "node"); } /** * {@inheritDoc} */ @Override protected RowMapperListener getEntityRowMapper(RowMapperListener entityListener) { return new NodeRowMapper(entityListener); } /** * {@inheritDoc} */ @Override protected String[] getTypeSpecificFieldNames() { return TYPE_SPECIFIC_FIELD_NAMES; } /** * {@inheritDoc} */ @Override protected EntityContainerFactory getContainerFactory() { return new NodeContainerFactory(); } /** * {@inheritDoc} */ @Override protected List> getFeatureHistoryPopulators( String selectedEntityTableName, MapSqlParameterSource parameterSource) { return Collections.emptyList(); } } NodeRowMapper.java000066400000000000000000000024721253404521400337570ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.sql.ResultSet; import java.sql.SQLException; import org.openstreetmap.osmosis.core.database.RowMapperListener; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.util.FixedPrecisionCoordinateConvertor; /** * Maps node result set rows into node objects. */ public class NodeRowMapper implements RowMapperListener { private RowMapperListener listener; /** * Creates a new instance. * * @param listener * The destination for result objects. */ public NodeRowMapper(RowMapperListener listener) { this.listener = listener; } /** * {@inheritDoc} */ @Override public void process(CommonEntityData data, ResultSet resultSet) throws SQLException { double latitude; double longitude; Node node; latitude = FixedPrecisionCoordinateConvertor.convertToDouble(resultSet.getInt("latitude")); longitude = FixedPrecisionCoordinateConvertor.convertToDouble(resultSet.getInt("longitude")); node = new Node(data, latitude, longitude); listener.process(node, resultSet); } } RelationDao.java000066400000000000000000000144301253404521400334330ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainerFactory; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainerFactory; import org.openstreetmap.osmosis.core.database.DbFeatureHistory; import org.openstreetmap.osmosis.core.database.DbFeatureHistoryRowMapper; import org.openstreetmap.osmosis.core.database.DbFeatureRowMapper; import org.openstreetmap.osmosis.core.database.DbOrderedFeature; import org.openstreetmap.osmosis.core.database.DbOrderedFeatureHistoryComparator; import org.openstreetmap.osmosis.core.database.DbOrderedFeatureRowMapper; import org.openstreetmap.osmosis.core.database.RelationMemberCollectionLoader; import org.openstreetmap.osmosis.core.database.RowMapperListener; import org.openstreetmap.osmosis.core.database.SortingStoreRowMapperListener; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.sort.common.FileBasedSort; import org.openstreetmap.osmosis.core.store.SingleClassObjectSerializationFactory; import org.openstreetmap.osmosis.core.store.StoreReleasingIterator; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.SqlParameterSource; /** * Provides access to relations in the database. */ public class RelationDao extends EntityDao { private static final Logger LOG = Logger.getLogger(RelationDao.class.getName()); private static final String[] TYPE_SPECIFIC_FIELD_NAMES = new String[] {}; /** * Creates a new instance. * * @param jdbcTemplate * Used to access the database. */ public RelationDao(JdbcTemplate jdbcTemplate) { super(jdbcTemplate, "relation"); } /** * {@inheritDoc} */ @Override protected RowMapperListener getEntityRowMapper(RowMapperListener entityListener) { return new RelationRowMapper(entityListener); } /** * {@inheritDoc} */ @Override protected String[] getTypeSpecificFieldNames() { return TYPE_SPECIFIC_FIELD_NAMES; } /** * {@inheritDoc} */ @Override protected EntityContainerFactory getContainerFactory() { return new RelationContainerFactory(); } private ReleasableIterator>> getRelationMemberHistory( String selectedEntityStatement, SqlParameterSource parameterSource) { FileBasedSort>> sortingStore = new FileBasedSort>>( new SingleClassObjectSerializationFactory(DbFeatureHistory.class), new DbOrderedFeatureHistoryComparator(), true); try { String sql; SortingStoreRowMapperListener>> storeListener; DbFeatureHistoryRowMapper> dbFeatureHistoryRowMapper; DbFeatureRowMapper dbFeatureRowMapper; DbOrderedFeatureRowMapper dbOrderedFeatureRowMapper; RelationMemberRowMapper relationNodeRowMapper; ReleasableIterator>> resultIterator; sql = "SELECT rm.relation_id AS id, rm.member_id, rm.member_role, rm.member_type, rm.version, rm.sequence_id" + " FROM " + "relation_members rm" + " INNER JOIN " + selectedEntityStatement + " t ON rm.relation_id = t.relation_id AND rm.version = t.version"; LOG.log(Level.FINER, "Relation member history query: " + sql); // Sends all received data into the object store. storeListener = new SortingStoreRowMapperListener>>(sortingStore); // Retrieves the version information associated with the feature. dbFeatureHistoryRowMapper = new DbFeatureHistoryRowMapper>(storeListener); // Retrieves the sequence number associated with the feature. dbOrderedFeatureRowMapper = new DbOrderedFeatureRowMapper(dbFeatureHistoryRowMapper); // Retrieves the entity information associated with the feature. dbFeatureRowMapper = new DbFeatureRowMapper(dbOrderedFeatureRowMapper); // Retrieves the basic feature information. relationNodeRowMapper = new RelationMemberRowMapper(dbFeatureRowMapper); // Perform the query passing the row mapper chain to process rows in a streamy fashion. getNamedParamJdbcTemplate().query(sql, parameterSource, relationNodeRowMapper); // Open a iterator on the store that will release the store upon completion. resultIterator = new StoreReleasingIterator>>( sortingStore.iterate(), sortingStore); // The store itself shouldn't be released now that it has been attached to the iterator. sortingStore = null; return resultIterator; } finally { if (sortingStore != null) { sortingStore.release(); } } } /** * {@inheritDoc} */ @Override protected List> getFeatureHistoryPopulators( String selectedEntityTableName, MapSqlParameterSource parameterSource) { ReleasableIterator>> relationNodeIterator; List> featurePopulators; featurePopulators = new ArrayList>(); // Get the relation nodes for the selected entities. relationNodeIterator = getRelationMemberHistory(selectedEntityTableName, parameterSource); // Wrap the relation node source into a feature history populator that can attach them to their // owning relations. featurePopulators.add( new FeatureHistoryPopulator>( relationNodeIterator, new RelationMemberCollectionLoader())); return featurePopulators; } } RelationMemberRowMapper.java000066400000000000000000000027511253404521400357770ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.sql.ResultSet; import java.sql.SQLException; import org.openstreetmap.osmosis.core.database.RowMapperListener; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.springframework.jdbc.core.RowCallbackHandler; /** * Maps relation member result set rows into relation member objects. */ public class RelationMemberRowMapper implements RowCallbackHandler { private RowMapperListener listener; private MemberTypeParser memberTypeParser; /** * Creates a new instance. * * @param listener * The destination for result objects. */ public RelationMemberRowMapper(RowMapperListener listener) { this.listener = listener; memberTypeParser = new MemberTypeParser(); } /** * {@inheritDoc} */ @Override public void processRow(ResultSet resultSet) throws SQLException { long memberId; EntityType memberType; String memberRole; RelationMember relationMember; memberId = resultSet.getLong("member_id"); memberType = memberTypeParser.parse(resultSet.getString("member_type")); memberRole = resultSet.getString("member_role"); relationMember = new RelationMember(memberId, memberType, memberRole); listener.process(relationMember, resultSet); } } RelationRowMapper.java000066400000000000000000000020311253404521400346360ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.sql.ResultSet; import java.sql.SQLException; import org.openstreetmap.osmosis.core.database.RowMapperListener; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; /** * Maps relation result set rows into relation objects. */ public class RelationRowMapper implements RowMapperListener { private RowMapperListener listener; /** * Creates a new instance. * * @param listener * The destination for result objects. */ public RelationRowMapper(RowMapperListener listener) { this.listener = listener; } /** * {@inheritDoc} */ @Override public void process(CommonEntityData data, ResultSet resultSet) throws SQLException { Relation relation; relation = new Relation(data); listener.process(relation, resultSet); } } ReplicationQueryPredicates.java000066400000000000000000000037141253404521400365400ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.util.ArrayList; import java.util.List; /** * Contains the parameters required to perform a single replication from the database. */ public class ReplicationQueryPredicates { private long bottomTransactionId; private long topTransactionId; private List readyList; private List activeList; /** * Creates a new instance. * * @param bottomTransactionId * The transaction id to begin querying from. This will be included in the query. * @param topTransactionId * The transaction id to stop querying at. This will not be included in the query. */ public ReplicationQueryPredicates(long bottomTransactionId, long topTransactionId) { this.bottomTransactionId = bottomTransactionId; this.topTransactionId = topTransactionId; readyList = new ArrayList(); activeList = new ArrayList(); } /** * Gets the transaction id to begin querying from. This will be included in the query. * * @return The transaction id. */ public long getBottomTransactionId() { return bottomTransactionId; } /** * Gets the transaction id to stop querying at. This will not be included in the query. * * @return The transaction id. */ public long getTopTransactionId() { return topTransactionId; } /** * Gets the transaction ready list. These will be included in the query in addition to those the ids * in the range defined by the bottom and top transaction id. * * @return The transaction id list. */ public List getReadyList() { return readyList; } /** * Gets the transaction active list. These will be excluded from the query results due to them * being active transactions at the point when the snapshot was taken. * * @return The transaction id list. */ public List getActiveList() { return activeList; } } ReplicationSource.java000066400000000000000000000013301253404521400346570ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; /** * Provides {@link Replicator} with change streams that it consumes. */ public interface ReplicationSource { /** * Retrieves the changes that have were made by a set of transactions. * * @param predicates * Contains the predicates defining the transactions to be queried. * @return An iterator pointing at the identified records. */ ReleasableIterator getHistory(ReplicationQueryPredicates predicates); } ReplicationState.java000066400000000000000000000127731253404521400345140ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.StringTokenizer; /** * Contains the state to be remembered between replication invocations. This state ensures that no * data is missed during replication, and none is repeated. */ public class ReplicationState extends org.openstreetmap.osmosis.replication.common.ReplicationState { private long txnMax; private long txnMaxQueried; private List txnActive; private List txnReady; /** * Creates a new instance with all values set to defaults. */ public ReplicationState() { super(); this.txnMax = 0; this.txnMaxQueried = 0; this.txnActive = new ArrayList(); this.txnReady = new ArrayList(); } /** * Creates a new instance. * * @param txnMax * The maximum transaction id in the database. * @param txnMaxQueried * The maximum transaction id currently replicated from the database. * @param txnActive * The currently active transaction ids. * @param txnReady * The previously active transaction ids that can now be queried. * @param timestamp * The maximum timestamp of data currently read from the database. * @param sequenceNumber * The replication sequence number. */ public ReplicationState(long txnMax, long txnMaxQueried, List txnActive, List txnReady, Date timestamp, long sequenceNumber) { super(timestamp, sequenceNumber); this.txnMax = txnMax; this.txnMaxQueried = txnMaxQueried; this.txnActive = new ArrayList(txnActive); this.txnReady = new ArrayList(txnReady); } /** * Creates a new instance. * * @param properties * The properties to load state from. */ public ReplicationState(Map properties) { load(properties); } /** * Loads all state from the provided properties object. * * @param properties * The properties to be read. */ public void load(Map properties) { super.load(properties); txnMax = Long.parseLong(properties.get("txnMax")); txnMaxQueried = Long.parseLong(properties.get("txnMaxQueried")); txnActive = fromString(properties.get("txnActiveList")); txnReady = fromString(properties.get("txnReadyList")); } @Override public void store(Map properties) { super.store(properties); properties.put("txnMax", Long.toString(txnMax)); properties.put("txnMaxQueried", Long.toString(txnMaxQueried)); properties.put("txnActiveList", toString(txnActive)); properties.put("txnReadyList", toString(txnReady)); } @Override public Map store() { Map properties = new HashMap(); store(properties); return properties; } private String toString(List values) { StringBuilder buffer; buffer = new StringBuilder(); for (long value : values) { if (buffer.length() > 0) { buffer.append(','); } buffer.append(value); } return buffer.toString(); } private List fromString(String values) { StringTokenizer tokens; List result; tokens = new StringTokenizer(values, ","); result = new ArrayList(); while (tokens.hasMoreTokens()) { result.add(Long.parseLong(tokens.nextToken())); } return result; } /** * Gets the maximum transaction id in the database. * * @return The transaction id. */ public long getTxnMax() { return txnMax; } /** * Sets the maximum transaction id in the database. * * @param txnMax * The transaction id. */ public void setTxnMax(long txnMax) { this.txnMax = txnMax; } /** * Gets the maximum transaction id currently replicated from the database. * * @return The transaction id. */ public long getTxnMaxQueried() { return txnMaxQueried; } /** * Sets the maximum transaction id currently replicated from the database. * * @param txnMaxQueried * The transaction id. */ public void setTxnMaxQueried(long txnMaxQueried) { this.txnMaxQueried = txnMaxQueried; } /** * Gets the currently active transaction ids. These cannot be replicated until they have * committed. * * @return The list of transaction ids. */ public List getTxnActive() { return txnActive; } /** * Gets the previously active transaction ids that can now be queried. * * @return The list of transaction ids. */ public List getTxnReady() { return txnReady; } /** * {@inheritDoc} */ @Override public boolean equals(Object obj) { boolean result; if (obj instanceof ReplicationState) { ReplicationState compareState = (ReplicationState) obj; if (super.equals(obj) && txnMax == compareState.txnMax && txnMaxQueried == compareState.txnMaxQueried && txnActive.equals(compareState.txnActive) && txnReady.equals(compareState.txnReady)) { result = true; } else { result = false; } } else { result = false; } return result; } @Override public int hashCode() { return super.hashCode() + (int) txnMax + (int) txnMaxQueried; } @Override public String toString() { return "ReplicationState(txnMax=" + txnMax + ", txnMaxQueried=" + txnMaxQueried + ", txnActive=" + txnActive + ", txnReady=" + txnReady + ", timestamp=" + getTimestamp() + ", sequenceNumber=" + getSequenceNumber() + ")"; } } osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl/Replicator.java000066400000000000000000000321031253404521400334120ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; /** * Replicates changes from the database utilising transaction snapshots. */ public class Replicator { private static final Logger LOG = Logger.getLogger(Replicator.class.getName()); /** * The number of special transactions beginning from 0. */ private static final int SPECIAL_TRANSACTION_OFFSET = 3; /** * This is the maximum number of transaction ids sent in a single query. If * larger than 2 power 16 it fails due to a 16 bit number failing, but still * fails below that with a stack limit being exceeded. The current value is * near to the maximum value known to work, it will work slightly higher but * this is a round number. It is dependent on the max_stack_depth parameter * defined in postgresql.conf. */ private static final int TRANSACTION_QUERY_SIZE_MAX = 25000; private ChangeSink changeSink; private ReplicationSource source; private TransactionManager txnManager; private SystemTimeLoader systemTimeLoader; private int iterations; private int minInterval; private int maxInterval; /** * Creates a new instance. * * @param source * The source for all replication changes. * @param changeSink * The destination for all replicated changes. * @param snapshotLoader * Loads transaction snapshots from the database. * @param systemTimeLoader * Loads the current system time from the database. * @param iterations * The number of replication intervals to execute. 0 means * infinite. * @param minInterval * The minimum number of milliseconds between intervals. * @param maxInterval * The maximum number of milliseconds between intervals if no new * data is available. This isn't a hard limit because processing * latency may increase the duration. */ public Replicator(ReplicationSource source, ChangeSink changeSink, TransactionManager snapshotLoader, SystemTimeLoader systemTimeLoader, int iterations, int minInterval, int maxInterval) { this.source = source; this.changeSink = changeSink; this.txnManager = snapshotLoader; this.systemTimeLoader = systemTimeLoader; this.iterations = iterations; this.minInterval = minInterval; this.maxInterval = maxInterval; } /** * Obtains a new transaction shapshot from the database and updates the * state to match. * * @param state * The replication state. */ private void obtainNewSnapshot(ReplicationState state) { TransactionSnapshot transactionSnapshot; // Obtain the latest transaction snapshot from the database. transactionSnapshot = txnManager.getTransactionSnapshot(); // Update the xmax value. state.setTxnMax(transactionSnapshot.getXMax()); // Any items in the old active transaction list but not in the new // active transaction list must be added to the ready list. for (Iterator i = state.getTxnActive().iterator(); i.hasNext();) { Long id; id = i.next(); if (!transactionSnapshot.getXIpList().contains(id)) { // They only need to be added if the maximum queried xmax has // been passed. if (compareTxnIds(id, state.getTxnMaxQueried()) < 0) { state.getTxnReady().add(id); } } } // The active transaction list must be updated to match the latest // snapshot. state.getTxnActive().clear(); state.getTxnActive().addAll(transactionSnapshot.getXIpList()); if (LOG.isLoggable(Level.FINER)) { LOG.finer("Updated replication state with new snapshot, maxTxnQueried=" + state.getTxnMaxQueried() + ", maxTxn=" + state.getTxnMax() + ", txnActiveList=" + state.getTxnActive() + ", txnReadyList=" + state.getTxnReady() + "."); } } /** * This performs a comparison of the two transaction ids using 32-bit * arithmetic. The result is (id1 - id2), but with both numbers cast to an * integer prior to the comparison. This provides a correct result even in * the case where the transaction id has wrapped around to 0. * * @param id1 * The first transaction id. * @param id2 * The second transaction id. * @return The difference between the two transaction ids (id1 - id2). */ private int compareTxnIds(long id1, long id2) { return ((int) id1) - ((int) id2); } /** * This adds an offset to the transaction id. It takes into account the * special values 0-2 and adds an extra 3 to the offset accordingly. * * @param id * The transaction id. * @param increment * The amount to increment the id. * @return The result transaction id. */ private long incrementTxnId(long id, int increment) { int oldId; int newId; oldId = (int) id; newId = oldId + increment; if (oldId < 0 && newId >= 0) { newId += SPECIAL_TRANSACTION_OFFSET; } return newId; } private ReplicationQueryPredicates buildQueryPredicates(ReplicationState state) { long topTransactionId; int rangeLength; ReplicationQueryPredicates predicates; // The top transaction id of the next query is the current xMax up to a // maximum of // TRANSACTION_QUERY_SIZE_MAX transactions. topTransactionId = state.getTxnMax(); rangeLength = compareTxnIds(topTransactionId, state.getTxnMaxQueried()); if (rangeLength > TRANSACTION_QUERY_SIZE_MAX) { topTransactionId = incrementTxnId(state.getTxnMaxQueried(), TRANSACTION_QUERY_SIZE_MAX); } // Build the predicate object with the new range. predicates = new ReplicationQueryPredicates(state.getTxnMaxQueried(), topTransactionId); // Update the state with the new queried marker. state.setTxnMaxQueried(topTransactionId); // Copy the active transaction list into the predicate. predicates.getActiveList().addAll(state.getTxnActive()); // The state object will only contain ready ids for transaction ranges // that have passed already so we must add all of them to the predicate // so they get included in this query. predicates.getReadyList().addAll(state.getTxnReady()); // The ready list can be cleared on the state object now. state.getTxnReady().clear(); if (LOG.isLoggable(Level.FINER)) { LOG.finer("Query predicates updated, bottomXid=" + predicates.getBottomTransactionId() + ", topXid=" + predicates.getTopTransactionId() + ", activeXidList=" + predicates.getActiveList() + ", readyXidList=" + predicates.getReadyList() + "."); } return predicates; } private void copyChanges(ReleasableIterator sourceIterator, ReplicationState state) { try { Date currentTimestamp; // As we process, we must update the timestamp to match the latest // record we have received. currentTimestamp = state.getTimestamp(); while (sourceIterator.hasNext()) { ChangeContainer change; Date nextTimestamp; change = sourceIterator.next(); nextTimestamp = change.getEntityContainer().getEntity().getTimestamp(); if (currentTimestamp.compareTo(nextTimestamp) < 0) { currentTimestamp = nextTimestamp; } changeSink.process(change); } state.setTimestamp(currentTimestamp); } finally { sourceIterator.release(); } } /** * Replicates the next set of changes from the database. */ public void replicate() { try { replicateLoop(); } finally { changeSink.release(); } } /** * The main replication loop. This continues until the maximum number of * replication intervals has been reached. */ private void replicateLoop() { // Perform replication up to the number of iterations, or infinitely if // set to 0. for (int iterationCount = 1; true; iterationCount++) { // Perform the replication interval. txnManager.executeWithinTransaction(new Runnable() { @Override public void run() { replicateImpl(); } }); // Stop if we've reached the target number of iterations. if (iterations > 0 && iterationCount >= iterations) { LOG.fine("Exiting replication loop."); break; } } } /** * Replicates the next set of changes from the database. */ private void replicateImpl() { ReplicationState state; ReplicationQueryPredicates predicates; Date systemTimestamp; Map metaData; // Create an initial replication state. state = new ReplicationState(); // Initialise the sink and provide it with a reference to the state // object. A single state instance is shared by both ends of the // pipeline. metaData = new HashMap(1); metaData.put(ReplicationState.META_DATA_KEY, state); changeSink.initialize(metaData); // Wait until the minimum delay interval has been reached. while (true) { /* * Determine the time of processing. Note that we must do this after * obtaining the database transaction snapshot. A key rule in * replication is that the timestamp we specify in our replication state * is always equal to or later than all data timestamps. This allows * consumers to know that when they pick a timestamp to start * replicating from that *all* data created after that timestamp will be * included in subsequent replications. */ systemTimestamp = systemTimeLoader.getSystemTime(); if (LOG.isLoggable(Level.FINER)) { LOG.finer("Loaded system time " + systemTimestamp + " from the database."); } // Continue onto next step if we've reached the minimum interval or // if our remaining interval exceeds the maximum (clock skew). long remainingInterval = state.getTimestamp().getTime() + minInterval - systemTimestamp.getTime(); if (remainingInterval <= 0 || remainingInterval > minInterval) { break; } else { try { Thread.sleep(remainingInterval); } catch (InterruptedException e) { throw new OsmosisRuntimeException("Unable to sleep until next replication iteration.", e); } } } // Wait until either data becomes available or the maximum interval is reached. while (true) { // Update our view of the current database transaction state. obtainNewSnapshot(state); // Continue onto next step if data is available. if (state.getTxnMaxQueried() != state.getTxnMax() || state.getTxnReady().size() > 0) { break; } systemTimestamp = systemTimeLoader.getSystemTime(); if (LOG.isLoggable(Level.FINER)) { LOG.finer("Loaded system time " + systemTimestamp + " from the database."); } // Continue onto next step if we've reached the maximum interval or // if our remaining interval exceeds the maximum (clock skew). long remainingInterval = state.getTimestamp().getTime() + maxInterval - systemTimestamp.getTime(); if (remainingInterval <= 0 || remainingInterval > maxInterval) { break; } else { long sleepInterval = remainingInterval; if (sleepInterval > minInterval) { sleepInterval = minInterval; } try { Thread.sleep(sleepInterval); } catch (InterruptedException e) { throw new OsmosisRuntimeException("Unable to sleep until data becomes available.", e); } } } LOG.fine("Processing replication sequence."); /* * We must get the latest timestamp before proceeding. Using an earlier * timestamp runs the risk of marking a replication sequence with a * timestamp that is too early which may lead to replication clients * starting with a later sequence than they should. */ systemTimestamp = systemTimeLoader.getSystemTime(); if (LOG.isLoggable(Level.FINER)) { LOG.finer("Loaded system time " + systemTimestamp + " from the database."); } // If this is the first interval we are setting an initial state but not // performing any replication. if (state.getSequenceNumber() == 0) { // We are starting from the current point so we are at the current // database timestamp and transaction id. state.setTimestamp(systemTimestamp); state.setTxnMaxQueried(state.getTxnMax()); } else { // Obtain the predicates to use during the query. predicates = buildQueryPredicates(state); // Write the changes to the destination. if (predicates.getBottomTransactionId() != predicates.getTopTransactionId()) { copyChanges(source.getHistory(predicates), state); } /* * If we have completely caught up to the database, we update the * timestamp to the database system timestamp. Otherwise we leave * the timestamp set at the value determined while processing * changes. We update to the system timestamp when caught up to * ensure that a current timestamp is provided to consumers in the * case where no data has been created. */ if (compareTxnIds(state.getTxnMaxQueried(), state.getTxnMax()) >= 0) { state.setTimestamp(systemTimestamp); } } // Commit changes. changeSink.complete(); LOG.fine("Replication sequence complete."); } } SchemaVersionValidator.java000066400000000000000000000121731253404521400356500ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.apidb.common.DatabaseContext; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; /** * Reads the version number stored in the schema_info table and verifies that it matches the * expected version. * * @author Brett Henderson */ public class SchemaVersionValidator { private static Logger log = Logger.getLogger(SchemaVersionValidator.class.getName()); private static final String SELECT_SQL = "SELECT version FROM schema_migrations"; private final DatabasePreferences preferences; private final DatabaseContext dbCtx; private boolean validated; /** * Creates a new instance. * * @param loginCredentials Contains all information required to connect to the database. * @param preferences The database preferences. */ public SchemaVersionValidator(DatabaseLoginCredentials loginCredentials, DatabasePreferences preferences) { this.preferences = preferences; dbCtx = new DatabaseContext(loginCredentials); } /** * Validates that the schema migrations match the expected list of migrations. This method * caches the result allowing it to be called multiple times without a performance penalty. * * @param expectedMigrations The expected schema migrations. */ public void validateVersion(String[] expectedMigrations) { if (!validated) { validateDBVersion(expectedMigrations); validated = true; } } /** * Performs the database lookup and validates the expected version. * * @param expectedMigrations The expected schema migrations. */ private void validateDBVersion(String[] expectedMigrations) { if (preferences.getValidateSchemaVersion()) { try { ResultSet resultSet; Set actualMigrationSet; Set expectedMigrationSet; List matchingMigrations; // Load the expected migrations into a Set. expectedMigrationSet = new HashSet(); for (String expectedMigration : expectedMigrations) { expectedMigrationSet.add(expectedMigration); } // Load the database migrations into a Set. actualMigrationSet = new HashSet(); resultSet = dbCtx.executeQuery(SELECT_SQL); while (resultSet.next()) { actualMigrationSet.add(resultSet.getString("version")); } resultSet.close(); // Remove items from both sets that are identical. matchingMigrations = new ArrayList(); for (String migration : expectedMigrationSet) { if (actualMigrationSet.contains(migration)) { matchingMigrations.add(migration); } } for (String migration : matchingMigrations) { expectedMigrationSet.remove(migration); actualMigrationSet.remove(migration); } // If either Set contains elements, we have a schema version mismatch. if (expectedMigrationSet.size() > 0 || actualMigrationSet.size() > 0) { StringBuilder errorMessage; errorMessage = new StringBuilder(); errorMessage.append("Database version mismatch."); if (expectedMigrationSet.size() > 0) { errorMessage.append(" The schema is missing migrations " + expectedMigrationSet + ", may need to upgrade schema or specify validateSchemaVersion=no."); } if (actualMigrationSet.size() > 0) { errorMessage.append(" The schema contains unexpected migrations " + actualMigrationSet + ", may need to upgrade osmosis or specify validateSchemaVersion=no."); } if (preferences.getAllowIncorrectSchemaVersion()) { log.warning(errorMessage.toString()); } else { throw new OsmosisRuntimeException(errorMessage.toString()); } } } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to read the schema version from the schema info table.", e); } finally { cleanup(); } } } /** * Releases all resources allocated during execution. */ private void cleanup() { dbCtx.release(); } } SystemTimeLoader.java000066400000000000000000000007411253404521400344640ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.util.Date; /** * Provides {@link Replicator} with access to the system time on the database server. This avoids * relying on the clock of this system which may be different. */ public interface SystemTimeLoader { /** * Gets the system time of the database server. * * @return The timestamp. */ Date getSystemTime(); } TagCollectionLoader.java000066400000000000000000000012321253404521400351040ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.util.Collection; import org.openstreetmap.osmosis.core.database.FeatureCollectionLoader; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; /** * Loads tags from entities. * * @param * The type of entity. */ public class TagCollectionLoader implements FeatureCollectionLoader { /** * {@inheritDoc} */ @Override public Collection getFeatureCollection(T entity) { return entity.getTags(); } } TagRowMapper.java000066400000000000000000000020471253404521400336030ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.sql.ResultSet; import java.sql.SQLException; import org.openstreetmap.osmosis.core.database.RowMapperListener; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.springframework.jdbc.core.RowCallbackHandler; /** * Maps tag result set rows into tag objects. */ public class TagRowMapper implements RowCallbackHandler { private RowMapperListener listener; /** * Creates a new instance. * * @param listener * The destination for result objects. */ public TagRowMapper(RowMapperListener listener) { this.listener = listener; } /** * {@inheritDoc} */ @Override public void processRow(ResultSet resultSet) throws SQLException { String key; String value; Tag tag; key = resultSet.getString("k"); value = resultSet.getString("v"); tag = new Tag(key, value); listener.process(tag, resultSet); } } osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl/TimeDao.java000066400000000000000000000017441253404521400326370ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.util.Date; import org.springframework.jdbc.core.JdbcTemplate; /** * A DAO providing access to the system time on the database server. This avoids relying on the * clock of this system which may be different. */ public class TimeDao implements SystemTimeLoader { private JdbcTemplate jdbcTemplate; /** * Creates a new instance. * * @param jdbcTemplate * Used to access the database. */ public TimeDao(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } /** * Gets the system time of the database server. * * @return The timestamp. */ public Date getSystemTime() { // The timeofday function is the only one that returns wall clock time. // Others return the time of the start of the transaction. return jdbcTemplate.queryForObject("SELECT clock_timestamp()", Date.class); } } TransactionDao.java000066400000000000000000000034571253404521400341520ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.apidb.common.DatabaseContext2; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallbackWithoutResult; /** * Reads active transaction ids from the database allowing up-to-current queries to be performed * when extracting changesets from the history tables. */ public class TransactionDao implements TransactionManager { private static final Logger LOG = Logger.getLogger(TransactionDao.class.getName()); private DatabaseContext2 dbCtx; private JdbcTemplate jdbcTemplate; /** * Creates a new instance. * * @param dbCtx * Used to access the database. */ public TransactionDao(DatabaseContext2 dbCtx) { this.dbCtx = dbCtx; jdbcTemplate = dbCtx.getJdbcTemplate(); } @Override public TransactionSnapshot getTransactionSnapshot() { String snapshotString; TransactionSnapshot snapshot; snapshotString = jdbcTemplate.queryForObject("SELECT txid_current_snapshot()", String.class); snapshot = new TransactionSnapshot(snapshotString); if (LOG.isLoggable(Level.FINER)) { LOG.finer("Loaded new database snapshot, xmin=" + snapshot.getXMin() + ", xmax=" + snapshot.getXMax() + ", xiplist=" + snapshot.getXIpList()); } return snapshot; } @Override public void executeWithinTransaction(final Runnable target) { dbCtx.executeWithinTransaction(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus arg0) { target.run(); } }); } } TransactionManager.java000066400000000000000000000011071253404521400350070ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; /** * Obtains transaction snapshots used for replication. */ public interface TransactionManager { /** * Obtains the current database snapshot. * * @return The transaction snapshot. */ TransactionSnapshot getTransactionSnapshot(); /** * Executes the specified object within a transaction. * * @param target * The object containing the logic to execute. */ void executeWithinTransaction(Runnable target); } TransactionSnapshot.java000066400000000000000000000027761253404521400352510ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; /** * Represents the data associated with a database transaction snapshot providing information about * currently in-flight transactions. */ public class TransactionSnapshot { private long xMin; private long xMax; private List xIpList; /** * Creates a new instance. * * @param snapshotString * The snapshot string in format "xMin:xMax:inflight1,inflight2,...". */ public TransactionSnapshot(String snapshotString) { StringTokenizer tokenizer; tokenizer = new StringTokenizer(snapshotString, ":"); xMin = Long.parseLong(tokenizer.nextToken()); xMax = Long.parseLong(tokenizer.nextToken()); xIpList = new ArrayList(); if (tokenizer.hasMoreTokens()) { tokenizer = new StringTokenizer(tokenizer.nextToken(), ","); while (tokenizer.hasMoreTokens()) { xIpList.add(Long.parseLong(tokenizer.nextToken())); } } } /** * Gets the earliest still active transaction. * * @return The transaction id. */ public long getXMin() { return xMin; } /** * Gets the next transaction to be created. * * @return The transaction id. */ public long getXMax() { return xMax; } /** * Gets the list of active transactions. * * @return The transaction ids. */ public List getXIpList() { return xIpList; } } UserManager.java000066400000000000000000000143701253404521400334460ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashSet; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.apidb.common.DatabaseContext; import org.openstreetmap.osmosis.core.database.ReleasableStatementContainer; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.lifecycle.Releasable; /** * Creates or loads the details of the Osmosis user in the database. * * @author Brett Henderson */ public class UserManager implements Releasable { private static final Logger LOG = Logger.getLogger(UserManager.class.getName()); private static final String SELECT_SQL_USER_EXISTS = "SELECT Count(id) AS userCount FROM users WHERE id = ?"; private static final String INSERT_SQL_USER = "INSERT INTO users (id, email, pass_crypt," + " creation_time, display_name, data_public, description, home_lat, home_lon, home_zoom," + " nearby, pass_salt) VALUES (?, ?, '00000000000000000000000000000000', NOW(), ?, ?," + " ?, 0, 0, 3, 50, '00000000')"; private static final String UPDATE_SQL_USER = "UPDATE users SET display_name = ? WHERE id = ?"; private final DatabaseContext dbCtx; private final Set updatedUsers; private final ReleasableStatementContainer statementContainer; private PreparedStatement statementInsert; private PreparedStatement statementExists; private PreparedStatement statementUpdate; /** * Creates a new instance. * * @param dbCtx The database context to use for all database access. */ public UserManager(DatabaseContext dbCtx) { this.dbCtx = dbCtx; updatedUsers = new HashSet(); statementContainer = new ReleasableStatementContainer(); } /** * Checks if the specified user exists in the database. * * @param user The user to check for. * @return True if the user exists, false otherwise. */ private boolean doesUserExistInDb(OsmUser user) { int prmIndex; ResultSet resultSet; if (statementExists == null) { statementExists = statementContainer.add(dbCtx.prepareStatementForStreaming(SELECT_SQL_USER_EXISTS)); } resultSet = null; try { boolean result; prmIndex = 1; statementExists.setInt(prmIndex++, user.getId()); resultSet = statementExists.executeQuery(); resultSet.next(); if (resultSet.getInt("userCount") == 0) { result = false; } else { result = true; } resultSet.close(); resultSet = null; return result; } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to check if user with id " + user.getId() + " exists in the database.", e); } finally { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to close existing user result set.", e); } } } } /** * Inserts the specified user into the database. * * @param user The user to be inserted. */ private void insertUser(OsmUser user) { int prmIndex; String userName; boolean dataPublic; if (statementInsert == null) { statementInsert = statementContainer.add(dbCtx.prepareStatement(INSERT_SQL_USER)); } if (OsmUser.NONE.equals(user)) { userName = "Osmosis Anonymous"; dataPublic = false; } else { userName = user.getName(); dataPublic = true; } try { prmIndex = 1; statementInsert.setInt(prmIndex++, user.getId()); statementInsert.setString(prmIndex++, "osmosis_user_" + user.getId() + "@example.com"); statementInsert.setString(prmIndex++, userName); statementInsert.setBoolean(prmIndex++, dataPublic); statementInsert.setString(prmIndex++, userName); statementInsert.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert user with id " + user.getId() + " into the database.", e); } } /** * Updates the specified user in the database. * * @param user The user to be updated. */ private void updateUser(OsmUser user) { int prmIndex; if (statementUpdate == null) { statementUpdate = statementContainer.add(dbCtx.prepareStatement(UPDATE_SQL_USER)); } try { String userName; if (OsmUser.NONE.equals(user)) { userName = "Osmosis Anonymous"; } else { userName = user.getName(); } prmIndex = 1; statementUpdate.setString(prmIndex++, userName); statementUpdate.setInt(prmIndex++, user.getId()); statementUpdate.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to update user with id " + user.getId() + " in the database.", e); } } /** * Adds the user to the database or updates the name of the existing database entry if one * already exists with the same id. * * @param user The user to be created or updated. */ public void addOrUpdateUser(OsmUser user) { if (!updatedUsers.contains(user.getId())) { if (doesUserExistInDb(user)) { updateUser(user); } else { insertUser(user); } updatedUsers.add(user.getId()); } } /** * {@inheritDoc} */ @Override public void release() { statementContainer.release(); } } osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl/WayDao.java000066400000000000000000000136671253404521400325100ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainerFactory; import org.openstreetmap.osmosis.core.container.v0_6.WayContainerFactory; import org.openstreetmap.osmosis.core.database.DbFeatureHistory; import org.openstreetmap.osmosis.core.database.DbFeatureHistoryRowMapper; import org.openstreetmap.osmosis.core.database.DbFeatureRowMapper; import org.openstreetmap.osmosis.core.database.DbOrderedFeature; import org.openstreetmap.osmosis.core.database.DbOrderedFeatureHistoryComparator; import org.openstreetmap.osmosis.core.database.DbOrderedFeatureRowMapper; import org.openstreetmap.osmosis.core.database.RowMapperListener; import org.openstreetmap.osmosis.core.database.SortingStoreRowMapperListener; import org.openstreetmap.osmosis.core.database.WayNodeCollectionLoader; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.sort.common.FileBasedSort; import org.openstreetmap.osmosis.core.store.SingleClassObjectSerializationFactory; import org.openstreetmap.osmosis.core.store.StoreReleasingIterator; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.SqlParameterSource; /** * Provides access to ways in the database. */ public class WayDao extends EntityDao { private static final Logger LOG = Logger.getLogger(WayDao.class.getName()); private static final String[] TYPE_SPECIFIC_FIELD_NAMES = new String[] {}; /** * Creates a new instance. * * @param jdbcTemplate * Used to access the database. */ public WayDao(JdbcTemplate jdbcTemplate) { super(jdbcTemplate, "way"); } /** * {@inheritDoc} */ @Override protected RowMapperListener getEntityRowMapper(RowMapperListener entityListener) { return new WayRowMapper(entityListener); } /** * {@inheritDoc} */ @Override protected String[] getTypeSpecificFieldNames() { return TYPE_SPECIFIC_FIELD_NAMES; } /** * {@inheritDoc} */ @Override protected EntityContainerFactory getContainerFactory() { return new WayContainerFactory(); } private ReleasableIterator>> getWayNodeHistory( String selectedEntityStatement, SqlParameterSource parameterSource) { FileBasedSort>> sortingStore = new FileBasedSort>>( new SingleClassObjectSerializationFactory(DbFeatureHistory.class), new DbOrderedFeatureHistoryComparator(), true); try { String sql; SortingStoreRowMapperListener>> storeListener; DbFeatureHistoryRowMapper> dbFeatureHistoryRowMapper; DbFeatureRowMapper dbFeatureRowMapper; DbOrderedFeatureRowMapper dbOrderedFeatureRowMapper; WayNodeRowMapper wayNodeRowMapper; ReleasableIterator>> resultIterator; sql = "SELECT wn.way_id AS id, wn.node_id, wn.version, wn.sequence_id" + " FROM " + "way_nodes wn" + " INNER JOIN " + selectedEntityStatement + " t ON wn.way_id = t.way_id AND wn.version = t.version"; LOG.log(Level.FINER, "Way node history query: " + sql); // Sends all received data into the object store. storeListener = new SortingStoreRowMapperListener>>(sortingStore); // Retrieves the version information associated with the feature. dbFeatureHistoryRowMapper = new DbFeatureHistoryRowMapper>(storeListener); // Retrieves the sequence number associated with the feature. dbOrderedFeatureRowMapper = new DbOrderedFeatureRowMapper(dbFeatureHistoryRowMapper); // Retrieves the entity information associated with the feature. dbFeatureRowMapper = new DbFeatureRowMapper(dbOrderedFeatureRowMapper); // Retrieves the basic feature information. wayNodeRowMapper = new WayNodeRowMapper(dbFeatureRowMapper); // Perform the query passing the row mapper chain to process rows in a streamy fashion. getNamedParamJdbcTemplate().query(sql, parameterSource, wayNodeRowMapper); // Open a iterator on the store that will release the store upon completion. resultIterator = new StoreReleasingIterator>>( sortingStore.iterate(), sortingStore); // The store itself shouldn't be released now that it has been attached to the iterator. sortingStore = null; return resultIterator; } finally { if (sortingStore != null) { sortingStore.release(); } } } /** * {@inheritDoc} */ @Override protected List> getFeatureHistoryPopulators( String selectedEntityStatement, MapSqlParameterSource parameterSource) { ReleasableIterator>> wayNodeIterator; List> featurePopulators; featurePopulators = new ArrayList>(); // Get the way nodes for the selected entities. wayNodeIterator = getWayNodeHistory(selectedEntityStatement, parameterSource); // Wrap the way node source into a feature history populator that can attach them to their // owning ways. featurePopulators.add( new FeatureHistoryPopulator>( wayNodeIterator, new WayNodeCollectionLoader())); return featurePopulators; } } WayNodeRowMapper.java000066400000000000000000000020431253404521400344320ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.sql.ResultSet; import java.sql.SQLException; import org.openstreetmap.osmosis.core.database.RowMapperListener; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.springframework.jdbc.core.RowCallbackHandler; /** * Maps way node result set rows into way node objects. */ public class WayNodeRowMapper implements RowCallbackHandler { private RowMapperListener listener; /** * Creates a new instance. * * @param listener * The destination for result objects. */ public WayNodeRowMapper(RowMapperListener listener) { this.listener = listener; } /** * {@inheritDoc} */ @Override public void processRow(ResultSet resultSet) throws SQLException { long nodeId; WayNode wayNode; nodeId = resultSet.getLong("node_id"); wayNode = new WayNode(nodeId); listener.process(wayNode, resultSet); } } WayRowMapper.java000066400000000000000000000017351253404521400336330ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.sql.ResultSet; import java.sql.SQLException; import org.openstreetmap.osmosis.core.database.RowMapperListener; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.Way; /** * Maps way result set rows into way objects. */ public class WayRowMapper implements RowMapperListener { private RowMapperListener listener; /** * Creates a new instance. * * @param listener * The destination for result objects. */ public WayRowMapper(RowMapperListener listener) { this.listener = listener; } /** * {@inheritDoc} */ @Override public void process(CommonEntityData data, ResultSet resultSet) throws SQLException { Way way; way = new Way(data); listener.process(way, resultSet); } } osmosis-0.44.1/osmosis-apidb/src/main/resources/000077500000000000000000000000001253404521400215725ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/main/resources/osmosis-plugins.conf000066400000000000000000000000611253404521400256110ustar00rootroot00000000000000org.openstreetmap.osmosis.apidb.ApidbPluginLoaderosmosis-0.44.1/osmosis-apidb/src/test/000077500000000000000000000000001253404521400176135ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/test/java/000077500000000000000000000000001253404521400205345ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/test/java/org/000077500000000000000000000000001253404521400213235ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/test/java/org/openstreetmap/000077500000000000000000000000001253404521400242115ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/test/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400257055ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/test/java/org/openstreetmap/osmosis/apidb/000077500000000000000000000000001253404521400267645ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/test/java/org/openstreetmap/osmosis/apidb/v0_6/000077500000000000000000000000001253404521400275365ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/test/java/org/openstreetmap/osmosis/apidb/v0_6/ApiDbTest.java000066400000000000000000000245211253404521400322240ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6; import java.io.File; import java.io.IOException; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import java.util.TimeZone; import org.junit.Test; import org.openstreetmap.osmosis.apidb.v0_6.impl.DatabaseUtilities; import org.openstreetmap.osmosis.core.Osmosis; import org.openstreetmap.osmosis.testutil.AbstractDataTest; /** * Tests for PostgreSQL tasks. * * @author Brett Henderson */ public class ApiDbTest extends AbstractDataTest { private static final String DATE_FORMAT = "yyyy-MM-dd_HH:mm:ss"; private final DatabaseUtilities dbUtils = new DatabaseUtilities(dataUtils); private String convertUTCTimeToLocalTime(String dateString) throws ParseException { DateFormat inFormat; DateFormat outFormat; Date date; inFormat = new SimpleDateFormat(DATE_FORMAT, Locale.US); inFormat.setTimeZone(TimeZone.getTimeZone("UTC")); outFormat = new SimpleDateFormat(DATE_FORMAT, Locale.US); date = inFormat.parse(dateString); return outFormat.format(date); } /** * A basic test loading an osm file into a mysql database, then dumping it again and verifying * that it is identical. * * @throws IOException if any file operations fail. */ @Test public void testLoadAndDump() throws IOException { File authFile; File inputFile; File outputFile; // Generate input files. authFile = dbUtils.getAuthorizationFile(); inputFile = dataUtils.createDataFile("v0_6/db-snapshot.osm"); outputFile = dataUtils.newFile(); // Remove all existing data from the database. dbUtils.truncateDatabase(); // Load the database with a dataset. Osmosis.run(new String[] { "-q", "--read-xml-0.6", inputFile.getPath(), "--write-apidb-0.6", "authFile=" + authFile.getPath(), "allowIncorrectSchemaVersion=true" }); // Dump the database to an osm file. Osmosis.run(new String[] { "-q", "--read-apidb-0.6", "authFile=" + authFile.getPath(), "allowIncorrectSchemaVersion=true", "--tag-sort-0.6", "--write-xml-0.6", outputFile.getPath() }); // Validate that the output file matches the input file. dataUtils.compareFiles(inputFile, outputFile); } /** * A basic test loading an osm file into a apidb database, then dumping it from current tables * and verifying that it is identical. * * @throws IOException if any file operations fail. */ @Test public void testLoadAndCurrentDump() throws IOException { File authFile; File inputFile; File outputFile; // Generate input files. authFile = dbUtils.getAuthorizationFile(); inputFile = dataUtils.createDataFile("v0_6/db-snapshot.osm"); outputFile = File.createTempFile("test", ".osm"); // Remove all existing data from the database. dbUtils.truncateDatabase(); // Load the database with a dataset. Osmosis.run(new String[] { "-q", "--read-xml-0.6", inputFile.getPath(), "--write-apidb-0.6", "authFile=" + authFile.getPath(), "allowIncorrectSchemaVersion=true" }); // Dump the database to an osm file. Osmosis.run(new String[] { "-q", "--read-apidb-current-0.6", "authFile=" + authFile.getPath(), "allowIncorrectSchemaVersion=true", "--tag-sort-0.6", "--write-xml-0.6", outputFile.getPath() }); // Validate that the output file matches the input file. dataUtils.compareFiles(inputFile, outputFile); } /** * A test loading an osm file into a apidb database, then applying a changeset, then dumping it * again and verifying the output is as expected. * * @throws IOException if any file operations fail. */ @Test public void testApplyChangeset() throws IOException { File authFile; File snapshotFile; File changesetFile; File expectedResultFile; File actualResultFile; // Generate input files. authFile = dbUtils.getAuthorizationFile(); snapshotFile = dataUtils.createDataFile("v0_6/db-snapshot.osm"); changesetFile = dataUtils.createDataFile("v0_6/db-changeset.osc"); expectedResultFile = dataUtils.createDataFile("v0_6/db-changeset-expected.osm"); actualResultFile = File.createTempFile("test", ".osm"); // Remove all existing data from the database. dbUtils.truncateDatabase(); // Load the database with the snapshot file. Osmosis.run(new String[] { "-q", "--read-xml-0.6", snapshotFile.getPath(), "--write-apidb-0.6", "authFile=" + authFile.getPath(), "allowIncorrectSchemaVersion=true" }); // Apply the changeset file to the database. Osmosis.run(new String[] { "-q", "--read-xml-change-0.6", changesetFile.getPath(), "--write-apidb-change-0.6", "authFile=" + authFile.getPath(), "allowIncorrectSchemaVersion=true" }); // Dump the database to an osm file. Osmosis.run(new String[] { "-q", "--read-apidb-0.6", "authFile=" + authFile.getPath(), "allowIncorrectSchemaVersion=true", "--tag-sort-0.6", "--write-xml-0.6", actualResultFile.getPath() }); // Validate that the dumped file matches the expected result. dataUtils.compareFiles(expectedResultFile, actualResultFile); } /** * A test loading an osm file into a apidb database, then applying a changeset, then dumping the * original snapshot timeframe and verifying the output is as expected. * * @throws IOException if any file operations fail. * @throws ParseException if any date operations fail. */ @Test public void testSnapshotDump() throws IOException, ParseException { File authFile; File snapshotFile; File changesetFile; File expectedResultFile; File actualResultFile; // Generate input files. authFile = dbUtils.getAuthorizationFile(); snapshotFile = dataUtils.createDataFile("v0_6/db-snapshot.osm"); changesetFile = dataUtils.createDataFile("v0_6/db-changeset.osc"); expectedResultFile = dataUtils.createDataFile("v0_6/db-snapshot-b.osm"); actualResultFile = File.createTempFile("test", ".osm"); // Remove all existing data from the database. dbUtils.truncateDatabase(); // Load the database with the snapshot file. Osmosis.run(new String[] { "-q", "--read-xml-0.6", snapshotFile.getPath(), "--write-apidb-0.6", "authFile=" + authFile.getPath(), "allowIncorrectSchemaVersion=true" }); // Apply the changeset file to the database. Osmosis.run(new String[] { "-q", "--read-xml-change-0.6", changesetFile.getPath(), "--write-apidb-change-0.6", "authFile=" + authFile.getPath(), "allowIncorrectSchemaVersion=true" }); // Dump the database to an osm file. Osmosis.run(new String[] { "-q", "--read-apidb-0.6", "snapshotInstant=" + convertUTCTimeToLocalTime("2008-01-03_00:00:00"), "authFile=" + authFile.getPath(), "allowIncorrectSchemaVersion=true", "--tag-sort-0.6", "--write-xml-0.6", actualResultFile.getPath() }); // Validate that the dumped file matches the expected result. dataUtils.compareFiles(expectedResultFile, actualResultFile); } /** * A test loading an osm file into a apidb database, then applying a changeset, then extracting * the changeset timeframe and verifying the output is as expected. * * @throws IOException if any file operations fail. * @throws ParseException if any date operations fail. */ @Test public void testChangesetDump() throws IOException, ParseException { File authFile; File snapshotFile; File changesetFile; File expectedResultFile; File actualResultFile; // Generate input files. authFile = dbUtils.getAuthorizationFile(); snapshotFile = dataUtils.createDataFile("v0_6/db-snapshot.osm"); changesetFile = dataUtils.createDataFile("v0_6/db-changeset.osc"); expectedResultFile = dataUtils.createDataFile("v0_6/db-changeset-b.osc"); actualResultFile = File.createTempFile("test", ".osm"); // Remove all existing data from the database. dbUtils.truncateDatabase(); // Load the database with the snapshot file. Osmosis.run(new String[] { "-q", "--read-xml-0.6", snapshotFile.getPath(), "--write-apidb-0.6", "authFile=" + authFile.getPath(), "allowIncorrectSchemaVersion=true" }); // Apply the changeset file to the database. Osmosis.run(new String[] { "-q", "--read-xml-change-0.6", changesetFile.getPath(), "--write-apidb-change-0.6", "authFile=" + authFile.getPath(), "allowIncorrectSchemaVersion=true" }); // Dump the changeset to an osm file. Osmosis.run(new String[] { "-q", "--read-apidb-change-0.6", "intervalBegin=" + convertUTCTimeToLocalTime("2008-01-03_00:00:00"), "intervalEnd=" + convertUTCTimeToLocalTime("2008-01-04_00:00:00"), "authFile=" + authFile.getPath(), "allowIncorrectSchemaVersion=true", "--write-xml-change-0.6", actualResultFile.getPath() }); // Validate that the dumped file matches the expected result. dataUtils.compareFiles(expectedResultFile, actualResultFile); } } ApidbFileReplicatorTest.java000066400000000000000000000101741253404521400350310ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/test/java/org/openstreetmap/osmosis/apidb/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6; import java.io.File; import java.io.IOException; import org.junit.Test; import org.openstreetmap.osmosis.apidb.v0_6.impl.DatabaseUtilities; import org.openstreetmap.osmosis.core.Osmosis; import org.openstreetmap.osmosis.testutil.AbstractDataTest; /** * Tests the file-based database replicator. */ public class ApidbFileReplicatorTest extends AbstractDataTest { private final DatabaseUtilities dbUtils = new DatabaseUtilities(dataUtils); /** * A basic test loading an osm file into an API database and verifying that it gets replicated correctly. * * @throws IOException if any file operations fail. */ @Test public void testLoadAndDump() throws IOException { File authFile; File snapshotFile; File changesetFile; File outputFile; File workingDirectory; // Generate input files. authFile = dbUtils.getAuthorizationFile(); snapshotFile = dataUtils.createDataFile("v0_6/db-snapshot.osm"); changesetFile = dataUtils.createDataFile("v0_6/db-replicate-changeset.osc"); outputFile = dataUtils.newFile(); workingDirectory = dataUtils.newFolder(); // Remove all existing data from the database. dbUtils.truncateDatabase(); // Initialise replication. Osmosis.run(new String[] { "-q", "--replicate-apidb-0.6", "authFile=" + authFile.getPath(), "allowIncorrectSchemaVersion=true", "--write-replication", "workingDirectory=" + workingDirectory.getPath() }); // Load the database with a dataset. Osmosis.run(new String[] { "-q", "--read-xml-0.6", snapshotFile.getPath(), "--write-apidb-0.6", "authFile=" + authFile.getPath(), "allowIncorrectSchemaVersion=true" }); // Run replication. Osmosis.run(new String[] { "-q", "--replicate-apidb-0.6", "authFile=" + authFile.getPath(), "allowIncorrectSchemaVersion=true", "--write-replication", "workingDirectory=" + workingDirectory.getPath() }); // Apply the changeset file to the database. Osmosis.run(new String[] { "-q", "--read-xml-change-0.6", changesetFile.getPath(), "--write-apidb-change-0.6", "authFile=" + authFile.getPath(), "allowIncorrectSchemaVersion=true" }); // Run replication. Osmosis.run(new String[] { "-q", "--replicate-apidb-0.6", "authFile=" + authFile.getPath(), "allowIncorrectSchemaVersion=true", "--write-replication", "workingDirectory=" + workingDirectory.getPath() }); // Ensure that replication runs successfully even if no data is available. Osmosis.run(new String[] { "-q", "--replicate-apidb-0.6", "authFile=" + authFile.getPath(), "allowIncorrectSchemaVersion=true", "--write-replication", "workingDirectory=" + workingDirectory.getPath() }); // Ensure that replication can run with multiple loops. Osmosis.run(new String[] { "-q", "--replicate-apidb-0.6", "authFile=" + authFile.getPath(), "allowIncorrectSchemaVersion=true", "iterations=2", "--write-replication", "workingDirectory=" + workingDirectory.getPath() }); // Decompress the result file. Osmosis.run(new String[] { "-q", "--read-xml-change-0.6", new File(workingDirectory, "000/000/002.osc.gz").getPath(), "--write-xml-change-0.6", outputFile.getPath() }); // Validate that the replicated file matches the input file. dataUtils.compareFiles(changesetFile, outputFile); } } osmosis-0.44.1/osmosis-apidb/src/test/java/org/openstreetmap/osmosis/apidb/v0_6/impl/000077500000000000000000000000001253404521400304775ustar00rootroot00000000000000ChangesetManagerTest.java000066400000000000000000000032341253404521400353210ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/test/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import org.junit.Test; import org.openstreetmap.osmosis.apidb.common.DatabaseContext; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.testutil.AbstractDataTest; /** * Tests for the changeset manager class. * * @author Brett Henderson */ public class ChangesetManagerTest extends AbstractDataTest { private final DatabaseUtilities dbUtils = new DatabaseUtilities(dataUtils); /** * Tests the changeset manager. */ @Test public void testChangeset() { DatabaseContext dbCtx; UserManager userManager; ChangesetManager changesetManager; OsmUser user; long changesetId; user = new OsmUser(1, "user"); changesetId = 2; dbCtx = dbUtils.createDatabaseContext(); // Reset the database to a clean state. dbUtils.truncateDatabase(); userManager = new UserManager(dbCtx); changesetManager = new ChangesetManager(dbCtx); userManager.addOrUpdateUser(user); // Create the changeset in the database. changesetManager.addChangesetIfRequired(changesetId, user); // Make the same call which should just return if the changeset is already known. changesetManager.addChangesetIfRequired(changesetId, user); // Create a new instance of the manager to verify that it copes with a non-cached changeset. changesetManager = new ChangesetManager(dbCtx); changesetManager.addChangesetIfRequired(changesetId, user); dbCtx.release(); } } DatabaseUtilities.java000066400000000000000000000047751253404521400347000ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/test/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.io.File; import org.openstreetmap.osmosis.apidb.common.DatabaseContext; import org.openstreetmap.osmosis.core.Osmosis; import org.openstreetmap.osmosis.core.database.AuthenticationPropertiesLoader; import org.openstreetmap.osmosis.core.database.DatabaseConstants; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.testutil.TestDataUtilities; /** * Contains re-usable functionality for manipulating the database during tests. * * @author Brett Henderson */ public class DatabaseUtilities { private static final String AUTHFILE = "v0_6/apidb-authfile.txt"; private static final String AUTHFILE_PROPERTY = "db.apidb.authfile"; private TestDataUtilities dataUtils; /** * Creates a new instance. * * @param dataUtils * The test data manager. */ public DatabaseUtilities(TestDataUtilities dataUtils) { this.dataUtils = dataUtils; } /** * Creates a new database context pointing at the test database. * * @return A fully configured database context. */ public DatabaseContext createDatabaseContext() { AuthenticationPropertiesLoader credentialsLoader; DatabaseLoginCredentials credentials; credentials = new DatabaseLoginCredentials(DatabaseConstants.TASK_DEFAULT_HOST, DatabaseConstants.TASK_DEFAULT_DATABASE, DatabaseConstants.TASK_DEFAULT_USER, DatabaseConstants.TASK_DEFAULT_PASSWORD, DatabaseConstants.TASK_DEFAULT_FORCE_UTF8, DatabaseConstants.TASK_DEFAULT_PROFILE_SQL, DatabaseConstants.TASK_DEFAULT_DB_TYPE); credentialsLoader = new AuthenticationPropertiesLoader(getAuthorizationFile()); credentialsLoader.updateLoginCredentials(credentials); return new DatabaseContext(credentials); } /** * Removes all data from the database. */ public void truncateDatabase() { // Remove all existing data from the database. Osmosis.run(new String[] { "-q", "--truncate-apidb-0.6", "authFile=" + getAuthorizationFile().getPath(), "allowIncorrectSchemaVersion=true" }); } /** * Returns the location of the database authorization file. * * @return The authorization file. */ public File getAuthorizationFile() { return dataUtils.createDataFile(AUTHFILE_PROPERTY, AUTHFILE); } } MockReplicationDestination.java000066400000000000000000000047501253404521400365560ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/test/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; /** * A mocked replication destination allowing the existing replication state to be loaded and the * current state maintained. All data processing calls such as process will be ignored. */ public class MockReplicationDestination implements ChangeSink { private boolean stateExists; private ReplicationState currentState; private Map storedState; /** * Creates a new instance with no state. */ public MockReplicationDestination() { stateExists = false; storedState = new HashMap(); } /** * Creates a new instance with an initial state. * * @param initialState * The initial replication state. */ public MockReplicationDestination(ReplicationState initialState) { this(); initialState.store(storedState); stateExists = true; } /** * {@inheritDoc} */ public void initialize(Map metaData) { // Get the replication state from the upstream task. if (!metaData.containsKey(ReplicationState.META_DATA_KEY)) { throw new OsmosisRuntimeException( "No replication state has been provided in metadata key " + ReplicationState.META_DATA_KEY + "."); } currentState = (ReplicationState) metaData.get(ReplicationState.META_DATA_KEY); // Initialise the state from the stored state if it exists and increment // the sequence number. if (stateExists) { currentState.load(storedState); currentState.setSequenceNumber(currentState.getSequenceNumber() + 1); } } /** * {@inheritDoc} */ @Override public void process(ChangeContainer change) { // Do nothing. } /** * {@inheritDoc} */ @Override public void complete() { currentState.store(storedState); stateExists = true; } /** * {@inheritDoc} */ @Override public void release() { // Do nothing. } /** * Returns the current state object tracked internally. This will be a state * object provided by a caller in the initialize method. It will remain * available after complete and release have been called. * * @return The current state. */ public ReplicationState getCurrentState() { return currentState; } } MockReplicationSource.java000066400000000000000000000021501253404521400355250ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/test/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.util.ArrayList; import java.util.List; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.store.EmptyIterator; /** * A mocked replication source capturing provided predicates for later analysis and returning empty * data sets on each call. */ public class MockReplicationSource implements ReplicationSource { private List predicatesList = new ArrayList(); /** * Gets the query predicates passed to this mock during execution. * * @return The query predicates. */ public List getPredicatesList() { return predicatesList; } /** * {@inheritDoc} */ @Override public ReleasableIterator getHistory(ReplicationQueryPredicates predicates) { predicatesList.add(predicates); return new EmptyIterator(); } } MockSystemTimeLoader.java000066400000000000000000000011761253404521400353340ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/test/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * A mocked system time loader allowing canned times to be returned. */ public class MockSystemTimeLoader implements SystemTimeLoader { private List times = new ArrayList(); /** * Gets the currently available times. * * @return The times. */ public List getTimes() { return times; } /** * {@inheritDoc} */ @Override public Date getSystemTime() { return times.remove(0); } } MockTransactionSnapshotLoader.java000066400000000000000000000014311253404521400372300ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/test/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.util.ArrayList; import java.util.List; /** * A mocked transaction snapshot loader allowing canned snapshots to be returned. */ public class MockTransactionSnapshotLoader implements TransactionManager { private List snapshots = new ArrayList(); /** * Gets the currently available snapshots. * * @return The snapshots. */ public List getSnapshots() { return snapshots; } @Override public TransactionSnapshot getTransactionSnapshot() { return snapshots.remove(0); } @Override public void executeWithinTransaction(Runnable target) { target.run(); } } ReplicationSequenceFormatterTest.java000066400000000000000000000047501253404521400377570ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/test/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import org.junit.Assert; import org.junit.Test; import org.openstreetmap.osmosis.replication.common.ReplicationSequenceFormatter; /** * Tests the replication file sequence formatter. */ public class ReplicationSequenceFormatterTest { /** * Tests that a sequence is formatted correctly when no format is defined. */ @Test public void testMinimalFormat() { final int minimumLength = 0; final int groupingLength = 0; final long sequenceNumber = 100; String formattedSequenceNumber; formattedSequenceNumber = new ReplicationSequenceFormatter(minimumLength, groupingLength).getFormattedName(sequenceNumber, ".osc.gz"); Assert.assertEquals("The formatted sequence number is incorrect.", "100.osc.gz", formattedSequenceNumber); } /** * Tests that a number can be formatted correctly when using a simple 0 padded format. */ @Test public void testFixedFormat() { final int minimumLength = 9; final int groupingLength = 0; final long sequenceNumber = 100; String formattedSequenceNumber; formattedSequenceNumber = new ReplicationSequenceFormatter(minimumLength, groupingLength).getFormattedName(sequenceNumber, ".osc.gz"); Assert.assertEquals("The formatted sequence number is incorrect.", "000000100.osc.gz", formattedSequenceNumber); } /** * Tests that a number can be formatted correctly when including path separators with no fixed width. */ @Test public void testMinimalPathFormat() { final int minimumLength = 0; final int groupingLength = 3; final long sequenceNumber = 1000; String formattedSequenceNumber; formattedSequenceNumber = new ReplicationSequenceFormatter(minimumLength, groupingLength).getFormattedName(sequenceNumber, ".osc.gz"); Assert.assertEquals("The formatted sequence number is incorrect.", "1/000.osc.gz", formattedSequenceNumber); } /** * Tests that a number can be formatted correctly when including path separators and a fixed width. */ @Test public void testFixedPathFormat() { final int minimumLength = 9; final int groupingLength = 3; final long sequenceNumber = 100; String formattedSequenceNumber; formattedSequenceNumber = new ReplicationSequenceFormatter(minimumLength, groupingLength).getFormattedName(sequenceNumber, ".osc.gz"); Assert.assertEquals("The formatted sequence number is incorrect.", "000/000/100.osc.gz", formattedSequenceNumber); } } ReplicatorTest.java000066400000000000000000000254731253404521400342420ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/test/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Collections; import java.util.Date; import org.junit.Assert; import org.junit.Test; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Tests for the Replicator class. */ public class ReplicatorTest { private Date buildDate(String rawDate) { try { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(rawDate); } catch (ParseException e) { throw new OsmosisRuntimeException("The date could not be parsed.", e); } } /** * Tests replication behaviour during initialisation. Initialisation occurs the first time * replication is run. */ @Test public void testInitialization() { Replicator replicator; MockReplicationSource source; MockReplicationDestination destination; MockTransactionSnapshotLoader snapshotLoader; MockSystemTimeLoader timeLoader; ReplicationState state; // Build the mocks. source = new MockReplicationSource(); destination = new MockReplicationDestination(); snapshotLoader = new MockTransactionSnapshotLoader(); timeLoader = new MockSystemTimeLoader(); // Instantiate the new replicator. replicator = new Replicator(source, destination, snapshotLoader, timeLoader, 1, 0, 0); // Provide initialisation data. timeLoader.getTimes().add(buildDate("2009-10-11 12:13:14")); timeLoader.getTimes().add(buildDate("2009-10-11 12:13:14")); snapshotLoader.getSnapshots().add(new TransactionSnapshot("100:200:110,112")); // Launch the replication process. replicator.replicate(); // Verify the final state. state = destination.getCurrentState(); Assert.assertEquals("Incorrect final state.", new ReplicationState( 200, 200, Arrays.asList(new Long[]{110L, 112L}), Arrays.asList(new Long[]{}), buildDate("2009-10-11 12:13:14"), 0), state); } /** * Tests replication behaviour when no replication is required. */ @Test public void testNoAction() { Replicator replicator; MockReplicationSource source; MockReplicationDestination destination; MockTransactionSnapshotLoader snapshotLoader; MockSystemTimeLoader timeLoader; ReplicationState initialState; ReplicationState finalState; // Build initial replication state. initialState = new ReplicationState( 200, 200, Arrays.asList(new Long[]{110L, 112L}), Arrays.asList(new Long[]{}), buildDate("2009-10-11 12:13:14"), 0); // Build the mocks. source = new MockReplicationSource(); destination = new MockReplicationDestination(initialState); snapshotLoader = new MockTransactionSnapshotLoader(); timeLoader = new MockSystemTimeLoader(); // Instantiate the new replicator. replicator = new Replicator(source, destination, snapshotLoader, timeLoader, 1, 0, 0); // We want the snapshot loader to return the same snapshot to simulate no database changes. snapshotLoader.getSnapshots().add(new TransactionSnapshot("100:200:110,112")); // But we want the clock time to have progressed. timeLoader.getTimes().add(buildDate("2009-10-11 12:13:15")); timeLoader.getTimes().add(buildDate("2009-10-11 12:13:15")); timeLoader.getTimes().add(buildDate("2009-10-11 12:13:15")); // Launch the replication process. replicator.replicate(); // Verify that the final state does not match the initial state, but that the only // difference is the time and increment sequence number. finalState = destination.getCurrentState(); Assert.assertFalse("Final state should not match initial state.", finalState.equals(initialState)); finalState.setTimestamp(initialState.getTimestamp()); finalState.setSequenceNumber(finalState.getSequenceNumber() - 1); Assert.assertTrue("Final state should match initial state after updating timestamp.", finalState.equals(initialState)); // Verify that no changes were replicated. Assert.assertTrue("No changes should have been replicated.", source.getPredicatesList().size() == 0); } /** * Tests replication behaviour when a simple replication interval is required. */ @Test public void testSimpleIncrement() { Replicator replicator; MockReplicationSource source; MockReplicationDestination destination; MockTransactionSnapshotLoader snapshotLoader; MockSystemTimeLoader timeLoader; ReplicationState state; ReplicationQueryPredicates predicates; // Build initial replication state. state = new ReplicationState( 200, 200, Arrays.asList(new Long[]{}), Arrays.asList(new Long[]{}), buildDate("2009-10-11 12:13:14"), 0); // Build the mocks. source = new MockReplicationSource(); destination = new MockReplicationDestination(state); snapshotLoader = new MockTransactionSnapshotLoader(); timeLoader = new MockSystemTimeLoader(); // Instantiate the new replicator. replicator = new Replicator(source, destination, snapshotLoader, timeLoader, 1, 0, 0); // Set the snapshot loader to return a snapshot with higher xMax. snapshotLoader.getSnapshots().add(new TransactionSnapshot("100:220")); // We also want the clock time to have progressed. timeLoader.getTimes().add(buildDate("2009-10-11 12:13:15")); timeLoader.getTimes().add(buildDate("2009-10-11 12:13:15")); // Launch the replication process. replicator.replicate(); // Verify that the final state is correct. state = destination.getCurrentState(); Assert.assertEquals("Incorrect final state.", new ReplicationState( 220, 220, Arrays.asList(new Long[]{}), Arrays.asList(new Long[]{}), buildDate("2009-10-11 12:13:15"), 1), state); // Verify that the correct changes were replicated. Assert.assertTrue("A single interval should have been replicated.", source.getPredicatesList().size() == 1); predicates = source.getPredicatesList().get(0); Assert.assertEquals("Incorrect active list.", Collections.emptyList(), predicates.getActiveList()); Assert.assertEquals("Incorrect ready list.", Collections.emptyList(), predicates.getReadyList()); Assert.assertEquals("Incorrect bottom transaction id.", 200, predicates.getBottomTransactionId()); Assert.assertEquals("Incorrect top transaction id.", 220, predicates.getTopTransactionId()); } /** * Tests replication behaviour when active list manipulation is required. */ @Test public void testInFlightTxnIncrement() { Replicator replicator; MockReplicationSource source; MockReplicationDestination destination; MockTransactionSnapshotLoader snapshotLoader; MockSystemTimeLoader timeLoader; ReplicationState state; ReplicationQueryPredicates predicates; // Build initial replication state. state = new ReplicationState( 200, 200, Arrays.asList(new Long[]{180L, 185L}), Arrays.asList(new Long[]{}), buildDate("2009-10-11 12:13:14"), 0); // Build the mocks. source = new MockReplicationSource(); destination = new MockReplicationDestination(state); snapshotLoader = new MockTransactionSnapshotLoader(); timeLoader = new MockSystemTimeLoader(); // Instantiate the new replicator. replicator = new Replicator(source, destination, snapshotLoader, timeLoader, 1, 0, 0); // Set the snapshot loader to return a snapshot with higher xMax. snapshotLoader.getSnapshots().add(new TransactionSnapshot("100:220:185")); // We also want the clock time to have progressed. timeLoader.getTimes().add(buildDate("2009-10-11 12:13:15")); timeLoader.getTimes().add(buildDate("2009-10-11 12:13:15")); // Launch the replication process. replicator.replicate(); // Verify that the final state is correct. state = destination.getCurrentState(); Assert.assertEquals("Incorrect final state.", new ReplicationState( 220, 220, Arrays.asList(new Long[]{185L}), Arrays.asList(new Long[]{}), buildDate("2009-10-11 12:13:15"), 1), state); // Verify that the correct changes were replicated. Assert.assertTrue("A single interval should have been replicated.", source.getPredicatesList().size() == 1); predicates = source.getPredicatesList().get(0); Assert.assertEquals("Incorrect active list.", Arrays.asList(new Long[]{185L}), predicates.getActiveList()); Assert.assertEquals("Incorrect ready list.", Arrays.asList(new Long[]{180L}), predicates.getReadyList()); Assert.assertEquals("Incorrect bottom transaction id.", 200, predicates.getBottomTransactionId()); Assert.assertEquals("Incorrect top transaction id.", 220, predicates.getTopTransactionId()); } /** * Tests replication behaviour when catching up from outage and some active transactions are overtaken. */ @Test public void testOutageCatchupWithActiveTxns() { Replicator replicator; MockReplicationSource source; MockReplicationDestination destination; MockTransactionSnapshotLoader snapshotLoader; MockSystemTimeLoader timeLoader; ReplicationState state; ReplicationQueryPredicates predicates; // Build initial replication state. state = new ReplicationState( 5, 5, Arrays.asList(new Long[]{24000L, 26000L}), Arrays.asList(new Long[]{}), buildDate("2009-10-11 12:13:14"), 0); // Build the mocks. source = new MockReplicationSource(); destination = new MockReplicationDestination(state); snapshotLoader = new MockTransactionSnapshotLoader(); timeLoader = new MockSystemTimeLoader(); // Instantiate the new replicator. replicator = new Replicator(source, destination, snapshotLoader, timeLoader, 1, 0, 0); // Set the snapshot loader to return a snapshot with higher xMax. snapshotLoader.getSnapshots().add(new TransactionSnapshot("20000:30000:26000")); // We also want the clock time to have progressed. timeLoader.getTimes().add(buildDate("2009-10-11 12:13:15")); timeLoader.getTimes().add(buildDate("2009-10-11 12:13:15")); // Launch the replication process. replicator.replicate(); // Verify that the final state is correct. state = destination.getCurrentState(); Assert.assertEquals("Incorrect final state.", new ReplicationState( 30000, 25005, Arrays.asList(new Long[]{26000L}), Arrays.asList(new Long[]{}), buildDate("2009-10-11 12:13:14"), 1), state); // Verify that the correct changes were replicated. Assert.assertTrue("A single interval should have been replicated.", source.getPredicatesList().size() == 1); predicates = source.getPredicatesList().get(0); Assert.assertEquals("Incorrect active list.", Arrays.asList(new Long[]{26000L}), predicates.getActiveList()); Assert.assertEquals("Incorrect ready list.", Arrays.asList(new Long[]{}), predicates.getReadyList()); Assert.assertEquals("Incorrect bottom transaction id.", 5, predicates.getBottomTransactionId()); Assert.assertEquals("Incorrect top transaction id.", 25005, predicates.getTopTransactionId()); } } TransactionSnapshotTest.java000066400000000000000000000014751253404521400361370ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/test/java/org/openstreetmap/osmosis/apidb/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.util.Arrays; import org.junit.Assert; import org.junit.Test; /** * Tests the transaction snapshot class. */ public class TransactionSnapshotTest { /** * Tests the database snapshot string parsing. */ @Test public void testParseSnapshot() { TransactionSnapshot snapshot; snapshot = new TransactionSnapshot("1234:5678:101112,131415,161718"); Assert.assertEquals("xMin is incorrect.", 1234, snapshot.getXMin()); Assert.assertEquals("xMax is incorrect.", 5678, snapshot.getXMax()); Assert.assertEquals("xIpList is incorrect.", Arrays.asList(new Long[] { new Long(101112), new Long(131415), new Long(161718) }), snapshot.getXIpList()); } } osmosis-0.44.1/osmosis-apidb/src/test/resources/000077500000000000000000000000001253404521400216255ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/test/resources/data/000077500000000000000000000000001253404521400225365ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/test/resources/data/template/000077500000000000000000000000001253404521400243515ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/test/resources/data/template/v0_6/000077500000000000000000000000001253404521400251235ustar00rootroot00000000000000osmosis-0.44.1/osmosis-apidb/src/test/resources/data/template/v0_6/apidb-authfile.txt000066400000000000000000000001201253404521400305330ustar00rootroot00000000000000host=localhost database=api06_test user=osm password=password dbType=postgresql osmosis-0.44.1/osmosis-apidb/src/test/resources/data/template/v0_6/db-changeset-b.osc000066400000000000000000000022201253404521400303700ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-apidb/src/test/resources/data/template/v0_6/db-changeset-expected.osm000066400000000000000000000037221253404521400317720ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-apidb/src/test/resources/data/template/v0_6/db-changeset.osc000066400000000000000000000030721253404521400301570ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-apidb/src/test/resources/data/template/v0_6/db-replicate-changeset.osc000066400000000000000000000022201253404521400321170ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-apidb/src/test/resources/data/template/v0_6/db-snapshot-b.osm000066400000000000000000000037311253404521400303100ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-apidb/src/test/resources/data/template/v0_6/db-snapshot.osm000066400000000000000000000037261253404521400300750ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-areafilter/000077500000000000000000000000001253404521400171045ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/.checkstyle000066400000000000000000000010051253404521400212370ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-areafilter/.gitignore000066400000000000000000000000531253404521400210720ustar00rootroot00000000000000.classpath .project .settings /bin /build osmosis-0.44.1/osmosis-areafilter/build.gradle000066400000000000000000000002131253404521400213570ustar00rootroot00000000000000dependencies { compile project(':osmosis-core') testCompile project(':osmosis-xml') testCompile project(':osmosis-testutil') } osmosis-0.44.1/osmosis-areafilter/src/000077500000000000000000000000001253404521400176735ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/main/000077500000000000000000000000001253404521400206175ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/main/java/000077500000000000000000000000001253404521400215405ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/main/java/org/000077500000000000000000000000001253404521400223275ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/main/java/org/openstreetmap/000077500000000000000000000000001253404521400252155ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/main/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400267115ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/main/java/org/openstreetmap/osmosis/areafilter/000077500000000000000000000000001253404521400310275ustar00rootroot00000000000000AreaFilterPluginLoader.java000066400000000000000000000023201253404521400361340ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/main/java/org/openstreetmap/osmosis/areafilter// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.areafilter; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.areafilter.v0_6.BoundingBoxFilterFactory; import org.openstreetmap.osmosis.areafilter.v0_6.PolygonFilterFactory; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.plugin.PluginLoader; /** * The plugin loader for the API Schema tasks. * * @author Brett Henderson */ public class AreaFilterPluginLoader implements PluginLoader { /** * {@inheritDoc} */ @Override public Map loadTaskFactories() { Map factoryMap; factoryMap = new HashMap(); factoryMap.put("bounding-box", new BoundingBoxFilterFactory()); factoryMap.put("bb", new BoundingBoxFilterFactory()); factoryMap.put("bounding-polygon", new PolygonFilterFactory()); factoryMap.put("bp", new PolygonFilterFactory()); factoryMap.put("bounding-box-0.6", new BoundingBoxFilterFactory()); factoryMap.put("bounding-polygon-0.6", new PolygonFilterFactory()); return factoryMap; } } osmosis-0.44.1/osmosis-areafilter/src/main/java/org/openstreetmap/osmosis/areafilter/common/000077500000000000000000000000001253404521400323175ustar00rootroot00000000000000PolygonFileReader.java000066400000000000000000000211421253404521400364550ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/main/java/org/openstreetmap/osmosis/areafilter/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.areafilter.common; import java.awt.geom.Area; import java.awt.geom.Path2D; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Reads the contents of a polygon file into an Area instance. *

* The file format is defined at http://www.maproom.psu.edu/dcw/. An example is * provided here. The first line contains the name of the file, the second line * contains the name of an individual polygon and if it is prefixed with ! it * means it is a negative polygon to be subtracted from the resultant extraction * polygon. *

 * australia_v
 * 1
 *      0.1446763E+03    -0.3825659E+02
 *      0.1446693E+03    -0.3826255E+02
 *      0.1446627E+03    -0.3825661E+02
 *      0.1446763E+03    -0.3824465E+02
 *      0.1446813E+03    -0.3824343E+02
 *      0.1446824E+03    -0.3824484E+02
 *      0.1446826E+03    -0.3825356E+02
 *      0.1446876E+03    -0.3825210E+02
 *      0.1446919E+03    -0.3824719E+02
 *      0.1447006E+03    -0.3824723E+02
 *      0.1447042E+03    -0.3825078E+02
 *      0.1446758E+03    -0.3826229E+02
 *      0.1446693E+03    -0.3826255E+02
 * END
 * !2
 *      0.1422483E+03    -0.3839481E+02
 *      0.1422436E+03    -0.3839315E+02
 *      0.1422496E+03    -0.3839070E+02
 *      0.1422543E+03    -0.3839025E+02
 *      0.1422574E+03    -0.3839155E+02
 *      0.1422467E+03    -0.3840065E+02
 *      0.1422433E+03    -0.3840048E+02
 *      0.1422420E+03    -0.3839857E+02
 *      0.1422436E+03    -0.3839315E+02
 * END
 * END
 * 
* * @author Brett Henderson */ public class PolygonFileReader { /** * Our logger for debug and error -output. */ private static final Logger LOG = Logger.getLogger(PolygonFileReader.class.getName()); /** * Where we read from. */ private Reader fileReader; /** * The filename for error-messages. */ private String polygonFile; /** * The name of the polygon as stated in the file-header. */ private String myPolygonName; /** * Creates a new instance. * * @param polygonFile * The file to read polygon units from. * @param name to report in debug output */ public PolygonFileReader(final InputStream polygonFile, final String name) { this.polygonFile = name; this.fileReader = new InputStreamReader(polygonFile); } /** * Creates a new instance. * * @param polygonFile * The file to read polygon units from. */ public PolygonFileReader(final File polygonFile) { try { this.polygonFile = polygonFile.getName(); this.fileReader = new FileReader(polygonFile); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to read from polygon file " + polygonFile + ".", e); } } /** * Releases any resources remaining open. */ private void cleanup() { if (fileReader != null) { try { fileReader.close(); } catch (Exception e) { LOG.log(Level.SEVERE, "Unable to close polygon file reader.", e); } finally { fileReader = null; } } } /** * Builds an Area configured with the polygon information defined in the * file. * * @return A fully configured area. */ public Area loadPolygon() { try { Area resultArea; BufferedReader bufferedReader; // Create a new area. resultArea = new Area(); // Open the polygon file. bufferedReader = new BufferedReader(fileReader); // Read the file header. myPolygonName = bufferedReader.readLine(); if (myPolygonName == null || myPolygonName.trim().length() == 0) { throw new OsmosisRuntimeException("The file must begin with a header naming the polygon file."); } // We now loop until no more sections are available. while (true) { String sectionHeader; boolean positivePolygon; Area sectionArea; // Read until a non-empty line is obtained. do { // Read the section header. sectionHeader = bufferedReader.readLine(); // It is invalid for the file to end without a global "END" record. if (sectionHeader == null) { throw new OsmosisRuntimeException("File terminated prematurely without a section END record."); } // Remove any whitespace. sectionHeader = sectionHeader.trim(); } while (sectionHeader.length() == 0); // Stop reading when the global END record is reached. if ("END".equals(sectionHeader)) { break; } // If the section header begins with a ! then the polygon is to // be subtracted from the result area. positivePolygon = (sectionHeader.charAt(0) != '!'); // Create an area for this polygon. sectionArea = loadSectionPolygon(bufferedReader); // Add or subtract the section area from the overall area as // appropriate. if (positivePolygon) { resultArea.add(sectionArea); } else { resultArea.subtract(sectionArea); } } return resultArea; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to read from polygon file " + polygonFile + ".", e); } finally { cleanup(); } } /** * Loads an individual polygon from the polygon file. * * @param bufferedReader * The reader connected to the polygon file placed at the first * record of a polygon section. * @return An area representing the section polygon. */ private Area loadSectionPolygon(BufferedReader bufferedReader) throws IOException { Path2D.Double polygonPath; double[] beginPoint = null; // Create a new path to represent this polygon. polygonPath = new Path2D.Double(); while (true) { String sectionLine; double[] coordinates; // Read until a non-empty line is obtained. do { sectionLine = bufferedReader.readLine(); // It is invalid for the file to end without a section "END" record. if (sectionLine == null) { throw new OsmosisRuntimeException("File terminated prematurely without a section END record."); } // Remove any whitespace. sectionLine = sectionLine.trim(); } while (sectionLine.length() == 0); // Stop reading when the section END record is reached. if ("END".equals(sectionLine)) { break; } // Parse the line into its coordinates. coordinates = parseCoordinates(sectionLine); // Add the current point to the path. if (beginPoint != null) { polygonPath.lineTo(coordinates[0], coordinates[1]); } else { polygonPath.moveTo(coordinates[0], coordinates[1]); beginPoint = coordinates; } } // If we received data, draw another line from the final point back to the beginning point. if (beginPoint != null) { polygonPath.moveTo(beginPoint[0], beginPoint[1]); } // Convert the path into an area and return. return new Area(polygonPath); } /** * Parses a coordinate line into its constituent double precision * coordinates. * * @param coordinateLine * The raw file line. * @return A pair of coordinate values, first is longitude, second is * latitude. */ private double[] parseCoordinates(String coordinateLine) { String[] rawTokens; double[] results; int tokenCount; // Split the line into its sub strings separated by whitespace. rawTokens = coordinateLine.split("\\s"); // Copy the non-zero tokens into a result array. tokenCount = 0; results = new double[2]; for (int i = 0; i < rawTokens.length; i++) { if (rawTokens[i].length() > 0) { // Ensure we have no more than 2 coordinate values. if (tokenCount >= 2) { throw new OsmosisRuntimeException( "A polygon coordinate line must contain 2 numbers, not (" + coordinateLine + ")." ); } // Parse the token into a double precision number. try { results[tokenCount++] = Double.parseDouble(rawTokens[i]); } catch (NumberFormatException e) { throw new OsmosisRuntimeException( "Unable to parse " + rawTokens[i] + " into a double precision number."); } } } // Ensure we found two tokens. if (tokenCount < 2) { throw new OsmosisRuntimeException("Could not find two coordinates on line (" + coordinateLine + ")."); } return results; } /** * This method must only be called after {@link #loadPolygon()}. * @return The name of the polygon as stated in the file-header. */ public String getPolygonName() { return myPolygonName; } } osmosis-0.44.1/osmosis-areafilter/src/main/java/org/openstreetmap/osmosis/areafilter/v0_6/000077500000000000000000000000001253404521400316015ustar00rootroot00000000000000AreaFilter.java000066400000000000000000000437441253404521400344170ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/main/java/org/openstreetmap/osmosis/areafilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.areafilter.v0_6; import java.util.Iterator; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityProcessor; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.openstreetmap.osmosis.core.filter.common.IdTracker; import org.openstreetmap.osmosis.core.filter.common.IdTrackerFactory; import org.openstreetmap.osmosis.core.filter.common.IdTrackerType; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.store.SimpleObjectStore; import org.openstreetmap.osmosis.core.store.SingleClassObjectSerializationFactory; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.task.v0_6.SinkSource; /** * A base class for all tasks filter entities within an area. * * @author Brett Henderson * @author Karl Newman */ public abstract class AreaFilter implements SinkSource, EntityProcessor { private Sink sink; private IdTracker availableNodes; // Nodes within the area. private IdTracker requiredNodes; // Nodes needed to complete referencing entities. private IdTracker availableWays; // Ways within the area. private IdTracker requiredWays; // Ways needed to complete referencing relations. private IdTracker availableRelations; // Relations within the area. private IdTracker requiredRelations; // Relations needed to complete referencing relations. private boolean clipIncompleteEntities; private boolean completeWays; private boolean completeRelations; private boolean storeEntities; private boolean cascadingRelations; private SimpleObjectStore allWays; private SimpleObjectStore allNodes; // this duplicates as a container for held-back relations in the cascadingRelations case: private SimpleObjectStore allRelations; /** * Creates a new instance. * * @param idTrackerType * Defines the id tracker implementation to use. * @param clipIncompleteEntities * If true, entities referring to non-existent entities will be * modified to ensure referential integrity. For example, ways * will be modified to only include nodes inside the area. * @param completeWays * Include all nodes for ways which have at least one node inside * the filtered area. * @param completeRelations * Include all relations referenced by other relations which have * members inside the filtered area. * @param cascadingRelations * Make sure that a relation referencing a relation which is included * will also be included. */ public AreaFilter( IdTrackerType idTrackerType, boolean clipIncompleteEntities, boolean completeWays, boolean completeRelations, boolean cascadingRelations) { this.clipIncompleteEntities = clipIncompleteEntities; // Allowing complete relations without complete ways is very difficult and not allowed for // now. this.completeWays = completeWays || completeRelations; this.completeRelations = completeRelations; // cascadingRelations is included for free with any of the complete options so you don't // need it if those are set. this.cascadingRelations = cascadingRelations && !completeRelations && !completeWays; availableNodes = IdTrackerFactory.createInstance(idTrackerType); requiredNodes = IdTrackerFactory.createInstance(idTrackerType); availableWays = IdTrackerFactory.createInstance(idTrackerType); requiredWays = IdTrackerFactory.createInstance(idTrackerType); availableRelations = IdTrackerFactory.createInstance(idTrackerType); requiredRelations = IdTrackerFactory.createInstance(idTrackerType); // If either complete ways or complete relations are required, then all data must be stored // during processing. storeEntities = completeWays || completeRelations; if (storeEntities) { allNodes = new SimpleObjectStore( new SingleClassObjectSerializationFactory(NodeContainer.class), "afn", true); allWays = new SimpleObjectStore( new SingleClassObjectSerializationFactory(WayContainer.class), "afw", true); allRelations = new SimpleObjectStore( new SingleClassObjectSerializationFactory(RelationContainer.class), "afr", true); } else if (cascadingRelations) { allRelations = new SimpleObjectStore( new SingleClassObjectSerializationFactory(RelationContainer.class), "afr", true); } } /** * {@inheritDoc} */ public void initialize(Map metaData) { sink.initialize(metaData); } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { // Ask the entity container to invoke the appropriate processing method // for the entity type. entityContainer.process(this); } /** * {@inheritDoc} */ public void process(BoundContainer boundContainer) { // By default, pass it on unchanged sink.process(boundContainer); } /** * Indicates if the node lies within the area required. * * @param node * The node to be checked. * @return True if the node lies within the area. */ protected abstract boolean isNodeWithinArea(Node node); /** * {@inheritDoc} */ public void process(NodeContainer container) { Node node; node = container.getEntity(); // Check if we're storing entities for later. if (storeEntities) { allNodes.add(container); } // Only add the node if it lies within the box boundaries. if (isNodeWithinArea(node)) { availableNodes.set(node.getId()); // If we're not storing entities, we pass it on immediately. if (!storeEntities) { emitNode(container); } } } /** * {@inheritDoc} */ public void process(WayContainer container) { Way way; boolean inArea; way = container.getEntity(); // Check if we're storing entities for later. if (storeEntities) { allWays.add(container); } // First look through all the nodes to see if any are within the filtered area inArea = false; for (WayNode nodeReference : way.getWayNodes()) { if (availableNodes.get(nodeReference.getNodeId())) { inArea = true; break; } } // If the way has at least one node in the filtered area. if (inArea) { availableWays.set(way.getId()); // If complete ways are desired, mark any unavailable nodes as required. if (completeWays) { for (WayNode nodeReference : way.getWayNodes()) { long nodeId = nodeReference.getNodeId(); if (!availableNodes.get(nodeId)) { requiredNodes.set(nodeId); } } } // If we're not storing entities, we pass it on immediately. if (!storeEntities) { emitWay(container); } } } /** * {@inheritDoc} */ public void process(RelationContainer container) { Relation relation; boolean inArea; boolean holdBackRelation; relation = container.getEntity(); // First look through all the node and way members to see if any are within the filtered area inArea = false; holdBackRelation = false; for (RelationMember member : relation.getMembers()) { switch (member.getMemberType()) { case Node: inArea = availableNodes.get(member.getMemberId()); break; case Way: inArea = availableWays.get(member.getMemberId()); break; case Relation: inArea = availableRelations.get(member.getMemberId()); break; default: break; } if (inArea) { break; } } if (cascadingRelations) { // && referencesOtherRelation && (!inArea || clipIncompleteEntities)) { holdBackRelation = true; } // Check if we're storing entities for later. if (storeEntities || holdBackRelation) { allRelations.add(container); } // If the relation has at least one member in the filtered area. if (inArea) { availableRelations.set(relation.getId()); // If we're not storing entities, we pass it on immediately. if (!storeEntities && !holdBackRelation) { emitRelation(container); } } } /** * Sends a node to the sink. This will perform any necessary transformations on the node before * sending it. * * @param nodeContainer * Node to be sent. */ private void emitNode(NodeContainer nodeContainer) { sink.process(nodeContainer); } /** * Sends a way to the sink. This will perform any necessary transformations on the way before * sending it. * * @param wayContainer * Way to be sent. */ private void emitWay(WayContainer wayContainer) { if (clipIncompleteEntities) { WayContainer filteredWayContainer; Way filteredWay; filteredWayContainer = wayContainer.getWriteableInstance(); filteredWay = filteredWayContainer.getEntity(); // Remove node references for nodes that are unavailable. for (Iterator i = filteredWay.getWayNodes().iterator(); i.hasNext();) { WayNode nodeReference = i.next(); if (!availableNodes.get(nodeReference.getNodeId())) { i.remove(); } } // Only add ways that contain nodes. if (filteredWay.getWayNodes().size() > 0) { sink.process(filteredWayContainer); } } else { sink.process(wayContainer); } } /** * Sends a relation to the sink. This will perform any necessary transformations on the way before * sending it. * * @param relationContainer * Relation to be sent. */ private void emitRelation(RelationContainer relationContainer) { if (clipIncompleteEntities) { RelationContainer filteredRelationContainer; Relation filteredRelation; filteredRelationContainer = relationContainer.getWriteableInstance(); filteredRelation = filteredRelationContainer.getEntity(); // Remove members for entities that are unavailable. for (Iterator i = filteredRelation.getMembers().iterator(); i.hasNext();) { RelationMember member = i.next(); EntityType memberType; long memberId; memberType = member.getMemberType(); memberId = member.getMemberId(); switch (memberType) { case Node: if (!availableNodes.get(memberId)) { i.remove(); } break; case Way: if (!availableWays.get(memberId)) { i.remove(); } break; case Relation: if (!availableRelations.get(memberId)) { i.remove(); } break; default: break; } } // Only add relations that contain entities. if (filteredRelation.getMembers().size() > 0) { sink.process(filteredRelationContainer); } } else { sink.process(relationContainer); } } private boolean selectParentRelationsPass() { ReleasableIterator i = allRelations.iterate(); try { int selectionCount; selectionCount = 0; while (i.hasNext()) { Relation relation = i.next().getEntity(); long relationId = relation.getId(); // Ignore relations that have already been selected. if (!availableRelations.get(relationId)) { // This relation becomes an available relation if one of its member // relations is also available. for (RelationMember member : relation.getMembers()) { if (member.getMemberType().equals(EntityType.Relation)) { if (availableRelations.get(member.getMemberId())) { availableRelations.set(relationId); selectionCount++; } } } } } return selectionCount > 0; } finally { i.release(); } } /** * Walk up the relation tree. This means iterating through relations until all parent relations * of existing relations are marked in the available list. We may have to do this multiple times * depending on the nesting level of relations. */ private void selectParentRelations() { boolean selectionsMade; do { selectionsMade = selectParentRelationsPass(); } while (selectionsMade); } /** * Select all relation members of type relation for existing selected relations. This may need * to be called several times until all children are selected. * * @return True if additional selections were made an another pass is needed. */ private boolean selectChildRelationsPass() { ReleasableIterator i = allRelations.iterate(); try { int selectionCount; selectionCount = 0; while (i.hasNext()) { Relation relation = i.next().getEntity(); long relationId = relation.getId(); // Only examine available relations. if (availableRelations.get(relationId)) { // Select the child if it hasn't already been selected. for (RelationMember member : relation.getMembers()) { if (member.getMemberType().equals(EntityType.Relation)) { long memberId = member.getMemberId(); if (!availableRelations.get(memberId)) { availableRelations.set(memberId); selectionCount++; } } } } } return selectionCount > 0; } finally { i.release(); } } /** * Select all relation members of type node or way for existing selected relations. */ private void selectChildNonRelationsPass() { ReleasableIterator i = allRelations.iterate(); try { while (i.hasNext()) { Relation relation = i.next().getEntity(); long relationId = relation.getId(); // Only examine available relations. if (availableRelations.get(relationId)) { // Select the member if it hasn't already been selected. for (RelationMember member : relation.getMembers()) { switch (member.getMemberType()) { case Node: availableNodes.set(member.getMemberId()); break; case Way: availableWays.set(member.getMemberId()); break; default: break; } } } } } finally { i.release(); } } /** * Select all nodes within already selected ways. */ private void selectWayNodes() { ReleasableIterator i = allWays.iterate(); try { while (i.hasNext()) { Way way = i.next().getEntity(); long wayId = way.getId(); // Only examine available relations. if (availableWays.get(wayId)) { // Select all nodes within the way. for (WayNode wayNode : way.getWayNodes()) { availableNodes.set(wayNode.getNodeId()); } } } } finally { i.release(); } } private void buildCompleteRelations() { boolean selectionsMade; // Select all child relation members of type relation. do { selectionsMade = selectChildRelationsPass(); } while (selectionsMade); // Select all child relation members of type way or node. selectChildNonRelationsPass(); // Select all way nodes of existing nodes. selectWayNodes(); } private void pumpNodesToSink() { ReleasableIterator i = allNodes.iterate(); try { while (i.hasNext()) { NodeContainer nodeContainer = i.next(); if (availableNodes.get(nodeContainer.getEntity().getId())) { emitNode(nodeContainer); } } } finally { i.release(); } } private void pumpWaysToSink() { ReleasableIterator i = allWays.iterate(); try { while (i.hasNext()) { WayContainer wayContainer = i.next(); if (availableWays.get(wayContainer.getEntity().getId())) { emitWay(wayContainer); } } } finally { i.release(); } } private void pumpRelationsToSink() { ReleasableIterator i = allRelations.iterate(); try { while (i.hasNext()) { RelationContainer relationContainer = i.next(); if (availableRelations.get(relationContainer.getEntity().getId())) { emitRelation(relationContainer); } } } finally { i.release(); } } /** * {@inheritDoc} */ public void complete() { // If we've stored entities temporarily, we now need to forward the selected ones to the output. if (storeEntities) { // Select all parents of current relations. selectParentRelations(); // Merge required ids into available ids. availableNodes.setAll(requiredNodes); availableWays.setAll(requiredWays); availableRelations.setAll(requiredRelations); requiredNodes = null; requiredWays = null; requiredRelations = null; if (completeRelations) { buildCompleteRelations(); } // Send the selected entities to the output. pumpNodesToSink(); pumpWaysToSink(); pumpRelationsToSink(); } else if (cascadingRelations) { // Select all parents of current relations. selectParentRelations(); availableRelations.setAll(requiredRelations); // nodes, ways, and relations *not* referencing other relations will already have // been written in this mode. we only pump the remaining ones, relations that // reference other relations. this may result in an un-ordered relation stream. pumpRelationsToSink(); } sink.complete(); } /** * {@inheritDoc} */ public void release() { if (allNodes != null) { allNodes.release(); } if (allWays != null) { allWays.release(); } if (allRelations != null) { allRelations.release(); } sink.release(); } /** * {@inheritDoc} */ public void setSink(Sink sink) { this.sink = sink; } } AreaFilterTaskManagerFactory.java000066400000000000000000000020331253404521400400470ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/main/java/org/openstreetmap/osmosis/areafilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.areafilter.v0_6; import org.openstreetmap.osmosis.core.filter.common.IdTrackerType; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; /** * Extends the basic task manager factory functionality with area filter task * specific common methods. * * @author Brett Henderson */ public abstract class AreaFilterTaskManagerFactory extends TaskManagerFactory { private static final IdTrackerType DEFAULT_ID_TRACKER_TYPE = IdTrackerType.Dynamic; /** * Utility method for retrieving the login credentials for a database * connection. * * @param taskConfig * Contains all information required to instantiate and configure * the task. * @return The entity identifier tracker type. */ protected IdTrackerType getIdTrackerType(TaskConfiguration taskConfig) { return DEFAULT_ID_TRACKER_TYPE; } } BoundingBoxFilter.java000066400000000000000000000070441253404521400357560ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/main/java/org/openstreetmap/osmosis/areafilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.areafilter.v0_6; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.filter.common.IdTrackerType; /** * Provides a filter for extracting all entities that lie within a specific geographical box * identified by latitude and longitude coordinates. * * @author Brett Henderson */ public class BoundingBoxFilter extends AreaFilter { private Bound bound; // use a Bound for the internal representation /** * Creates a new instance with the specified geographical coordinates. When filtering, nodes * right on the edge of the box will be included. * * @param idTrackerType * Defines the id tracker implementation to use. * @param left * The longitude marking the left edge of the bounding box. * @param right * The longitude marking the right edge of the bounding box. * @param top * The latitude marking the top edge of the bounding box. * @param bottom * The latitude marking the bottom edge of the bounding box. * @param clipIncompleteEntities * If true, entities referring to non-existent entities will be * modified to ensure referential integrity. For example, ways * will be modified to only include nodes inside the area. * @param completeWays * Include all nodes for ways which have at least one node inside the filtered area. * @param completeRelations * Include all relations referenced by other relations which have members inside the * filtered area. * @param cascadingRelations * Include all relations that reference other relations which have members inside the * filtered area. This is less costly than completeRelations. */ public BoundingBoxFilter(IdTrackerType idTrackerType, double left, double right, double top, double bottom, boolean clipIncompleteEntities, boolean completeWays, boolean completeRelations, boolean cascadingRelations) { super(idTrackerType, clipIncompleteEntities, completeWays, completeRelations, cascadingRelations); this.bound = new Bound(right, left, top, bottom, ""); } /** * {@inheritDoc} */ @Override public void process(BoundContainer boundContainer) { Bound newBound; /* * The order of calling intersect is important because the first non-empty origin string * will be used for the resulting Bound, and we want the origin string from the pipeline * Bound to be used. */ newBound = boundContainer.getEntity().intersect(bound); // intersect will return null if there is no overlapping area if (newBound != null) { // Send on a bound element clipped to the area super.process(new BoundContainer(newBound)); } } /** * {@inheritDoc} */ @Override protected boolean isNodeWithinArea(Node node) { double latitude; double longitude; latitude = node.getLatitude(); longitude = node.getLongitude(); /* * Check the node coordinates against the bounding box by comparing them to each "simple" * bound. */ for (Bound b : bound.toSimpleBound()) { if (b.getTop() >= latitude && b.getBottom() <= latitude && b.getLeft() <= longitude && b.getRight() >= longitude) { return true; } } return false; } } BoundingBoxFilterFactory.java000066400000000000000000000105631253404521400373060ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/main/java/org/openstreetmap/osmosis/areafilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.areafilter.v0_6; import org.openstreetmap.osmosis.core.filter.common.IdTrackerType; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkSourceManager; /** * The task manager factory for a bounding box filter. * * @author Brett Henderson */ public class BoundingBoxFilterFactory extends AreaFilterTaskManagerFactory { private static final String ARG_LEFT = "left"; private static final String ARG_RIGHT = "right"; private static final String ARG_TOP = "top"; private static final String ARG_BOTTOM = "bottom"; private static final String ARG_X1 = "x1"; private static final String ARG_Y1 = "y1"; private static final String ARG_X2 = "x2"; private static final String ARG_Y2 = "y2"; private static final String ARG_ZOOM = "zoom"; private static final String ARG_CLIP_INCOMPLETE_ENTITIES = "clipIncompleteEntities"; private static final String ARG_COMPLETE_WAYS = "completeWays"; private static final String ARG_COMPLETE_RELATIONS = "completeRelations"; private static final String ARG_CASCADING_RELATIONS = "cascadingRelations"; private static final double DEFAULT_LEFT = -180; private static final double DEFAULT_RIGHT = 180; private static final double DEFAULT_TOP = 90; private static final double DEFAULT_BOTTOM = -90; private static final int DEFAULT_ZOOM = 12; private static final boolean DEFAULT_CLIP_INCOMPLETE_ENTITIES = false; private static final boolean DEFAULT_COMPLETE_WAYS = false; private static final boolean DEFAULT_COMPLETE_RELATIONS = false; private static final boolean DEFAULT_CASCADING_RELATIONS = false; private double xToLon(int zoom, int x) { double unit = 360 / Math.pow(2, zoom); return -180 + x * unit; } private double projectF(double lat) { // Project latitude to mercator return Math.log(Math.tan(lat) + 1 / Math.cos(lat)); } private double projectMercToLat(double y) { return Math.toDegrees(Math.atan(Math.sinh(y))); } private double yToLat(int zoom, int y) { // Convert zoom/y to mercator // Get maximum range of mercator coordinates double limitY = projectF(Math.atan(Math.sinh(Math.PI))); double limitY2 = projectF((Math.atan(Math.sinh(-Math.PI)))); double rangeY = limitY - limitY2; double unit = 1 / Math.pow(2, zoom); double relY = limitY - rangeY * y * unit; // Mercator to latitude return projectMercToLat(relY); } /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { IdTrackerType idTrackerType; double left; double right; double top; double bottom; boolean clipIncompleteEntities; boolean completeWays; boolean completeRelations; boolean cascadingRelations; int zoom; // Get the task arguments. idTrackerType = getIdTrackerType(taskConfig); left = getDoubleArgument(taskConfig, ARG_LEFT, DEFAULT_LEFT); right = getDoubleArgument(taskConfig, ARG_RIGHT, DEFAULT_RIGHT); top = getDoubleArgument(taskConfig, ARG_TOP, DEFAULT_TOP); bottom = getDoubleArgument(taskConfig, ARG_BOTTOM, DEFAULT_BOTTOM); clipIncompleteEntities = getBooleanArgument( taskConfig, ARG_CLIP_INCOMPLETE_ENTITIES, DEFAULT_CLIP_INCOMPLETE_ENTITIES); completeWays = getBooleanArgument(taskConfig, ARG_COMPLETE_WAYS, DEFAULT_COMPLETE_WAYS); completeRelations = getBooleanArgument(taskConfig, ARG_COMPLETE_RELATIONS, DEFAULT_COMPLETE_RELATIONS); cascadingRelations = getBooleanArgument(taskConfig, ARG_CASCADING_RELATIONS, DEFAULT_CASCADING_RELATIONS); zoom = getIntegerArgument(taskConfig, ARG_ZOOM, DEFAULT_ZOOM); if (doesArgumentExist(taskConfig, ARG_X1)) { int x1 = getIntegerArgument(taskConfig, ARG_X1); left = xToLon(zoom, x1); right = xToLon(zoom, getIntegerArgument(taskConfig, ARG_X2, x1) + 1); } if (doesArgumentExist(taskConfig, ARG_Y1)) { int y1 = getIntegerArgument(taskConfig, ARG_Y1); top = yToLat(zoom, y1); bottom = yToLat(zoom, getIntegerArgument(taskConfig, ARG_Y2, y1) + 1); } return new SinkSourceManager( taskConfig.getId(), new BoundingBoxFilter(idTrackerType, left, right, top, bottom, clipIncompleteEntities, completeWays, completeRelations, cascadingRelations), taskConfig.getPipeArgs() ); } } PolygonFilter.java000066400000000000000000000104521253404521400351640ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/main/java/org/openstreetmap/osmosis/areafilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.areafilter.v0_6; import java.awt.geom.Area; import java.awt.geom.Rectangle2D; import java.io.File; import org.openstreetmap.osmosis.areafilter.common.PolygonFileReader; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.filter.common.IdTrackerType; /** * Provides a filter for extracting all entities that lie within a specific * geographical box identified by latitude and longitude coordinates. * * @author Brett Henderson */ public class PolygonFilter extends AreaFilter { private File polygonFile; private Area area; /** * Creates a new instance. * * @param idTrackerType * Defines the id tracker implementation to use. * @param polygonFile * The file containing the polygon coordinates. * @param clipIncompleteEntities * If true, entities referring to non-existent entities will be * modified to ensure referential integrity. For example, ways * will be modified to only include nodes inside the area. * @param completeWays * Include all nodes for ways which have at least one node inside the filtered area. * @param completeRelations * Include all relations referenced by other relations which have members inside * the filtered area. * @param cascadingRelations * Include all relations that reference other relations which have members inside the * filtered area. This is less costly than completeRelations. */ public PolygonFilter( IdTrackerType idTrackerType, File polygonFile, boolean clipIncompleteEntities, boolean completeWays, boolean completeRelations, boolean cascadingRelations) { super(idTrackerType, clipIncompleteEntities, completeWays, completeRelations, cascadingRelations); this.polygonFile = polygonFile; area = null; } /** * {@inheritDoc} */ @Override public void process(BoundContainer boundContainer) { Bound newBound = null; // Configure the area if it hasn't been created yet. (Should this be in an "initialize" method?) if (area == null) { area = new PolygonFileReader(polygonFile).loadPolygon(); } for (Bound b : boundContainer.getEntity().toSimpleBound()) { if (newBound == null) { newBound = simpleBoundIntersect(b); } else { newBound = newBound.union(simpleBoundIntersect(b)); } } if (newBound != null) { super.process(new BoundContainer(newBound)); } } /** * Get the simple intersection of this polygon with the passed Bound. * * @param bound * Bound with which to intersect. Must be "simple" (not cross antimeridian). * @return Bound resulting rectangular area after intersection */ private Bound simpleBoundIntersect(Bound bound) { Rectangle2D r; double width, height; Bound newBound = null; Area a2 = (Area) area.clone(); // make a copy so we don't disturb the original /* * Note that AWT uses the computer graphics convention with the origin at the top left, so * top and bottom are reversed for a Rectangle2D vs. a Bound. */ if (bound.getLeft() > bound.getRight()) { return null; } width = bound.getRight() - bound.getLeft(); height = bound.getTop() - bound.getBottom(); /* * Perform the intersect against the Area itself instead of its bounding box for maximum * precision. */ a2.intersect(new Area(new Rectangle2D.Double( bound.getLeft(), bound.getBottom(), width, height))); if (!a2.isEmpty()) { r = a2.getBounds2D(); newBound = new Bound( r.getMaxX(), r.getMinX(), r.getMaxY(), r.getMinY(), bound.getOrigin()); } return newBound; } /** * {@inheritDoc} */ @Override protected boolean isNodeWithinArea(Node node) { double latitude; double longitude; // Configure the area if it hasn't been created yet. if (area == null) { area = new PolygonFileReader(polygonFile).loadPolygon(); } latitude = node.getLatitude(); longitude = node.getLongitude(); return area.contains(longitude, latitude); } } PolygonFilterFactory.java000066400000000000000000000046531253404521400365220ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/main/java/org/openstreetmap/osmosis/areafilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.areafilter.v0_6; import java.io.File; import org.openstreetmap.osmosis.core.filter.common.IdTrackerType; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkSourceManager; /** * The task manager factory for a polygon filter. * * @author Brett Henderson */ public class PolygonFilterFactory extends AreaFilterTaskManagerFactory { private static final String ARG_FILE = "file"; private static final String DEFAULT_FILE = "polygon.txt"; private static final String ARG_CLIP_INCOMPLETE_ENTITIES = "clipIncompleteEntities"; private static final String ARG_COMPLETE_WAYS = "completeWays"; private static final String ARG_COMPLETE_RELATIONS = "completeRelations"; private static final String ARG_CASCADING_RELATIONS = "cascadingRelations"; private static final boolean DEFAULT_CLIP_INCOMPLETE_ENTITIES = false; private static final boolean DEFAULT_COMPLETE_WAYS = false; private static final boolean DEFAULT_COMPLETE_RELATIONS = false; private static final boolean DEFAULT_CASCADING_RELATIONS = false; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { IdTrackerType idTrackerType; String fileName; File file; boolean clipIncompleteEntities; boolean completeWays; boolean completeRelations; boolean cascadingRelations; // Get the task arguments. idTrackerType = getIdTrackerType(taskConfig); fileName = getStringArgument(taskConfig, ARG_FILE, DEFAULT_FILE); clipIncompleteEntities = getBooleanArgument( taskConfig, ARG_CLIP_INCOMPLETE_ENTITIES, DEFAULT_CLIP_INCOMPLETE_ENTITIES); completeWays = getBooleanArgument(taskConfig, ARG_COMPLETE_WAYS, DEFAULT_COMPLETE_WAYS); completeRelations = getBooleanArgument(taskConfig, ARG_COMPLETE_RELATIONS, DEFAULT_COMPLETE_RELATIONS); cascadingRelations = getBooleanArgument(taskConfig, ARG_CASCADING_RELATIONS, DEFAULT_CASCADING_RELATIONS); // Create a file object from the file name provided. file = new File(fileName); return new SinkSourceManager( taskConfig.getId(), new PolygonFilter(idTrackerType, file, clipIncompleteEntities, completeWays, completeRelations, cascadingRelations), taskConfig.getPipeArgs() ); } } osmosis-0.44.1/osmosis-areafilter/src/main/resources/000077500000000000000000000000001253404521400226315ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/main/resources/osmosis-plugins.conf000066400000000000000000000000731253404521400266530ustar00rootroot00000000000000org.openstreetmap.osmosis.areafilter.AreaFilterPluginLoaderosmosis-0.44.1/osmosis-areafilter/src/test/000077500000000000000000000000001253404521400206525ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/test/java/000077500000000000000000000000001253404521400215735ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/test/java/org/000077500000000000000000000000001253404521400223625ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/test/java/org/openstreetmap/000077500000000000000000000000001253404521400252505ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/test/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400267445ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/test/java/org/openstreetmap/osmosis/areafilter/000077500000000000000000000000001253404521400310625ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/test/java/org/openstreetmap/osmosis/areafilter/v0_6/000077500000000000000000000000001253404521400316345ustar00rootroot00000000000000AreaFilterTest.java000066400000000000000000000140641253404521400353030ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/test/java/org/openstreetmap/osmosis/areafilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.areafilter.v0_6; import java.io.File; import java.io.IOException; import org.junit.Test; import org.openstreetmap.osmosis.core.Osmosis; import org.openstreetmap.osmosis.testutil.AbstractDataTest; /** * Tests the area filter implementation. */ public class AreaFilterTest extends AbstractDataTest { /** * A basic test verifying that the area filter includes all data when the complete planet is selected. * * @throws IOException * if any file operations fail. */ @Test public void testEntirePlanet() throws IOException { File inputFile; File expectedOutputFile; File actualOutputFile; // Generate input files. inputFile = dataUtils.createDataFile("v0_6/areafilter-in.osm"); expectedOutputFile = dataUtils.createDataFile("v0_6/areafilter-out-whole.osm"); actualOutputFile = dataUtils.newFile(); // Load the database with a dataset. Osmosis.run( new String [] { "-q", "--read-xml-0.6", inputFile.getPath(), "--bounding-box", "--tag-sort-0.6", "--write-xml-0.6", actualOutputFile.getPath() } ); // Validate that the output file matches the input file. dataUtils.compareFiles(expectedOutputFile, actualOutputFile); } /** * Performs a standard bounding box filter. * * @throws IOException * if any file operations fail. */ @Test public void testBboxFilterStandard() throws IOException { File inputFile; File expectedOutputFile; File actualOutputFile; // Generate input files. inputFile = dataUtils.createDataFile("v0_6/areafilter-in.osm"); expectedOutputFile = dataUtils.createDataFile("v0_6/areafilter-out-standard.osm"); actualOutputFile = dataUtils.newFile(); // Load the database with a dataset. Osmosis.run( new String [] { "-q", "--read-xml-0.6", inputFile.getPath(), "--bounding-box", "left=-10", "top=10", "right=10", "bottom=-10", "--tag-sort-0.6", "--write-xml-0.6", actualOutputFile.getPath() } ); // Validate that the output file matches the input file. dataUtils.compareFiles(expectedOutputFile, actualOutputFile); } /** * Performs a standard bounding box filter with the cascadingRelations feature added. * * @throws IOException * if any file operations fail. */ @Test public void testBboxFilterCascadingRelations() throws IOException { File inputFile; File expectedOutputFile; File actualOutputFile; // Generate input files. inputFile = dataUtils.createDataFile("v0_6/areafilter-in.osm"); expectedOutputFile = dataUtils.createDataFile("v0_6/areafilter-out-cascadingrelations.osm"); actualOutputFile = dataUtils.newFile(); // Load the database with a dataset. Osmosis.run( new String [] { "-q", "--read-xml-0.6", inputFile.getPath(), "--bounding-box", "cascadingRelations=yes", "left=-10", "top=10", "right=10", "bottom=-10", "--tag-sort-0.6", "--write-xml-0.6", actualOutputFile.getPath() } ); // Validate that the output file matches the input file. dataUtils.compareFiles(expectedOutputFile, actualOutputFile); } /** * Performs a bounding box filter with the completeWays option enabled. * * @throws IOException * if any file operations fail. */ @Test public void testBboxFilterCompleteWays() throws IOException { File inputFile; File expectedOutputFile; File actualOutputFile; // Generate input files. inputFile = dataUtils.createDataFile("v0_6/areafilter-in.osm"); expectedOutputFile = dataUtils.createDataFile("v0_6/areafilter-out-completeways.osm"); actualOutputFile = dataUtils.newFile(); // Load the database with a dataset. Osmosis.run( new String [] { "-q", "--read-xml-0.6", inputFile.getPath(), "--bounding-box", "completeWays=yes", "left=-10", "top=10", "right=10", "bottom=-10", "--tag-sort-0.6", "--write-xml-0.6", actualOutputFile.getPath() } ); // Validate that the output file matches the input file. dataUtils.compareFiles(expectedOutputFile, actualOutputFile); } /** * Performs a bounding box filter with the completeRelations option enabled. * * @throws IOException * if any file operations fail. */ @Test public void testBboxFilterCompleteRelations() throws IOException { File inputFile; File expectedOutputFile; File actualOutputFile; // Generate input files. inputFile = dataUtils.createDataFile("v0_6/areafilter-in.osm"); expectedOutputFile = dataUtils.createDataFile("v0_6/areafilter-out-completerelations.osm"); actualOutputFile = dataUtils.newFile(); // Load the database with a dataset. Osmosis.run( new String [] { "-q", "--read-xml-0.6", inputFile.getPath(), "--bounding-box", "completeRelations=yes", "left=-10", "top=10", "right=10", "bottom=-10", "--tag-sort-0.6", "--write-xml-0.6", actualOutputFile.getPath() } ); // Validate that the output file matches the input file. dataUtils.compareFiles(expectedOutputFile, actualOutputFile); } /** * Performs a bounding box filter with the clipIncompleteEntities option enabled. * * @throws IOException * if any file operations fail. */ @Test public void testBboxFilterClipIncompleteEntities() throws IOException { File inputFile; File expectedOutputFile; File actualOutputFile; // Generate input files. inputFile = dataUtils.createDataFile("v0_6/areafilter-in.osm"); expectedOutputFile = dataUtils.createDataFile("v0_6/areafilter-out-clipincompleteentities.osm"); actualOutputFile = dataUtils.newFile(); // Load the database with a dataset. Osmosis.run( new String [] { "-q", "--read-xml-0.6", inputFile.getPath(), "--bounding-box", "clipIncompleteEntities=yes", "left=-10", "top=10", "right=10", "bottom=-10", "--tag-sort-0.6", "--write-xml-0.6", actualOutputFile.getPath() } ); // Validate that the output file matches the input file. dataUtils.compareFiles(expectedOutputFile, actualOutputFile); } } BoundingBoxFilterTest.java000066400000000000000000000122061253404521400366450ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/test/java/org/openstreetmap/osmosis/areafilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.areafilter.v0_6; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.filter.common.IdTrackerType; import org.openstreetmap.osmosis.testutil.v0_6.SinkEntityInspector; /** * @author Karl Newman * */ public class BoundingBoxFilterTest { private SinkEntityInspector entityInspector; private AreaFilter simpleAreaFilter; private Bound intersectingBound; private Bound nonIntersectingBound; private Node inAreaNode; private Node outOfAreaNode; private Node edgeNodeEast; private Node edgeNodeWest; private Node edgeNodeNorth; private Node edgeNodeSouth; /** * Performs pre-test activities. */ @Before public void setUp() { OsmUser user; List tags; user = new OsmUser(12, "OsmosisTest"); // All nodes have an empty tags list. tags = new ArrayList(); entityInspector = new SinkEntityInspector(); // simpleAreaFilter doesn't cross antimeridian; no complete ways or relations simpleAreaFilter = new BoundingBoxFilter( IdTrackerType.Dynamic, -20, 20, 20, -20, false, false, false, false); simpleAreaFilter.setSink(entityInspector); intersectingBound = new Bound(30, 10, 30, 10, "intersecting"); nonIntersectingBound = new Bound(-30, -50, 10, -10, "nonintersecting"); inAreaNode = new Node(new CommonEntityData(1234, 0, new Date(), user, 0, tags), 10, 10); outOfAreaNode = new Node(new CommonEntityData(1235, 0, new Date(), user, 0, tags), 30, 30); edgeNodeEast = new Node(new CommonEntityData(1236, 0, new Date(), user, 0, tags), 10, 20); edgeNodeWest = new Node(new CommonEntityData(1237, 0, new Date(), user, 0, tags), 10, -20); edgeNodeNorth = new Node(new CommonEntityData(1238, 0, new Date(), user, 0, tags), 20, 10); edgeNodeSouth = new Node(new CommonEntityData(1239, 0, new Date(), user, 0, tags), -20, 10); } /** * Performs post-test activities. */ @After public void tearDown() { simpleAreaFilter.release(); } /** * Test passing a Bound which intersects the filter area. */ @Test public final void testProcessBoundContainer1() { Bound compareBound; simpleAreaFilter.process(new BoundContainer(intersectingBound)); simpleAreaFilter.complete(); compareBound = (Bound) entityInspector.getLastEntityContainer().getEntity(); assertTrue(Double.compare(compareBound.getRight(), 20) == 0); assertTrue(Double.compare(compareBound.getLeft(), 10) == 0); assertTrue(Double.compare(compareBound.getTop(), 20) == 0); assertTrue(Double.compare(compareBound.getBottom(), 10) == 0); assertTrue(compareBound.getOrigin().equals("intersecting")); } /** * Test the non-passing of a Bound which does not intersect the filter area. */ @Test public final void testProcessBoundContainer2() { simpleAreaFilter.process(new BoundContainer(nonIntersectingBound)); simpleAreaFilter.complete(); assertNull(entityInspector.getLastEntityContainer()); } /** * Test a node inside the area. */ @Test public final void testIsNodeWithinArea1() { assertTrue( "Node lying inside filter area not considered inside area", simpleAreaFilter.isNodeWithinArea(inAreaNode)); } /** * Test a node outside the area. */ @Test public final void testIsNodeWithinArea2() { assertFalse( "Node lying outside filter area not considered outside area", simpleAreaFilter.isNodeWithinArea(outOfAreaNode)); } /** * Test a node on the East edge of the area. */ @Test public final void testIsNodeWithinArea3() { assertTrue( "Node lying on East edge of filter area not considered inside area", simpleAreaFilter.isNodeWithinArea(edgeNodeEast)); } /** * Test a node on the West edge of the area. */ @Test public final void testIsNodeWithinArea4() { assertTrue( "Node lying on West edge of filter area not considered inside area", simpleAreaFilter.isNodeWithinArea(edgeNodeWest)); } /** * Test a node on the North edge of the area. */ @Test public final void testIsNodeWithinArea5() { assertTrue( "Node lying on North edge of filter area not considered inside area", simpleAreaFilter.isNodeWithinArea(edgeNodeNorth)); } /** * Test a node on the South edge of the area. */ @Test public final void testIsNodeWithinArea6() { assertTrue( "Node lying on South edge of filter area not considered inside area", simpleAreaFilter.isNodeWithinArea(edgeNodeSouth)); } } PolygonFilterTest.java000066400000000000000000000116121253404521400360560ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/test/java/org/openstreetmap/osmosis/areafilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.areafilter.v0_6; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.io.File; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.filter.common.IdTrackerType; import org.openstreetmap.osmosis.testutil.v0_6.SinkEntityInspector; /** * Tests the polygon area filter implementation. * * @author Karl Newman */ public class PolygonFilterTest { private File polygonFile; private SinkEntityInspector entityInspector; private AreaFilter polyAreaFilter; private Bound intersectingBound; private Bound crossingIntersectingBound; private Bound nonIntersectingBound; private Node inAreaNode; private Node outOfAreaNode; private Node edgeNode; /** * Performs pre-test activities. */ @Before public void setUp() { OsmUser user; List tags; user = new OsmUser(12, "OsmosisTest"); // All nodes have an empty tags list. tags = new ArrayList(); polygonFile = new File(getClass().getResource("testPolygon.txt").getFile()); entityInspector = new SinkEntityInspector(); // polyAreaFilter has a notch out of the Northeast corner. polyAreaFilter = new PolygonFilter(IdTrackerType.Dynamic, polygonFile, false, false, false, false); polyAreaFilter.setSink(entityInspector); intersectingBound = new Bound(30, 0, 30, 0, "intersecting"); crossingIntersectingBound = new Bound(-10, 10, 30, -30, "crossing intersecting"); nonIntersectingBound = new Bound(30, 15, 30, 15, "nonintersecting"); inAreaNode = new Node(new CommonEntityData(1234, 0, new Date(), user, 0, tags), 5, 10); outOfAreaNode = new Node(new CommonEntityData(1235, 0, new Date(), user, 0, tags), 15, 15); edgeNode = new Node(new CommonEntityData(1236, 0, new Date(), user, 0, tags), 15, 10); } /** * Performs post-test activities. */ @After public void tearDown() { polyAreaFilter.release(); } /** * Test passing a Bound which intersects the filter area. */ @Test public final void testProcessBoundContainer1() { Bound compareBound; polyAreaFilter.process(new BoundContainer(intersectingBound)); polyAreaFilter.complete(); compareBound = (Bound) entityInspector.getLastEntityContainer().getEntity(); assertTrue(Double.compare(compareBound.getRight(), 20) == 0); assertTrue(Double.compare(compareBound.getLeft(), 0) == 0); assertTrue(Double.compare(compareBound.getTop(), 20) == 0); assertTrue(Double.compare(compareBound.getBottom(), 0) == 0); assertTrue(compareBound.getOrigin().equals("intersecting")); } /** * Test passing a Bound which crosses the antimeredian and intersects the filter area. */ @Test public final void testProcessBoundContainer2() { Bound compareBound; polyAreaFilter.process(new BoundContainer(crossingIntersectingBound)); polyAreaFilter.complete(); compareBound = (Bound) entityInspector.getLastEntityContainer().getEntity(); assertTrue(Double.compare(compareBound.getRight(), 20) == 0); assertTrue(Double.compare(compareBound.getLeft(), -20) == 0); assertTrue(Double.compare(compareBound.getTop(), 20) == 0); assertTrue(Double.compare(compareBound.getBottom(), -20) == 0); assertTrue(compareBound.getOrigin().equals("crossing intersecting")); } /** * Test the non-passing of a Bound which does not intersect the filter area. */ @Test public final void testProcessBoundContainer3() { polyAreaFilter.process(new BoundContainer(nonIntersectingBound)); polyAreaFilter.complete(); assertNull(entityInspector.getLastEntityContainer()); } /** * Test a Node that falls inside the filter area. */ @Test public final void testIsNodeWithinArea1() { assertTrue( "Node lying inside filter area not considered inside area.", polyAreaFilter.isNodeWithinArea(inAreaNode)); } /** * Test a Node that falls outside the filter area (inside the notched-out area of the polygon). */ @Test public final void testIsNodeWithinArea2() { assertFalse( "Node lying outside filter area not considered outside area.", polyAreaFilter.isNodeWithinArea(outOfAreaNode)); } /** * Test a Node that falls on the edge of the filter area. */ @Test public final void testIsNodeWithinArea3() { assertFalse( "Node lying on edge of filter area not considered inside area.", polyAreaFilter.isNodeWithinArea(edgeNode)); } } osmosis-0.44.1/osmosis-areafilter/src/test/resources/000077500000000000000000000000001253404521400226645ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/test/resources/data/000077500000000000000000000000001253404521400235755ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/test/resources/data/template/000077500000000000000000000000001253404521400254105ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/test/resources/data/template/v0_6/000077500000000000000000000000001253404521400261625ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/test/resources/data/template/v0_6/areafilter-in.osm000066400000000000000000000045711253404521400314330ustar00rootroot00000000000000 areafilter-out-cascadingrelations.osm000066400000000000000000000032501253404521400354010ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/test/resources/data/template/v0_6 areafilter-out-clipincompleteentities.osm000066400000000000000000000025001253404521400363150ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/test/resources/data/template/v0_6 areafilter-out-completerelations.osm000066400000000000000000000045671253404521400353110ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/test/resources/data/template/v0_6 areafilter-out-completeways.osm000066400000000000000000000035161253404521400342650ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/test/resources/data/template/v0_6 osmosis-0.44.1/osmosis-areafilter/src/test/resources/data/template/v0_6/areafilter-out-standard.osm000066400000000000000000000026141253404521400334260ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-areafilter/src/test/resources/data/template/v0_6/areafilter-out-whole.osm000066400000000000000000000041351253404521400327440ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-areafilter/src/test/resources/org/000077500000000000000000000000001253404521400234535ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/test/resources/org/openstreetmap/000077500000000000000000000000001253404521400263415ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/test/resources/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400300355ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/test/resources/org/openstreetmap/osmosis/areafilter/000077500000000000000000000000001253404521400321535ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/test/resources/org/openstreetmap/osmosis/areafilter/v0_6/000077500000000000000000000000001253404521400327255ustar00rootroot00000000000000testPolygon.txt000066400000000000000000000004311253404521400357340ustar00rootroot00000000000000osmosis-0.44.1/osmosis-areafilter/src/test/resources/org/openstreetmap/osmosis/areafilter/v0_6testpolygon 1 -0.2000000E+02 0.2000000E+02 0.1000000E+02 0.2000000E+02 0.1000000E+02 0.1000000E+02 0.2000000E+02 0.1000000E+02 0.2000000E+02 -0.2000000E+02 -0.2000000E+02 -0.2000000E+02 -0.2000000E+02 0.2000000E+02 END END osmosis-0.44.1/osmosis-core/000077500000000000000000000000001253404521400157165ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/.checkstyle000066400000000000000000000010051253404521400200510ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-core/.gitignore000066400000000000000000000002641253404521400177100ustar00rootroot00000000000000.classpath .project .settings /bin /build /src/main/java/org/openstreetmap/osmosis/core/OsmosisConstants.java /src/main/resources/org/openstreetmap/osmosis/core/plugin/plugin.xml osmosis-0.44.1/osmosis-core/build.gradle000066400000000000000000000056131253404521400202020ustar00rootroot00000000000000configurations { // Exclude because all necessary APIs are included in the JDK. all*.exclude group: 'xml-apis', module: 'xml-apis' // Exclude because Stax is included in the JDK from java 1.6 onwards. all*.exclude group: 'javax.xml.stream', module: 'stax-api' } dependencies { compile group: 'net.sf.jpf', name: 'jpf', version: dependencyVersionJpf compile group: 'org.codehaus.woodstox', name: 'woodstox-core-lgpl', version: dependencyVersionWoodstoxCore compile group: 'org.codehaus.woodstox', name: 'stax2-api', version: dependencyVersionWoodstoxStax2 compile group: 'org.apache.commons', name: 'commons-compress', version: dependencyVersionCommonsCompress compile group: 'xerces', name: 'xercesImpl', version: dependencyVersionXerces } /* * Define a custom task to automatically generate the OsmosisConstants file * and update the java compilation task to depend on it. */ task generateJavaSources { description = 'Generates the OsmosisConstants java file with the current version number.' // Build file objects for our template file, and output java file. def commonPathPrefix = "$projectDir/src/main/java/org/openstreetmap/osmosis/core/OsmosisConstants.java" def outputFile = new File(commonPathPrefix) def inputFile = new File(commonPathPrefix + ".template") /* * Declare inputs and outputs of the task to allow gradle to determine if * it is up to date. */ inputs.file inputFile inputs.property('version', version) outputs.file outputFile doLast { // Insert the version string into the constants file. def fileContent = inputFile.getText() fileContent = fileContent.replace("no-version-specified", version) outputFile.write(fileContent) } } // Define task dependency to ensure constants file is always up to date. compileJava.dependsOn generateJavaSources /* * Define a custom task to automatically generate the plugin.xml file * and update the copy resources task to depend on it. */ task generateResources { description = 'Generates the plugin.xml file with the current version number.' // Build file objects for our template file, and output java file. def commonPathPrefix = "$projectDir/src/main/resources/org/openstreetmap/osmosis/core/plugin/plugin.xml" def outputFile = new File(commonPathPrefix) def inputFile = new File(commonPathPrefix + ".template") /* * Declare inputs and outputs of the task to allow gradle to determine if * it is up to date. */ inputs.file inputFile outputs.file outputFile doLast { // Insert the version string into the constants file. def fileContent = inputFile.getText() fileContent = fileContent.replace("no-version-specified", version) outputFile.write(fileContent) } } // Define task dependency to ensure constants file is always up to date. processResources.dependsOn generateResources osmosis-0.44.1/osmosis-core/doc/000077500000000000000000000000001253404521400164635ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/doc/OsmApi06.xsd000066400000000000000000000125551253404521400205510ustar00rootroot00000000000000 A name value pair describing the entity to which it is attached. The base type from which all OSM top-level data inherit. A single geo-spatial point. Maps a node into a way. A way node. A geo-spatial path between points. Maps an entity to a role within a relation. A relation member. A logical data item without geo-spatial representation that relates several data items together. A node. A way. A relation. A collection of entities. A collection of entities. A collection of entities to be created. A collection of entities to be modified. A collection of entities to be deleted. A collection of change items. A collection of changes. osmosis-0.44.1/osmosis-core/doc/contributors.txt000066400000000000000000000015211253404521400217600ustar00rootroot00000000000000Brett Henderson - Initial implementation and much of codebase. Marcus Wolschon - XmlDownloader (--read-api) task. - JPF plugin support. Karl Newman - Area filtering task (--bounding-box, --bounding-polygon) improvements. Pipeline bound support. - Windows launch batch file. - Significant portion of 0.6 enhancements. Stefan Baebler - "-" alias for stdin/stdout to file reading/writing tasks. Christoph Sommer - Way tag and used node filtering tasks. Jochen Topf - Pgsql simple schema fixes to use correct SRID. - Launch script fixes. - Build script fixes to preserve executable launch script permissions. - Pgsql simple schema refactoring to align with production MySQL schema names. Aurelien Jacobs - Node key and node value filtering tasks. Jiri Klement - Bounding box filter slippy map coordinate arguments. - Fast Woodstock based xml reading. osmosis-0.44.1/osmosis-core/src/000077500000000000000000000000001253404521400165055ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/assembly/000077500000000000000000000000001253404521400203245ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/assembly/distribution.xml000066400000000000000000000033101253404521400235620ustar00rootroot00000000000000 distribution dir zip false true *.txt bin bin true debian debian true doc doc true script script true config lib true plexus.conf target lib true *.jar false lib/default osmosis-0.44.1/osmosis-core/src/main/000077500000000000000000000000001253404521400174315ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/000077500000000000000000000000001253404521400203525ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/000077500000000000000000000000001253404521400211415ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/000077500000000000000000000000001253404521400240275ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400255235ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/000077500000000000000000000000001253404521400264535ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/CorePluginLoader.java000066400000000000000000000134651253404521400325250ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.bound.v0_6.BoundComputerFactory; import org.openstreetmap.osmosis.core.bound.v0_6.BoundSetterFactory; import org.openstreetmap.osmosis.core.buffer.v0_6.ChangeBufferFactory; import org.openstreetmap.osmosis.core.buffer.v0_6.EntityBufferFactory; import org.openstreetmap.osmosis.core.misc.v0_6.EmptyChangeReaderFactory; import org.openstreetmap.osmosis.core.misc.v0_6.EmptyReaderFactory; import org.openstreetmap.osmosis.core.misc.v0_6.NullChangeWriterFactory; import org.openstreetmap.osmosis.core.misc.v0_6.NullWriterFactory; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.plugin.PluginLoader; import org.openstreetmap.osmosis.core.progress.v0_6.ChangeProgressLoggerFactory; import org.openstreetmap.osmosis.core.progress.v0_6.EntityProgressLoggerFactory; import org.openstreetmap.osmosis.core.report.v0_6.EntityReporterFactory; import org.openstreetmap.osmosis.core.report.v0_6.IntegrityReporterFactory; import org.openstreetmap.osmosis.core.sort.v0_6.ChangeForSeekableApplierComparator; import org.openstreetmap.osmosis.core.sort.v0_6.ChangeForStreamableApplierComparator; import org.openstreetmap.osmosis.core.sort.v0_6.ChangeSorterFactory; import org.openstreetmap.osmosis.core.sort.v0_6.ChangeTagSorterFactory; import org.openstreetmap.osmosis.core.sort.v0_6.EntityByTypeThenIdComparator; import org.openstreetmap.osmosis.core.sort.v0_6.EntityContainerComparator; import org.openstreetmap.osmosis.core.sort.v0_6.EntitySorterFactory; import org.openstreetmap.osmosis.core.sort.v0_6.TagSorterFactory; import org.openstreetmap.osmosis.core.tee.v0_6.ChangeTeeFactory; import org.openstreetmap.osmosis.core.tee.v0_6.EntityTeeFactory; /** * The plugin loader for the core tasks. * * @author Brett Henderson */ public class CorePluginLoader implements PluginLoader { /** * {@inheritDoc} */ @Override public Map loadTaskFactories() { Map factoryMap; EntitySorterFactory entitySorterFactory06; ChangeSorterFactory changeSorterFactory06; factoryMap = new HashMap(); // Configure factories that require additional information. entitySorterFactory06 = new EntitySorterFactory(); entitySorterFactory06.registerComparator("TypeThenId", new EntityContainerComparator( new EntityByTypeThenIdComparator()), true); changeSorterFactory06 = new ChangeSorterFactory(); changeSorterFactory06.registerComparator("streamable", new ChangeForStreamableApplierComparator(), true); changeSorterFactory06.registerComparator("seekable", new ChangeForSeekableApplierComparator(), false); // Register factories. factoryMap.put("sort", entitySorterFactory06); factoryMap.put("s", entitySorterFactory06); factoryMap.put("sort-change", changeSorterFactory06); factoryMap.put("sc", changeSorterFactory06); factoryMap.put("write-null", new NullWriterFactory()); factoryMap.put("wn", new NullWriterFactory()); factoryMap.put("write-null-change", new NullChangeWriterFactory()); factoryMap.put("wnc", new NullChangeWriterFactory()); factoryMap.put("buffer", new EntityBufferFactory()); factoryMap.put("b", new EntityBufferFactory()); factoryMap.put("buffer-change", new ChangeBufferFactory()); factoryMap.put("bc", new ChangeBufferFactory()); factoryMap.put("report-entity", new EntityReporterFactory()); factoryMap.put("re", new EntityReporterFactory()); factoryMap.put("report-integrity", new IntegrityReporterFactory()); factoryMap.put("ri", new IntegrityReporterFactory()); factoryMap.put("log-progress", new EntityProgressLoggerFactory()); factoryMap.put("lp", new EntityProgressLoggerFactory()); factoryMap.put("log-progress-change", new ChangeProgressLoggerFactory()); factoryMap.put("lpc", new ChangeProgressLoggerFactory()); factoryMap.put("tee", new EntityTeeFactory()); factoryMap.put("t", new EntityTeeFactory()); factoryMap.put("tee-change", new ChangeTeeFactory()); factoryMap.put("tc", new ChangeTeeFactory()); factoryMap.put("read-empty", new EmptyReaderFactory()); factoryMap.put("rem", new EmptyReaderFactory()); factoryMap.put("read-empty-change", new EmptyChangeReaderFactory()); factoryMap.put("remc", new EmptyChangeReaderFactory()); factoryMap.put("compute-bounding-box", new BoundComputerFactory()); factoryMap.put("cbb", new BoundComputerFactory()); factoryMap.put("set-bounding-box", new BoundSetterFactory()); factoryMap.put("sbb", new BoundSetterFactory()); factoryMap.put("sort-0.6", entitySorterFactory06); factoryMap.put("sort-change-0.6", changeSorterFactory06); factoryMap.put("write-null-0.6", new NullWriterFactory()); factoryMap.put("write-null-change-0.6", new NullChangeWriterFactory()); factoryMap.put("buffer-0.6", new EntityBufferFactory()); factoryMap.put("buffer-change-0.6", new ChangeBufferFactory()); factoryMap.put("report-entity-0.6", new EntityReporterFactory()); factoryMap.put("report-integrity-0.6", new IntegrityReporterFactory()); factoryMap.put("log-progress-0.6", new EntityProgressLoggerFactory()); factoryMap.put("log-progress-change-0.6", new ChangeProgressLoggerFactory()); factoryMap.put("tee-0.6", new EntityTeeFactory()); factoryMap.put("tee-change-0.6", new ChangeTeeFactory()); factoryMap.put("read-empty-0.6", new EmptyReaderFactory()); factoryMap.put("read-empty-change-0.6", new EmptyChangeReaderFactory()); factoryMap.put("tag-sort-0.6", new TagSorterFactory()); factoryMap.put("tag-sort-change-0.6", new ChangeTagSorterFactory()); factoryMap.put("compute-bounding-box-0.6", new BoundComputerFactory()); factoryMap.put("set-bounding-box-0.6", new BoundSetterFactory()); return factoryMap; } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/LogLevels.java000066400000000000000000000024251253404521400312150ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core; import java.util.logging.Level; /** * Utility class for mapping integer numbers to log levels. * * @author Brett Henderson */ public final class LogLevels { /** * This class cannot be instantiated. */ private LogLevels() { // Not callable. } /** * This is the default offset into the LOG_LEVELS array. */ public static final int DEFAULT_LEVEL_INDEX = 3; /** * Defines the log levels supported from the command line. */ public static final Level [] LOG_LEVELS = { Level.OFF, Level.SEVERE, Level.WARNING, Level.INFO, Level.FINE, Level.FINER, Level.FINEST }; /** * Map a log level index to a log level. This will clip log levels to * allowable levels if the value is outside the maximum bounds. * * @param logLevelIndex * The requested log level index. * @return The log level associated with the index. */ public static Level getLogLevel(int logLevelIndex) { // Ensure that the log level is within allowable bounds. if (logLevelIndex < 0) { logLevelIndex = 0; } if (logLevelIndex >= LOG_LEVELS.length) { logLevelIndex = LOG_LEVELS.length - 1; } return LOG_LEVELS[logLevelIndex]; } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/Osmosis.java000066400000000000000000000070541253404521400307600ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core; import java.util.logging.ConsoleHandler; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.cli.CommandLineParser; import org.openstreetmap.osmosis.core.pipeline.common.Pipeline; /** * The main entry point for the command line application. * * @author Brett Henderson */ public final class Osmosis { private static final Logger LOG = Logger.getLogger(Osmosis.class.getName()); /** * This class cannot be instantiated. */ private Osmosis() { } /** * The entry point to the application. * * @param args * The command line arguments. */ public static void main(String[] args) { try { run(args); System.exit(0); } catch (Throwable t) { LOG.log(Level.SEVERE, "Execution aborted.", t); } System.exit(1); } /** * This contains the real functionality of the main method. It is kept * separate to allow the application to be invoked within other applications * without a System.exit being called. *

* Typically an application shouldn't directly invoke this method, it should * instantiate its own pipeline. * * @param args * The command line arguments. */ public static void run(String[] args) { CommandLineParser commandLineParser; TaskRegistrar taskRegistrar; Pipeline pipeline; long startTime; long finishTime; startTime = System.currentTimeMillis(); configureLoggingConsole(); commandLineParser = new CommandLineParser(); // Parse the command line arguments into a consumable form. commandLineParser.parse(args); // Configure the new logging level. configureLoggingLevel(commandLineParser.getLogLevelIndex()); LOG.info("Osmosis Version " + OsmosisConstants.VERSION); taskRegistrar = new TaskRegistrar(); taskRegistrar.initialize(commandLineParser.getPlugins()); pipeline = new Pipeline(taskRegistrar.getFactoryRegister()); LOG.info("Preparing pipeline."); pipeline.prepare(commandLineParser.getTaskInfoList()); LOG.info("Launching pipeline execution."); pipeline.execute(); LOG.info("Pipeline executing, waiting for completion."); pipeline.waitForCompletion(); LOG.info("Pipeline complete."); finishTime = System.currentTimeMillis(); LOG.info("Total execution time: " + (finishTime - startTime) + " milliseconds."); } /** * Configures logging to write all output to the console. */ private static void configureLoggingConsole() { Logger rootLogger; Handler consoleHandler; rootLogger = Logger.getLogger(""); // Remove any existing handlers. for (Handler handler : rootLogger.getHandlers()) { rootLogger.removeHandler(handler); } // Add a new console handler. consoleHandler = new ConsoleHandler(); consoleHandler.setLevel(Level.ALL); rootLogger.addHandler(consoleHandler); } /** * Configures the logging level. * * @param level * The index of the logging level to apply. */ private static void configureLoggingLevel(int logLevelIndex) { Logger rootLogger; rootLogger = Logger.getLogger(""); // Set the required logging level. rootLogger.setLevel(LogLevels.getLogLevel(logLevelIndex)); // Set spring logging to one level lower. Logger.getLogger("org.springframework").setLevel(LogLevels.getLogLevel(logLevelIndex - 1)); // Minimise the JPF logging. Logger.getLogger("org.java.plugin").setLevel(Level.WARNING); } } OsmosisConstants.java.template000066400000000000000000000007211253404521400344020ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core; /** * Constants shared across the Osmosis application. * * @author Brett Henderson */ public final class OsmosisConstants { /** * This class cannot be instantiated. */ private OsmosisConstants() { } /** * Defines the version of the Osmosis application. */ public static final String VERSION = "no-version-specified"; } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/OsmosisException.java000066400000000000000000000027141253404521400326350ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core; /** * The root of the checked exception hierarchy for the application. All typed * exceptions subclass this exception. * * @author Brett Henderson */ public abstract class OsmosisException extends Exception { private static final long serialVersionUID = 1L; /** * Constructs a new exception with null as its detail message. */ public OsmosisException() { super(); } /** * Constructs a new exception with the specified detail message. The * cause is not initialized, and may subsequently be initialized by * a call to {@link #initCause}. * * @param message the detail message. */ public OsmosisException(String message) { super(message); } /** * Constructs a new exception with the specified cause and a detail * message of (cause==null ? null : cause.toString()) (which * typically contains the class and detail message of cause). * * @param cause the cause. */ public OsmosisException(Throwable cause) { super(cause); } /** * Constructs a new exception with the specified detail message and * cause. * * @param message the detail message. * @param cause the cause. */ public OsmosisException(String message, Throwable cause) { super(message, cause); } } OsmosisRuntimeException.java000066400000000000000000000027731253404521400341270ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core; /** * The root of the unchecked exception hierarchy for the application. All typed * runtime exceptions subclass this exception. * * @author Brett Henderson */ public class OsmosisRuntimeException extends RuntimeException { private static final long serialVersionUID = 1L; /** * Constructs a new exception with null as its detail message. */ public OsmosisRuntimeException() { super(); } /** * Constructs a new exception with the specified detail message. The * cause is not initialized, and may subsequently be initialized by * a call to {@link #initCause}. * * @param message the detail message. */ public OsmosisRuntimeException(String message) { super(message); } /** * Constructs a new exception with the specified cause and a detail * message of (cause==null ? null : cause.toString()) (which * typically contains the class and detail message of cause). * * @param cause the cause. */ public OsmosisRuntimeException(Throwable cause) { super(cause); } /** * Constructs a new exception with the specified detail message and * cause. * * @param message the detail message. * @param cause the cause. */ public OsmosisRuntimeException(String message, Throwable cause) { super(message, cause); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/TaskRegistrar.java000066400000000000000000000261121253404521400321050ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core; import java.io.BufferedReader; import java.io.File; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.logging.Logger; import org.java.plugin.JpfException; import org.java.plugin.ObjectFactory; import org.java.plugin.PluginLifecycleException; import org.java.plugin.PluginManager; import org.java.plugin.PluginManager.PluginLocation; import org.java.plugin.registry.Extension; import org.java.plugin.registry.ExtensionPoint; import org.java.plugin.registry.ManifestProcessingException; import org.java.plugin.registry.PluginDescriptor; import org.java.plugin.standard.StandardPluginLocation; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactoryRegister; import org.openstreetmap.osmosis.core.plugin.PluginLoader; /** * Provides the initialisation logic for registering all task factories. * * @author Brett Henderson */ public class TaskRegistrar { /** * Our logger for debug and error -output. */ private static final Logger LOG = Logger.getLogger(TaskRegistrar.class.getName()); /** * The register containing all known task manager factories. */ private TaskManagerFactoryRegister factoryRegister; /** * Creates a new instance. */ public TaskRegistrar() { factoryRegister = new TaskManagerFactoryRegister(); } /** * Returns the configured task manager factory register configured. * * @return The task manager factory register. */ public TaskManagerFactoryRegister getFactoryRegister() { return factoryRegister; } /** * Initialises factories for all tasks. Loads additionally specified plugins * as well as default tasks. * * @param plugins * The class names of all plugins to be loaded. */ public void initialize(List plugins) { // Register the built-in plugins. loadBuiltInPlugins(); // Register the plugins specified on the command line. for (String plugin : plugins) { loadPlugin(plugin); } // Register the plugins loaded via JPF. loadJPFPlugins(); } private void loadBuiltInPlugins() { final String pluginResourceName = "osmosis-plugins.conf"; try { for (URL pluginConfigurationUrl : Collections.list(Thread.currentThread() .getContextClassLoader().getResources(pluginResourceName))) { InputStream pluginInputStream; BufferedReader pluginReader; LOG.finer("Loading plugin configuration file from url " + pluginConfigurationUrl + "."); pluginInputStream = pluginConfigurationUrl.openStream(); if (pluginInputStream == null) { throw new OsmosisRuntimeException("Cannot open URL " + pluginConfigurationUrl + "."); } try { pluginReader = new BufferedReader(new InputStreamReader(pluginInputStream)); for (;;) { String plugin; plugin = pluginReader.readLine(); if (plugin == null) { break; } plugin = plugin.trim(); if (!plugin.isEmpty()) { LOG.finer("Loading plugin via loader " + plugin + "."); loadPlugin(plugin); } } } finally { try { pluginInputStream.close(); } catch (IOException e) { LOG.warning("Unable to close plugin resource " + pluginResourceName + "."); } } } } catch (IOException e) { throw new OsmosisRuntimeException( "Unable to load the plugins based on " + pluginResourceName + " resources."); } } /** * Loads the tasks implemented as plugins. * */ private void loadJPFPlugins() { PluginManager pluginManager; // Create a new JPF plugin manager. pluginManager = ObjectFactory.newInstance().createManager(); // Search known locations for plugin files. LOG.fine("Searching for JPF plugins."); List locations = gatherJpfPlugins(); // Register the core plugin. LOG.fine("Registering the core plugin."); registerCorePlugin(pluginManager); // Register all located plugins. LOG.fine("Registering the extension plugins."); if (locations.size() == 0) { // There are no plugins available so stop processing here. return; } registerJpfPlugins(pluginManager, locations); // Initialise all of the plugins that have been registered. LOG.fine("Activating the plugins."); // load plugins for the task-extension-point PluginDescriptor core = pluginManager.getRegistry() .getPluginDescriptor("org.openstreetmap.osmosis.core.plugin.Core"); ExtensionPoint point = pluginManager.getRegistry().getExtensionPoint(core.getId(), "Task"); for (Iterator it = point.getConnectedExtensions().iterator(); it.hasNext();) { Extension ext = it.next(); PluginDescriptor descr = ext.getDeclaringPluginDescriptor(); try { pluginManager.enablePlugin(descr, true); pluginManager.activatePlugin(descr.getId()); ClassLoader classLoader = pluginManager.getPluginClassLoader(descr); loadPluginClass(ext.getParameter("class").valueAsString(), classLoader); } catch (PluginLifecycleException e) { throw new OsmosisRuntimeException("Cannot load JPF-plugin '" + ext.getId() + "' for extensionpoint '" + ext.getExtendedPointId() + "'", e); } } } /** * Register the core plugin from which other plugins will extend. * * @param pluginManager * The plugin manager to register the plugin with. */ private void registerCorePlugin(PluginManager pluginManager) { try { URL core; PluginDescriptor coreDescriptor; // Get the plugin configuration file. core = getClass().getResource("/org/openstreetmap/osmosis/core/plugin/plugin.xml"); LOG.finest("Plugin URL: " + core); // Register the core plugin in the plugin registry. pluginManager.getRegistry().register(new URL[] {core}); // Get the plugin descriptor from the registry. coreDescriptor = pluginManager.getRegistry().getPluginDescriptor( "org.openstreetmap.osmosis.core.plugin.Core"); // Enable the plugin. pluginManager.enablePlugin(coreDescriptor, true); pluginManager.activatePlugin("org.openstreetmap.osmosis.core.plugin.Core"); } catch (ManifestProcessingException e) { throw new OsmosisRuntimeException("Unable to register core plugin.", e); } catch (PluginLifecycleException e) { throw new OsmosisRuntimeException("Unable to enable core plugin.", e); } } /** * Register the given JPF-plugins with the {@link PluginManager}. * * @param locations * the plugins found */ private void registerJpfPlugins(PluginManager pluginManager, List locations) { if (locations == null) { throw new IllegalArgumentException("null plugin-list given"); } try { pluginManager.publishPlugins(locations.toArray(new PluginLocation[locations.size()])); } catch (JpfException e) { throw new OsmosisRuntimeException("Unable to publish plugins.", e); } } /** * @return a list of all JPF-plugins found. */ private List gatherJpfPlugins() { File[] pluginsDirs = new File[] { new File("plugins"), new File(System.getProperty("user.home") + "/.openstreetmap" + File.separator + "osmosis" + File.separator + "plugins"), new File(System.getenv("APPDATA") + File.separator + "openstreetmap" + File.separator + "osmosis" + File.separator + "plugins") }; FilenameFilter pluginFileNameFilter = new FilenameFilter() { /** * @param dir * the directory of the file * @param name * the unqualified name of the file * @return true if this may be a plugin-file */ public boolean accept(final File dir, final String name) { return name.toLowerCase().endsWith(".zip") || name.toLowerCase().endsWith(".jar"); } }; List locations = new LinkedList(); for (File pluginDir : pluginsDirs) { LOG.finer("Loading plugins in " + pluginDir.getAbsolutePath()); if (!pluginDir.exists()) { continue; } File[] plugins = pluginDir.listFiles(pluginFileNameFilter); try { for (int i = 0; i < plugins.length; i++) { LOG.finest("Found plugin " + plugins[i].getAbsolutePath()); PluginLocation location = StandardPluginLocation.create(plugins[i]); if (location != null) { locations.add(location); } else { LOG.warning("JPF Plugin " + plugins[i].getAbsolutePath() + " is malformed and cannot be loaded."); } } } catch (MalformedURLException e) { throw new OsmosisRuntimeException("Cannot create plugin location " + pluginDir.getAbsolutePath(), e); } } return locations; } /** * Loads the tasks associated with a plugin (old plugin-api). * * @param plugin * The plugin loader class name. */ private void loadPlugin(final String plugin) { ClassLoader classLoader; // Obtain the thread context class loader. This becomes important if run // within an application server environment where plugins might be // inaccessible to this class's classloader. classLoader = Thread.currentThread().getContextClassLoader(); loadPluginClass(plugin, classLoader); } /** * Load the given plugin, old API or new JPF. * * @param pluginClassName * the name of the class to instantiate * @param classLoader * the ClassLoader to use */ @SuppressWarnings("unchecked") private void loadPluginClass(final String pluginClassName, final ClassLoader classLoader) { Class untypedPluginClass; PluginLoader pluginLoader; Map pluginTasks; // Load the plugin class. try { untypedPluginClass = classLoader.loadClass(pluginClassName); } catch (ClassNotFoundException e) { throw new OsmosisRuntimeException("Unable to load plugin class (" + pluginClassName + ").", e); } // Verify that the plugin implements the plugin loader interface. if (!PluginLoader.class.isAssignableFrom(untypedPluginClass)) { throw new OsmosisRuntimeException("The class (" + pluginClassName + ") does not implement interface (" + PluginLoader.class.getName() + "). Maybe it's not a plugin?"); } Class pluginClass = (Class) untypedPluginClass; // Instantiate the plugin loader. try { pluginLoader = pluginClass.newInstance(); } catch (InstantiationException e) { throw new IllegalArgumentException("Unable to instantiate plugin class (" + pluginClassName + ").", e); } catch (IllegalAccessException e) { throw new IllegalArgumentException("Unable to instantiate plugin class (" + pluginClassName + ").", e); } // Obtain the plugin task factories with their names. pluginTasks = pluginLoader.loadTaskFactories(); // Register the plugin tasks. for (Entry taskEntry : pluginTasks.entrySet()) { factoryRegister.register(taskEntry.getKey(), taskEntry.getValue()); } } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/bound/000077500000000000000000000000001253404521400275625ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/bound/v0_6/000077500000000000000000000000001253404521400303345ustar00rootroot00000000000000BoundComputer.java000066400000000000000000000072021253404521400337070ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/bound/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.bound.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityProcessor; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.store.GenericObjectSerializationFactory; import org.openstreetmap.osmosis.core.store.SimpleObjectStore; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.task.v0_6.SinkSource; /** * Computes the minimal bounding box of an entity stream. * * A bound entity is emitted iff there are nodes on the input stream. * * Upstream bound entities are never passed through. If there is a bound entity * on the input stream, it is overwritten if there are any nodes or removed if * there are no nodes on the input stream. * * This implementation caches all objects of the input stream in a simple object * store. * * @author Igor Podolskiy */ public class BoundComputer implements SinkSource, EntityProcessor { private Sink sink; private SimpleObjectStore objects; private double top; private double bottom; private double left; private double right; private boolean nodesSeen; private String origin; /** * Creates a new bounding box computer instance. * * @param origin * The origin for the bound to set. */ public BoundComputer(String origin) { objects = new SimpleObjectStore(new GenericObjectSerializationFactory(), "cbbo", true); bottom = 0; top = 0; left = 0; right = 0; nodesSeen = false; this.origin = origin; } @Override public void initialize(Map metaTags) { sink.initialize(metaTags); } @Override public void process(EntityContainer entityContainer) { entityContainer.process(this); } @Override public void complete() { objects.complete(); if (nodesSeen) { sink.process(new BoundContainer(new Bound(right, left, top, bottom, this.origin))); } ReleasableIterator iter = null; try { iter = objects.iterate(); while (iter.hasNext()) { sink.process(iter.next()); } } finally { if (iter != null) { iter.release(); } } sink.complete(); } @Override public void release() { sink.release(); objects.release(); } @Override public void setSink(Sink sink) { this.sink = sink; } @Override public void process(BoundContainer bound) { // Do nothing, we'll generate a new bound later on } @Override public void process(NodeContainer nodeContainer) { Node node = nodeContainer.getEntity(); if (nodesSeen) { left = Math.min(left, node.getLongitude()); right = Math.max(right, node.getLongitude()); bottom = Math.min(bottom, node.getLatitude()); top = Math.max(top, node.getLatitude()); } else { left = node.getLongitude(); right = node.getLongitude(); top = node.getLatitude(); bottom = node.getLatitude(); nodesSeen = true; } objects.add(nodeContainer); } @Override public void process(WayContainer way) { objects.add(way); } @Override public void process(RelationContainer relation) { objects.add(relation); } } BoundComputerFactory.java000066400000000000000000000020551253404521400352400ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/bound/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.bound.v0_6; import org.openstreetmap.osmosis.core.OsmosisConstants; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkSourceManager; /** * The task manager factory for a bounding box computer. * * @author Igor Podolskiy */ public class BoundComputerFactory extends TaskManagerFactory { private static final String ARG_ORIGIN = "origin"; private static final String DEFAULT_ORIGIN = "Osmosis/" + OsmosisConstants.VERSION; @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String origin = getStringArgument(taskConfig, ARG_ORIGIN, DEFAULT_ORIGIN); return new SinkSourceManager(taskConfig.getId(), new BoundComputer(origin), taskConfig.getPipeArgs()); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/bound/v0_6/BoundSetter.java000066400000000000000000000040111253404521400334310ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.bound.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.task.v0_6.SinkSource; /** * Ensures the bound entity in the output stream exists with a specific value or * is not present. * * @author Igor Podolskiy */ public class BoundSetter implements SinkSource { private Sink sink; private boolean boundProcessed; private Bound newBound; /** * Creates a new instance of the bound setter. * * @param newBound * the new bound to set, or

null
to remove the bound */ public BoundSetter(Bound newBound) { this.newBound = newBound; this.boundProcessed = false; } @Override public void initialize(Map metaTags) { sink.initialize(metaTags); } @Override public void process(EntityContainer entityContainer) { if (boundProcessed) { sink.process(entityContainer); } else { // processFirstEntity will send all data downstream as needed processFirstEntity(entityContainer); boundProcessed = true; } } private void processFirstEntity(EntityContainer entityContainer) { if (entityContainer.getEntity().getType() == EntityType.Bound) { if (newBound == null) { // Just returning won't pass the entity downstream return; } else { sink.process(new BoundContainer(newBound)); } } else { if (newBound != null) { sink.process(new BoundContainer(newBound)); } sink.process(entityContainer); } } @Override public void complete() { sink.complete(); } @Override public void release() { sink.release(); } @Override public void setSink(Sink sink) { this.sink = sink; } } BoundSetterFactory.java000066400000000000000000000071561253404521400347170ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/bound/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.bound.v0_6; import org.openstreetmap.osmosis.core.OsmosisConstants; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkSourceManager; /** * Task manager factory for the bound setter task. * * @author Igor Podolskiy */ public class BoundSetterFactory extends TaskManagerFactory { private static final String ARG_LEFT = "left"; private static final String ARG_RIGHT = "right"; private static final String ARG_TOP = "top"; private static final String ARG_BOTTOM = "bottom"; private static final String ARG_X1 = "x1"; private static final String ARG_Y1 = "y1"; private static final String ARG_X2 = "x2"; private static final String ARG_Y2 = "y2"; private static final String ARG_ZOOM = "zoom"; private static final String ARG_REMOVE = "remove"; private static final String ARG_ORIGIN = "origin"; private static final double DEFAULT_LEFT = -180; private static final double DEFAULT_RIGHT = 180; private static final double DEFAULT_TOP = 90; private static final double DEFAULT_BOTTOM = -90; private static final int DEFAULT_ZOOM = 12; private static final String DEFAULT_ORIGIN = "Osmosis/" + OsmosisConstants.VERSION; private static final boolean DEFAULT_REMOVE = false; private double xToLon(int zoom, int x) { double unit = 360 / Math.pow(2, zoom); return -180 + x * unit; } private double projectF(double lat) { // Project latitude to mercator return Math.log(Math.tan(lat) + 1 / Math.cos(lat)); } private double projectMercToLat(double y) { return Math.toDegrees(Math.atan(Math.sinh(y))); } private double yToLat(int zoom, int y) { // Convert zoom/y to mercator // Get maximum range of mercator coordinates double limitY = projectF(Math.atan(Math.sinh(Math.PI))); double limitY2 = projectF((Math.atan(Math.sinh(-Math.PI)))); double rangeY = limitY - limitY2; double unit = 1 / Math.pow(2, zoom); double relY = limitY - rangeY * y * unit; // Mercator to latitude return projectMercToLat(relY); } @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { double left; double right; double top; double bottom; int zoom; Bound newBound = null; String origin = null; boolean remove; remove = getBooleanArgument(taskConfig, ARG_REMOVE, DEFAULT_REMOVE); if (!remove) { origin = getStringArgument(taskConfig, ARG_ORIGIN, DEFAULT_ORIGIN); left = getDoubleArgument(taskConfig, ARG_LEFT, DEFAULT_LEFT); right = getDoubleArgument(taskConfig, ARG_RIGHT, DEFAULT_RIGHT); top = getDoubleArgument(taskConfig, ARG_TOP, DEFAULT_TOP); bottom = getDoubleArgument(taskConfig, ARG_BOTTOM, DEFAULT_BOTTOM); zoom = getIntegerArgument(taskConfig, ARG_ZOOM, DEFAULT_ZOOM); if (doesArgumentExist(taskConfig, ARG_X1)) { int x1 = getIntegerArgument(taskConfig, ARG_X1); left = xToLon(zoom, x1); right = xToLon(zoom, getIntegerArgument(taskConfig, ARG_X2, x1) + 1); } if (doesArgumentExist(taskConfig, ARG_Y1)) { int y1 = getIntegerArgument(taskConfig, ARG_Y1); top = yToLat(zoom, y1); bottom = yToLat(zoom, getIntegerArgument(taskConfig, ARG_Y2, y1) + 1); } newBound = new Bound(right, left, top, bottom, origin); } return new SinkSourceManager(taskConfig.getId(), new BoundSetter(newBound), taskConfig.getPipeArgs()); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/buffer/000077500000000000000000000000001253404521400277245ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/buffer/v0_6/000077500000000000000000000000001253404521400304765ustar00rootroot00000000000000ChangeBuffer.java000066400000000000000000000036721253404521400336110ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/buffer/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.buffer.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.store.DataPostbox; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSinkRunnableChangeSource; /** * Splits the pipeline so that it can be processed on multiple threads. The * input thread to this task stores data in a buffer which blocks if it fills * up. This task runs on a new thread which reads data from the buffer and * writes it to the destination. * * @author Brett Henderson */ public class ChangeBuffer implements ChangeSinkRunnableChangeSource { private ChangeSink changeSink; private DataPostbox buffer; /** * Creates a new instance. * * @param bufferCapacity * The size of the buffer to use. */ public ChangeBuffer(int bufferCapacity) { buffer = new DataPostbox(bufferCapacity); } /** * {@inheritDoc} */ public void initialize(Map metaData) { buffer.initialize(metaData); } /** * {@inheritDoc} */ public void process(ChangeContainer changeContainer) { buffer.put(changeContainer); } /** * {@inheritDoc} */ public void complete() { buffer.complete(); } /** * {@inheritDoc} */ public void release() { buffer.release(); } /** * {@inheritDoc} */ public void setChangeSink(ChangeSink changeSink) { this.changeSink = changeSink; } /** * Sends all input data to the sink. */ public void run() { try { changeSink.initialize(buffer.outputInitialize()); while (buffer.hasNext()) { changeSink.process(buffer.getNext()); } changeSink.complete(); buffer.outputComplete(); } finally { changeSink.release(); buffer.outputRelease(); } } } ChangeBufferFactory.java000066400000000000000000000022521253404521400351320ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/buffer/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.buffer.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.ChangeSinkRunnableChangeSourceManager; /** * The task manager factory for a change buffer. * * @author Brett Henderson */ public class ChangeBufferFactory extends TaskManagerFactory { private static final String ARG_BUFFER_CAPACITY = "bufferCapacity"; private static final int DEFAULT_BUFFER_CAPACITY = 20; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { int bufferCapacity; // Get the task arguments. bufferCapacity = getIntegerArgument( taskConfig, ARG_BUFFER_CAPACITY, getDefaultIntegerArgument(taskConfig, DEFAULT_BUFFER_CAPACITY) ); return new ChangeSinkRunnableChangeSourceManager( taskConfig.getId(), new ChangeBuffer(bufferCapacity), taskConfig.getPipeArgs() ); } } EntityBuffer.java000066400000000000000000000035321253404521400336730ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/buffer/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.buffer.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.store.DataPostbox; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.task.v0_6.SinkRunnableSource; /** * Splits the pipeline so that it can be processed on multiple threads. The * input thread to this task stores data in a buffer which blocks if it fills * up. This task runs on a new thread which reads data from the buffer and * writes it to the destination. * * @author Brett Henderson */ public class EntityBuffer implements SinkRunnableSource { private Sink sink; private DataPostbox buffer; /** * Creates a new instance. * * @param bufferCapacity * The size of the buffer to use. */ public EntityBuffer(int bufferCapacity) { buffer = new DataPostbox(bufferCapacity); } /** * {@inheritDoc} */ public void initialize(Map metaData) { buffer.initialize(metaData); } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { buffer.put(entityContainer); } /** * {@inheritDoc} */ public void complete() { buffer.complete(); } /** * {@inheritDoc} */ public void release() { buffer.release(); } /** * {@inheritDoc} */ public void setSink(Sink sink) { this.sink = sink; } /** * Sends all input data to the sink. */ public void run() { try { sink.initialize(buffer.outputInitialize()); while (buffer.hasNext()) { sink.process(buffer.getNext()); } sink.complete(); buffer.outputComplete(); } finally { sink.release(); buffer.outputRelease(); } } } EntityBufferFactory.java000066400000000000000000000022231253404521400352170ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/buffer/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.buffer.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkRunnableSourceManager; /** * The task manager factory for an entity buffer. * * @author Brett Henderson */ public class EntityBufferFactory extends TaskManagerFactory { private static final String ARG_BUFFER_CAPACITY = "bufferCapacity"; private static final int DEFAULT_BUFFER_CAPACITY = 20; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { int bufferCapacity; // Get the task arguments. bufferCapacity = getIntegerArgument( taskConfig, ARG_BUFFER_CAPACITY, getDefaultIntegerArgument(taskConfig, DEFAULT_BUFFER_CAPACITY) ); return new SinkRunnableSourceManager( taskConfig.getId(), new EntityBuffer(bufferCapacity), taskConfig.getPipeArgs() ); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/change/000077500000000000000000000000001253404521400277005ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/change/v0_6/000077500000000000000000000000001253404521400304525ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/change/v0_6/impl/000077500000000000000000000000001253404521400314135ustar00rootroot00000000000000TimestampSetter.java000066400000000000000000000026421253404521400353350ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/change/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.change.v0_6.impl; import java.util.Calendar; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.domain.common.SimpleTimestampContainer; import org.openstreetmap.osmosis.core.domain.common.TimestampContainer; /** * Updates the current timestamp on to entities. Note that the same time will be applied to all * entities and will be the time that the internal timestamp was first derived. */ public class TimestampSetter { private TimestampContainer timestamp; /** * Creates a new instance. */ public TimestampSetter() { Calendar calendar; calendar = Calendar.getInstance(); calendar.set(Calendar.MILLISECOND, 0); timestamp = new SimpleTimestampContainer(calendar.getTime()); } /** * Updates the timestamp on the supplied entity. A new entity container may be created if the * existing one is read-only. * * @param entityContainer * The container holding the entity to be modified. * @return A container holding an updated entity. */ public EntityContainer updateTimestamp(EntityContainer entityContainer) { EntityContainer resultContainer; resultContainer = entityContainer.getWriteableInstance(); resultContainer.getEntity().setTimestampContainer(timestamp); return resultContainer; } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/cli/000077500000000000000000000000001253404521400272225ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/cli/CommandLineParser.java000066400000000000000000000257371253404521400334460ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.cli; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.pipeline.common.PipelineConstants; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; /** * Parses command line arguments into a form that can be consumed by the rest of * the application. * * @author Brett Henderson */ public class CommandLineParser { private static final String GLOBAL_ARGUMENT_PREFIX = "-"; private static final String TASK_ARGUMENT_PREFIX = "--"; private static final String OPTION_QUIET_SHORT = "q"; private static final String OPTION_QUIET_LONG = "quiet"; private static final String OPTION_VERBOSE_SHORT = "v"; private static final String OPTION_VERBOSE_LONG = "verbose"; private static final String OPTION_PLUGIN_SHORT = "p"; private static final String OPTION_PLUGIN_LONG = "plugin"; /** * The index into the LOG_LEVELS array for the default log level. */ private static final int DEFAULT_LOG_LEVEL_INDEX = 3; private List taskConfigList; private int quietValue; private int verboseValue; private List plugins; /** * Creates a new instance. */ public CommandLineParser() { taskConfigList = new ArrayList(); quietValue = 0; verboseValue = 0; plugins = new ArrayList(); } /** * Parses the command line arguments. * * @param programArgs * The arguments. */ public void parse(String [] programArgs) { List globalOptions; // Create the global options list. globalOptions = new ArrayList(); // Process the command line arguments to build all nodes in the pipeline. for (int i = 0; i < programArgs.length;) { String arg; arg = programArgs[i]; if (arg.indexOf(TASK_ARGUMENT_PREFIX) == 0) { i = parseTask(programArgs, i); } else if (arg.indexOf(GLOBAL_ARGUMENT_PREFIX) == 0) { i = parseGlobalOption(globalOptions, programArgs, i); } else { throw new OsmosisRuntimeException("Expected argument " + (i + 1) + " to be an option or task name."); } } // Process the global options. for (GlobalOptionConfiguration globalOption : globalOptions) { if (isArgumentForOption(OPTION_QUIET_SHORT, OPTION_QUIET_LONG, globalOption.name)) { quietValue = parseOptionIntegerWithDefault(globalOption, 0) + 1; } else if (isArgumentForOption(OPTION_VERBOSE_SHORT, OPTION_VERBOSE_LONG, globalOption.name)) { verboseValue = parseOptionIntegerWithDefault(globalOption, 0) + 1; } else if (isArgumentForOption(OPTION_PLUGIN_SHORT, OPTION_PLUGIN_LONG, globalOption.name)) { plugins.add(parseOptionString(globalOption)); } else { throw new OsmosisRuntimeException("Argument " + (globalOption.offset + 1) + " specifies an unrecognised option \"" + GLOBAL_ARGUMENT_PREFIX + globalOption.name + "\"."); } } } /** * Checks if the current command line argument is for the specified option. * * @param shortOptionName * The short name of the option to check for. * @param longOptionName * The long name of the option to check for. * @param argument * The command line argument without the option prefix. * @return True if the argument is for the specified option. */ private boolean isArgumentForOption(String shortOptionName, String longOptionName, String argument) { return shortOptionName.equals(argument) || longOptionName.equals(argument); } /** * Determines if an argument is a parameter to the current option/task or * the start of another option/task. * * @param argument * The argument. * @return True if this is an option parameter. */ private boolean isOptionParameter(String argument) { if (argument.length() >= GLOBAL_ARGUMENT_PREFIX.length()) { if (argument.substring(0, GLOBAL_ARGUMENT_PREFIX.length()).equals(GLOBAL_ARGUMENT_PREFIX)) { return false; } } if (argument.length() >= TASK_ARGUMENT_PREFIX.length()) { if (argument.substring(0, TASK_ARGUMENT_PREFIX.length()).equals(TASK_ARGUMENT_PREFIX)) { return false; } } return true; } /** * Parses a command line option into an integer. If none is specified, zero * will be returned. * * @param globalOption * The global option to be parsed. * @return The integer value. */ private int parseOptionIntegerWithDefault(GlobalOptionConfiguration globalOption, int defaultValue) { int result; // If no parameters are available, we use the default value. if (globalOption.parameters.size() <= 0) { return defaultValue; } // An integer option may only have one parameter. if (globalOption.parameters.size() > 1) { throw new OsmosisRuntimeException( "Expected argument " + (globalOption.offset + 1) + " to have no more than one parameter."); } // Parse the option. try { result = Integer.parseInt(globalOption.parameters.get(0)); } catch (NumberFormatException e) { throw new OsmosisRuntimeException( "Expected argument " + (globalOption.offset + 2) + " to contain an integer value."); } return result; } /** * Parses a command line option into an string. * * @param globalOption * The global option to be parsed. */ private String parseOptionString(GlobalOptionConfiguration globalOption) { // A string option must have one parameter. if (globalOption.parameters.size() != 1) { throw new OsmosisRuntimeException( "Expected argument " + (globalOption.offset + 1) + " to have one parameter."); } return globalOption.parameters.get(0); } /** * Parses the details of a single option. * * @param globalOptions * The list of global options being parsed, the new option will * be stored into this object. * @param programArgs * The command line arguments passed to this application. * @param offset * The current offset through the command line arguments. * @return The new offset through the command line arguments. */ private int parseGlobalOption(List globalOptions, String [] programArgs, int offset) { int i; String argument; GlobalOptionConfiguration globalOption; i = offset; argument = programArgs[i++].substring(1); globalOption = new GlobalOptionConfiguration(); globalOption.name = argument; globalOption.offset = offset; // Loop until the next option or task is reached and add the arguments as parameters to the option. while ((i < programArgs.length) && isOptionParameter(programArgs[i])) { globalOption.parameters.add(programArgs[i++]); } // Add the fully populated global option object to the list. globalOptions.add(globalOption); return i; } /** * Parses the details of a single task and creates a task information object. * * @param programArgs * The command line arguments passed to this application. * @param offset * The current offset through the command line arguments. * @return The new offset through the command line arguments. */ private int parseTask(String [] programArgs, int offset) { int i; String taskType; Map taskArgs; Map pipeArgs; String taskId; int defaultArgIndex; String defaultArg; i = offset; // Extract the task type from the current argument. taskType = programArgs[i++].substring(TASK_ARGUMENT_PREFIX.length()); // Build up a list of task and pipe arguments. taskArgs = new HashMap(); pipeArgs = new HashMap(); defaultArg = null; defaultArgIndex = -1; while (i < programArgs.length) { String arg; int equalsIndex; String argName; String argValue; arg = programArgs[i]; if (arg.indexOf(TASK_ARGUMENT_PREFIX) == 0) { break; } equalsIndex = arg.indexOf("="); // If an equals sign exists this is a named argument, otherwise it is a default argument. if (equalsIndex >= 0) { // Check if the name component of the argument exists. if (equalsIndex == 0) { throw new OsmosisRuntimeException( "Argument " + (i + 1) + " doesn't contain a name before the '=' (ie. name=value)."); } // Check if the value component of the argument exists. if (equalsIndex >= (arg.length() - 1)) { throw new OsmosisRuntimeException( "Argument " + (i + 1) + " doesn't contain a value after the '=' (ie. name=value)."); } // Split the argument into name and value. argName = arg.substring(0, equalsIndex); argValue = arg.substring(equalsIndex + 1); // Add pipeline arguments to pipeArgs, all other arguments to taskArgs. // A pipeline arg is inPipe, inPipe.x, outPipe or outPipe.x. if ( PipelineConstants.IN_PIPE_ARGUMENT_PREFIX.equals(argName) || argName.indexOf(PipelineConstants.IN_PIPE_ARGUMENT_PREFIX + ".") == 0 || PipelineConstants.OUT_PIPE_ARGUMENT_PREFIX.equals(argName) || argName.indexOf(PipelineConstants.OUT_PIPE_ARGUMENT_PREFIX + ".") == 0) { pipeArgs.put(argName, argValue); } else { taskArgs.put(argName, argValue); } } else { if (defaultArgIndex >= 0) { throw new OsmosisRuntimeException( "Only one default (un-named) argument can exist per task. Arguments " + (i + 1) + " and " + (defaultArgIndex + 1) + " have no name."); } defaultArg = arg; defaultArgIndex = i; } i++; } // Build a unique task id. taskId = (taskConfigList.size() + 1) + "-" + taskType; // Create a new task information object and add it to the list. taskConfigList.add( new TaskConfiguration(taskId, taskType, pipeArgs, taskArgs, defaultArg) ); return i; } /** * The list of task information objects. * * @return The taskInfoList. */ public List getTaskInfoList() { return taskConfigList; } /** * Gets the level of logging required. This is a number that can be used to * access a log level from the LogLevels class. * * @return The index of the log level to be used. */ public int getLogLevelIndex() { return DEFAULT_LOG_LEVEL_INDEX + verboseValue - quietValue; } /** * Returns the plugins to be loaded. * * @return The list of plugin class names. */ public List getPlugins() { return plugins; } /** * A data storage class holding information relating to a global option * during parsing. */ private class GlobalOptionConfiguration { /** * The name of the option. */ public String name; /** * The parameters for the option. */ public List parameters; /** * The command line argument offset of this global option. */ public int offset; /** * Creates a new instance. */ public GlobalOptionConfiguration() { parameters = new ArrayList(); } } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/container/000077500000000000000000000000001253404521400304355ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/container/v0_6/000077500000000000000000000000001253404521400312075ustar00rootroot00000000000000BoundContainer.java000066400000000000000000000030371253404521400347100ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/container/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.container.v0_6; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; /** * Entity container implementation for bound. * * @author knewman */ public class BoundContainer extends EntityContainer { private Bound bound; /** * Creates a new instance. * * @param bound * The bound to wrap. */ public BoundContainer(Bound bound) { this.bound = bound; } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers * within the store. */ public BoundContainer(StoreReader sr, StoreClassRegister scr) { bound = new Bound(sr, scr); } /** * {@inheritDoc} */ @Override public void store(StoreWriter sw, StoreClassRegister scr) { bound.store(sw, scr); } /** * {@inheritDoc} */ @Override public void process(EntityProcessor processor) { processor.process(this); } /** * {@inheritDoc} */ @Override public Bound getEntity() { return bound; } /** * {@inheritDoc} */ @Override public BoundContainer getWriteableInstance() { if (bound.isReadOnly()) { return new BoundContainer(bound.getWriteableInstance()); } else { return this; } } } BoundContainerFactory.java000066400000000000000000000007201253404521400362340ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/container/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.container.v0_6; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; /** * A container factory for bound objects. */ public class BoundContainerFactory implements EntityContainerFactory { /** * {@inheritDoc} */ @Override public EntityContainer createContainer(Bound entity) { return new BoundContainer(entity); } } BoundContainerIterator.java000066400000000000000000000020471253404521400364220ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/container/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.container.v0_6; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; /** * Wraps a set of bound items into bound containers. * * @author Brett Henderson */ public class BoundContainerIterator implements ReleasableIterator { private ReleasableIterator source; /** * Creates a new instance. * * @param source The input source. */ public BoundContainerIterator(ReleasableIterator source) { this.source = source; } /** * {@inheritDoc} */ @Override public boolean hasNext() { return source.hasNext(); } /** * {@inheritDoc} */ @Override public BoundContainer next() { return new BoundContainer(source.next()); } /** * {@inheritDoc} */ @Override public void remove() { source.remove(); } /** * {@inheritDoc} */ @Override public void release() { source.release(); } } ChangeContainer.java000066400000000000000000000037421253404521400350310ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/container/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.container.v0_6; import org.openstreetmap.osmosis.core.store.GenericObjectReader; import org.openstreetmap.osmosis.core.store.GenericObjectWriter; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; import org.openstreetmap.osmosis.core.store.Storeable; import org.openstreetmap.osmosis.core.task.common.ChangeAction; /** * Holds an EntityContainer and an associated action. * * @author Brett Henderson */ public class ChangeContainer implements Storeable { private EntityContainer entityContainer; private ChangeAction action; /** * Creates a new instance. * * @param entityContainer * The entity to store. * @param action * The action to store. */ public ChangeContainer(EntityContainer entityContainer, ChangeAction action) { this.entityContainer = entityContainer; this.action = action; } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers * within the store. */ public ChangeContainer(StoreReader sr, StoreClassRegister scr) { entityContainer = (EntityContainer) new GenericObjectReader(sr, scr).readObject(); action = ChangeAction.valueOf(sr.readString()); } /** * {@inheritDoc} */ public void store(StoreWriter sw, StoreClassRegister scr) { new GenericObjectWriter(sw, scr).writeObject(entityContainer); sw.writeString(action.toString()); } /** * Returns the contained entity. * * @return The entity. */ public EntityContainer getEntityContainer() { return entityContainer; } /** * Returns the contained action. * * @return The action. */ public ChangeAction getAction() { return action; } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/container/v0_6/Dataset.java000066400000000000000000000011311253404521400334330ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.container.v0_6; /** * Allows entire datasets to be passed between tasks. Tasks supporting this data * type are expected to perform operations that require random access to an * entire data set which cannot be performed in a "streamy" fashion. * * @author Brett Henderson */ public interface Dataset { /** * Creates a new reader instance providing access to the data within this * set. * * @return A new dataset reader. */ DatasetContext createReader(); } DatasetContext.java000066400000000000000000000054651253404521400347370ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/container/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.container.v0_6; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.lifecycle.Completable; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; /** * Provides access to data within a Dataset. Every thread must access a Dataset through its own * reader. A reader must be released after use. It must be completed in order to ensure changes are * committed. * * @author Brett Henderson */ public interface DatasetContext extends Completable { /** * Returns the manager for manipulating node instances. * * @return The node manager. */ EntityManager getNodeManager(); /** * Returns the manager for manipulating way instances. * * @return The way manager. */ EntityManager getWayManager(); /** * Returns the manager for manipulating relation instances. * * @return The relation manager. */ EntityManager getRelationManager(); /** * Retrieves a specific node by its identifier. * * @param id * The id of the node. * @return The node. * @deprecated The node manager should be used instead. */ @Deprecated Node getNode(long id); /** * Retrieves a specific way by its identifier. * * @param id * The id of the way. * @return The way. * @deprecated The node manager should be used instead. */ @Deprecated Way getWay(long id); /** * Retrieves a specific relation by its identifier. * * @param id * The id of the relation. * @return The relation. * @deprecated The node manager should be used instead. */ @Deprecated Relation getRelation(long id); /** * Allows the entire dataset to be iterated across. * * @return An iterator pointing to the start of the collection. */ ReleasableIterator iterate(); /** * Allows all data within a bounding box to be iterated across. * * @param left * The longitude marking the left edge of the bounding box. * @param right * The longitude marking the right edge of the bounding box. * @param top * The latitude marking the top edge of the bounding box. * @param bottom * The latitude marking the bottom edge of the bounding box. * @param completeWays * If true, all nodes within the ways will be returned even if * they lie outside the box. * @return An iterator pointing to the start of the result data. */ ReleasableIterator iterateBoundingBox( double left, double right, double top, double bottom, boolean completeWays); } EntityContainer.java000066400000000000000000000021331253404521400351110ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/container/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.container.v0_6; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.store.Storeable; /** * Implementations of this class allow data entities to be processed without the * caller knowing their type. * * @author Brett Henderson */ public abstract class EntityContainer implements Storeable { /** * Calls the appropriate process method with the contained entity. * * @param processor * The processor to invoke. */ public abstract void process(EntityProcessor processor); /** * Returns the contained entity. * * @return The entity. */ public abstract Entity getEntity(); /** * Returns an instance containing a writeable entity. If the entity within this instance is * already writeable then "this" will be returned, otherwise a cloned entity and container will * be created. * * @return A container holding a writeable entity. */ public abstract EntityContainer getWriteableInstance(); } EntityContainerBuilder.java000066400000000000000000000104501253404521400364210ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/container/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.container.v0_6; import org.openstreetmap.osmosis.core.domain.v0_6.EntityBuilder; import org.openstreetmap.osmosis.core.domain.v0_6.NodeBuilder; import org.openstreetmap.osmosis.core.domain.v0_6.RelationBuilder; import org.openstreetmap.osmosis.core.domain.v0_6.WayBuilder; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.task.v0_6.Source; /** * Provides a mechanism to manipulate entities without directly manipulating and instantiating their * containers. This class does nothing by default, sub-classes must override methods to add their * own functionality * * @author Brett Henderson * * @deprecated The builder classes are not required because entities are now writeable. */ @Deprecated public class EntityContainerBuilder implements EntityProcessor, Source { private Sink sink; private NodeBuilder nodeBuilder; private WayBuilder wayBuilder; private RelationBuilder relationBuilder; /** * Creates a new instance. */ public EntityContainerBuilder() { nodeBuilder = new NodeBuilder(); wayBuilder = new WayBuilder(); relationBuilder = new RelationBuilder(); } /** * Performs generic entity processing. This should be overridden by * implementations wishing to perform generic entity processing. * * @param builder * The entity builder to be processed. * @return True if modifications were made to the entity builder during * processing. */ protected boolean processEntity(EntityBuilder builder) { return false; } /** * Performs node specific processing. This should be overridden by * implementations wishing to perform node processing. * * @param entityBuilder * The entity builder to be processed. * @return True if modifications were made to the entity builder during * processing. */ protected boolean processNode(NodeBuilder entityBuilder) { return false; } /** * Performs way specific processing. This should be overridden by * implementations wishing to perform way processing. * * @param entityBuilder * The entity builder to be processed. * @return True if modifications were made to the entity builder during * processing. */ protected boolean processWay(WayBuilder entityBuilder) { return false; } /** * Performs relation specific processing. This should be overridden by * implementations wishing to perform relation processing. * * @param entityBuilder * The entity builder to be processed. * @return True if modifications were made to the entity builder during * processing. */ protected boolean processRelation(RelationBuilder entityBuilder) { return false; } /** * {@inheritDoc} */ @Override public void process(BoundContainer boundContainer) { sink.process(boundContainer); } /** * {@inheritDoc} */ @Override public void process(NodeContainer nodeContainer) { boolean modified; nodeBuilder.initialize(nodeContainer.getEntity()); modified = false; modified = modified || processEntity(nodeBuilder); modified = modified || processNode(nodeBuilder); if (modified) { sink.process(new NodeContainer(nodeBuilder.buildEntity())); } else { sink.process(nodeContainer); } } /** * {@inheritDoc} */ @Override public void process(WayContainer wayContainer) { boolean modified; wayBuilder.initialize(wayContainer.getEntity()); modified = false; modified = modified || processEntity(wayBuilder); modified = modified || processWay(wayBuilder); if (modified) { sink.process(new WayContainer(wayBuilder.buildEntity())); } else { sink.process(wayContainer); } } /** * {@inheritDoc} */ @Override public void process(RelationContainer relationContainer) { boolean modified; relationBuilder.initialize(relationContainer.getEntity()); modified = false; modified = modified || processEntity(relationBuilder); modified = modified || processRelation(relationBuilder); if (modified) { sink.process(new RelationContainer(relationBuilder.buildEntity())); } else { sink.process(relationContainer); } } /** * {@inheritDoc} */ @Override public void setSink(Sink sink) { this.sink = sink; } } EntityContainerFactory.java000066400000000000000000000007671253404521400364540ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/container/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.container.v0_6; /** * Wraps entity objects in containers suitable for the entity type. * * @param * The type of entity. */ public interface EntityContainerFactory { /** * Wraps the entity in a container. * * @param entity * The entity to be wrapped. * @return The entity container. */ EntityContainer createContainer(T entity); } EntityManager.java000066400000000000000000000027341253404521400345500ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/container/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.container.v0_6; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; /** * Defines the dataset methods available for manipulating entities. * * @author Brett Henderson * @param * The entity type to be supported. */ public interface EntityManager { /** * Retrieves an entity by its identifier. * * @param id * The id of the entity. * @return The entity. */ T getEntity(long id); /** * Returns an iterator providing access to all entities in the database. * * @return The entity iterator. */ ReleasableIterator iterate(); /** * Indicates if the specified entity exists in the database. * * @param id * The id of the entity. * @return True if the entity exists, false otherwise. */ boolean exists(long id); /** * Adds the specified entity to the database. * * @param entity * The entity to add. */ void addEntity(T entity); /** * Updates the specified entity details in the database. * * @param entity * The entity to update. */ void modifyEntity(T entity); /** * Removes the specified entity from the database. * * @param entityId * The id of the entity to remove. */ void removeEntity(long entityId); } EntityProcessor.java000066400000000000000000000015541253404521400351540ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/container/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.container.v0_6; /** * EntityContainer implementations call implementations of this class to * perform entity type specific processing. * * @author Brett Henderson */ public interface EntityProcessor { /** * Process the bound. * * @param bound * The bound to be processed. */ void process(BoundContainer bound); /** * Process the node. * * @param node * The node to be processed. */ void process(NodeContainer node); /** * Process the way. * * @param way * The way to be processed. */ void process(WayContainer way); /** * Process the relation. * * @param relation * The relation to be processed. */ void process(RelationContainer relation); } NodeContainer.java000066400000000000000000000030201253404521400345160ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/container/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.container.v0_6; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; /** * Entity container implementation for nodes. * * @author Brett Henderson */ public class NodeContainer extends EntityContainer { private Node node; /** * Creates a new instance. * * @param node * The node to wrap. */ public NodeContainer(Node node) { this.node = node; } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers * within the store. */ public NodeContainer(StoreReader sr, StoreClassRegister scr) { node = new Node(sr, scr); } /** * {@inheritDoc} */ public void store(StoreWriter sw, StoreClassRegister scr) { node.store(sw, scr); } /** * {@inheritDoc} */ @Override public void process(EntityProcessor processor) { processor.process(this); } /** * {@inheritDoc} */ @Override public Node getEntity() { return node; } /** * {@inheritDoc} */ @Override public NodeContainer getWriteableInstance() { if (node.isReadOnly()) { return new NodeContainer(node.getWriteableInstance()); } else { return this; } } } NodeContainerFactory.java000066400000000000000000000007121253404521400360530ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/container/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.container.v0_6; import org.openstreetmap.osmosis.core.domain.v0_6.Node; /** * A container factory for node objects. */ public class NodeContainerFactory implements EntityContainerFactory { /** * {@inheritDoc} */ @Override public EntityContainer createContainer(Node entity) { return new NodeContainer(entity); } } NodeContainerIterator.java000066400000000000000000000020301253404521400362300ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/container/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.container.v0_6; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; /** * Wraps a set of nodes into node containers. * * @author Brett Henderson */ public class NodeContainerIterator implements ReleasableIterator { private ReleasableIterator source; /** * Creates a new instance. * * @param source The input source. */ public NodeContainerIterator(ReleasableIterator source) { this.source = source; } /** * {@inheritDoc} */ @Override public boolean hasNext() { return source.hasNext(); } /** * {@inheritDoc} */ @Override public NodeContainer next() { return new NodeContainer(source.next()); } /** * {@inheritDoc} */ @Override public void remove() { source.remove(); } /** * {@inheritDoc} */ @Override public void release() { source.release(); } } RelationContainer.java000066400000000000000000000031501253404521400354120ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/container/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.container.v0_6; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; /** * Entity container implementation for relations. * * @author Brett Henderson */ public class RelationContainer extends EntityContainer { private Relation relation; /** * Creates a new instance. * * @param relation * The relation to wrap. */ public RelationContainer(Relation relation) { this.relation = relation; } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers * within the store. */ public RelationContainer(StoreReader sr, StoreClassRegister scr) { relation = new Relation(sr, scr); } /** * {@inheritDoc} */ public void store(StoreWriter sw, StoreClassRegister scr) { relation.store(sw, scr); } /** * {@inheritDoc} */ @Override public void process(EntityProcessor processor) { processor.process(this); } /** * {@inheritDoc} */ @Override public Relation getEntity() { return relation; } /** * {@inheritDoc} */ @Override public RelationContainer getWriteableInstance() { if (relation.isReadOnly()) { return new RelationContainer(relation.getWriteableInstance()); } else { return this; } } } RelationContainerFactory.java000066400000000000000000000007421253404521400367460ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/container/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.container.v0_6; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; /** * A container factory for relation objects. */ public class RelationContainerFactory implements EntityContainerFactory { /** * {@inheritDoc} */ @Override public EntityContainer createContainer(Relation entity) { return new RelationContainer(entity); } } RelationContainerIterator.java000066400000000000000000000021001253404521400371160ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/container/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.container.v0_6; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; /** * Wraps a set of relations into relation containers. * * @author Brett Henderson */ public class RelationContainerIterator implements ReleasableIterator { private ReleasableIterator source; /** * Creates a new instance. * * @param source The input source. */ public RelationContainerIterator(ReleasableIterator source) { this.source = source; } /** * {@inheritDoc} */ @Override public boolean hasNext() { return source.hasNext(); } /** * {@inheritDoc} */ @Override public RelationContainer next() { return new RelationContainer(source.next()); } /** * {@inheritDoc} */ @Override public void remove() { source.remove(); } /** * {@inheritDoc} */ @Override public void release() { source.release(); } } WayContainer.java000066400000000000000000000027721253404521400344060ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/container/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.container.v0_6; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; /** * Entity container implementation for ways. * * @author Brett Henderson */ public class WayContainer extends EntityContainer { private Way way; /** * Creates a new instance. * * @param way * The way to wrap. */ public WayContainer(Way way) { this.way = way; } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers * within the store. */ public WayContainer(StoreReader sr, StoreClassRegister scr) { way = new Way(sr, scr); } /** * {@inheritDoc} */ public void store(StoreWriter sw, StoreClassRegister scr) { way.store(sw, scr); } /** * {@inheritDoc} */ @Override public void process(EntityProcessor processor) { processor.process(this); } /** * {@inheritDoc} */ @Override public Way getEntity() { return way; } /** * {@inheritDoc} */ @Override public WayContainer getWriteableInstance() { if (way.isReadOnly()) { return new WayContainer(way.getWriteableInstance()); } else { return this; } } } WayContainerFactory.java000066400000000000000000000007041253404521400357270ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/container/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.container.v0_6; import org.openstreetmap.osmosis.core.domain.v0_6.Way; /** * A container factory for way objects. */ public class WayContainerFactory implements EntityContainerFactory { /** * {@inheritDoc} */ @Override public EntityContainer createContainer(Way entity) { return new WayContainer(entity); } } WayContainerIterator.java000066400000000000000000000020161253404521400361070ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/container/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.container.v0_6; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; /** * Wraps a set of ways into way containers. * * @author Brett Henderson */ public class WayContainerIterator implements ReleasableIterator { private ReleasableIterator source; /** * Creates a new instance. * * @param source The input source. */ public WayContainerIterator(ReleasableIterator source) { this.source = source; } /** * {@inheritDoc} */ @Override public boolean hasNext() { return source.hasNext(); } /** * {@inheritDoc} */ @Override public WayContainer next() { return new WayContainer(source.next()); } /** * {@inheritDoc} */ @Override public void remove() { source.remove(); } /** * {@inheritDoc} */ @Override public void release() { source.release(); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/database/000077500000000000000000000000001253404521400302175ustar00rootroot00000000000000AuthenticationPropertiesLoader.java000066400000000000000000000064631253404521400371770ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/database// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.database; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Loads database authentication details from a properties file. *

* The recognised properties are: *

    *
  • host
  • *
  • database
  • *
  • user
  • *
  • password
  • *
  • db
  • *
* * @author Brett Henderson */ public class AuthenticationPropertiesLoader { private static final Logger LOG = Logger.getLogger(AuthenticationPropertiesLoader.class.getName()); private static final String KEY_HOST = "host"; private static final String KEY_DATABASE = "database"; private static final String KEY_USER = "user"; private static final String KEY_PASSWORD = "password"; private static final String KEY_DBTYPE = "dbType"; private final File propertiesFile; private Properties properties; /** * Creates a new instance. * * @param propertiesFile The location of the properties file containing authentication * information. */ public AuthenticationPropertiesLoader(File propertiesFile) { this.propertiesFile = propertiesFile; } private Properties loadProperties(File configFile) { Properties loadedProperties; FileInputStream fileInputStream = null; loadedProperties = new Properties(); try { fileInputStream = new FileInputStream(configFile); loadedProperties.load(fileInputStream); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to load properties from config file " + configFile + ".", e); } finally { if (fileInputStream != null) { try { fileInputStream.close(); } catch (IOException e) { LOG.log(Level.WARNING, "Unable to close input stream for properties file " + configFile + ".", e); } } } return loadedProperties; } /** * Updates the login credentials with values from the properties file. Only values contained in * the properties file will be added. * * @param loginCredentials The login credentials to be updated. */ public void updateLoginCredentials(DatabaseLoginCredentials loginCredentials) { if (properties == null) { properties = loadProperties(propertiesFile); } if (properties.containsKey(KEY_HOST)) { loginCredentials.setHost(properties.getProperty(KEY_HOST)); } if (properties.containsKey(KEY_DATABASE)) { loginCredentials.setDatabase(properties.getProperty(KEY_DATABASE)); } if (properties.containsKey(KEY_USER)) { loginCredentials.setUser(properties.getProperty(KEY_USER)); } if (properties.containsKey(KEY_PASSWORD)) { loginCredentials.setPassword(properties.getProperty(KEY_PASSWORD)); } if (properties.containsKey(KEY_DBTYPE)) { loginCredentials.setDbType(properties.getProperty(KEY_DBTYPE)); } } } DatabaseConstants.java000066400000000000000000000064661253404521400344200ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/database// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.database; /** * Defines common constants shared between database tasks. * * @author Brett Henderson */ public final class DatabaseConstants { /** * This class cannot be instantiated. */ private DatabaseConstants() { } /** * The task argument for specifying an database authorisation properties file. */ public static final String TASK_ARG_AUTH_FILE = "authFile"; /** * The task argument for specifying the host for a database connection. */ public static final String TASK_ARG_HOST = "host"; /** * The task argument for specifying the database instance for a database connection. */ public static final String TASK_ARG_DATABASE = "database"; /** * The task argument for specifying the user for a database connection. */ public static final String TASK_ARG_USER = "user"; /** * The task argument for specifying the database type to be used. */ public static final String TASK_ARG_DB_TYPE = "dbType"; /** * The task argument for specifying the password for a database connection. */ public static final String TASK_ARG_PASSWORD = "password"; /** * The task argument for specifying whether schema version validation should be performed. */ public static final String TASK_ARG_VALIDATE_SCHEMA_VERSION = "validateSchemaVersion"; /** * The task argument for specifying what should occur if an invalid schema version is * encountered. */ public static final String TASK_ARG_ALLOW_INCORRECT_SCHEMA_VERSION = "allowIncorrectSchemaVersion"; /** * The task argument for forcing a utf-8 database connection. */ public static final String TASK_ARG_FORCE_UTF8 = "forceUtf8"; /** * The task argument for enabling profiling on the database connection. */ public static final String TASK_ARG_PROFILE_SQL = "profileSql"; /** * The default host for a database connection. */ public static final String TASK_DEFAULT_HOST = "localhost"; /** * The default database for a database connection. */ public static final String TASK_DEFAULT_DATABASE = "osm"; /** * The default user for a database connection. */ public static final String TASK_DEFAULT_USER = null; /** * The default password for a database connection. */ public static final DatabaseType TASK_DEFAULT_DB_TYPE = DatabaseType.POSTGRESQL; /** * The default password for a database connection. */ public static final String TASK_DEFAULT_PASSWORD = null; /** * The default value for whether schema version validation should be performed. */ public static final boolean TASK_DEFAULT_VALIDATE_SCHEMA_VERSION = true; /** * The default value for whether the program should allow an incorrect schema version. */ public static final boolean TASK_ALLOW_INCORRECT_SCHEMA_VERSION = false; /** * The default value for forcing a utf-8 connection. */ public static final boolean TASK_DEFAULT_FORCE_UTF8 = false; /** * The default value for enabling profile on a database connection. */ public static final boolean TASK_DEFAULT_PROFILE_SQL = false; } DatabaseLoginCredentials.java000066400000000000000000000111201253404521400356510ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/database// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.database; /** * Stores all information required to connect to a database. * * @author Brett Henderson */ public class DatabaseLoginCredentials { private String datasourceJndiLocation; private String host; private String database; private String user; private String password; private boolean forceUtf8; private boolean profileSql; private DatabaseType dbType; /** * Creates a new instance. * * @param datasourceJndiLocation * The location of the data source in JNDI. */ public DatabaseLoginCredentials(String datasourceJndiLocation) { this.datasourceJndiLocation = datasourceJndiLocation; } /** * Creates a new instance. * * @param host * The server hosting the database. * @param database * The database instance. * @param user * The user name for authentication. * @param password * The password for authentication. * @param forceUtf8 * If true, the database connection will be forced to use utf-8 instead of the * database default. * @param profileSql * If true, profile logging will be enabled on the database connection causing all * queries to be logged to stderr. * @param dbType * The database type. */ public DatabaseLoginCredentials(String host, String database, String user, String password, boolean forceUtf8, boolean profileSql, DatabaseType dbType) { this.host = host; this.database = database; this.user = user; this.password = password; this.forceUtf8 = forceUtf8; this.profileSql = profileSql; this.dbType = dbType; } /** * Gets the location of the datasource in JNDI. If null, new connections * will need to be created using other parameters. * * @return The datasource location in JNDI. */ public String getDatasourceJndiLocation() { return datasourceJndiLocation; } /** * Returns the host. * * @return The host. */ public String getHost() { return host; } /** * Updates the host. * * @param host The new host. */ public void setHost(String host) { this.host = host; } /** * Returns the database. * * @return The database. */ public String getDatabase() { return database; } /** * Updates the database. * * @param database The new database. */ public void setDatabase(String database) { this.database = database; } /** * Returns the user. * * @return The user. */ public String getUser() { return user; } /** * Updates the user. * * @param user The new user. */ public void setUser(String user) { this.user = user; } /** * Returns the password. * * @return The password. */ public String getPassword() { return password; } /** * Updates the password. * * @param password The new password. */ public void setPassword(String password) { this.password = password; } /** * Returns the force utf-8 flag. * * @return The force utf-8 flag. */ public boolean getForceUtf8() { return forceUtf8; } /** * Updates the force utf-8 flag. * * @param forceUtf8 The new force utf-8 flag. */ public void setForceUtf8(boolean forceUtf8) { this.forceUtf8 = forceUtf8; } /** * Returns the profile SQL flag. * * @return The profile SQL flag. */ public boolean getProfileSql() { return profileSql; } /** * Updates the profile SQL flag. * * @param profileSql The new profile SQL flag. */ public void setProfileSql(boolean profileSql) { this.profileSql = profileSql; } /** * Return database type. * * @return database type */ public DatabaseType getDbType() { return dbType; } /** * Updates database type. * * @param dbType database type */ public void setDbType(DatabaseType dbType) { this.dbType = dbType; } /** * Updates the database type. * * @param property * The database type property. */ public void setDbType(String property) { this.dbType = DatabaseType.fromString(property); } } DatabasePreferences.java000066400000000000000000000036051253404521400346750ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/database// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.database; /** * Stores parameters that can be used to configure database behaviour. * * @author Brett Henderson */ public class DatabasePreferences { private boolean validateSchemaVersion; private boolean allowIncorrectSchemaVersion; /** * Creates a new instance. * * @param validateSchemaVersion * Specifies whether a schema version check should be performed. * @param allowIncorrectSchemaVersion * Defines behaviour on an incorrect schema version. If true, a * warning will be logged. If false, execution will abort. */ public DatabasePreferences(boolean validateSchemaVersion, boolean allowIncorrectSchemaVersion) { this.validateSchemaVersion = validateSchemaVersion; this.allowIncorrectSchemaVersion = allowIncorrectSchemaVersion; } /** * Returns the validateSchemaVersion flag. * * @return The validateSchemaVersion value. */ public boolean getValidateSchemaVersion() { return validateSchemaVersion; } /** * Updates the validateSchemaVersion flag. * * @param validateSchemaVersion * The new validateSchemaVersion value. */ public void setValidateSchemaVersion(boolean validateSchemaVersion) { this.validateSchemaVersion = validateSchemaVersion; } /** * Returns the allowIncorrectSchemaVersion flag. * * @return The allowIncorrectSchemaVersion value. */ public boolean getAllowIncorrectSchemaVersion() { return allowIncorrectSchemaVersion; } /** * Updates the allowIncorrectSchemaVersion flag. * * @param allowIncorrectSchemaVersion * The new allowIncorrectSchemaVersion value. */ public void setAllowIncorrectSchemaVersion(boolean allowIncorrectSchemaVersion) { this.allowIncorrectSchemaVersion = allowIncorrectSchemaVersion; } } DatabaseTaskManagerFactory.java000066400000000000000000000103051253404521400361540ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/database// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.database; import java.io.File; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; /** * Extends the basic task manager factory functionality with MySQL task specific common methods. * * @author Brett Henderson */ public abstract class DatabaseTaskManagerFactory extends TaskManagerFactory { /** * Utility method for retrieving the login credentials for a database connection. * * @param taskConfig Contains all information required to instantiate and configure the task. * @return The credentials for the database connection. */ protected DatabaseLoginCredentials getDatabaseLoginCredentials(TaskConfiguration taskConfig) { DatabaseLoginCredentials loginCredentials; // Create a new credential object with default values. loginCredentials = new DatabaseLoginCredentials(DatabaseConstants.TASK_DEFAULT_HOST, DatabaseConstants.TASK_DEFAULT_DATABASE, DatabaseConstants.TASK_DEFAULT_USER, DatabaseConstants.TASK_DEFAULT_PASSWORD, DatabaseConstants.TASK_DEFAULT_FORCE_UTF8, DatabaseConstants.TASK_DEFAULT_PROFILE_SQL, DatabaseConstants.TASK_DEFAULT_DB_TYPE); // If an authentication properties file has been supplied, load override // values from there. if (doesArgumentExist(taskConfig, DatabaseConstants.TASK_ARG_AUTH_FILE)) { AuthenticationPropertiesLoader authLoader; authLoader = new AuthenticationPropertiesLoader(new File(getStringArgument(taskConfig, DatabaseConstants.TASK_ARG_AUTH_FILE))); authLoader.updateLoginCredentials(loginCredentials); } // Update the credentials with any explicit arguments provided on the // command line. loginCredentials.setHost(getStringArgument(taskConfig, DatabaseConstants.TASK_ARG_HOST, loginCredentials .getHost())); loginCredentials.setDatabase(getStringArgument(taskConfig, DatabaseConstants.TASK_ARG_DATABASE, loginCredentials.getDatabase())); loginCredentials.setUser(getStringArgument(taskConfig, DatabaseConstants.TASK_ARG_USER, loginCredentials .getUser())); loginCredentials.setPassword(getStringArgument(taskConfig, DatabaseConstants.TASK_ARG_PASSWORD, loginCredentials.getPassword())); loginCredentials.setForceUtf8(getBooleanArgument(taskConfig, DatabaseConstants.TASK_ARG_FORCE_UTF8, loginCredentials.getForceUtf8())); loginCredentials.setProfileSql(getBooleanArgument(taskConfig, DatabaseConstants.TASK_ARG_PROFILE_SQL, loginCredentials.getProfileSql())); loginCredentials.setDbType(getStringArgument(taskConfig, DatabaseConstants.TASK_ARG_DB_TYPE, loginCredentials .getDbType().toString())); return loginCredentials; } /** * Utility method for retrieving the login credentials for a database connection. * * @param taskConfig Contains all information required to instantiate and configure the task. * @return The value of the argument. */ protected DatabasePreferences getDatabasePreferences(TaskConfiguration taskConfig) { DatabasePreferences preferences; // Create a new preferences object with default values. preferences = new DatabasePreferences(DatabaseConstants.TASK_DEFAULT_VALIDATE_SCHEMA_VERSION, DatabaseConstants.TASK_ALLOW_INCORRECT_SCHEMA_VERSION); // Update the preferences with any explicit arguments provided on the // command line. preferences.setValidateSchemaVersion(getBooleanArgument(taskConfig, DatabaseConstants.TASK_ARG_VALIDATE_SCHEMA_VERSION, preferences.getValidateSchemaVersion())); preferences .setAllowIncorrectSchemaVersion(getBooleanArgument(taskConfig, DatabaseConstants.TASK_ARG_ALLOW_INCORRECT_SCHEMA_VERSION, preferences .getAllowIncorrectSchemaVersion())); return preferences; } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/database/DatabaseType.java000066400000000000000000000016301253404521400334300ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.database; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Represents the different database types. */ public enum DatabaseType { /** * The PostgreSQL database. */ POSTGRESQL, /** * The MySQL database. */ MYSQL; /** * Gets a database type value based on a string name. * * @param name * The database type string. * @return The strongly typed database type. */ public static DatabaseType fromString(String name) { if (POSTGRESQL.toString().equalsIgnoreCase(name)) { return POSTGRESQL; } else if (MYSQL.toString().equalsIgnoreCase(name)) { return MYSQL; } else { throw new OsmosisRuntimeException("The database type name " + name + " is not recognized."); } } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/database/DbFeature.java000066400000000000000000000036151253404521400327300ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.database; import org.openstreetmap.osmosis.core.store.GenericObjectReader; import org.openstreetmap.osmosis.core.store.GenericObjectWriter; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; import org.openstreetmap.osmosis.core.store.Storeable; /** * A data class for representing a database record for an entity feature. This * aggregates a standard entity feature type with a field relating it to the * owning entity. * * @author Brett Henderson * @param * The feature type to be encapsulated. */ public class DbFeature implements Storeable { private long entityId; private T feature; /** * Creates a new instance. * * @param entityId * The owning entity id. * @param feature * The feature being referenced. */ public DbFeature(long entityId, T feature) { this.entityId = entityId; this.feature = feature; } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers * within the store. */ @SuppressWarnings("unchecked") public DbFeature(StoreReader sr, StoreClassRegister scr) { this( sr.readLong(), (T) new GenericObjectReader(sr, scr).readObject() ); } /** * {@inheritDoc} */ public void store(StoreWriter sw, StoreClassRegister scr) { sw.writeLong(entityId); new GenericObjectWriter(sw, scr).writeObject(feature); } /** * @return The entity id. */ public long getEntityId() { return entityId; } /** * @return The entity feature. */ public T getFeature() { return feature; } } DbFeatureComparator.java000066400000000000000000000013361253404521400346770ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/database// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.database; import java.util.Comparator; import org.openstreetmap.osmosis.core.store.Storeable; /** * A comparator for sorting database feature objects by entity id. * * @author Brett Henderson * @param * The encapsulated feature type. */ public class DbFeatureComparator implements Comparator> { /** * {@inheritDoc} */ public int compare(DbFeature o1, DbFeature o2) { long idDelta; idDelta = o1.getEntityId() - o2.getEntityId(); if (idDelta < 0) { return -1; } else if (idDelta > 0) { return 1; } return 0; } } DbFeatureHistory.java000066400000000000000000000036201253404521400342270ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/database// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.database; import org.openstreetmap.osmosis.core.store.GenericObjectReader; import org.openstreetmap.osmosis.core.store.GenericObjectWriter; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; import org.openstreetmap.osmosis.core.store.Storeable; /** * A data class representing a history record for an entity feature. * * @author Brett Henderson * @param * The type of entity feature that this class stores history for. */ public class DbFeatureHistory implements Storeable { private T feature; private int version; /** * Creates a new instance. * * @param feature * The contained feature. * @param version * The version field. */ public DbFeatureHistory(T feature, int version) { this.feature = feature; this.version = version; } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers * within the store. */ @SuppressWarnings("unchecked") public DbFeatureHistory(StoreReader sr, StoreClassRegister scr) { feature = (T) new GenericObjectReader(sr, scr).readObject(); version = sr.readInteger(); } /** * {@inheritDoc} */ public void store(StoreWriter sw, StoreClassRegister scr) { new GenericObjectWriter(sw, scr).writeObject(feature); sw.writeInteger(version); } /** * Gets the contained feature. * * @return The feature. */ public T getFeature() { return feature; } /** * Gets the version value. * * @return The version value. */ public int getVersion() { return version; } } DbFeatureHistoryComparator.java000066400000000000000000000016401253404521400362570ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/database// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.database; import java.util.Comparator; import org.openstreetmap.osmosis.core.store.Storeable; /** * A comparator for sorting database feature objects by entity id, then entity version. * * @param * The encapsulated feature type. */ public class DbFeatureHistoryComparator implements Comparator>> { private DbFeatureComparator featureComparator = new DbFeatureComparator(); /** * {@inheritDoc} */ public int compare(DbFeatureHistory> o1, DbFeatureHistory> o2) { int parentComparison; parentComparison = featureComparator.compare(o1.getFeature(), o2.getFeature()); if (parentComparison != 0) { return parentComparison; } return o1.getVersion() - o2.getVersion(); } } DbFeatureHistoryRowMapper.java000066400000000000000000000020641253404521400360650ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/database// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.database; import java.sql.ResultSet; import java.sql.SQLException; import org.openstreetmap.osmosis.core.store.Storeable; /** * Wraps database features within a database feature object containing the owning entity id. * * @param * The type of feature to be wrapped. */ public class DbFeatureHistoryRowMapper implements RowMapperListener { private RowMapperListener> listener; /** * Creates a new instance. * * @param listener * The destination for result objects. */ public DbFeatureHistoryRowMapper(RowMapperListener> listener) { this.listener = listener; } /** * {@inheritDoc} */ @Override public void process(T data, ResultSet resultSet) throws SQLException { int version; // Get the entity version. version = resultSet.getInt("version"); listener.process(new DbFeatureHistory(data, version), resultSet); } } DbFeatureRowMapper.java000066400000000000000000000020011253404521400344720ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/database// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.database; import java.sql.ResultSet; import java.sql.SQLException; import org.openstreetmap.osmosis.core.store.Storeable; /** * Wraps database features within a database feature object containing the owning entity id. * * @param * The type of feature to be wrapped. */ public class DbFeatureRowMapper implements RowMapperListener { private RowMapperListener> listener; /** * Creates a new instance. * * @param listener * The destination for result objects. */ public DbFeatureRowMapper(RowMapperListener> listener) { this.listener = listener; } /** * {@inheritDoc} */ @Override public void process(T data, ResultSet resultSet) throws SQLException { long id; // Get the owning entity id. id = resultSet.getLong("id"); listener.process(new DbFeature(id, data), resultSet); } } DbOrderedFeature.java000066400000000000000000000032471253404521400341570ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/database// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.database; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; import org.openstreetmap.osmosis.core.store.Storeable; /** * A data class for representing a way node database record. This extends a way * node with fields relating it to the owning way. * * @author Brett Henderson * @param * The feature type to be encapsulated. */ public class DbOrderedFeature extends DbFeature { private int sequenceId; /** * Creates a new instance. * * @param entityId * The owning entity id. * @param feature * The feature being referenced. * @param sequenceId * The order of this feature within the entity. */ public DbOrderedFeature(long entityId, T feature, int sequenceId) { super(entityId, feature); this.sequenceId = sequenceId; } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers * within the store. */ public DbOrderedFeature(StoreReader sr, StoreClassRegister scr) { super(sr, scr); this.sequenceId = sr.readInteger(); } /** * {@inheritDoc} */ @Override public void store(StoreWriter sw, StoreClassRegister scr) { super.store(sw, scr); sw.writeInteger(sequenceId); } /** * @return The sequence id. */ public int getSequenceId() { return sequenceId; } } DbOrderedFeatureHistoryComparator.java000066400000000000000000000022041253404521400375610ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/database// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.database; import java.util.Comparator; import org.openstreetmap.osmosis.core.store.Storeable; /** * A comparator for sorting database feature objects by entity id, then entity version, then feature sequence. * * @param * The encapsulated feature type. */ public class DbOrderedFeatureHistoryComparator implements Comparator>> { private DbFeatureComparator featureComparator = new DbFeatureComparator(); /** * {@inheritDoc} */ @Override public int compare(DbFeatureHistory> o1, DbFeatureHistory> o2) { int parentComparison; int versionDelta; parentComparison = featureComparator.compare(o1.getFeature(), o2.getFeature()); if (parentComparison != 0) { return parentComparison; } versionDelta = o1.getVersion() - o2.getVersion(); if (versionDelta != 0) { return versionDelta; } return o1.getFeature().getSequenceId() - o2.getFeature().getSequenceId(); } } DbOrderedFeatureRowMapper.java000066400000000000000000000021721253404521400360100ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/database// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.database; import java.sql.ResultSet; import java.sql.SQLException; import org.openstreetmap.osmosis.core.store.Storeable; /** * Wraps database features within a database feature object containing the owning entity id. * * @param * The type of feature to be wrapped. */ public class DbOrderedFeatureRowMapper implements RowMapperListener> { private RowMapperListener> listener; /** * Creates a new instance. * * @param listener * The destination for result objects. */ public DbOrderedFeatureRowMapper(RowMapperListener> listener) { this.listener = listener; } /** * {@inheritDoc} */ @Override public void process(DbFeature data, ResultSet resultSet) throws SQLException { int sequence; // Get the entity sequence number. sequence = resultSet.getInt("sequence_id"); listener.process(new DbOrderedFeature(data.getEntityId(), data.getFeature(), sequence), resultSet); } } FeatureCollectionLoader.java000066400000000000000000000013331253404521400355410ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/database// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.database; import java.util.Collection; /** * Retrieves feature collections from entities. This allows feature collections to be loaded in a * generic way without requiring knowledge of the type of feature being dealt with. * * @param * The type of entity. * @param * The type of feature. */ public interface FeatureCollectionLoader { /** * Gets the feature collection from the entity. * * @param entity * The entity containing the collection. * @return The feature collection. */ Collection getFeatureCollection(Te entity); } FeaturePopulator.java000066400000000000000000000010101253404521400342740ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/database// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.database; import org.openstreetmap.osmosis.core.lifecycle.Releasable; /** * Populates an entity with its features. * * @param * The type of entity to be populated. */ public interface FeaturePopulator extends Releasable { /** * Populates the specified entity. * * @param entity * The entity to be populated. */ void populateFeatures(T entity); } RelationMemberCollectionLoader.java000066400000000000000000000011261253404521400370530ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/database// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.database; import java.util.Collection; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; /** * Loads relation members from relations. */ public class RelationMemberCollectionLoader implements FeatureCollectionLoader { /** * {@inheritDoc} */ @Override public Collection getFeatureCollection(Relation entity) { return entity.getMembers(); } } ReleasableStatementContainer.java000066400000000000000000000033321253404521400365730ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/database// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.database; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.lifecycle.Releasable; /** * A container for database statement objects that must be freed. This * implementation simplifies the management of many statements that must be * released as a group. * * @author Brett Henderson */ public class ReleasableStatementContainer implements Releasable { private static final Logger LOG = Logger.getLogger(ReleasableStatementContainer.class.getName()); private List objects; /** * Creates a new instance. */ public ReleasableStatementContainer() { objects = new ArrayList(); } /** * Adds a new object to be managed. The object is returned to allow method * chaining. * * @param * The type of statement being stored. * @param statement * The statement to be stored. * @return The statement that was stored. */ public T add(T statement) { objects.add(statement); return statement; } /** * Removes all objects. They will no longer be released. */ public void clear() { objects.clear(); } /** * {@inheritDoc} */ @Override public void release() { for (Statement statement : objects) { try { statement.close(); } catch (SQLException e) { // We're inside a release method therefore can't throw an exception. LOG.log(Level.WARNING, "Unable to close database statement.", e); } } objects.clear(); } } RowMapperListener.java000066400000000000000000000014711253404521400344300ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/database// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.database; import java.sql.ResultSet; import java.sql.SQLException; /** * Receives result objects produced by row mapper implementations. This is used in streaming * scenarios where a database result set produces too many results to fit into memory. * * @param The type of object to be produced. */ public interface RowMapperListener { /** * Processes the provided object. * * @param data * The object read from the result set. * @param resultSet * The result set pointing at the current row. * @throws SQLException * if an error occurs reading from the result set. */ void process(T data, ResultSet resultSet) throws SQLException; } SortingStoreRowMapperListener.java000066400000000000000000000017261253404521400370160ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/database// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.database; import java.sql.ResultSet; import java.sql.SQLException; import org.openstreetmap.osmosis.core.sort.common.FileBasedSort; import org.openstreetmap.osmosis.core.store.Storeable; /** * A row mapper listener that writes all objects into an object sortingStore. * * @param * The type of object to be stored. */ public class SortingStoreRowMapperListener implements RowMapperListener { private FileBasedSort sortingStore; /** * Creates a new instance. * * @param sortingStore * The sortingStore to receive objects. */ public SortingStoreRowMapperListener(FileBasedSort sortingStore) { this.sortingStore = sortingStore; } /** * {@inheritDoc} */ @Override public void process(T data, ResultSet resultSet) throws SQLException { sortingStore.add(data); } } WayNodeCollectionLoader.java000066400000000000000000000010401253404521400355070ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/database// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.database; import java.util.Collection; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; /** * Loads way nodes from ways. */ public class WayNodeCollectionLoader implements FeatureCollectionLoader { /** * {@inheritDoc} */ @Override public Collection getFeatureCollection(Way entity) { return entity.getWayNodes(); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/domain/000077500000000000000000000000001253404521400277225ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/domain/common/000077500000000000000000000000001253404521400312125ustar00rootroot00000000000000SimpleTimestampContainer.java000066400000000000000000000015071253404521400367610ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/domain/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.domain.common; import java.util.Date; /** * A timestamp container implementation that holds a standard date object. * * @author Brett Henderson */ public class SimpleTimestampContainer implements TimestampContainer { private Date timestamp; /** * Creates a new instance. * * @param timestamp * The timestamp to be managed. */ public SimpleTimestampContainer(Date timestamp) { this.timestamp = timestamp; } /** * {@inheritDoc} */ @Override public String getFormattedTimestamp(TimestampFormat timestampFormat) { return timestampFormat.formatTimestamp(timestamp); } /** * {@inheritDoc} */ @Override public Date getTimestamp() { return timestamp; } } TimestampContainer.java000066400000000000000000000014511253404521400356050ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/domain/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.domain.common; import java.util.Date; /** * Defines the interface for a class holding timestamps in one or both of parsed * and unparsed forms. This allows a date to remain in text form throughout a * pipeline if both ends utilise the date in the same format. * * @author Brett Henderson */ public interface TimestampContainer { /** * @return The timestamp. */ Date getTimestamp(); /** * Gets the timestamp in a string format. * * @param timestampFormat * The formatter to use for formatting the timestamp into a * string. * @return The timestamp string. */ String getFormattedTimestamp(TimestampFormat timestampFormat); } TimestampFormat.java000066400000000000000000000027511253404521400351170ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/domain/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.domain.common; import java.util.Date; /** * Concrete implementations of this class support dates in a specific format. * This is used for the lazy timestamp parsing functionality whereby dates can * be passed through the entire pipeline in unparsed string form if both ends * use the same date format. *

* Note that all methods within this class must be threadsafe because it may be * utilised concurrently at many points throughout a processing pipeline. * * @author Brett Henderson */ public abstract class TimestampFormat { /** * Formats the date object into string form. * * @param timestamp * The date to be formatted. * @return The formatted date string. */ public abstract String formatTimestamp(Date timestamp); /** * Parses a date string into date form. * * @param timestamp * The date string to be parsed. * @return The date object. */ public abstract Date parseTimestamp(String timestamp); /** * Indicates if the specified date format object supports the same date * format as this object. * * @param timestampFormat * The date format to compare against. * @return True if the date format is equivalent between the two date * objects. */ public boolean isEquivalent(TimestampFormat timestampFormat) { return getClass().equals(timestampFormat.getClass()); } } UnparsedTimestampContainer.java000066400000000000000000000033121253404521400373050ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/domain/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.domain.common; import java.util.Date; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * A timestamp container implementation that holds a timestamp in textual form. * * @author Brett Henderson */ public class UnparsedTimestampContainer implements TimestampContainer { private TimestampFormat managedTimestampFormat; private String timestampString; private Date timestamp; /** * Creates a new instance. * * @param timestampFormat * The format to use for parsing the timestamp string. * @param timestampString * The timestamp in unparsed string form. */ public UnparsedTimestampContainer(TimestampFormat timestampFormat, String timestampString) { this.managedTimestampFormat = timestampFormat; this.timestampString = timestampString; if (timestampString == null) { throw new OsmosisRuntimeException("The entity timestamp attribute is missing."); } } /** * {@inheritDoc} */ @Override public String getFormattedTimestamp(TimestampFormat timestampFormat) { if (timestampString != null && managedTimestampFormat.isEquivalent(timestampFormat)) { return timestampString; } // Ensure the timestamp has been parsed. getTimestamp(); if (timestamp != null) { return timestampFormat.formatTimestamp(timestamp); } else { return ""; } } /** * {@inheritDoc} */ @Override public Date getTimestamp() { if (timestamp == null && timestampString != null && timestampString.length() > 0) { timestamp = managedTimestampFormat.parseTimestamp(timestampString); } return timestamp; } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/domain/v0_6/000077500000000000000000000000001253404521400304745ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/domain/v0_6/Bound.java000066400000000000000000000361511253404521400324140ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.domain.v0_6; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.LinkedList; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; /** * A data class representing an OSM data bound element. * * @author Karl Newman */ public class Bound extends Entity implements Comparable { private static final double MIN_LATITUDE = -90.0; private static final double MAX_LATITUDE = 90.0; private static final double MIN_LONGITUDE = -180.0; private static final double MAX_LONGITUDE = 180.0; private double right; private double left; private double top; private double bottom; private String origin; /** * Creates a new instance which covers the entire planet. * * @param origin * The origin (source) of the data, typically a URI * */ public Bound(String origin) { this(MAX_LONGITUDE, MIN_LONGITUDE, MAX_LATITUDE, MIN_LATITUDE, origin); } /** * Creates a new instance with the specified boundaries. * * @param right * The longitude coordinate of the right (East) edge of the bound * @param left * The longitude coordinate of the left (West) edge of the bound * @param top * The latitude coordinate of the top (North) edge of the bound * @param bottom * The latitude coordinate of the bottom (South) edge of the bound * @param origin * The origin (source) of the data, typically a URI */ public Bound(double right, double left, double top, double bottom, String origin) { super(new CommonEntityData(0, 0, new Date(), OsmUser.NONE, 0)); // minimal underlying entity // Check if any coordinates are out of bounds if (Double.compare(right, MAX_LONGITUDE + 1.0d) > 0 || Double.compare(right, MIN_LONGITUDE - 1.0d) < 0 || Double.compare(left, MAX_LONGITUDE + 1.0d) > 0 || Double.compare(left, MIN_LONGITUDE - 1.0d) < 0 || Double.compare(top, MAX_LATITUDE + 1.0d) > 0 || Double.compare(top, MIN_LATITUDE - 1.0d) < 0 || Double.compare(bottom, MAX_LATITUDE + 1.0d) > 0 || Double.compare(bottom, MIN_LATITUDE - 1.0d) < 0) { throw new IllegalArgumentException("Bound coordinates outside of valid range"); } if (Double.compare(top, bottom) < 0) { throw new IllegalArgumentException("Bound top < bottom"); } this.right = right; this.left = left; this.top = top; this.bottom = bottom; this.origin = origin; } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers within the store. */ public Bound(StoreReader sr, StoreClassRegister scr) { super(sr, scr); this.right = sr.readDouble(); this.left = sr.readDouble(); this.top = sr.readDouble(); this.bottom = sr.readDouble(); this.origin = sr.readString(); } /** * {@inheritDoc} */ @Override public void store(StoreWriter sw, StoreClassRegister scr) { super.store(sw, scr); sw.writeDouble(right); sw.writeDouble(left); sw.writeDouble(top); sw.writeDouble(bottom); sw.writeString(origin); } /** * {@inheritDoc} */ @Override public EntityType getType() { return EntityType.Bound; } /** * @return The right (East) bound longitude */ public double getRight() { return right; } /** * @return The left (West) bound longitude */ public double getLeft() { return left; } /** * @return The top (North) bound latitude */ public double getTop() { return top; } /** * @return The bottom (South) bound latitude */ public double getBottom() { return bottom; } /** * @return the origin */ public String getOrigin() { return origin; } /** * Calculate the intersected area of this with the specified bound. * * @param intersectingBound * Bound element with which to calculate the intersection * @return Bound Resultant intersection of the two bound object */ public Bound intersect(Bound intersectingBound) { String newOrigin; double newRight = 0.0, newLeft = 0.0, newTop, newBottom; boolean intersect180, this180; // flags to indicate bound cross antimeridian if (intersectingBound == null) { return null; // no intersection } // first check the vertical intersection newTop = Math.min(this.getTop(), intersectingBound.getTop()); newBottom = Math.max(this.getBottom(), intersectingBound.getBottom()); if (Double.compare(newBottom, newTop) >= 0) { // no north-south intersecting region return null; } intersect180 = (Double.compare(intersectingBound.getLeft(), intersectingBound.getRight()) > 0); this180 = (Double.compare(this.getLeft(), this.getRight()) > 0); if ((intersect180 && this180) || !(intersect180 || this180)) { // if both or neither cross the antimeridian, use the simple case newRight = Math.min(this.getRight(), intersectingBound.getRight()); newLeft = Math.max(this.getLeft(), intersectingBound.getLeft()); if (!(intersect180 || this180) && (Double.compare(newLeft, newRight) >= 0)) { /* * This is only applicable for the case where neither cross the antimeridian, * because if both cross, they must intersect. */ return null; // no intersecting area } } else { Bound b1, b2; // stand-ins for this and intersectingBound if (intersect180 && !this180) { // passed parameter Bound crosses the antimeridian, this Bound doesn't b1 = this; b2 = intersectingBound; } else { // this Bound crosses the antimeridian, passed parameter Bound doesn't b1 = intersectingBound; b2 = this; } if (Double.compare(b1.getRight(), b2.getLeft()) > 0 && Double.compare(b1.getLeft(), b2.getRight()) < 0) { // intersects on both sides of the antimeridian--just pick the smaller of the // two Double diff1 = b1.getRight() - b1.getLeft(); Double diff2 = b2.getRight() - MIN_LONGITUDE + MAX_LONGITUDE - b2.getLeft(); if (Double.compare(diff1, diff2) <= 0) { newRight = b1.getRight(); newLeft = b1.getLeft(); } else { newRight = b2.getRight(); newLeft = b2.getLeft(); } } else if (Double.compare(b1.getRight(), b2.getLeft()) > 0) { // intersects on the East side of the antimeridian newRight = b1.getRight(); newLeft = b2.getLeft(); } else if (Double.compare(b1.getLeft(), b2.getRight()) < 0) { // intersects on the West side of the antimeridian newRight = b2.getRight(); newLeft = b1.getLeft(); } } if (Double.compare(newRight, newLeft) == 0) { return null; } // Keep the origin string from this if it's not blank, otherwise use the origin string from // the intersecting Bound if (origin != "") { newOrigin = origin; } else { newOrigin = intersectingBound.origin; } return new Bound(newRight, newLeft, newTop, newBottom, newOrigin); } /** * Calculate the union area of this with the specified bound. Not a strict mathematical union, * but the smallest rectangular area which includes both bound. Thus, result may include areas * not contained in the original bound. * * @param unionBound * Bound element with which to calculate the union * @return Bound Resultant union of the two bound objects */ public Bound union(Bound unionBound) { double newRight = 0.0, newLeft = 0.0, newTop, newBottom; String newOrigin; if (unionBound == null) { return this; // nothing to compute a union with } // First compute the vertical union newTop = Math.max(this.getTop(), unionBound.getTop()); newBottom = Math.min(this.getBottom(), unionBound.getBottom()); if (Double.compare(newBottom, newTop) >= 0) { // no north-south intersecting region return null; } // Next check the (likely) common case where one of the bound covers the planet if ((Double.compare(this.getLeft(), MIN_LONGITUDE) == 0 && Double.compare( this.getRight(), MAX_LONGITUDE) == 0) || (Double.compare(unionBound.getLeft(), MIN_LONGITUDE) == 0 && Double.compare( unionBound.getRight(), MAX_LONGITUDE) == 0)) { newRight = MAX_LONGITUDE; newLeft = MIN_LONGITUDE; } else { boolean union180, this180; // flags to indicate bound cross antimeridian double size1, size2; // resulting union sizes for comparison union180 = (Double.compare(unionBound.getLeft(), unionBound.getRight()) > 0); this180 = (Double.compare(this.getLeft(), this.getRight()) > 0); if (union180 && this180) { // if both cross the antimeridian, then the union will cross, too. newRight = Math.max(this.getRight(), unionBound.getRight()); newLeft = Math.min(this.getLeft(), unionBound.getLeft()); } else if (!(union180 || this180)) { // neither cross the antimeridian, but the union might // first calculate the size of a simple union which doesn't cross the antimeridian size1 = Math.max(this.getRight(), unionBound.getRight()) - Math.min(this.getLeft(), unionBound.getLeft()); // then calculate the size of the resulting union which does cross the antimeridian size2 = (Math.min(this.getRight(), unionBound.getRight()) - MIN_LONGITUDE) + (MAX_LONGITUDE - Math.max(this.getLeft(), unionBound.getLeft())); // now pick the smaller of the two if (Double.compare(size1, size2) <= 0) { newRight = Math.max(this.getRight(), unionBound.getRight()); newLeft = Math.min(this.getLeft(), unionBound.getLeft()); } else { newRight = Math.min(this.getRight(), unionBound.getRight()); newLeft = Math.max(this.getLeft(), unionBound.getLeft()); } } else { // One of the Bound crosses the antimeridian, the other doesn't Bound b1, b2; if (union180 && !this180) { // passed parameter Bound crosses the antimeridian, this Bound doesn't b1 = unionBound; b2 = this; } else { // this Bound crosses the antimeridian, passed parameter Bound doesn't b1 = this; b2 = unionBound; } // check for the case where the two Bound overlap on both edges such that the union // covers the planet. if (Double.compare(b1.getRight(), b2.getLeft()) >= 0 && Double.compare(b1.getLeft(), b2.getRight()) <= 0) { newLeft = MIN_LONGITUDE; newRight = MAX_LONGITUDE; } else { // first calculate the size of a union with the simple bound added to the left size1 = (Math.max(b1.getRight(), b2.getRight()) - MIN_LONGITUDE) + (MAX_LONGITUDE - b1.getLeft()); // first calculate the size of a union with the simple bound added to the right size2 = (b1.getRight() - MIN_LONGITUDE) + (MAX_LONGITUDE - Math.min(b1.getLeft(), b2.getLeft())); // now pick the smaller of the two if (Double.compare(size1, size2) <= 0) { newRight = Math.max(b1.getRight(), b2.getRight()); newLeft = b1.getLeft(); } else { newRight = b1.getRight(); newLeft = Math.min(b1.getLeft(), b2.getLeft()); } } } } if (Double.compare(newRight, newLeft) == 0) { return null; } // Keep the origin string from this if it's not blank, otherwise use the origin string from // the union Bound if (this.getOrigin() != null && !this.getOrigin().equals("")) { newOrigin = getOrigin(); } else { newOrigin = unionBound.getOrigin(); } return new Bound(newRight, newLeft, newTop, newBottom, newOrigin); } /** * Retrieve a collection of Bound objects which collectively comprise the entirety of this * Bound but individually do not cross the antimeridian and thus can be used in simple area * operations. The degenerate case will return this Bound. * * @return Iterable collection of Bound elements */ public Iterable toSimpleBound() { Collection c = new LinkedList(); if (Double.compare(this.getLeft(), this.getRight()) < 0) { // simple case, just return this c.add(this); } else { // split the bound into two parts--one on either side of the antimeridian c.add(new Bound( MAX_LONGITUDE, this.getLeft(), this.getTop(), this.getBottom(), this.getOrigin())); c.add(new Bound( this.getRight(), MIN_LONGITUDE, this.getTop(), this.getBottom(), this.getOrigin())); } return Collections.unmodifiableCollection(c); } /** * Compares this bound to the specified bound. The bound comparison is based * on a comparison of area, latitude, and longitude in that order. * * @param comparisonBound * The bound to compare to. * @return 0 if equal, < 0 if this sorts before comparison (this is * "smaller"), and > 0 if this sorts before comparison (this is * "bigger") */ public int compareTo(Bound comparisonBound) { double areaT = 0.0, areaC = 0.0; int result; /* * This is a very simple "area" calculation just using the coordinate values, not accounting * for any projections. */ for (Bound b : this.toSimpleBound()) { areaT += (b.getRight() - b.getLeft()) * (b.getTop() - b.getBottom()); } for (Bound b : comparisonBound.toSimpleBound()) { areaC += (b.getRight() - b.getLeft()) * (b.getTop() - b.getBottom()); } // Use Double.compare (instead of < and >) to catch unique border cases result = Double.compare(areaT, areaC); if (result != 0) { return result; } result = Double.compare(this.getTop(), comparisonBound.getTop()); if (result != 0) { return result; } result = Double.compare(this.getBottom(), comparisonBound.getBottom()); if (result != 0) { return result; } result = Double.compare(this.getLeft(), comparisonBound.getLeft()); if (result != 0) { return result; } result = Double.compare(this.getRight(), comparisonBound.getRight()); if (result != 0) { return result; } String myOrigin = this.getOrigin(); String otherOrigin = comparisonBound.getOrigin(); // null origin is considered "less" than non-null origin if (myOrigin == null) { if (otherOrigin == null) { return 0; } else { return -1; } } else { if (otherOrigin == null) { return 1; } else { return myOrigin.compareTo(otherOrigin); } } } /** * {@inheritDoc} */ @Override public boolean equals(Object o) { if (o instanceof Bound) { return compareTo((Bound) o) == 0; } else { return false; } } /** * {@inheritDoc} */ @Override public int hashCode() { /* * As per the hashCode definition, this doesn't have to be unique it * just has to return the same value for any two objects that compare * equal. Using both id and version will provide a good distribution of * values but is simple to calculate. */ return (int) getId() + getVersion(); } /** * {@inheritDoc} */ @Override public Bound getWriteableInstance() { return this; } /** * ${@inheritDoc}. */ @Override public String toString() { return "Bound(top=" + getTop() + ", bottom=" + getBottom() + ", left=" + getLeft() + ", right=" + getRight() + ")"; } } CommonEntityData.java000066400000000000000000000320241253404521400345000ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/domain/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.domain.v0_6; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.domain.common.SimpleTimestampContainer; import org.openstreetmap.osmosis.core.domain.common.TimestampContainer; import org.openstreetmap.osmosis.core.domain.common.TimestampFormat; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; import org.openstreetmap.osmosis.core.store.Storeable; import org.openstreetmap.osmosis.core.util.LazyHashMap; import org.openstreetmap.osmosis.core.util.LongAsInt; /** * Contains data common to all entity types. This is separated from the entity class to allow it to * be instantiated before all the data required for a full entity is available. */ public class CommonEntityData implements Storeable { private long id; private int version; private int changesetId; private TimestampContainer timestampContainer; private OsmUser user; private TagCollection tags; private Map metaTags; private boolean readOnly; /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestamp * The last updated timestamp. * @param user * The user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. */ public CommonEntityData(long id, int version, Date timestamp, OsmUser user, long changesetId) { // Chain to the more specific constructor this(id, version, new SimpleTimestampContainer(timestamp), user, changesetId); } /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestampContainer * The container holding the timestamp in an alternative * timestamp representation. * @param user * The user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. */ public CommonEntityData( long id, int version, TimestampContainer timestampContainer, OsmUser user, long changesetId) { init(id, timestampContainer, user, version, changesetId); tags = new TagCollectionImpl(); metaTags = new LazyHashMap(); } /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestamp * The last updated timestamp. * @param user * The user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. * @param tags * The tags to apply to the object. */ public CommonEntityData( long id, int version, Date timestamp, OsmUser user, long changesetId, Collection tags) { // Chain to the more specific constructor this(id, version, new SimpleTimestampContainer(timestamp), user, changesetId, tags); } /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestampContainer * The container holding the timestamp in an alternative * timestamp representation. * @param user * The user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. * @param tags * The tags to apply to the object. */ public CommonEntityData(long id, int version, TimestampContainer timestampContainer, OsmUser user, long changesetId, Collection tags) { init(id, timestampContainer, user, version, changesetId); this.tags = new TagCollectionImpl(tags); metaTags = new LazyHashMap(); } /** * Initializes non-collection attributes. * * @param newId * The unique identifier. * @param newTimestampContainer * The container holding the timestamp in an alternative timestamp representation. * @param newUser * The user that last modified this entity. * @param newVersion * The version of the entity. * @param changesetId * The id of the changeset that this version of the entity was created by. */ private void init(long newId, TimestampContainer newTimestampContainer, OsmUser newUser, int newVersion, long newChangesetId) { this.id = newId; this.timestampContainer = newTimestampContainer; this.user = newUser; this.version = newVersion; this.changesetId = LongAsInt.longToInt(newChangesetId); } private static TimestampContainer readTimestampContainer(StoreReader sr, StoreClassRegister scr) { if (sr.readBoolean()) { return new SimpleTimestampContainer(new Date(sr.readLong())); } else { return null; } } private static OsmUser readOsmUser(StoreReader sr, StoreClassRegister scr) { OsmUser user; // We could follow the same approach as timestamps and use a boolean to // indicate the existence of a user or not. But most entities have a // user so this would increase the space consumed on disk. So I'm taking // a small hit in instantiating unnecessary OsmUser objects when no user // is available. user = new OsmUser(sr, scr); if (user.equals(OsmUser.NONE)) { return OsmUser.NONE; } else { return user; } } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers * within the store. */ public CommonEntityData(StoreReader sr, StoreClassRegister scr) { this( sr.readLong(), sr.readInteger(), readTimestampContainer(sr, scr), readOsmUser(sr, scr), sr.readInteger(), new TagCollectionImpl(sr, scr) ); int metaTagCount; metaTagCount = sr.readInteger(); metaTags = new LazyHashMap(); for (int i = 0; i < metaTagCount; i++) { metaTags.put(sr.readString(), sr.readString()); } } /** * {@inheritDoc} */ public void store(StoreWriter sw, StoreClassRegister scr) { sw.writeLong(id); sw.writeInteger(version); if (getTimestamp() != null) { sw.writeBoolean(true); sw.writeLong(timestampContainer.getTimestamp().getTime()); } else { sw.writeBoolean(false); } user.store(sw, scr); sw.writeInteger(changesetId); tags.store(sw, scr); sw.writeInteger(metaTags.size()); for (Entry tag : metaTags.entrySet()) { sw.writeString(tag.getKey()); sw.writeString(tag.getValue().toString()); } } /** * Compares the tags on this entity to the specified tags. The tag * comparison is based on a comparison of key and value in that order. * * @param comparisonTags * The tags to compare to. * @return 0 if equal, < 0 if considered "smaller", and > 0 if considered * "bigger". */ protected int compareTags(Collection comparisonTags) { List tags1; List tags2; tags1 = new ArrayList(tags); tags2 = new ArrayList(comparisonTags); Collections.sort(tags1); Collections.sort(tags2); // The list with the most tags is considered bigger. if (tags1.size() != tags2.size()) { return tags1.size() - tags2.size(); } // Check the individual tags. for (int i = 0; i < tags1.size(); i++) { int result = tags1.get(i).compareTo(tags2.get(i)); if (result != 0) { return result; } } // There are no differences. return 0; } /** * Gets the identifier. * * @return The id. */ public long getId() { return id; } /** * Sets the identifier. * * @param id * The identifier. */ public void setId(long id) { assertWriteable(); this.id = id; } /** * Gets the version. * * @return The version. */ public int getVersion() { return version; } /** * Sets the version. * * @param version * The version. */ public void setVersion(int version) { assertWriteable(); this.version = version; } /** * Gets the timestamp in date form. This is the standard method for * retrieving timestamp information. * * @return The timestamp. */ public Date getTimestamp() { return timestampContainer.getTimestamp(); } /** * Sets the timestamp in date form. This is the standard method of updating a timestamp. * * @param timestamp * The timestamp. */ public void setTimestamp(Date timestamp) { assertWriteable(); timestampContainer = new SimpleTimestampContainer(timestamp); } /** * Gets the timestamp container object which may hold the timestamp in a * different format. This is most useful if creating new copies of entities * because it can avoid the need to parse timestamp information into Date * form. * * @return The timestamp container. */ public TimestampContainer getTimestampContainer() { return timestampContainer; } /** * Sets the timestamp container object allowing the timestamp to be held in a different format. * This should be used if a date is already held in a timestamp container, or if date parsing * can be avoided. * * @param timestampContainer * The timestamp container. */ public void setTimestampContainer(TimestampContainer timestampContainer) { assertWriteable(); this.timestampContainer = timestampContainer; } /** * Gets the timestamp in a string format. If the entity already contains a * string in string format it will return the original unparsed string * instead of formatting a date object. * * @param timestampFormat * The formatter to use for formatting the timestamp into a * string. * @return The timestamp string. */ public String getFormattedTimestamp(TimestampFormat timestampFormat) { return timestampContainer.getFormattedTimestamp(timestampFormat); } /** * Returns the user who last edited the entity. * * @return The user. */ public OsmUser getUser() { return user; } /** * Sets the last modification user. * * @param user * The user. */ public void setUser(OsmUser user) { assertWriteable(); this.user = user; } /** * Gets the id of the changeset that this version of the entity was created by. * * @return The changeset id. */ public long getChangesetId() { return changesetId; } /** * Sets the id of the changeset that this version of the entity was created by. * * @param changesetId * The changeset id. */ public void setChangesetId(long changesetId) { assertWriteable(); this.changesetId = LongAsInt.longToInt(changesetId); } /** * Returns the attached tags. If the class is read-only, the collection will * be read-only. * * @return The tags. */ public Collection getTags() { return tags; } /** * Returns the attached meta tags. If the class is read-only, the collection will * be read-only. * * @return The metaTags. */ public Map getMetaTags() { return metaTags; } /** * Indicates if the object has been set to read-only. A read-only object * must be cloned in order to make updates. This allows objects shared * between multiple threads to be locked for thread safety. * * @return True if the object is read-only. */ public boolean isReadOnly() { return readOnly; } /** * Ensures that the object is writeable. If not an exception will be thrown. * This is intended to be called within all update methods. */ protected void assertWriteable() { if (readOnly) { throw new OsmosisRuntimeException( "The object has been marked as read-only. It must be cloned to make changes."); } } /** * Configures the object to be read-only. This should be called if the object is to be processed * by multiple threads concurrently. It updates the read-only status of the object, and makes * all collections unmodifiable. This must be overridden by sub-classes to make their own * collections unmodifiable. */ public void makeReadOnly() { if (!readOnly) { tags = new UnmodifiableTagCollection(tags); metaTags = Collections.unmodifiableMap(metaTags); readOnly = true; } } /** * Returns a writable instance of this object. If the object is read-only a clone is created, * if it is already writable then this object is returned. * * @return A writable instance of this object. */ public CommonEntityData getWriteableInstance() { if (isReadOnly()) { return new CommonEntityData(id, version, timestampContainer, user, changesetId, tags); } else { return this; } } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/domain/v0_6/Entity.java000066400000000000000000000235611253404521400326220ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.domain.v0_6; import java.util.Collection; import java.util.Date; import java.util.Map; import org.openstreetmap.osmosis.core.domain.common.TimestampContainer; import org.openstreetmap.osmosis.core.domain.common.TimestampFormat; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; import org.openstreetmap.osmosis.core.store.Storeable; /** * A data class representing a single OSM entity. All top level data types * inherit from this class. * * @author Brett Henderson */ public abstract class Entity implements Storeable { private CommonEntityData entityData; /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestamp * The last updated timestamp. * @param user * The user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. * @deprecated As of 0.40, replaced by Entity(entityData). */ public Entity(long id, int version, Date timestamp, OsmUser user, long changesetId) { entityData = new CommonEntityData(id, version, timestamp, user, changesetId); } /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestampContainer * The container holding the timestamp in an alternative * timestamp representation. * @param user * The user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. * @deprecated As of 0.40, replaced by Entity(entityData). */ public Entity(long id, int version, TimestampContainer timestampContainer, OsmUser user, long changesetId) { entityData = new CommonEntityData(id, version, timestampContainer, user, changesetId); } /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestamp * The last updated timestamp. * @param user * The user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. * @param tags * The tags to apply to the object. * @deprecated As of 0.40, replaced by Entity(entityData). */ public Entity(long id, int version, Date timestamp, OsmUser user, long changesetId, Collection tags) { entityData = new CommonEntityData(id, version, timestamp, user, changesetId, tags); } /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestampContainer * The container holding the timestamp in an alternative * timestamp representation. * @param user * The user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. * @param tags * The tags to apply to the object. * @deprecated As of 0.40, replaced by Entity(entityData). */ public Entity(long id, int version, TimestampContainer timestampContainer, OsmUser user, long changesetId, Collection tags) { entityData = new CommonEntityData(id, version, timestampContainer, user, changesetId, tags); } /** * Creates a new instance. * * @param entityData * The data to store in the entity. This instance is used directly and is not cloned. */ public Entity(CommonEntityData entityData) { this.entityData = entityData.getWriteableInstance(); } /** * Creates a new instance. * * @param originalEntity * The entity to clone from. */ protected Entity(Entity originalEntity) { this.entityData = originalEntity.entityData.getWriteableInstance(); } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers * within the store. */ public Entity(StoreReader sr, StoreClassRegister scr) { entityData = new CommonEntityData(sr, scr); } /** * {@inheritDoc} */ public void store(StoreWriter sw, StoreClassRegister scr) { entityData.store(sw, scr); } /** * Compares the tags on this entity to the specified tags. The tag * comparison is based on a comparison of key and value in that order. * * @param comparisonTags * The tags to compare to. * @return 0 if equal, < 0 if considered "smaller", and > 0 if considered * "bigger". */ protected int compareTags(Collection comparisonTags) { return entityData.compareTags(comparisonTags); } /** * Returns the specific data type represented by this entity. * * @return The entity type enum value. */ public abstract EntityType getType(); /** * Gets the identifier. * * @return The id. */ public long getId() { return entityData.getId(); } /** * Sets the identifier. * * @param id * The identifier. */ public void setId(long id) { entityData.setId(id); } /** * Gets the version. * * @return The version. */ public int getVersion() { return entityData.getVersion(); } /** * Sets the version. * * @param version * The version. */ public void setVersion(int version) { entityData.setVersion(version); } /** * Gets the timestamp in date form. This is the standard method for * retrieving timestamp information. * * @return The timestamp. */ public Date getTimestamp() { return entityData.getTimestamp(); } /** * Sets the timestamp in date form. This is the standard method of updating a timestamp. * * @param timestamp * The timestamp. */ public void setTimestamp(Date timestamp) { entityData.setTimestamp(timestamp); } /** * Gets the timestamp container object which may hold the timestamp in a * different format. This is most useful if creating new copies of entities * because it can avoid the need to parse timestamp information into Date * form. * * @return The timestamp container. */ public TimestampContainer getTimestampContainer() { return entityData.getTimestampContainer(); } /** * Sets the timestamp container object allowing the timestamp to be held in a different format. * This should be used if a date is already held in a timestamp container, or if date parsing * can be avoided. * * @param timestampContainer * The timestamp container. */ public void setTimestampContainer(TimestampContainer timestampContainer) { entityData.setTimestampContainer(timestampContainer); } /** * Gets the timestamp in a string format. If the entity already contains a * string in string format it will return the original unparsed string * instead of formatting a date object. * * @param timestampFormat * The formatter to use for formatting the timestamp into a * string. * @return The timestamp string. */ public String getFormattedTimestamp(TimestampFormat timestampFormat) { return entityData.getFormattedTimestamp(timestampFormat); } /** * Returns the user who last edited the entity. * * @return The user. */ public OsmUser getUser() { return entityData.getUser(); } /** * Sets the last modification user. * * @param user * The user. */ public void setUser(OsmUser user) { entityData.setUser(user); } /** * Gets the id of the changeset that this version of the entity was created by. * * @return The changeset id. */ public long getChangesetId() { return entityData.getChangesetId(); } /** * Sets the id of the changeset that this version of the entity was created by. * * @param changesetId * The changeset id. */ public void setChangesetId(long changesetId) { entityData.setChangesetId(changesetId); } /** * Returns the attached tags. If the class is read-only, the collection will * be read-only. * * @return The tags. */ public Collection getTags() { return entityData.getTags(); } /** * Returns the attached meta tags. If the class is read-only, the collection will * be read-only. * * @return The meta tags. */ public Map getMetaTags() { return entityData.getMetaTags(); } /** * Indicates if the object has been set to read-only. A read-only object * must be cloned in order to make updates. This allows objects shared * between multiple threads to be locked for thread safety. * * @return True if the object is read-only. */ public boolean isReadOnly() { return entityData.isReadOnly(); } /** * Ensures that the object is writeable. If not an exception will be thrown. * This is intended to be called within all update methods. */ protected void assertWriteable() { entityData.assertWriteable(); } /** * Configures the object to be read-only. This should be called if the object is to be processed * by multiple threads concurrently. It updates the read-only status of the object, and makes * all collections unmodifiable. This must be overridden by sub-classes to make their own * collections unmodifiable. */ public void makeReadOnly() { entityData.makeReadOnly(); } /** * Returns a writeable instance of this entity. If the object is read-only a clone is created, * if it is already writeable then this object is returned. * * @return A writeable instance of this entity. */ public abstract Entity getWriteableInstance(); } EntityBuilder.java000066400000000000000000000210731253404521400340460ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/domain/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.domain.v0_6; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import org.openstreetmap.osmosis.core.domain.common.SimpleTimestampContainer; import org.openstreetmap.osmosis.core.domain.common.TimestampContainer; import org.openstreetmap.osmosis.core.store.Storeable; import org.openstreetmap.osmosis.core.util.LongAsInt; /** * Provides facilities to specify the contents of entity and create new instances. Entities * themselves are immutable to support concurrent access, this class provides a means of * manipulating them. * * @author Brett Henderson * * @param * The type of entity to be built. * * @deprecated Builder classes are not required because entities are now writeable. */ @Deprecated public abstract class EntityBuilder implements Storeable { /** * The unique entity identifier. */ protected long id; /** * The current entity version. */ protected int version; /** * The entity timestamp container. */ protected TimestampContainer timestampContainer; /** * The user who created the entity. */ protected OsmUser user; /** * The entity changeset identifier. */ protected int changesetId; /** * The tags describing the entity. */ protected Collection tags; /** * Creates a new instance. */ public EntityBuilder() { tags = new ArrayList(); } /** * Creates a new instance. * * @param entity * The entity to initialise to. */ public EntityBuilder(Entity entity) { this(); initialize(entity); } /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestamp * The last updated timestamp. * @param user * The user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. */ public EntityBuilder(long id, int version, Date timestamp, OsmUser user, long changesetId) { this(); initialize(id, version, timestamp, user, changesetId); } /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestampContainer * The container holding the timestamp in an alternative * timestamp representation. * @param user * The user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. */ public EntityBuilder(long id, int version, TimestampContainer timestampContainer, OsmUser user, long changesetId) { this(); initialize(id, version, timestampContainer, user, changesetId); } /** * Initializes the contents of the builder to the specified data. * * @param entity * The entity to initialise to. * @return This object allowing method chaining. */ protected EntityBuilder initialize(Entity entity) { // Delegate to the more specific method. initialize(entity.getId(), entity.getVersion(), entity.getTimestampContainer(), entity.getUser(), entity .getChangesetId()); tags.addAll(entity.getTags()); return this; } /** * Initializes the contents of the builder to the specified data. * * @param newId * The unique identifier. * @param newVersion * The version of the entity. * @param newTimestamp * The last updated timestamp. * @param newUser * The user that last modified this entity. * @param newChangesetId * The id of the changeset that this version of the entity was created by. * @return This object allowing method chaining. */ protected EntityBuilder initialize(long newId, int newVersion, Date newTimestamp, OsmUser newUser, long newChangesetId) { // Delegate to the more specific method. initialize(newId, newVersion, new SimpleTimestampContainer(newTimestamp), newUser, newChangesetId); return this; } /** * Initializes the contents of the builder to the specified data. * * @param newId * The unique identifier. * @param newVersion * The version of the entity. * @param newTimestampContainer * The container holding the timestamp in an alternative * timestamp representation. * @param newUser * The user that last modified this entity. * @param newChangesetId * The id of the changeset that this version of the entity was created by. * @return This object allowing method chaining. */ protected EntityBuilder initialize( long newId, int newVersion, TimestampContainer newTimestampContainer, OsmUser newUser, long newChangesetId) { this.id = newId; this.timestampContainer = newTimestampContainer; this.user = newUser; this.changesetId = LongAsInt.longToInt(newChangesetId); this.version = newVersion; this.tags.clear(); return this; } /** * Sets a new id value. * * @param newId * The new id. * @return This object allowing method chaining. */ public EntityBuilder setId(long newId) { this.id = newId; return this; } /** * Gets the current id value. * * @return The id. */ public long getId() { return id; } /** * Sets a new version value. * * @param newVersion * The new version. * @return This object allowing method chaining. */ public EntityBuilder setVersion(int newVersion) { this.version = newVersion; return this; } /** * Gets the current version value. * * @return The id. */ public int getVersion() { return version; } /** * Sets a new timestamp value. * * @param timestamp * The new timestamp. * @return This object allowing method chaining. */ public EntityBuilder setTimestamp(Date timestamp) { this.timestampContainer = new SimpleTimestampContainer(timestamp); return this; } /** * Gets the current timestamp value. * * @return The timestamp. */ public Date getTimestamp() { return timestampContainer.getTimestamp(); } /** * Sets a new timestamp value. * * @param newTimestampContainer * The timestamp wrapped within a container. * @return This object allowing method chaining. */ public EntityBuilder setTimestamp(TimestampContainer newTimestampContainer) { this.timestampContainer = newTimestampContainer; return this; } /** * Gets the current timestamp value. * * @return The timestamp container holding the current timestamp. */ public TimestampContainer getTimestampContainer() { return timestampContainer; } /** * Sets a new user value. * * @param newUser * The new user. * @return This object allowing method chaining. */ public EntityBuilder setUser(OsmUser newUser) { this.user = newUser; return this; } /** * Gets the current user value. * * @return The user. */ public OsmUser getUser() { return user; } /** * Gets the id of the changeset that this version of the entity was created by. * * @return The changeset id. */ public long getChangesetId() { return changesetId; } /** * Sets the id of the changeset that this version of the entity was created by. * * @param newChangesetId * The changeset id. * @return This object allowing method chaining. */ public EntityBuilder setChangesetId(long newChangesetId) { this.changesetId = LongAsInt.longToInt(newChangesetId); return this; } /** * Obtains the tags. * * @return The tags. */ public Collection getTags() { return tags; } /** * Remove all existing tags. * * @return This object allowing method chaining. */ public EntityBuilder clearTags() { tags.clear(); return this; } /** * Sets a new tags value. * * @param newTags * The new tags. * @return This object allowing method chaining. */ public EntityBuilder setTags(Collection newTags) { tags.clear(); tags.addAll(newTags); return this; } /** * Adds a new tag. * * @param tag * The new tag. * @return This object allowing method chaining. */ public EntityBuilder addTag(Tag tag) { tags.add(tag); return this; } /** * Builds a new entity instance based on the current data. * * @return The new entity instance. */ public abstract T buildEntity(); } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/domain/v0_6/EntityType.java000066400000000000000000000010771253404521400334620ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.domain.v0_6; /** * An enum representing the different data types in the OSM data model. * * @author Brett Henderson */ public enum EntityType { /** * Representation of the latitude/longitude bounding box of the entity stream. */ Bound, /** * Represents a geographical point. */ Node, /** * Represents a set of segments forming a path. */ Way, /** * Represents a relationship between multiple entities. */ Relation } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/domain/v0_6/Node.java000066400000000000000000000225121253404521400322260ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.domain.v0_6; import java.util.Collection; import java.util.Date; import org.openstreetmap.osmosis.core.domain.common.SimpleTimestampContainer; import org.openstreetmap.osmosis.core.domain.common.TimestampContainer; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; import org.openstreetmap.osmosis.core.util.FixedPrecisionCoordinateConvertor; /** * A data class representing a single OSM node. * * @author Brett Henderson */ public class Node extends Entity implements Comparable { private double latitude; private double longitude; /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestamp * The last updated timestamp. * @param user * The user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. * @param latitude * The geographic latitude. * @param longitude * The geographic longitude. * @deprecated As of 0.40, replaced by Node(entityData, latitude, longitude). */ public Node( long id, int version, Date timestamp, OsmUser user, long changesetId, double latitude, double longitude) { // Chain to the more-specific constructor this(id, version, new SimpleTimestampContainer(timestamp), user, changesetId, latitude, longitude); } /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestampContainer * The container holding the timestamp in an alternative timestamp representation. * @param user * The name of the user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. * @param latitude * The geographic latitude. * @param longitude * The geographic longitude. * @deprecated As of 0.40, replaced by Node(entityData, latitude, longitude). */ public Node(long id, int version, TimestampContainer timestampContainer, OsmUser user, long changesetId, double latitude, double longitude) { super(id, version, timestampContainer, user, changesetId); init(latitude, longitude); } /** * Creates a new instance. * * @param entityData * The common entity data. * @param latitude * The geographic latitude. * @param longitude * The geographic longitude. */ public Node(CommonEntityData entityData, double latitude, double longitude) { super(entityData); init(latitude, longitude); } /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestamp * The last updated timestamp. * @param user * The user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. * @param tags * The tags to apply to the object. * @param latitude * The geographic latitude. * @param longitude * The geographic longitude. * @deprecated As of 0.40, replaced by Node(entityData, latitude, longitude). */ public Node(long id, int version, Date timestamp, OsmUser user, long changesetId, Collection tags, double latitude, double longitude) { // Chain to the more-specific constructor this(id, version, new SimpleTimestampContainer(timestamp), user, changesetId, tags, latitude, longitude); } /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestampContainer * The container holding the timestamp in an alternative timestamp representation. * @param user * The name of the user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. * @param tags * The tags to apply to the object. * @param latitude * The geographic latitude. * @param longitude * The geographic longitude. * @deprecated As of 0.40, replaced by Node(entityData, latitude, longitude). */ public Node(long id, int version, TimestampContainer timestampContainer, OsmUser user, long changesetId, Collection tags, double latitude, double longitude) { super(id, version, timestampContainer, user, changesetId, tags); init(latitude, longitude); } /** * Creates a new instance. * * @param originalNode * The node to clone from. */ private Node(Node originalNode) { super(originalNode); init(originalNode.latitude, originalNode.longitude); } /** * Initializes non-collection attributes. * * @param newLatitude * The geographic latitude. * @param newLongitude * The geographic longitude. */ private void init(double newLatitude, double newLongitude) { this.latitude = newLatitude; this.longitude = newLongitude; } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers within the store. */ public Node(StoreReader sr, StoreClassRegister scr) { super(sr, scr); this.latitude = FixedPrecisionCoordinateConvertor.convertToDouble(sr.readInteger()); this.longitude = FixedPrecisionCoordinateConvertor.convertToDouble(sr.readInteger()); } /** * {@inheritDoc} */ @Override public void store(StoreWriter sw, StoreClassRegister scr) { super.store(sw, scr); sw.writeInteger(FixedPrecisionCoordinateConvertor.convertToFixed(latitude)); sw.writeInteger(FixedPrecisionCoordinateConvertor.convertToFixed(longitude)); } /** * {@inheritDoc} */ @Override public EntityType getType() { return EntityType.Node; } /** * {@inheritDoc} */ @Override public boolean equals(Object o) { if (o instanceof Node) { return compareTo((Node) o) == 0; } else { return false; } } /** * {@inheritDoc} */ @Override public int hashCode() { /* * As per the hashCode definition, this doesn't have to be unique it just has to return the * same value for any two objects that compare equal. Using both id and version will provide * a good distribution of values but is simple to calculate. */ return (int) getId() + getVersion(); } /** * Compares this node to the specified node. The node comparison is based on * a comparison of id, version, latitude, longitude, timestamp and tags in * that order. * * @param comparisonNode * The node to compare to. * @return 0 if equal, < 0 if considered "smaller", and > 0 if * considered "bigger". */ public int compareTo(Node comparisonNode) { if (this.getId() < comparisonNode.getId()) { return -1; } if (this.getId() > comparisonNode.getId()) { return 1; } if (this.getVersion() < comparisonNode.getVersion()) { return -1; } if (this.getVersion() > comparisonNode.getVersion()) { return 1; } if (this.latitude < comparisonNode.latitude) { return -1; } if (this.latitude > comparisonNode.latitude) { return 1; } if (this.longitude < comparisonNode.longitude) { return -1; } if (this.longitude > comparisonNode.longitude) { return 1; } if (this.getTimestamp() == null && comparisonNode.getTimestamp() != null) { return -1; } if (this.getTimestamp() != null && comparisonNode.getTimestamp() == null) { return 1; } if (this.getTimestamp() != null && comparisonNode.getTimestamp() != null) { int result; result = this.getTimestamp().compareTo(comparisonNode.getTimestamp()); if (result != 0) { return result; } } return compareTags(comparisonNode.getTags()); } /** * Gets the latitude. * * @return The latitude. */ public double getLatitude() { return latitude; } /** * Sets the latitude. * * @param latitude * The latitude. */ public void setLatitude(double latitude) { assertWriteable(); this.latitude = latitude; } /** * Gets the longitude. * * @return The longitude. */ public double getLongitude() { return longitude; } /** * Sets the longitude. * * @param longitude * The longitude. */ public void setLongitude(double longitude) { assertWriteable(); this.longitude = longitude; } /** * {@inheritDoc} */ @Override public Node getWriteableInstance() { if (isReadOnly()) { return new Node(this); } else { return this; } } /** * ${@inheritDoc}. */ @Override public String toString() { String name = null; Collection tags = getTags(); for (Tag tag : tags) { if (tag.getKey() != null && tag.getKey().equalsIgnoreCase("name")) { name = tag.getValue(); break; } } if (name != null) { return "Node(id=" + getId() + ", #tags=" + getTags().size() + ", name='" + name + "')"; } return "Node(id=" + getId() + ", #tags=" + getTags().size() + ")"; } } NodeBuilder.java000066400000000000000000000161311253404521400334560ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/domain/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.domain.v0_6; import java.util.Date; import org.openstreetmap.osmosis.core.domain.common.TimestampContainer; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; /** * Provides the ability to manipulate nodes. * * @author Brett Henderson * * @deprecated Builder classes are not required because entities are now writeable. */ @Deprecated public class NodeBuilder extends EntityBuilder { private double latitude; private double longitude; /** * Creates a new instance. */ public NodeBuilder() { super(); } /** * Creates a new instance. * * @param entity * The entity to initialise to. */ public NodeBuilder(Node entity) { this(); initialize(entity); } /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestamp * The last updated timestamp. * @param user * The user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. * @param latitude * The latitude of the node. * @param longitude * The longitude of the entity. */ public NodeBuilder(long id, int version, Date timestamp, OsmUser user, long changesetId, double latitude, double longitude) { this(); initialize(id, version, timestamp, user, changesetId, latitude, longitude); } /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestampContainer * The container holding the timestamp in an alternative * timestamp representation. * @param user * The user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. * @param latitude * The latitude of the node. * @param longitude * The longitude of the entity. */ public NodeBuilder( long id, int version, TimestampContainer timestampContainer, OsmUser user, long changesetId, double latitude, double longitude) { this(); initialize(id, version, timestampContainer, user, changesetId, latitude, longitude); } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers * within the store. */ public NodeBuilder(StoreReader sr, StoreClassRegister scr) { this(); initialize(new Node(sr, scr)); } /** * {@inheritDoc} */ @Override public void store(StoreWriter sw, StoreClassRegister scr) { buildEntity().store(sw, scr); } /** * Initialises the state of this sub-class. * * @param newLatitude The latitude of the node. * @param newLongitude The longitude of the node. */ private void initializeLocal(double newLatitude, double newLongitude) { this.latitude = newLatitude; this.longitude = newLongitude; } /** * Initializes the contents of the builder to the specified data. * * @param node * The entity to initialise to. * @return This object allowing method chaining. */ public NodeBuilder initialize(Node node) { super.initialize(node); initializeLocal(node.getLatitude(), node.getLongitude()); return this; } /** * Initializes the contents of the builder to the specified data. * * @param newId * The unique identifier. * @param newVersion * The version of the entity. * @param newTimestamp * The last updated timestamp. * @param newUser * The user that last modified this entity. * @param newChangesetId * The id of the changeset that this version of the entity was created by. * @param newLatitude * The latitude of the node. * @param newLongitude * The longitude of the node. * @return This object allowing method chaining. */ public NodeBuilder initialize( long newId, int newVersion, Date newTimestamp, OsmUser newUser, long newChangesetId, double newLatitude, double newLongitude) { super.initialize(newId, newVersion, newTimestamp, newUser, newChangesetId); initializeLocal(newLatitude, newLongitude); return this; } /** * Initializes the contents of the builder to the specified data. * * @param newId * The unique identifier. * @param newVersion * The version of the entity. * @param newTimestampContainer * The container holding the timestamp in an alternative * timestamp representation. * @param newUser * The user that last modified this entity. * @param newChangesetId * The id of the changeset that this version of the entity was created by. * @param newLatitude * The latitude of the node. * @param newLongitude * The longitude of the node. * @return This object allowing method chaining. */ public NodeBuilder initialize( long newId, int newVersion, TimestampContainer newTimestampContainer, OsmUser newUser, long newChangesetId, double newLatitude, double newLongitude) { super.initialize(newId, newVersion, newTimestampContainer, newUser, newChangesetId); initializeLocal(newLatitude, newLongitude); return this; } /** * Sets a new latitude value. * * @param newLatitude * The new latitude. * @return This object allowing method chaining. */ public NodeBuilder setLatitude(double newLatitude) { this.latitude = newLatitude; return this; } /** * Gets the current latitude value. * * @return The latitude. */ public double getLatitude() { return latitude; } /** * Sets a new longitude value. * * @param newLongitude * The new longitude. * @return This object allowing method chaining. */ public NodeBuilder setLongitude(double newLongitude) { this.longitude = newLongitude; return this; } /** * Gets the current longitude value. * * @return The longitude. */ public double getLongitude() { return longitude; } /** * {@inheritDoc} */ @Override public Node buildEntity() { return new Node(id, version, timestampContainer, user, changesetId, tags, latitude, longitude); } /** * ${@inheritDoc}. */ @Override public String toString() { String name = null; for (Tag tag : tags) { if (tag.getKey() != null && tag.getKey().equalsIgnoreCase("name")) { name = tag.getValue(); break; } } if (name != null) { return "NodeBuilder(id=" + getId() + ", #tags=" + getTags().size() + ", name='" + name + "')"; } return "NodeBuilder(id=" + getId() + ", #tags=" + getTags().size() + ")"; } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/domain/v0_6/OsmUser.java000066400000000000000000000060301253404521400327330ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.domain.v0_6; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; import org.openstreetmap.osmosis.core.store.Storeable; /** * A value class representing a single OSM user, comprised of user name and id. * * This class is immutable, and the static factories are thread-safe. * * @author Karl Newman * @author Brett Henderson */ public class OsmUser implements Storeable { private String name; private int id; /** * User ID value to designate no id available. If this is set to 0, some * databases (ie. MySQL) will default a non-zero value upon insert. To avoid * special case code for each database with this issue, this value is made * negative. */ private static final int USER_ID_NONE = -1; /** * The user instance representing no user available or no user applicable. */ public static final OsmUser NONE = new OsmUser(USER_ID_NONE, ""); /** * Creates a new instance. * * @param id * The userId associated with the user name. * @param userName * The name of the user that this object represents. */ public OsmUser(int id, String userName) { if (userName == null) { throw new NullPointerException("The user name cannot be null."); } // Disallow a user to be created with the "NONE" id. if (NONE != null && id == USER_ID_NONE) { throw new OsmosisRuntimeException("A user id of " + USER_ID_NONE + " is not permitted."); } this.name = userName; this.id = id; } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers * within the store. */ public OsmUser(StoreReader sr, StoreClassRegister scr) { name = sr.readString(); id = sr.readInteger(); } /** * Stores all state to the specified store writer. * * @param sw * The writer that persists data to an underlying store. * @param scr * Maintains the mapping between classes and their identifiers * within the store. */ public void store(StoreWriter sw, StoreClassRegister scr) { sw.writeString(name); sw.writeInteger(id); } /** * {@inheritDoc} */ @Override public boolean equals(Object o) { OsmUser ou; if (!(o instanceof OsmUser)) { return false; } ou = (OsmUser) o; return name.equals(ou.name) && id == ou.id; } /** * {@inheritDoc} */ @Override public int hashCode() { int result; result = -17; result = 31 * result + name.hashCode(); result = 31 * result + id; return result; } /** * @return The userId. */ public int getId() { return id; } /** * @return The name of the user. */ public String getName() { return name; } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/domain/v0_6/Relation.java000066400000000000000000000233111253404521400331140ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.domain.v0_6; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.Iterator; import java.util.List; import org.openstreetmap.osmosis.core.domain.common.SimpleTimestampContainer; import org.openstreetmap.osmosis.core.domain.common.TimestampContainer; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; /** * A data class representing a single OSM relation. * * @author Brett Henderson */ public class Relation extends Entity implements Comparable { private List members; /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestamp * The last updated timestamp. * @param user * The user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. * @deprecated As of 0.40, replaced by Relation(entityData). */ public Relation(long id, int version, Date timestamp, OsmUser user, long changesetId) { // Chain to the more-specific constructor this(id, version, new SimpleTimestampContainer(timestamp), user, changesetId); } /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestampContainer * The container holding the timestamp in an alternative * timestamp representation. * @param user * The user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. * @deprecated As of 0.40, replaced by Relation(entityData). */ public Relation(long id, int version, TimestampContainer timestampContainer, OsmUser user, long changesetId) { super(id, version, timestampContainer, user, changesetId); this.members = new ArrayList(); } /** * Creates a new instance. * * @param entityData * The common entity data. */ public Relation(CommonEntityData entityData) { super(entityData); this.members = new ArrayList(); } /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestamp * The last updated timestamp. * @param user * The user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. * @param tags * The tags to apply to the object. * @param members * The members to apply to the object. * @deprecated As of 0.40, replaced by Relation(entityData, members). */ public Relation( long id, int version, Date timestamp, OsmUser user, long changesetId, Collection tags, List members) { // Chain to the more-specific constructor this(id, version, new SimpleTimestampContainer(timestamp), user, changesetId, tags, members); } /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestampContainer * The container holding the timestamp in an alternative * timestamp representation. * @param user * The user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. * @param tags * The tags to apply to the object. * @param members * The members to apply to the object. * @deprecated As of 0.40, replaced by Relation(entityData, members). */ public Relation( long id, int version, TimestampContainer timestampContainer, OsmUser user, long changesetId, Collection tags, List members) { super(id, version, timestampContainer, user, changesetId, tags); this.members = new ArrayList(members); } /** * Creates a new instance. * * @param entityData * The common entity data. * @param members * The members to apply to the object. */ public Relation( CommonEntityData entityData, List members) { super(entityData); this.members = new ArrayList(members); } /** * Creates a new instance. * * @param originalRelation * The relation to clone from. */ private Relation(Relation originalRelation) { super(originalRelation); this.members = new ArrayList(originalRelation.members); } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers * within the store. */ public Relation(StoreReader sr, StoreClassRegister scr) { super(sr, scr); int featureCount; featureCount = sr.readInteger(); members = new ArrayList(); for (int i = 0; i < featureCount; i++) { members.add(new RelationMember(sr, scr)); } } /** * {@inheritDoc} */ @Override public void store(StoreWriter sw, StoreClassRegister scr) { super.store(sw, scr); sw.writeInteger(members.size()); for (RelationMember relationMember : members) { relationMember.store(sw, scr); } } /** * {@inheritDoc} */ @Override public EntityType getType() { return EntityType.Relation; } /** * {@inheritDoc} */ @Override public boolean equals(Object o) { if (o instanceof Relation) { return compareTo((Relation) o) == 0; } else { return false; } } /** * {@inheritDoc} */ @Override public int hashCode() { /* * As per the hashCode definition, this doesn't have to be unique it * just has to return the same value for any two objects that compare * equal. Using both id and version will provide a good distribution of * values but is simple to calculate. */ return (int) getId() + getVersion(); } /** * Compares this member list to the specified member list. The bigger list * is considered bigger, if that is equal then each relation member is * compared. * * @param comparisonMemberList * The member list to compare to. * @return 0 if equal, < 0 if considered "smaller", and > 0 if * considered "bigger". */ protected int compareMemberList(Collection comparisonMemberList) { Iterator i; Iterator j; // The list with the most entities is considered bigger. if (members.size() != comparisonMemberList.size()) { return members.size() - comparisonMemberList.size(); } // Check the individual node references. i = members.iterator(); j = comparisonMemberList.iterator(); while (i.hasNext()) { int result = i.next().compareTo(j.next()); if (result != 0) { return result; } } // There are no differences. return 0; } /** * Compares this relation to the specified relation. The relation comparison * is based on a comparison of id, version, timestamp, and tags in that * order. * * @param comparisonRelation * The relation to compare to. * @return 0 if equal, < 0 if considered "smaller", and > 0 if * considered "bigger". */ public int compareTo(Relation comparisonRelation) { int memberListResult; if (this.getId() < comparisonRelation.getId()) { return -1; } if (this.getId() > comparisonRelation.getId()) { return 1; } if (this.getVersion() < comparisonRelation.getVersion()) { return -1; } if (this.getVersion() > comparisonRelation.getVersion()) { return 1; } if (this.getTimestamp() == null && comparisonRelation.getTimestamp() != null) { return -1; } if (this.getTimestamp() != null && comparisonRelation.getTimestamp() == null) { return 1; } if (this.getTimestamp() != null && comparisonRelation.getTimestamp() != null) { int result; result = this.getTimestamp().compareTo(comparisonRelation.getTimestamp()); if (result != 0) { return result; } } memberListResult = compareMemberList( comparisonRelation.members ); if (memberListResult != 0) { return memberListResult; } return compareTags(comparisonRelation.getTags()); } /** * {@inheritDoc} */ @Override public void makeReadOnly() { if (!isReadOnly()) { members = Collections.unmodifiableList(members); } super.makeReadOnly(); } /** * {@inheritDoc} */ @Override public Relation getWriteableInstance() { if (isReadOnly()) { return new Relation(this); } else { return this; } } /** * Returns the attached list of relation members. The returned list is * read-only. * * @return The member list. */ public List getMembers() { return members; } /** * ${@inheritDoc}. */ @Override public String toString() { String type = null; Collection tags = getTags(); for (Tag tag : tags) { if (tag.getKey() != null && tag.getKey().equalsIgnoreCase("type")) { type = tag.getValue(); break; } } if (type != null) { return "Relation(id=" + getId() + ", #tags=" + getTags().size() + ", type='" + type + "')"; } return "Relation(id=" + getId() + ", #tags=" + getTags().size() + ")"; } } RelationBuilder.java000066400000000000000000000146151253404521400343530ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/domain/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.domain.v0_6; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.openstreetmap.osmosis.core.domain.common.TimestampContainer; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; /** * Provides the ability to manipulate relations. * * @author Brett Henderson * * @deprecated Builder classes are not required because entities are now writeable. */ @Deprecated public class RelationBuilder extends EntityBuilder { private List members; /** * Creates a new instance. */ public RelationBuilder() { super(); members = new ArrayList(); } /** * Creates a new instance. * * @param entity * The entity to initialise to. */ public RelationBuilder(Relation entity) { this(); initialize(entity); } /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestamp * The last updated timestamp. * @param user * The user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. */ public RelationBuilder(long id, int version, Date timestamp, OsmUser user, long changesetId) { this(); initialize(id, version, timestamp, user, changesetId); } /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestampContainer * The container holding the timestamp in an alternative * timestamp representation. * @param user * The user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. */ public RelationBuilder( long id, TimestampContainer timestampContainer, OsmUser user, int version, long changesetId) { this(); initialize(id, version, timestampContainer, user, changesetId); } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers * within the store. */ public RelationBuilder(StoreReader sr, StoreClassRegister scr) { this(); initialize(new Relation(sr, scr)); } /** * {@inheritDoc} */ @Override public void store(StoreWriter sw, StoreClassRegister scr) { buildEntity().store(sw, scr); } /** * Initialises the state of this sub-class. */ private void initializeLocal() { members.clear(); } /** * Initializes the contents of the builder to the specified data. * * @param relation * The entity to initialise to. * @return This object allowing method chaining. */ public RelationBuilder initialize(Relation relation) { super.initialize(relation); initializeLocal(); members.addAll(relation.getMembers()); return this; } /** * Initializes the contents of the builder to the specified data. * * @param newId * The unique identifier. * @param newVersion * The version of the entity. * @param newTimestamp * The last updated timestamp. * @param newUser * The user that last modified this entity. * @param newChangesetId * The id of the changeset that this version of the entity was created by. * @return This object allowing method chaining. */ @Override public RelationBuilder initialize(long newId, int newVersion, Date newTimestamp, OsmUser newUser, long newChangesetId) { super.initialize(newId, newVersion, newTimestamp, newUser, newChangesetId); initializeLocal(); return this; } /** * Initializes the contents of the builder to the specified data. * * @param newId * The unique identifier. * @param newVersion * The version of the entity. * @param newTimestampContainer * The container holding the timestamp in an alternative * timestamp representation. * @param newUser * The user that last modified this entity. * @param newChangesetId * The id of the changeset that this version of the entity was created by. * @return This object allowing method chaining. */ @Override public RelationBuilder initialize(long newId, int newVersion, TimestampContainer newTimestampContainer, OsmUser newUser, long newChangesetId) { super.initialize(newId, newVersion, newTimestampContainer, newUser, newChangesetId); initializeLocal(); return this; } /** * Obtains the members. * * @return The members. */ public List getMembers() { return members; } /** * Remove all existing members. * * @return This object allowing method chaining. */ public RelationBuilder clearMembers() { members.clear(); return this; } /** * Sets a new members value. * * @param newMembers * The new relation members. * @return This object allowing method chaining. */ public RelationBuilder setMembers(List newMembers) { newMembers.clear(); newMembers.addAll(newMembers); return this; } /** * Adds a new member. * * @param member * The new member. * @return This object allowing method chaining. */ public RelationBuilder addMember(RelationMember member) { members.add(member); return this; } /** * {@inheritDoc} */ @Override public Relation buildEntity() { return new Relation(id, version, timestampContainer, user, changesetId, tags, members); } /** * ${@inheritDoc}. */ @Override public String toString() { String type = null; for (Tag tag : tags) { if (tag.getKey() != null && tag.getKey().equalsIgnoreCase("type")) { type = tag.getValue(); break; } } if (type != null) { return "RelationBuilder(id=" + getId() + ", #tags=" + getTags().size() + ", type='" + type + "')"; } return "RelationBuilder(id=" + getId() + ", #tags=" + getTags().size() + ")"; } } RelationMember.java000066400000000000000000000070401253404521400341660ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/domain/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.domain.v0_6; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; import org.openstreetmap.osmosis.core.store.Storeable; /** * A data class representing a single member within a relation entity. * * @author Brett Henderson */ public class RelationMember implements Comparable, Storeable { private long memberId; private EntityType memberType; private String memberRole; /** * Creates a new instance. * * @param memberId * The id of the entity that this member consists of. * @param memberType * The type of the entity that this member consists of. * @param memberRole * The role that this member forms within the relation. */ public RelationMember(long memberId, EntityType memberType, String memberRole) { this.memberId = memberId; this.memberType = memberType; this.memberRole = memberRole; if (memberType == null) { throw new IllegalArgumentException("null type given for relation-member"); } if (memberRole == null) { throw new IllegalArgumentException("null role given for relation-member"); } } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers * within the store. */ public RelationMember(StoreReader sr, StoreClassRegister scr) { this( sr.readLong(), EntityType.valueOf(sr.readString()), sr.readString() ); } /** * {@inheritDoc} */ public void store(StoreWriter sw, StoreClassRegister scr) { sw.writeLong(memberId); sw.writeString(memberType.toString()); sw.writeString(memberRole); } /** * Compares this relation member to the specified relation member. The * relation member comparison is based on a comparison of member type, then * member id, then role. * * @param relationMember * The relation member to compare to. * @return 0 if equal, < 0 if considered "smaller", and > 0 if * considered "bigger". */ public int compareTo(RelationMember relationMember) { long result; // Compare the member type. result = this.memberType.compareTo(relationMember.memberType); if (result > 0) { return 1; } else if (result < 0) { return -1; } // Compare the member id. result = this.memberId - relationMember.memberId; if (result > 0) { return 1; } else if (result < 0) { return -1; } // Compare the member role. result = this.memberRole.compareTo(relationMember.memberRole); if (result > 0) { return 1; } else if (result < 0) { return -1; } // No differences detected. return 0; } /** * Returns the id of the member entity. * * @return The member id. */ public long getMemberId() { return memberId; } /** * Returns the type of the member entity. * * @return The member type. */ public EntityType getMemberType() { return memberType; } /** * Returns the role that this member forms within the relation. * * @return The role. */ public String getMemberRole() { return memberRole; } /** * ${@inheritDoc}. */ @Override public String toString() { return "RelationMember(" + getMemberType() + " with id " + getMemberId() + " in the role '" + getMemberRole() + "')"; } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/domain/v0_6/Tag.java000066400000000000000000000042351253404521400320560ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.domain.v0_6; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; import org.openstreetmap.osmosis.core.store.Storeable; /** * A data class representing a single OSM tag. * * @author Brett Henderson */ public class Tag implements Comparable, Storeable { /** * The key identifying the tag. */ private String key; /** * The value associated with the tag. */ private String value; /** * Creates a new instance. * * @param key * The key identifying the tag. * @param value * The value associated with the tag. */ public Tag(String key, String value) { this.key = key; this.value = value; } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers * within the store. */ public Tag(StoreReader sr, StoreClassRegister scr) { this(sr.readString(), sr.readString()); } /** * {@inheritDoc} */ public void store(StoreWriter sw, StoreClassRegister scr) { sw.writeString(key); sw.writeString(value); } /** * Compares this tag to the specified tag. The tag comparison is based on a * comparison of key and value in that order. * * @param tag * The tag to compare to. * @return 0 if equal, < 0 if considered "smaller", and > 0 if * considered "bigger". */ public int compareTo(Tag tag) { int keyResult; keyResult = this.key.compareTo(tag.key); if (keyResult != 0) { return keyResult; } return this.value.compareTo(tag.value); } /** * @return The key. */ public String getKey() { return key; } /** * @return The value. */ public String getValue() { return value; } /** * ${@inheritDoc}. */ @Override public String toString() { return "Tag('" + getKey() + "'='" + getValue() + "')"; } } TagCollection.java000066400000000000000000000011131253404521400340030ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/domain/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.domain.v0_6; import java.util.Collection; import java.util.Map; import org.openstreetmap.osmosis.core.store.Storeable; /** * An extension to basic Collection behaviour adding convenience methods for working with tags. * * @author Brett Henderson */ public interface TagCollection extends Collection, Storeable { /** * Creates a map representation of the tags. * * @return The tags represented as a map. */ Map buildMap(); } TagCollectionImpl.java000066400000000000000000000035721253404521400346400ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/domain/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.domain.v0_6; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; import org.openstreetmap.osmosis.core.util.CollectionWrapper; import org.openstreetmap.osmosis.core.util.IntAsChar; /** * Maintains a collection of tags. * * @author Brett Henderson */ public class TagCollectionImpl extends CollectionWrapper implements TagCollection { /** * Creates a new instance. */ public TagCollectionImpl() { super(new ArrayList()); } /** * Creates a new instance. * * @param tags * The initial tags. */ public TagCollectionImpl(Collection tags) { super(new ArrayList(tags)); } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers * within the store. */ public TagCollectionImpl(StoreReader sr, StoreClassRegister scr) { super(new ArrayList()); int tagCount; tagCount = sr.readCharacter(); for (int i = 0; i < tagCount; i++) { add(new Tag(sr, scr)); } } /** * {@inheritDoc} */ @Override public void store(StoreWriter sw, StoreClassRegister scr) { sw.writeCharacter(IntAsChar.intToChar(size())); for (Tag tag : this) { tag.store(sw, scr); } } /** * {@inheritDoc} */ public Map buildMap() { Map tagMap; tagMap = new HashMap(size()); for (Tag tag : this) { tagMap.put(tag.getKey(), tag.getValue()); } return tagMap; } } UnmodifiableTagCollection.java000066400000000000000000000021701253404521400363260ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/domain/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.domain.v0_6; import java.util.Collections; import java.util.Map; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreWriter; import org.openstreetmap.osmosis.core.util.CollectionWrapper; /** * Wraps a tag collection and prevents modifications from being made to it. * * @author Brett Henderson */ public class UnmodifiableTagCollection extends CollectionWrapper implements TagCollection { private TagCollection wrappedTags; /** * Creates a new instance. * * @param wrappedTags * The tags to wrap. */ public UnmodifiableTagCollection(TagCollection wrappedTags) { super(Collections.unmodifiableCollection(wrappedTags)); this.wrappedTags = wrappedTags; } /** * {@inheritDoc} */ @Override public void store(StoreWriter sw, StoreClassRegister scr) { wrappedTags.store(sw, scr); } /** * {@inheritDoc} */ @Override public Map buildMap() { return wrappedTags.buildMap(); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/domain/v0_6/Way.java000066400000000000000000000231711253404521400321030ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.domain.v0_6; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.Iterator; import java.util.List; import org.openstreetmap.osmosis.core.domain.common.SimpleTimestampContainer; import org.openstreetmap.osmosis.core.domain.common.TimestampContainer; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; /** * A data class representing a single OSM way. * * @author Brett Henderson */ public class Way extends Entity implements Comparable { private List wayNodes; /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestamp * The last updated timestamp. * @param user * The user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. * @deprecated As of 0.40, replaced by Way(entityData). */ public Way(long id, int version, Date timestamp, OsmUser user, long changesetId) { // Chain to the more specific constructor this(id, version, new SimpleTimestampContainer(timestamp), user, changesetId); } /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestampContainer * The container holding the timestamp in an alternative * timestamp representation. * @param user * The name of the user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. * @deprecated As of 0.40, replaced by Way(entityData). */ public Way(long id, int version, TimestampContainer timestampContainer, OsmUser user, long changesetId) { super(id, version, timestampContainer, user, changesetId); this.wayNodes = new ArrayList(); } /** * Creates a new instance. * * @param entityData * The common entity data. */ public Way(CommonEntityData entityData) { super(entityData); this.wayNodes = new ArrayList(); } /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestamp * The last updated timestamp. * @param user * The user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. * @param tags * The tags to apply to the object. * @param wayNodes * The way nodes to apply to the object * @deprecated As of 0.40, replaced by Way(entityData, wayNodes). */ public Way(long id, int version, Date timestamp, OsmUser user, long changesetId, Collection tags, List wayNodes) { // Chain to the more specific constructor this(id, version, new SimpleTimestampContainer(timestamp), user, changesetId, tags, wayNodes); } /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestampContainer * The container holding the timestamp in an alternative * timestamp representation. * @param user * The name of the user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. * @param tags * The tags to apply to the object. * @param wayNodes * The way nodes to apply to the object * @deprecated As of 0.40, replaced by Way(entityData, wayNodes). */ public Way( long id, int version, TimestampContainer timestampContainer, OsmUser user, long changesetId, Collection tags, List wayNodes) { super(id, version, timestampContainer, user, changesetId, tags); this.wayNodes = new ArrayList(wayNodes); } /** * Creates a new instance. * * @param entityData * The common entity data. * @param wayNodes * The way nodes to apply to the object */ public Way( CommonEntityData entityData, List wayNodes) { super(entityData); this.wayNodes = new ArrayList(wayNodes); } /** * Creates a new instance. * * @param originalWay * The way to clone from. */ private Way(Way originalWay) { super(originalWay); this.wayNodes = new ArrayList(originalWay.wayNodes); } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers * within the store. */ public Way(StoreReader sr, StoreClassRegister scr) { super(sr, scr); int featureCount; featureCount = sr.readInteger(); wayNodes = new ArrayList(); for (int i = 0; i < featureCount; i++) { wayNodes.add(new WayNode(sr, scr)); } } /** * {@inheritDoc} */ @Override public void store(StoreWriter sw, StoreClassRegister scr) { super.store(sw, scr); sw.writeInteger(wayNodes.size()); for (WayNode wayNode : wayNodes) { wayNode.store(sw, scr); } } /** * {@inheritDoc} */ @Override public EntityType getType() { return EntityType.Way; } /** * {@inheritDoc} */ @Override public boolean equals(Object o) { if (o instanceof Way) { return compareTo((Way) o) == 0; } else { return false; } } /** * {@inheritDoc} */ @Override public int hashCode() { /* * As per the hashCode definition, this doesn't have to be unique it * just has to return the same value for any two objects that compare * equal. Using both id and version will provide a good distribution of * values but is simple to calculate. */ return (int) getId() + getVersion(); } /** * Compares this node list to the specified node list. The comparison is * based on a direct comparison of the node ids. * * @param comparisonWayNodes * The node list to compare to. * @return 0 if equal, < 0 if considered "smaller", and > 0 if * considered "bigger". */ protected int compareWayNodes(List comparisonWayNodes) { Iterator i; Iterator j; // The list with the most entities is considered bigger. if (wayNodes.size() != comparisonWayNodes.size()) { return wayNodes.size() - comparisonWayNodes.size(); } // Check the individual way nodes. i = wayNodes.iterator(); j = comparisonWayNodes.iterator(); while (i.hasNext()) { int result = i.next().compareTo(j.next()); if (result != 0) { return result; } } // There are no differences. return 0; } /** * Compares this way to the specified way. The way comparison is based on a * comparison of id, version, timestamp, wayNodeList and tags in that order. * * @param comparisonWay * The way to compare to. * @return 0 if equal, < 0 if considered "smaller", and > 0 if * considered "bigger". */ public int compareTo(Way comparisonWay) { int wayNodeListResult; if (this.getId() < comparisonWay.getId()) { return -1; } if (this.getId() > comparisonWay.getId()) { return 1; } if (this.getVersion() < comparisonWay.getVersion()) { return -1; } if (this.getVersion() > comparisonWay.getVersion()) { return 1; } if (this.getTimestamp() == null && comparisonWay.getTimestamp() != null) { return -1; } if (this.getTimestamp() != null && comparisonWay.getTimestamp() == null) { return 1; } if (this.getTimestamp() != null && comparisonWay.getTimestamp() != null) { int result; result = this.getTimestamp().compareTo(comparisonWay.getTimestamp()); if (result != 0) { return result; } } wayNodeListResult = compareWayNodes( comparisonWay.getWayNodes() ); if (wayNodeListResult != 0) { return wayNodeListResult; } return compareTags(comparisonWay.getTags()); } /** * {@inheritDoc} */ @Override public void makeReadOnly() { if (!isReadOnly()) { wayNodes = Collections.unmodifiableList(wayNodes); } super.makeReadOnly(); } /** * Returns the attached list of way nodes. The returned list is read-only. * * @return The wayNodeList. */ public List getWayNodes() { return wayNodes; } /** * {@inheritDoc} */ @Override public Way getWriteableInstance() { if (isReadOnly()) { return new Way(this); } else { return this; } } /** * Is this way closed? (A way is closed if the first node id equals the last node id.) * * @return True or false */ public boolean isClosed() { return wayNodes.get(0).getNodeId() == wayNodes.get(wayNodes.size() - 1).getNodeId(); } /** * ${@inheritDoc}. */ @Override public String toString() { String name = null; Collection tags = getTags(); for (Tag tag : tags) { if (tag.getKey() != null && tag.getKey().equalsIgnoreCase("name")) { name = tag.getValue(); break; } } if (name != null) { return "Way(id=" + getId() + ", #tags=" + getTags().size() + ", name='" + name + "')"; } return "Way(id=" + getId() + ", #tags=" + getTags().size() + ")"; } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/domain/v0_6/WayBuilder.java000066400000000000000000000143741253404521400334170ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.domain.v0_6; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.openstreetmap.osmosis.core.domain.common.TimestampContainer; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; /** * Provides the ability to manipulate ways. * * @author Brett Henderson * * @deprecated Builder classes are not required because entities are now writeable. */ @Deprecated public class WayBuilder extends EntityBuilder { private List wayNodes; /** * Creates a new instance. */ public WayBuilder() { super(); wayNodes = new ArrayList(); } /** * Creates a new instance. * * @param entity * The entity to initialise to. */ public WayBuilder(Way entity) { this(); initialize(entity); } /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestamp * The last updated timestamp. * @param user * The user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. */ public WayBuilder(long id, int version, Date timestamp, OsmUser user, long changesetId) { this(); initialize(id, version, timestamp, user, changesetId); } /** * Creates a new instance. * * @param id * The unique identifier. * @param version * The version of the entity. * @param timestampContainer * The container holding the timestamp in an alternative * timestamp representation. * @param user * The user that last modified this entity. * @param changesetId * The id of the changeset that this version of the entity was created by. */ public WayBuilder(long id, TimestampContainer timestampContainer, OsmUser user, long changesetId, int version) { this(); initialize(id, version, timestampContainer, user, changesetId); } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers * within the store. */ public WayBuilder(StoreReader sr, StoreClassRegister scr) { this(); initialize(new Way(sr, scr)); } /** * {@inheritDoc} */ @Override public void store(StoreWriter sw, StoreClassRegister scr) { buildEntity().store(sw, scr); } /** * Initialises the state of this sub-class. */ private void initializeLocal() { wayNodes.clear(); } /** * Initializes the contents of the builder to the specified data. * * @param way * The entity to initialise to. * @return This object allowing method chaining. */ public WayBuilder initialize(Way way) { super.initialize(way); initializeLocal(); wayNodes.addAll(way.getWayNodes()); return this; } /** * Initializes the contents of the builder to the specified data. * * @param newId * The unique identifier. * @param newVersion * The version of the entity. * @param newTimestamp * The last updated timestamp. * @param newUser * The user that last modified this entity. * @param newChangesetId * The id of the changeset that this version of the entity was created by. * @return This object allowing method chaining. */ @Override public WayBuilder initialize(long newId, int newVersion, Date newTimestamp, OsmUser newUser, long newChangesetId) { super.initialize(newId, newVersion, newTimestamp, newUser, newChangesetId); initializeLocal(); return this; } /** * Initializes the contents of the builder to the specified data. * * @param newId * The unique identifier. * @param newVersion * The version of the entity. * @param newTimestampContainer * The container holding the timestamp in an alternative * timestamp representation. * @param newUser * The user that last modified this entity. * @param newChangesetId * The id of the changeset that this version of the entity was created by. * @return This object allowing method chaining. */ @Override public WayBuilder initialize(long newId, int newVersion, TimestampContainer newTimestampContainer, OsmUser newUser, long newChangesetId) { super.initialize(newId, newVersion, newTimestampContainer, newUser, newChangesetId); initializeLocal(); return this; } /** * Obtains the way nodes. * * @return The way nodes. */ public List getWayNodes() { return wayNodes; } /** * Remove all existing way nodes. * * @return This object allowing method chaining. */ public WayBuilder clearWayNodes() { wayNodes.clear(); return this; } /** * Sets a new way nodes value. * * @param newWayNodes * The new way nodes. * @return This object allowing method chaining. */ public WayBuilder setWayNodes(List newWayNodes) { wayNodes.clear(); wayNodes.addAll(newWayNodes); return this; } /** * Adds a new way node. * * @param wayNode * The new way node. * @return This object allowing method chaining. */ public WayBuilder addWayNode(WayNode wayNode) { wayNodes.add(wayNode); return this; } /** * {@inheritDoc} */ @Override public Way buildEntity() { return new Way(id, version, timestampContainer, user, changesetId, tags, wayNodes); } /** * ${@inheritDoc}. */ @Override public String toString() { String name = null; for (Tag tag : tags) { if (tag.getKey() != null && tag.getKey().equalsIgnoreCase("name")) { name = tag.getValue(); break; } } if (name != null) { return "WayBuilder(id=" + getId() + ", #tags=" + getTags().size() + ", name='" + name + "')"; } return "WayBuilder(id=" + getId() + ", #tags=" + getTags().size() + ")"; } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/domain/v0_6/WayNode.java000066400000000000000000000036031253404521400327070ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.domain.v0_6; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; import org.openstreetmap.osmosis.core.store.Storeable; /** * A data class representing a reference to an OSM node. * * @author Brett Henderson */ public class WayNode implements Comparable, Storeable { private long nodeId; /** * Creates a new instance. * * @param nodeId * The unique identifier of the node being referred to. */ public WayNode(long nodeId) { this.nodeId = nodeId; } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers * within the store. */ public WayNode(StoreReader sr, StoreClassRegister scr) { this(sr.readLong()); } /** * {@inheritDoc} */ public void store(StoreWriter sw, StoreClassRegister scr) { sw.writeLong(nodeId); } /** * Compares this way node to the specified way node. The way node comparison * is based on a comparison of nodeId. * * @param wayNode * The way node to compare to. * @return 0 if equal, < 0 if considered "smaller", and > 0 if * considered "bigger". */ public int compareTo(WayNode wayNode) { long result; result = this.nodeId - wayNode.nodeId; if (result > 0) { return 1; } else if (result < 0) { return -1; } else { return 0; } } /** * @return The nodeId. */ public long getNodeId() { return nodeId; } /** * ${@inheritDoc}. */ @Override public String toString() { return "WayNode(nodeID=" + getNodeId() + ")"; } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/filter/000077500000000000000000000000001253404521400277405ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/filter/common/000077500000000000000000000000001253404521400312305ustar00rootroot00000000000000BitSetIdTracker.java000066400000000000000000000073361253404521400350100ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/filter/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.filter.common; import java.util.BitSet; import java.util.Iterator; import java.util.NoSuchElementException; import org.openstreetmap.osmosis.core.util.LongAsInt; /** * Implements the IdTracker interface using an internal JDK BitSet. The current * implementation only supports 31 bit numbers, but will be enhanced if and when * required. * * @author Brett Henderson */ public class BitSetIdTracker implements IdTracker { /** * The positive ids are stored within a bitset which cannot hold negative * values. It is not private to allow the IdIterator to access it * efficiently. */ /* package */ BitSet positiveSet; /** * The negative ids cannot be stored in the main bitset. They are stored in * a list implementation because the number of negative values is expected * to be small. It is not private to allow the IdIterator to access it * efficiently. */ /* package */ ListIdTracker negativeSet; /** * Creates a new instance. */ public BitSetIdTracker() { positiveSet = new BitSet(); negativeSet = new ListIdTracker(); } /** * {@inheritDoc} */ public void set(long id) { int intId; intId = LongAsInt.longToInt(id); if (intId >= 0) { positiveSet.set(intId); } else { negativeSet.set(intId); } } /** * {@inheritDoc} */ public boolean get(long id) { int intId; boolean result; intId = LongAsInt.longToInt(id); if (intId >= 0) { result = positiveSet.get(intId); } else { result = negativeSet.get(intId); } return result; } /** * {@inheritDoc} */ @Override public Iterator iterator() { return new IdIterator(); } /** * {@inheritDoc} */ @Override public void setAll(IdTracker idTracker) { for (Long id : idTracker) { set(id); } } /** * The iterator implementation for providing access to the list of ids. * * @author Brett Henderson */ private class IdIterator implements Iterator { /** * Tracks whether we're currently reading positive or negative bitsets. */ private boolean readingPositive; private long nextId; private boolean nextIdAvailable; private Iterator negativeIterator; /** * The current bit offset in the positive bitset. */ private int positiveOffset; /** * Creates a new instance. */ public IdIterator() { readingPositive = false; nextIdAvailable = false; positiveOffset = 0; } /** * {@inheritDoc} */ @Override public boolean hasNext() { if (!nextIdAvailable) { if (!readingPositive) { // Create a negative set iterator if one doesn't already exist. if (negativeIterator == null) { negativeIterator = negativeSet.iterator(); } // Get data from the negative iterator if available, if not // available switch to positive reading. if (negativeIterator.hasNext()) { nextId = negativeIterator.next(); nextIdAvailable = true; } else { negativeIterator = null; readingPositive = true; } } if (readingPositive) { int nextBitOffset; nextBitOffset = positiveSet.nextSetBit(positiveOffset); if (nextBitOffset >= 0) { nextId = nextBitOffset; nextIdAvailable = true; positiveOffset = nextBitOffset + 1; } } } return nextIdAvailable; } /** * {@inheritDoc} */ @Override public Long next() { if (!hasNext()) { throw new NoSuchElementException(); } nextIdAvailable = false; return nextId; } /** * {@inheritDoc} */ @Override public void remove() { throw new UnsupportedOperationException(); } } } DynamicIdTracker.java000066400000000000000000000132611253404521400351740ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/filter/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.filter.common; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; /** * Implements the IdTracker interface using a combination of BitSet and ListId trackers. It breaks * the overall address space into segments and automatically switches between implementations for each * chunk depending on which is more efficient. * * @author Brett Henderson */ public class DynamicIdTracker implements IdTracker { /** * Defines the number of ids managed by a single segment. */ /* package */ static final int SEGMENT_SIZE = 1024; private List segments; /** * Creates a new instance. */ public DynamicIdTracker() { segments = new ArrayList(); } private int calculateOffset(long id) { int offset; // A long modulo an integer is an integer. offset = (int) (id % SEGMENT_SIZE); // If the number is negative, we need to shift the number relative to the base of the // segment. if (offset < 0) { offset = SEGMENT_SIZE + offset; } return offset; } private DynamicIdTrackerSegment getSegment(long base, boolean createIfMissing) { int intervalBegin; int intervalEnd; DynamicIdTrackerSegment segment; segment = null; // Perform a binary search splitting the list in half each time until // the requested id is confirmed as existing or not. intervalBegin = 0; intervalEnd = segments.size(); for (boolean searchComplete = false; !searchComplete;) { int intervalSize; long currentBase; DynamicIdTrackerSegment currentSegment; // Calculate the interval size. intervalSize = intervalEnd - intervalBegin; // If no elements exist, we have no search to perform. If elements do exist then divide // and conquer while the size is large, then commence linear search once the size is // small. if (intervalSize == 0) { if (createIfMissing) { segment = new DynamicIdTrackerSegment(base); segments.add(intervalBegin, segment); } searchComplete = true; } else if (intervalSize >= 2) { int intervalMid; // Split the interval in two. intervalMid = intervalSize / 2 + intervalBegin; // Check whether the midpoint id is above or below the id // required. currentSegment = segments.get(intervalMid); currentBase = currentSegment.getBase(); if (currentBase == base) { segment = currentSegment; searchComplete = true; } else if (currentBase < base) { intervalBegin = intervalMid + 1; } else { intervalEnd = intervalMid; } } else { // Iterate through the entire interval. for (; intervalBegin < intervalEnd; intervalBegin++) { // Check if the current offset contains the id required. currentSegment = segments.get(intervalBegin); currentBase = currentSegment.getBase(); if (currentBase == base) { segment = currentSegment; break; } else if (currentBase > base) { // The requested segment should exist prior to the current segment. if (createIfMissing) { segment = new DynamicIdTrackerSegment(base); segments.add(intervalBegin, segment); } break; } } // The requested base is at the end of this interval where intervalBegin is currently pointing. if (segment == null && createIfMissing) { segment = new DynamicIdTrackerSegment(base); segments.add(intervalBegin, segment); } searchComplete = true; } } return segment; } /** * {@inheritDoc} */ @Override public boolean get(long id) { int offset; long base; DynamicIdTrackerSegment segment; offset = calculateOffset(id); base = id - offset; segment = getSegment(base, false); if (segment != null) { return segment.get(offset); } else { return false; } } /** * {@inheritDoc} */ @Override public void set(long id) { int offset; long base; DynamicIdTrackerSegment segment; offset = calculateOffset(id); base = id - offset; segment = getSegment(base, true); segment.set(offset); } /** * {@inheritDoc} */ @Override public void setAll(IdTracker idTracker) { for (Long id : idTracker) { set(id); } } /** * {@inheritDoc} */ @Override public Iterator iterator() { return new SegmentIdIterator(segments.iterator()); } private static class SegmentIdIterator implements Iterator { private Iterator segments; private Iterator currentSegmentIds; private long currentSegmentBase; /** * Creates a new instance. * * @param segments * The segments to iterate over. */ public SegmentIdIterator(Iterator segments) { this.segments = segments; } /** * {@inheritDoc} */ @Override public boolean hasNext() { for (;;) { if (currentSegmentIds == null) { if (segments.hasNext()) { DynamicIdTrackerSegment segment = segments.next(); currentSegmentIds = segment.iterator(); currentSegmentBase = segment.getBase(); } else { return false; } } if (currentSegmentIds.hasNext()) { return true; } else { currentSegmentIds = null; } } } /** * {@inheritDoc} */ @Override public Long next() { if (hasNext()) { return currentSegmentIds.next() + currentSegmentBase; } else { throw new NoSuchElementException(); } } /** * {@inheritDoc} */ @Override public void remove() { throw new UnsupportedOperationException(); } } } DynamicIdTrackerSegment.java000066400000000000000000000044211253404521400365150ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/filter/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.filter.common; import java.util.Iterator; /** * Stores the data for a single id range within the dynamic id tracker. It selects between the most * appropriate id tracker implementation depending on id density. * * @author Brett Henderson */ public class DynamicIdTrackerSegment implements Comparable, Iterable { private static final int BITSET_THRESHOLD = DynamicIdTracker.SEGMENT_SIZE / 32; private long base; private char setCount; private IdTracker idTracker; private boolean bitsetEnabled; /** * Creates a new instance. * * @param base * The minimum value represented by this segment. */ public DynamicIdTrackerSegment(long base) { this.base = base; idTracker = new ListIdTracker(); bitsetEnabled = false; } /** * Gets the base. * * @return The base. */ public long getBase() { return base; } /** * Gets the number of set ids in this segment. * * @return The set count. */ public long getSetCount() { return setCount; } /** * Checks whether the specified id is active. * * @param id * The identifier to be checked. * @return True if the identifier is active, false otherwise. */ public boolean get(long id) { return idTracker.get(id); } /** * Marks the specified id as active. * * @param id * The identifier to be flagged. */ public void set(long id) { if (!idTracker.get(id)) { idTracker.set(id); setCount++; // If the count threshold has been exceeded, switch to a bitset implementation. if (!bitsetEnabled && setCount > BITSET_THRESHOLD) { IdTracker bitsetIdTracker; bitsetIdTracker = new BitSetIdTracker(); bitsetIdTracker.setAll(idTracker); idTracker = bitsetIdTracker; bitsetEnabled = true; } } } /** * {@inheritDoc} */ @Override public int compareTo(DynamicIdTrackerSegment o) { long result; result = base - o.base; if (result == 0) { return 0; } else if (result > 0) { return 1; } else { return -1; } } /** * {@inheritDoc} */ @Override public Iterator iterator() { return idTracker.iterator(); } } IdTracker.java000066400000000000000000000017361253404521400336730ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/filter/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.filter.common; /** * Defines the interface for all class implementations allowing a set of ids to * be marked as in use. This is used in filter tasks for tracking which entities * have been selected. Implementations support negative numbers. * * @author Brett Henderson */ public interface IdTracker extends Iterable { /** * Marks the specified id as active. * * @param id * The identifier to be flagged. */ void set(long id); /** * Checks whether the specified id is active. * * @param id * The identifier to be checked. * @return True if the identifier is active, false otherwise. */ boolean get(long id); /** * Sets all the ids contained in the specified tracker. * * @param idTracker * The id tracker containing the ids to set. */ void setAll(IdTracker idTracker); } IdTrackerFactory.java000066400000000000000000000021021253404521400352070ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/filter/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.filter.common; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Creates IdTracker implementation instances depending on the requested id * tracker type. * * @author Brett Henderson */ public final class IdTrackerFactory { /** * This class cannot be instantiated. */ private IdTrackerFactory() { } /** * Creates the requested id tracker type. * * @param idTrackerType * The type of id tracker to instantiate. * @return The new id tracker. */ public static IdTracker createInstance(IdTrackerType idTrackerType) { if (IdTrackerType.BitSet.equals(idTrackerType)) { return new BitSetIdTracker(); } else if (IdTrackerType.IdList.equals(idTrackerType)) { return new ListIdTracker(); } else if (IdTrackerType.Dynamic.equals(idTrackerType)) { return new DynamicIdTracker(); } else { throw new OsmosisRuntimeException("The IdTrackerType " + idTrackerType + " is not recognised."); } } } IdTrackerType.java000066400000000000000000000024421253404521400345300ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/filter/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.filter.common; /** * Defines the different id tracker implementations available. * * @author Brett Henderson * */ public enum IdTrackerType { /** * The BitSet implementation maintains an array of bits set to 0 or 1. This is the most compact * storage representation for individual ids but is very wasteful when the ids are sparsely * allocated because a bit is allocated for every id in the id range. This should be used if a * large portion of the entire dataset must be stored. */ BitSet, /** * The IdList implementation maintains an array of selected ids. This use 32 bits per id but is * more efficient when a smaller number of ids are being stored. For example, in a bounding box * implementation this implementation will be more efficient if the bounding box contains less * than approximately 1/32 of the entire dataset. */ IdList, /** * The dynamic implementation maintains an array of segments. Each segment manages a fixed range * of ids. Each segment is created on demand. Each segment internally manages the id list with * either one of the two other id list implementations depending on the number of ids to be * managed. */ Dynamic } ListIdTracker.java000066400000000000000000000137721253404521400345320ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/filter/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.filter.common; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import org.openstreetmap.osmosis.core.util.LongAsInt; /** * Implements the IdTracker interface using a list of ids. The current * implementation only supports 31 bit numbers, but will be enhanced if and when * required. * * @author Brett Henderson */ public class ListIdTracker implements IdTracker { /** * The internal list size is multiplied by this factor when more space is * required. */ private static final double LIST_SIZE_EXTENSION_FACTOR = 1.5; /** * This is the main list of id values. It is allocated in chunks and the * maximum valid offset is defined by idOffset. */ /* package */ int[] idList; /** * Flags where the maximum written id offset occurs in the list. If new * values are added and the list is full, new space must be allocated. */ /* package */ int idOffset; private int maxIdAdded; private boolean sorted; /** * Creates a new instance. */ public ListIdTracker() { // This is being initialised with a very small array size because this class is now also // used within the DynamicIdTracker which relies on the ListIdTracker being efficient for // small amounts of data. // When storing large amounts of data, the overhead of extending the array more often in the // early stages is relatively small compared to the overall processing. For small amounts of // data, the size efficiency is most important. idList = new int[1]; idOffset = 0; maxIdAdded = Integer.MIN_VALUE; sorted = true; } /** * Increases the size of the id list to make space for new ids. */ private void extendIdList() { int[] newIdList; int newListLength; newListLength = (int) (idList.length * LIST_SIZE_EXTENSION_FACTOR); if (newListLength == idList.length) { newListLength++; } newIdList = new int[newListLength]; System.arraycopy(idList, 0, newIdList, 0, idList.length); idList = newIdList; } /** * If the list is unsorted, this method will re-order the contents. */ private void ensureListIsSorted() { if (!sorted) { List tmpList; int newIdOffset; tmpList = new ArrayList(idOffset); for (int i = 0; i < idOffset; i++) { tmpList.add(Integer.valueOf(idList[i])); } Collections.sort(tmpList); newIdOffset = 0; for (int i = 0; i < idOffset; i++) { int nextValue; nextValue = tmpList.get(i).intValue(); if (newIdOffset <= 0 || nextValue > idList[newIdOffset - 1]) { idList[newIdOffset++] = nextValue; } } idOffset = newIdOffset; sorted = true; } } /** * {@inheritDoc} */ public void set(long id) { int integerId; integerId = LongAsInt.longToInt(id); // Increase the id list size if it is full. if (idOffset >= idList.length) { extendIdList(); } idList[idOffset++] = integerId; // If ids are added out of order, the list will have to be sorted before // it can be searched using a binary search algorithm. if (integerId < maxIdAdded) { sorted = false; } else { maxIdAdded = integerId; } } /** * {@inheritDoc} */ public boolean get(long id) { int integerId; int intervalBegin; int intervalEnd; boolean idFound; integerId = LongAsInt.longToInt(id); // If the list is not sorted, it must be sorted prior to a search being // performed. ensureListIsSorted(); // Perform a binary search splitting the list in half each time until // the requested id is confirmed as existing or not. intervalBegin = 0; intervalEnd = idOffset; idFound = false; for (boolean searchComplete = false; !searchComplete;) { int intervalSize; // Calculate the interval size. intervalSize = intervalEnd - intervalBegin; // Divide and conquer if the size is large, otherwise commence // linear search. if (intervalSize >= 2) { int intervalMid; int currentId; // Split the interval in two. intervalMid = intervalSize / 2 + intervalBegin; // Check whether the midpoint id is above or below the id // required. currentId = idList[intervalMid]; if (currentId == integerId) { idFound = true; searchComplete = true; } else if (currentId < integerId) { intervalBegin = intervalMid + 1; } else { intervalEnd = intervalMid; } } else { // Iterate through the entire interval. for (int currentOffset = intervalBegin; currentOffset < intervalEnd; currentOffset++) { int currentId; // Check if the current offset contains the id required. currentId = idList[currentOffset]; if (currentId == integerId) { idFound = true; break; } } searchComplete = true; } } return idFound; } /** * {@inheritDoc} */ @Override public Iterator iterator() { // If the list is not sorted, it must be sorted prior to data being // returned. ensureListIsSorted(); return new IdIterator(); } /** * {@inheritDoc} */ @Override public void setAll(IdTracker idTracker) { for (Long id : idTracker) { set(id); } } /** * The iterator implementation for providing access to the list of ids. * * @author Brett Henderson */ private class IdIterator implements Iterator { private int iteratorOffset; /** * Creates a new instance. */ public IdIterator() { iteratorOffset = 0; } /** * {@inheritDoc} */ @Override public boolean hasNext() { return (iteratorOffset < idOffset); } /** * {@inheritDoc} */ @Override public Long next() { if (!hasNext()) { throw new NoSuchElementException(); } return (long) idList[iteratorOffset++]; } /** * {@inheritDoc} */ @Override public void remove() { throw new UnsupportedOperationException(); } } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/lifecycle/000077500000000000000000000000001253404521400304125ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/lifecycle/Completable.java000066400000000000000000000014621253404521400335070ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.lifecycle; /** * Some class implementations persist information and require notification to * complete all output prior to being released. In this case, clients of those * classes should call the complete method. * * @author Brett Henderson */ public interface Completable extends Releasable { /** * Ensures that all information is fully persisted. This includes database * commits, file buffer flushes, etc. Implementations must call complete on * any nested Completable objects. Where the releasable method of a * Releasable class should be called within a finally block, this method * should typically be the final statement within the try block. */ void complete(); } CompletableContainer.java000066400000000000000000000022461253404521400352740ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/lifecycle// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.lifecycle; import java.util.ArrayList; import java.util.List; /** * A container for completable objects that require complete and release calls * to be performed as a unit. * * @author Brett Henderson */ public class CompletableContainer implements Completable { private List objects; /** * Creates a new instance. */ public CompletableContainer() { objects = new ArrayList(); } /** * Adds a new object to be managed. The object is returned to allow method * chaining. * * @param * The type of object being stored. * @param object * The object to be stored. * @return The object that was stored. */ public T add(T object) { objects.add(object); return object; } /** * {@inheritDoc} */ @Override public void complete() { for (Completable object : objects) { object.complete(); } } /** * {@inheritDoc} */ @Override public void release() { for (Releasable object : objects) { object.release(); } } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/lifecycle/Releasable.java000066400000000000000000000020361253404521400333150ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.lifecycle; /** * Classes that hold heavyweight resources that can't wait for garbage * collection should implement this interface. It provides a release method that * should be called by all clients when the class is no longer required. This * release method is guaranteed not to throw exceptions and should always be * called within a finally clause. * * @author Brett Henderson */ public interface Releasable { /** * Performs resource cleanup tasks such as closing files, or database * connections. This must be called after all processing is complete. * Implementations should support calling release multiple times, however * this is not mandatory and cannot be relied on by clients. Implementations * must call release on any nested Releasable objects. It does not throw * exceptions and should be called within a finally block to ensure it is * called in exception scenarios. */ void release(); } ReleasableContainer.java000066400000000000000000000025541253404521400351060ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/lifecycle// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.lifecycle; import java.util.ArrayList; import java.util.List; /** * A container for releasable objects that must be freed. This implementation * simplifies the creation of many releasable objects that must succeed or fail * as a group. As each is created they are added to this container, and after * they're all created successfully they can be cleared from this container. * * @author Brett Henderson */ public class ReleasableContainer implements Releasable { private List objects; /** * Creates a new instance. */ public ReleasableContainer() { objects = new ArrayList(); } /** * Adds a new object to be managed. The object is returned to allow method * chaining. * * @param * The type of object being stored. * @param object * The object to be stored. * @return The object that was stored. */ public T add(T object) { objects.add(object); return object; } /** * Removes all objects. They will no longer be released. */ public void clear() { objects.clear(); } /** * {@inheritDoc} */ @Override public void release() { for (Releasable object : objects) { object.release(); } objects.clear(); } } ReleasableIterator.java000066400000000000000000000007221253404521400347500ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/lifecycle// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.lifecycle; import java.util.Iterator; /** * Defines an iterator that must be explicitly released after use. * * @param * The data type to be iterated. * @author Brett Henderson */ public interface ReleasableIterator extends Iterator, Releasable { // This combines multiple interfaces but doesn't add methods. } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/merge/000077500000000000000000000000001253404521400275525ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/merge/common/000077500000000000000000000000001253404521400310425ustar00rootroot00000000000000ConflictResolutionMethod.java000066400000000000000000000010101253404521400366040ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/merge/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.merge.common; /** * Defines the methods that can be used to resolve conflicts when two sources * contain the same element. */ public enum ConflictResolutionMethod { /** * Select the entity with the latest timestamp. */ Timestamp, /** * Select the entity from the latest input source. */ LatestSource, /** * Select the entity with the highest version number. */ Version } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/misc/000077500000000000000000000000001253404521400274065ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/misc/v0_6/000077500000000000000000000000001253404521400301605ustar00rootroot00000000000000EmptyChangeReader.java000066400000000000000000000014771253404521400343040ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/misc/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.misc.v0_6; import java.util.Collections; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.RunnableChangeSource; /** * An OSM data source that produces an empty change stream. * * @author Brett Henderson */ public class EmptyChangeReader implements RunnableChangeSource { private ChangeSink changeSink; /** * {@inheritDoc} */ @Override public void setChangeSink(ChangeSink changeSink) { this.changeSink = changeSink; } /** * {@inheritDoc} */ @Override public void run() { try { changeSink.initialize(Collections.emptyMap()); changeSink.complete(); } finally { changeSink.release(); } } } EmptyChangeReaderFactory.java000066400000000000000000000014731253404521400356300ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/misc/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.misc.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.RunnableChangeSourceManager; /** * The task manager factory for an empty change reader. * * @author Brett Henderson */ public class EmptyChangeReaderFactory extends TaskManagerFactory { /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { return new RunnableChangeSourceManager(taskConfig.getId(), new EmptyChangeReader(), taskConfig.getPipeArgs()); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/misc/v0_6/EmptyReader.java000066400000000000000000000013531253404521400332460ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.misc.v0_6; import java.util.Collections; import org.openstreetmap.osmosis.core.task.v0_6.RunnableSource; import org.openstreetmap.osmosis.core.task.v0_6.Sink; /** * An OSM data source that produces an empty entity stream. * * @author Brett Henderson */ public class EmptyReader implements RunnableSource { private Sink sink; /** * {@inheritDoc} */ @Override public void setSink(Sink sink) { this.sink = sink; } /** * {@inheritDoc} */ @Override public void run() { try { sink.initialize(Collections.emptyMap()); sink.complete(); } finally { sink.release(); } } } EmptyReaderFactory.java000066400000000000000000000014341253404521400345170ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/misc/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.misc.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.RunnableSourceManager; /** * The task manager factory for an empty reader. * * @author Brett Henderson */ public class EmptyReaderFactory extends TaskManagerFactory { /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { return new RunnableSourceManager(taskConfig.getId(), new EmptyReader(), taskConfig.getPipeArgs()); } } NullChangeWriter.java000066400000000000000000000016171253404521400341660ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/misc/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.misc.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; /** * An OSM change sink that discards all data sent to it. This is primarily * intended for benchmarking purposes. * * @author Brett Henderson */ public class NullChangeWriter implements ChangeSink { /** * {@inheritDoc} */ @Override public void initialize(Map metaTags) { // Nothing to do. } /** * {@inheritDoc} */ public void process(ChangeContainer change) { // Discard the data. } /** * Flushes all changes to file. */ public void complete() { // Nothing to do. } /** * Cleans up any open file handles. */ public void release() { // Nothing to do. } } NullChangeWriterFactory.java000066400000000000000000000014451253404521400355150ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/misc/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.misc.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.ChangeSinkManager; /** * The task manager factory for a null change writer. * * @author Brett Henderson */ public class NullChangeWriterFactory extends TaskManagerFactory { /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { return new ChangeSinkManager(taskConfig.getId(), new NullChangeWriter(), taskConfig.getPipeArgs()); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/misc/v0_6/NullWriter.java000066400000000000000000000016041253404521400331330ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.misc.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.task.v0_6.Sink; /** * An OSM data sink that discards all data sent to it. This is primarily * intended for benchmarking purposes. * * @author Brett Henderson */ public class NullWriter implements Sink { /** * {@inheritDoc} */ @Override public void initialize(Map metaTags) { // Nothing to do. } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { // Discard the data. } /** * Flushes all changes to file. */ public void complete() { // Nothing to do. } /** * Cleans up any open file handles. */ public void release() { // Nothing to do. } } NullWriterFactory.java000066400000000000000000000014061253404521400344040ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/misc/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.misc.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkManager; /** * The task manager factory for a null writer. * * @author Brett Henderson */ public class NullWriterFactory extends TaskManagerFactory { /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { return new SinkManager(taskConfig.getId(), new NullWriter(), taskConfig.getPipeArgs()); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/000077500000000000000000000000001253404521400302605ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/common/000077500000000000000000000000001253404521400315505ustar00rootroot00000000000000ActiveTaskManager.java000066400000000000000000000043301253404521400356650ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.common; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * This task manager implementation supports tasks that perform active * processing in a separate thread. * * @author Brett Henderson */ public abstract class ActiveTaskManager extends TaskManager { private static final Logger LOG = Logger.getLogger(ActiveTaskManager.class.getName()); private TaskRunner thread; /** * Creates a new instance. * * @param taskId * A unique identifier for the task. This is used to produce * meaningful errors when errors occur. * @param pipeArgs * The arguments defining input and output pipes for the task, * pipes are a logical concept for identifying how the tasks are * connected together. */ protected ActiveTaskManager(String taskId, Map pipeArgs) { super(taskId, pipeArgs); } /** * Returns the runnable task managed by this manager. * * @return The task. */ protected abstract Runnable getTask(); /** * {@inheritDoc} */ @Override public void execute() { LOG.fine("Launching task " + getTaskId() + " in a new thread."); if (thread != null) { throw new OsmosisRuntimeException("Task " + getTaskId() + " is already running."); } thread = new TaskRunner(getTask(), "Thread-" + getTaskId()); thread.start(); } /** * {@inheritDoc} */ @Override public boolean waitForCompletion() { LOG.fine("Waiting for task " + getTaskId() + " to complete."); if (thread != null) { boolean successful; try { thread.join(); } catch (InterruptedException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "The wait for task completion was interrupted.", e); } successful = thread.isSuccessful(); if (!successful) { LOG.log(Level.SEVERE, "Thread for task " + getTaskId() + " failed", thread.getException()); } thread = null; return successful; } return true; } } PassiveTaskManager.java000066400000000000000000000027041253404521400360670ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.common; import java.util.Map; import java.util.logging.Logger; /** * This task manager implementation supports tasks that perform passive * processing on data received from other tasks. * * @author Brett Henderson */ public abstract class PassiveTaskManager extends TaskManager { private static final Logger LOG = Logger.getLogger(PassiveTaskManager.class.getName()); /** * Creates a new instance. * * @param taskId * A unique identifier for the task. This is used to produce * meaningful errors when errors occur. * @param pipeArgs * The arguments defining input and output pipes for the task, * pipes are a logical concept for identifying how the tasks are * connected together. */ protected PassiveTaskManager(String taskId, Map pipeArgs) { super(taskId, pipeArgs); } /** * {@inheritDoc} */ @Override public void execute() { // Nothing to do for a sink because it passively receives data. LOG.fine("Task " + getTaskId() + " is passive, no execution required."); } /** * {@inheritDoc} */ @Override public boolean waitForCompletion() { // Nothing to do for a sink because it passively receives data. LOG.fine("Task " + getTaskId() + " is passive, no completion wait required."); return true; } } PipeTasks.java000066400000000000000000000125561253404521400342500ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.common; import java.util.ArrayDeque; import java.util.Deque; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.task.common.Task; /** * Maintains the tasks that have been registered as producing data during the * connection process. * * @author Brett Henderson */ public class PipeTasks { private static final Logger LOG = Logger.getLogger(PipeTasks.class.getName()); private Map namedTasks; private Deque defaultTasks; /** * Creates a new instance. */ public PipeTasks() { namedTasks = new HashMap(); defaultTasks = new ArrayDeque(); } /** * Adds the specified task using the specified name. * * @param taskId * The unique identifier of the task perfroming this request. * @param pipeName * The name to register the task under. * @param task * The task to be added. */ public void putTask(String taskId, String pipeName, Task task) { // Verify that the output pipe is not already taken. if (namedTasks.containsKey(pipeName)) { throw new OsmosisRuntimeException("Task " + taskId + " cannot write to pipe " + pipeName + " because the pipe is already being written to."); } namedTasks.put(pipeName, task); if (LOG.isLoggable(Level.FINE)) { LOG.fine("Task \"" + taskId + "\" produced pipe \"" + pipeName + "\""); } } /** * Adds the specified task to the default pipe list. * * @param taskId * The unique identifier of the task performing this request. * @param task * The task to be added. */ public void putTask(String taskId, Task task) { // Push the new task onto the top of the default pipe stack. defaultTasks.push(task); if (LOG.isLoggable(Level.FINE)) { LOG.fine("Task \"" + taskId + "\" produced unnamed pipe stored at level " + defaultTasks.size() + " in the default pipe stack."); } } /** * Checks if the specified task matches the required task type. * * @param requiredTaskType * The type of task required. * @param task * The task to be checked. * @return True if the task type is a match. */ private boolean verifyPipeType(Class requiredTaskType, Task task) { // Ensure the task is of the correct type. return requiredTaskType.isInstance(task); } /** * Removes and returns the task registered under the specified name. * * @param taskId * The unique identifier of the task perfroming this request. * @param pipeName * The name of the registered task. * @param requiredTaskType * The required type of the input task. * @return The matching task. */ public Task retrieveTask(String taskId, String pipeName, Class requiredTaskType) { Task task; if (!namedTasks.containsKey(pipeName)) { throw new OsmosisRuntimeException( "No pipe named " + pipeName + " is available as input for task " + taskId + "."); } task = namedTasks.remove(pipeName); // Ensure the task is of the correct type. if (!verifyPipeType(requiredTaskType, task)) { throw new OsmosisRuntimeException( "Task " + taskId + " does not support data provided by input pipe " + pipeName + "."); } if (LOG.isLoggable(Level.FINE)) { LOG.fine("Task \"" + taskId + "\" consumed pipe \"" + pipeName + "\""); } return task; } /** * Removes and returns the next available task registered under a default name. * * @param taskId * The unique identifier of the task perfroming this request. * @param requiredTaskType * The required type of the input task. * @return The matching task. */ public Task retrieveTask(String taskId, Class requiredTaskType) { Task task; int defaultTaskCount; defaultTaskCount = defaultTasks.size(); if (defaultTaskCount == 0) { throw new OsmosisRuntimeException("No default pipes are available as input for task " + taskId + "."); } task = defaultTasks.pop(); // Ensure the task is of the correct type. if (!verifyPipeType(requiredTaskType, task)) { throw new OsmosisRuntimeException( "Task " + taskId + " does not support data provided by default pipe stored at level " + (defaultTasks.size() + 1) + " in the default pipe stack."); } if (LOG.isLoggable(Level.FINE)) { LOG.fine("Task \"" + taskId + "\" consumed unnamed pipe stored at level " + defaultTaskCount + " in the default pipe stack."); } return task; } /** * Returns the number of pipes stored in this container. * * @return The number of pipes. */ public int size() { return namedTasks.size() + defaultTasks.size(); } /** * Returns how many default pipes are stored in this container. This is a * subset of the count returned by size(). * * @return The number of default pipes. */ public int defaultTaskSize() { return defaultTasks.size(); } /** * Returns the names of all of the currently registered pipes. * * @return The set of pipe names. */ public Set getPipeNames() { return namedTasks.keySet(); } } Pipeline.java000066400000000000000000000076411253404521400341110ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.common; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Manages a processing pipeline from parsing of arguments, to creating and * instantiating tasks, running of the pipeline, and waiting until pipeline * completion. * * @author Brett Henderson */ public class Pipeline { private static final Logger LOG = Logger.getLogger(Pipeline.class.getName()); private TaskManagerFactoryRegister factoryRegister; private List taskManagers; /** * Creates a new instance. * * @param factoryRegister * The register containing all known task manager factories. */ public Pipeline(TaskManagerFactoryRegister factoryRegister) { this.factoryRegister = factoryRegister; taskManagers = new ArrayList(); } /** * Creates a new node in the pipeline. The node will be created with the * correct task with all task parameters set. The tasks will not be * connected together. * * @param taskInfoList * The list of task information objects. */ private void buildTasks(List taskInfoList) { for (TaskConfiguration taskConfig : taskInfoList) { // Create the new task manager and add to the pipeline. taskManagers.add( factoryRegister.getInstance(taskConfig.getType()).createTaskManager(taskConfig) ); if (LOG.isLoggable(Level.FINE)) { LOG.fine("Created task \"" + taskConfig.getId() + "\""); } } } /** * Uses the pipe arguments specified for each task to connect the tasks appropriately. */ private void connectTasks() { PipeTasks pipeTasks; // Create a container to map between the pipe name and the task that has // last written to it. pipeTasks = new PipeTasks(); // Request each node to perform connection, each node will update the // pipe tasks as it provides and consumes pipes. for (TaskManager taskManager : taskManagers) { taskManager.connect(pipeTasks); if (LOG.isLoggable(Level.FINE)) { LOG.fine("Connected task \"" + taskManager.getTaskId() + "\""); } } // Validate that no pipes are left without sinks. if (pipeTasks.size() > 0) { StringBuilder namedPipes; // Build a list of pipes to include in the error. namedPipes = new StringBuilder(); for (String pipeName : pipeTasks.getPipeNames()) { if (namedPipes.length() > 0) { namedPipes.append(", "); } namedPipes.append(pipeName); } throw new OsmosisRuntimeException( "The following named pipes (" + namedPipes + ") and " + pipeTasks.defaultTaskSize() + " default pipes have not been terminated with appropriate output sinks." ); } } /** * Instantiates and configures all tasks within the pipeline. * * @param taskInfoList * The list of task information objects. */ public void prepare(List taskInfoList) { // Process the command line arguments to build all tasks in the pipeline. LOG.fine("Building tasks."); buildTasks(taskInfoList); // Connect the nodes in the pipeline. LOG.fine("Connecting tasks."); connectTasks(); } /** * Launches the execution of the tasks within the pipeline. */ public void execute() { // Initiate execution of all nodes. for (TaskManager taskManager : taskManagers) { taskManager.execute(); } } /** * Waits for all tasks within the pipeline to complete. */ public void waitForCompletion() { boolean successful; // Wait for completion of all nodes. successful = true; for (TaskManager taskManager : taskManagers) { if (!taskManager.waitForCompletion()) { successful = false; } } if (!successful) { throw new OsmosisRuntimeException("One or more tasks failed."); } } } PipelineConstants.java000066400000000000000000000014411253404521400357760ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.common; /** * Defines constants used by pipeline management. * * @author Brett Henderson */ public final class PipelineConstants { /** * This class cannot be instantiated. */ private PipelineConstants() { } /** * Defines the prefix used for command line input pipe arguments. */ public static final String IN_PIPE_ARGUMENT_PREFIX = "inPipe"; /** * Defines the prefix used for command line output pipe arguments. */ public static final String OUT_PIPE_ARGUMENT_PREFIX = "outPipe"; /** * Defines the prefix for default pipe names used when no pipes are * specified. */ public static final String DEFAULT_PIPE_PREFIX = "default"; } RunnableTaskManager.java000066400000000000000000000023721253404521400362240ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.common; import java.util.Map; import org.openstreetmap.osmosis.core.task.common.RunnableTask; /** * A task manager implementation for RunnableTask task implementations. * * @author Brett Henderson */ public class RunnableTaskManager extends ActiveTaskManager { private RunnableTask task; /** * Creates a new instance. * * @param taskId * A unique identifier for the task. This is used to produce * meaningful errors when errors occur. * @param task * The task instance to be managed. * @param pipeArgs * The arguments defining input and output pipes for the task, * pipes are a logical concept for identifying how the tasks are * connected together. */ public RunnableTaskManager(String taskId, RunnableTask task, Map pipeArgs) { super(taskId, pipeArgs); this.task = task; } /** * {@inheritDoc} */ @Override public void connect(PipeTasks pipeTasks) { // This type of task has no inputs or outputs. } /** * {@inheritDoc} */ @Override protected Runnable getTask() { return task; } } TaskConfiguration.java000066400000000000000000000035421253404521400357720ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.common; import java.util.Collections; import java.util.Map; /** * Contains all information relating to the configuration of a single task. * * @author Brett Henderson */ public class TaskConfiguration { private String id; private String type; private Map pipeArgs; private Map configArgs; private String defaultArg; /** * Creates a new instance. * * @param id The identifier of the task. * @param type The type of the task. * @param pipeArgs The pipe arguments for the task. * @param configArgs The configuration arguments for the task. * @param defaultArg The default argument for the task. */ public TaskConfiguration( String id, String type, Map pipeArgs, Map configArgs, String defaultArg) { this.id = id; this.type = type; this.pipeArgs = Collections.unmodifiableMap(pipeArgs); this.configArgs = Collections.unmodifiableMap(configArgs); this.defaultArg = defaultArg; } /** * The unique identifier for the task. * * @return The id. */ public String getId() { return id; } /** * The type of the task to be created. * * @return The type. */ public String getType() { return type; } /** * The pipeline connection arguments for the task. * * @return The pipeArgs. */ public Map getPipeArgs() { return pipeArgs; } /** * The configuration arguments for the task. * * @return The configArgs. */ public Map getConfigArgs() { return configArgs; } /** * Contains the single default argument (if supplied) to the task. * * @return The defaultArg or null if not available. */ public String getDefaultArg() { return defaultArg; } } TaskManager.java000066400000000000000000000156141253404521400345400ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.common; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.task.common.Task; /** * All task instances within a pipeline are managed by a task manager. This * manager is not responsible for the creation of the task, but it is * responsible for connecting it to its input and output tasks and responsible * for managing the invocation of the task. * * @author Brett Henderson */ public abstract class TaskManager { private String taskId; private Map inputPipeNames; private Map outputPipeNames; /** * Creates a new instance. * * @param taskId * A unique identifier for the task. This is used to produce * meaningful errors when errors occur. * @param pipeArgs * The arguments defining input and output pipes for the task, * pipes are a logical concept for identifying how the tasks are * connected together. */ protected TaskManager(String taskId, Map pipeArgs) { this.taskId = taskId; inputPipeNames = buildPipes(pipeArgs, true); outputPipeNames = buildPipes(pipeArgs, false); } /** * Returns the index of a pipe based upon its suffix. * * @param pipeArgNameSuffix * The suffix of the pipe argument name. * @return The index of the pipe being referred to by the pipe argument. */ private int getPipeIndex(String pipeArgNameSuffix) { int pipeIndex; // If there is no suffix, then it is the default pipe 0. // Otherwise we must check the suffix. if (pipeArgNameSuffix.length() <= 0) { pipeIndex = 0; } else { String indexString; // Validate that the suffix begins with a '.' character. if (pipeArgNameSuffix.indexOf('.') != 0) { throw new OsmosisRuntimeException( "Task " + taskId + " contains a pipe definition without '.' between prefix and suffix." ); } // The remaining suffix must be a number defining the index. indexString = pipeArgNameSuffix.substring(1); // Ensure the index exists. if (indexString.length() <= 0) { throw new OsmosisRuntimeException( "Task " + taskId + " contains a pipe definition without an index after the '.'." ); } // Parse the suffix string into a number. try { pipeIndex = Integer.parseInt(indexString); } catch (NumberFormatException e) { throw new OsmosisRuntimeException("Task " + taskId + " has a pipe with an incorrect index suffix."); } } return pipeIndex; } /** * Builds a list of pipe names keyed by their specified index. * * @param pipeArgs * The task pipe arguments. * @param buildInputPipes * If true will build the list of input pipes, else output pipes. * @return The list of pipe argument values. */ private Map buildPipes(Map pipeArgs, boolean buildInputPipes) { String pipeArgumentPrefix; String pipeType; Map pipes; pipes = new HashMap(); // Setup processing variables based on whether we're building input or // output pipes. if (buildInputPipes) { pipeArgumentPrefix = PipelineConstants.IN_PIPE_ARGUMENT_PREFIX; pipeType = "input"; } else { pipeArgumentPrefix = PipelineConstants.OUT_PIPE_ARGUMENT_PREFIX; pipeType = "output"; } // Iterate through all the pipes searching for the required pipe definitions. for (String pipeArgName : pipeArgs.keySet()) { // It is an input pipe definition if starts with the input pipe prefix. if (pipeArgName.indexOf(pipeArgumentPrefix) == 0) { Integer pipeIndex; pipeIndex = new Integer( getPipeIndex(pipeArgName.substring(pipeArgumentPrefix.length())) ); // Ensure that there aren't two pipes with the same index. if (pipes.containsKey(pipeIndex)) { throw new OsmosisRuntimeException( "Task " + taskId + " has a duplicate " + pipeType + " pipe with index " + pipeIndex + "."); } // The pipe is valid, so add it to the pipe map keyed by its index. pipes.put(pipeIndex, pipeArgs.get(pipeArgName)); } } return pipes; } /** * Finds the specified pipe task, unregisters it from the available tasks * and returns it. * * @param pipeTasks * The currently registered pipe tasks. * @param pipeIndex * The input pipe index for the current task. * @param requiredTaskType * The required type of the input task. * @return The task to be used as input at the specified index. */ protected Task getInputTask(PipeTasks pipeTasks, int pipeIndex, Class requiredTaskType) { Task inputTask; Integer pipeIndexO = new Integer(pipeIndex); // We use the specified pipe name if it exists, otherwise we get the // next available default pipe. if (inputPipeNames.containsKey(pipeIndexO)) { inputTask = pipeTasks.retrieveTask(taskId, inputPipeNames.get(pipeIndexO), requiredTaskType); } else { inputTask = pipeTasks.retrieveTask(taskId, requiredTaskType); } return inputTask; } /** * Registers the specified task as an output. * * @param pipeTasks * The currently registered pipe tasks. * @param outputTask * The task to be registered. * @param pipeIndex * The index of the pipe on the current task. */ protected void setOutputTask(PipeTasks pipeTasks, Task outputTask, int pipeIndex) { Integer pipeIndexO = new Integer(pipeIndex); // We use the specified pipe name if it exists, otherwise we register // using the next available default pipe name. if (outputPipeNames.containsKey(pipeIndexO)) { pipeTasks.putTask(taskId, outputPipeNames.get(pipeIndexO), outputTask); } else { pipeTasks.putTask(taskId, outputTask); } } /** * @return The taskId. */ protected String getTaskId() { return taskId; } /** * Connects the task to any input tasks based upon the pipes created by * source tasks, and makes any output pipes available to be used by * subsequent sink tasks. * * @param pipeTasks * The currently registered pipe tasks. This will be modified to * remove any consumed inputs, and modified to add new outputs. */ public abstract void connect(PipeTasks pipeTasks); /** * Begins execution of the task. For many sink tasks, this will not do * anything. Source tasks are likely to begin execution within a new thread. */ public abstract void execute(); /** * Waits until all tasks have completed execution before returning. This is * intended for source tasks that run within a separate thread, sink tasks * will not do anything here. * * @return True if the thread completed successfully. */ public abstract boolean waitForCompletion(); } TaskManagerFactory.java000066400000000000000000000305001253404521400360570ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.common; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashSet; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.TimeZone; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * All task implementations require a corresponding task manager factory. This * task manager factory is responsible for instantiating a task based upon * command line arguments, and instantiating a task manager to manage the task * within a pipeline. The factories are singleton instances registered globally * and re-used for every task to be created. * * @author Brett Henderson */ public abstract class TaskManagerFactory { private static final String DATE_FORMAT = "yyyy-MM-dd_HH:mm:ss"; private static final Locale DATE_LOCALE = Locale.US; /** * This stores the task options that have been accessed during task * configuration. Any unused options are typically misspelt options that * should raise an error. Minor overkill but this is stored as a thread * local to ensure multiple threads can access a factory safely. */ private ThreadLocal> accessedTaskOptions; /** * Creates a new instance. */ protected TaskManagerFactory() { accessedTaskOptions = new ThreadLocal>(); } /** * Create a new task manager containing a task instance. * * @param taskConfig * Contains all information required to instantiate and configure * the task. * @return The newly created task manager. */ public TaskManager createTaskManager(TaskConfiguration taskConfig) { TaskManager taskManager; // Create a new accessed task options store. accessedTaskOptions.set(new HashSet()); taskManager = createTaskManagerImpl(taskConfig); for (String argName : taskConfig.getConfigArgs().keySet()) { if (!accessedTaskOptions.get().contains(argName)) { throw new OsmosisRuntimeException( "Argument " + argName + " for task " + taskConfig.getId() + " was not recognised."); } } // Clear the accessed task options. accessedTaskOptions.set(null); return taskManager; } /** * Create a new task manager containing a task instance. * * @param taskConfig * Contains all information required to instantiate and configure * the task. * @return The newly created task manager. */ protected abstract TaskManager createTaskManagerImpl(TaskConfiguration taskConfig); /** * Checks if the specified argument has been supplied. * * @param taskConfig * Contains all information required to instantiate and configure * the task. * @param argName * The name of the argument. * @return True if the argument has been supplied. */ protected boolean doesArgumentExist(TaskConfiguration taskConfig, String argName) { return taskConfig.getConfigArgs().containsKey(argName); } /** * Utility method for retrieving the default argument for the task as a String. * * @param taskConfig * Contains all information required to instantiate and configure * the task. * @param defaultValue * The default value of the argument if not value is available. * @return The value of the argument. */ protected String getDefaultStringArgument(TaskConfiguration taskConfig, String defaultValue) { if (taskConfig.getDefaultArg() != null) { return taskConfig.getDefaultArg(); } else { return defaultValue; } } /** * Utility method for retrieving a String argument value from a Map of task * arguments. * * @param taskConfig * Contains all information required to instantiate and configure * the task. * @param argName * The name of the argument. * @return The value of the argument. */ protected String getStringArgument(TaskConfiguration taskConfig, String argName) { Map configArgs; accessedTaskOptions.get().add(argName); configArgs = taskConfig.getConfigArgs(); if (configArgs.containsKey(argName)) { return configArgs.get(argName); } else { throw new OsmosisRuntimeException( "Argument " + argName + " for task " + taskConfig.getId() + " does not exist."); } } /** * Utility method for retrieving a String argument value from a Map of task * arguments. * * @param taskConfig * Contains all information required to instantiate and configure * the task. * @param argName * The name of the argument. * @param defaultValue * The default value of the argument if not value is available. * @return The value of the argument. */ protected String getStringArgument(TaskConfiguration taskConfig, String argName, String defaultValue) { Map configArgs; accessedTaskOptions.get().add(argName); configArgs = taskConfig.getConfigArgs(); if (configArgs.containsKey(argName)) { return configArgs.get(argName); } else { return defaultValue; } } /** * Utility method for retrieving the default argument for the task as an integer. * * @param taskConfig * Contains all information required to instantiate and configure * the task. * @param defaultValue * The default value of the argument if not value is available. * @return The value of the argument. */ protected int getDefaultIntegerArgument(TaskConfiguration taskConfig, int defaultValue) { String defaultArg; defaultArg = taskConfig.getDefaultArg(); if (defaultArg != null) { try { return Integer.parseInt(defaultArg); } catch (NumberFormatException e) { throw new OsmosisRuntimeException( "Default argument for task " + taskConfig.getId() + " must be an integer number.", e); } } else { return defaultValue; } } /** * Utility method for retrieving an integer argument value from a Map of * task arguments. * * @param taskConfig * Contains all information required to instantiate and configure * the task. * @param argName * The name of the argument. * @return The value of the argument. */ protected int getIntegerArgument(TaskConfiguration taskConfig, String argName) { Map configArgs; accessedTaskOptions.get().add(argName); configArgs = taskConfig.getConfigArgs(); if (configArgs.containsKey(argName)) { try { return Integer.parseInt(configArgs.get(argName)); } catch (NumberFormatException e) { throw new OsmosisRuntimeException( "Argument " + argName + " for task " + taskConfig.getId() + " must be an integer number.", e); } } else { throw new OsmosisRuntimeException( "Argument " + argName + " for task " + taskConfig.getId() + " does not exist." ); } } /** * Utility method for retrieving an integer argument value from a Map of * task arguments. * * @param taskConfig * Contains all information required to instantiate and configure * the task. * @param argName * The name of the argument. * @param defaultValue * The default value of the argument if not value is available. * @return The value of the argument. */ protected int getIntegerArgument(TaskConfiguration taskConfig, String argName, int defaultValue) { Map configArgs; accessedTaskOptions.get().add(argName); configArgs = taskConfig.getConfigArgs(); if (configArgs.containsKey(argName)) { try { return Integer.parseInt(configArgs.get(argName)); } catch (NumberFormatException e) { throw new OsmosisRuntimeException( "Argument " + argName + " for task " + taskConfig.getId() + " must be an integer number.", e); } } else { return defaultValue; } } /** * Utility method for retrieving a double argument value from a Map of task * arguments. * * @param taskConfig * Contains all information required to instantiate and configure * the task. * @param argName * The name of the argument. * @param defaultValue * The default value of the argument if not value is available. * @return The value of the argument. */ protected double getDoubleArgument(TaskConfiguration taskConfig, String argName, double defaultValue) { Map configArgs; accessedTaskOptions.get().add(argName); configArgs = taskConfig.getConfigArgs(); if (configArgs.containsKey(argName)) { try { return Double.parseDouble(configArgs.get(argName)); } catch (NumberFormatException e) { throw new OsmosisRuntimeException( "Argument " + argName + " for task " + taskConfig.getId() + " must be a decimal number.", e); } } else { return defaultValue; } } /** * Utility method for retrieving a date argument value from a Map of task * arguments. * * @param taskConfig * Contains all information required to instantiate and configure * the task. * @param argName * The name of the argument. * @param defaultValue * The default value of the argument if not value is available. * @return The value of the argument. */ protected Date getDateArgument(TaskConfiguration taskConfig, String argName, Date defaultValue) { Map configArgs; accessedTaskOptions.get().add(argName); configArgs = taskConfig.getConfigArgs(); if (configArgs.containsKey(argName)) { try { SimpleDateFormat dateFormat; dateFormat = new SimpleDateFormat(DATE_FORMAT, DATE_LOCALE); return dateFormat.parse(configArgs.get(argName)); } catch (ParseException e) { throw new OsmosisRuntimeException( "Argument " + argName + " for task " + taskConfig.getId() + " must be a date in format " + DATE_FORMAT + ".", e); } } else { return defaultValue; } } /** * Utility method for retrieving a date argument value from a Map of task * arguments. * * @param taskConfig * Contains all information required to instantiate and configure * the task. * @param argName * The name of the argument. * @param timeZone * The time zone to parse the date in. * @return The value of the argument. */ protected Date getDateArgument(TaskConfiguration taskConfig, String argName, TimeZone timeZone) { Map configArgs; accessedTaskOptions.get().add(argName); configArgs = taskConfig.getConfigArgs(); if (configArgs.containsKey(argName)) { try { SimpleDateFormat dateFormat; dateFormat = new SimpleDateFormat(DATE_FORMAT, DATE_LOCALE); dateFormat.setTimeZone(timeZone); return dateFormat.parse(configArgs.get(argName)); } catch (ParseException e) { throw new OsmosisRuntimeException( "Argument " + argName + " for task " + taskConfig.getId() + " must be a date in format " + DATE_FORMAT + ".", e); } } else { throw new OsmosisRuntimeException("Argument " + argName + " for task " + taskConfig.getId() + " does not exist."); } } /** * Utility method for retrieving a boolean argument value from a Map of task * arguments. * * @param taskConfig * Contains all information required to instantiate and configure * the task. * @param argName * The name of the argument. * @param defaultValue * The default value of the argument if not value is available. * @return The value of the argument. */ protected boolean getBooleanArgument(TaskConfiguration taskConfig, String argName, boolean defaultValue) { Map configArgs; accessedTaskOptions.get().add(argName); configArgs = taskConfig.getConfigArgs(); if (configArgs.containsKey(argName)) { String rawValue; rawValue = configArgs.get(argName).toLowerCase(); if ("true".equals(rawValue) || "yes".equals(rawValue)) { return true; } else if ("false".equals(rawValue) || "no".equals(rawValue)) { return false; } else { throw new OsmosisRuntimeException( "Argument " + argName + " for task " + taskConfig.getId() + " must be one of yes, no, true or false."); } } else { return defaultValue; } } } TaskManagerFactoryRegister.java000066400000000000000000000031771253404521400375760ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.common; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Maintains the set of task manager factories each identified by one or more * unique names. This allows a pipeline to be configured dynamically such as * from a user provided command line. * * @author Brett Henderson */ public class TaskManagerFactoryRegister { /** * The global register of task manager factories, keyed by a unique * identifier. */ private Map factoryMap; /** * Creates a new instance. */ public TaskManagerFactoryRegister() { factoryMap = new HashMap(); } /** * Registers a new factory. * * @param taskType * The name the factory is identified by. * @param factory * The factory to be registered. */ public void register(String taskType, TaskManagerFactory factory) { if (factoryMap.containsKey(taskType)) { throw new OsmosisRuntimeException("Task type \"" + taskType + "\" already exists."); } factoryMap.put(taskType, factory); } /** * Get a task manager factory from the register. * * @param taskType * The type of task requiring a factory. * @return The factory instance. */ public TaskManagerFactory getInstance(String taskType) { if (!factoryMap.containsKey(taskType)) { throw new OsmosisRuntimeException("Task type " + taskType + " doesn't exist."); } return factoryMap.get(taskType); } } TaskRunner.java000066400000000000000000000027441253404521400344370ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.common; /** * A thread implementation for launching a runnable task. * * @author Brett Henderson */ public class TaskRunner extends Thread { /** * Becomes false if an uncaught exception occurs within the task * implementation. */ private boolean successful; /** * Contains the uncaught exception (if any) that has occurred within the * task implementation. */ private Throwable exception; /** * Creates a new instance. * * @param task * The task to be executed. * @param name * The name of the thread. */ public TaskRunner(Runnable task, String name) { super(task, name); successful = true; // Set an exception handler to capture the details of any failure. setUncaughtExceptionHandler( new UncaughtExceptionHandler() { @SuppressWarnings("synthetic-access") public void uncaughtException(Thread t, Throwable e) { successful = false; exception = e; } } ); } /** * This can be called after the thread has completed to determine if the * thread terminated normally. * * @return True if the thread terminated normally. */ public boolean isSuccessful() { return successful; } /** * Returns the reason for abnormal termination. * * @return The exception causing the failure. */ public Throwable getException() { return exception; } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/v0_6/000077500000000000000000000000001253404521400310325ustar00rootroot00000000000000ChangeSinkChangeSourceManager.java000066400000000000000000000034661253404521400374230ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.PassiveTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.PipeTasks; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSinkChangeSource; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSource; /** * A task manager implementation for task performing change sink and change * source functionality. * * @author Brett Henderson */ public class ChangeSinkChangeSourceManager extends PassiveTaskManager { private ChangeSinkChangeSource task; /** * Creates a new instance. * * @param taskId * A unique identifier for the task. This is used to produce * meaningful errors when errors occur. * @param task * The task instance to be managed. * @param pipeArgs * The arguments defining input and output pipes for the task, * pipes are a logical concept for identifying how the tasks are * connected together. */ public ChangeSinkChangeSourceManager(String taskId, ChangeSinkChangeSource task, Map pipeArgs) { super(taskId, pipeArgs); this.task = task; } /** * {@inheritDoc} */ @Override public void connect(PipeTasks pipeTasks) { ChangeSource source; // Get the input task. A sink only has one input, this corresponds to // pipe index 0. source = (ChangeSource) getInputTask(pipeTasks, 0, ChangeSource.class); // Cast the input feed to the correct type. // Connect the tasks. source.setChangeSink(task); // Register the task as an output. A source only has one output, this // corresponds to pipe index 0. setOutputTask(pipeTasks, task, 0); } } ChangeSinkManager.java000066400000000000000000000031111253404521400351170ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.PassiveTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.PipeTasks; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSource; /** * A task manager implementation for ChangeSink task implementations. * * @author Brett Henderson */ public class ChangeSinkManager extends PassiveTaskManager { private ChangeSink task; /** * Creates a new instance. * * @param taskId * A unique identifier for the task. This is used to produce * meaningful errors when errors occur. * @param task * The task instance to be managed. * @param pipeArgs * The arguments defining input and output pipes for the task, * pipes are a logical concept for identifying how the tasks are * connected together. */ public ChangeSinkManager(String taskId, ChangeSink task, Map pipeArgs) { super(taskId, pipeArgs); this.task = task; } /** * {@inheritDoc} */ @Override public void connect(PipeTasks pipeTasks) { ChangeSource source; // Get the input task. A sink only has one input, this corresponds to // pipe index 0. source = (ChangeSource) getInputTask(pipeTasks, 0, ChangeSource.class); // Cast the input feed to the correct type. // Connect the tasks. source.setChangeSink(task); } } ChangeSinkMultiChangeSourceManager.java000066400000000000000000000036751253404521400404400ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.PassiveTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.PipeTasks; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSinkMultiChangeSource; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSource; /** * A task manager implementation for task performing change sink and multi * change source functionality. * * @author Brett Henderson */ public class ChangeSinkMultiChangeSourceManager extends PassiveTaskManager { private ChangeSinkMultiChangeSource task; /** * Creates a new instance. * * @param taskId * A unique identifier for the task. This is used to produce * meaningful errors when errors occur. * @param task * The task instance to be managed. * @param pipeArgs * The arguments defining input and output pipes for the task, * pipes are a logical concept for identifying how the tasks are * connected together. */ public ChangeSinkMultiChangeSourceManager( String taskId, ChangeSinkMultiChangeSource task, Map pipeArgs) { super(taskId, pipeArgs); this.task = task; } /** * {@inheritDoc} */ @Override public void connect(PipeTasks pipeTasks) { ChangeSource source; int taskSourceCount; // Get the input task. A sink only has one input, this corresponds to // pipe index 0. source = (ChangeSource) getInputTask(pipeTasks, 0, ChangeSource.class); // Cast the input feed to the correct type. // Connect the tasks. source.setChangeSink(task); // Register all the sources provided by this task as outputs. taskSourceCount = task.getChangeSourceCount(); for (int i = 0; i < taskSourceCount; i++) { setOutputTask(pipeTasks, task.getChangeSource(i), i); } } } ChangeSinkRunnableChangeSourceManager.java000066400000000000000000000036031253404521400411030ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.ActiveTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.PipeTasks; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSinkRunnableChangeSource; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSource; /** * A task manager implementation for ChangeSinkRunnableChangeSource task implementations. * * @author Brett Henderson */ public class ChangeSinkRunnableChangeSourceManager extends ActiveTaskManager { private ChangeSinkRunnableChangeSource task; /** * Creates a new instance. * * @param taskId * A unique identifier for the task. This is used to produce * meaningful errors when errors occur. * @param task * The task instance to be managed. * @param pipeArgs * The arguments defining input and output pipes for the task, * pipes are a logical concept for identifying how the tasks are * connected together. */ public ChangeSinkRunnableChangeSourceManager(String taskId, ChangeSinkRunnableChangeSource task, Map pipeArgs) { super(taskId, pipeArgs); this.task = task; } /** * {@inheritDoc} */ @Override public void connect(PipeTasks pipeTasks) { ChangeSource source; // Get the input task. A sink only has one input, this corresponds to // pipe index 0. source = (ChangeSource) getInputTask(pipeTasks, 0, ChangeSource.class); // Connect the tasks. source.setChangeSink(task); // Register the task as an output. A source only has one output, this // corresponds to pipe index 0. setOutputTask(pipeTasks, task, 0); } /** * {@inheritDoc} */ @Override protected Runnable getTask() { return task; } } ChangeSinkSourceManager.java000066400000000000000000000034061253404521400363070ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.PassiveTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.PipeTasks; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSinkSource; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSource; /** * A task manager implementation for task performing change sink and source * functionality. * * @author Brett Henderson */ public class ChangeSinkSourceManager extends PassiveTaskManager { private ChangeSinkSource task; /** * Creates a new instance. * * @param taskId * A unique identifier for the task. This is used to produce * meaningful errors when errors occur. * @param task * The task instance to be managed. * @param pipeArgs * The arguments defining input and output pipes for the task, * pipes are a logical concept for identifying how the tasks are * connected together. */ public ChangeSinkSourceManager(String taskId, ChangeSinkSource task, Map pipeArgs) { super(taskId, pipeArgs); this.task = task; } /** * {@inheritDoc} */ @Override public void connect(PipeTasks pipeTasks) { ChangeSource source; // Get the input task. A sink only has one input, this corresponds to // pipe index 0. source = (ChangeSource) getInputTask(pipeTasks, 0, ChangeSource.class); // Cast the input feed to the correct type. // Connect the tasks. source.setChangeSink(task); // Register the task as an output. A source only has one output, this // corresponds to pipe index 0. setOutputTask(pipeTasks, task, 0); } } DatasetSinkManager.java000066400000000000000000000030421253404521400353220ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.PassiveTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.PipeTasks; import org.openstreetmap.osmosis.core.task.v0_6.DatasetSink; import org.openstreetmap.osmosis.core.task.v0_6.DatasetSource; /** * A task manager implementation for task performing dataset sink. * * @author Brett Henderson */ public class DatasetSinkManager extends PassiveTaskManager { private DatasetSink task; /** * Creates a new instance. * * @param taskId * A unique identifier for the task. This is used to produce * meaningful errors when errors occur. * @param task * The task instance to be managed. * @param pipeArgs * The arguments defining input and output pipes for the task, * pipes are a logical concept for identifying how the tasks are * connected together. */ public DatasetSinkManager(String taskId, DatasetSink task, Map pipeArgs) { super(taskId, pipeArgs); this.task = task; } /** * {@inheritDoc} */ @Override public void connect(PipeTasks pipeTasks) { DatasetSource source; // Get the input task. A sink only has one input, this corresponds to // pipe index 0. source = (DatasetSource) getInputTask(pipeTasks, 0, DatasetSource.class); // Connect the tasks. source.setDatasetSink(task); } } DatasetSinkSourceManager.java000066400000000000000000000034341253404521400365100ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.PassiveTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.PipeTasks; import org.openstreetmap.osmosis.core.task.v0_6.DatasetSinkSource; import org.openstreetmap.osmosis.core.task.v0_6.DatasetSource; /** * A task manager implementation for task performing dataset sink and source * functionality. * * @author Brett Henderson */ public class DatasetSinkSourceManager extends PassiveTaskManager { private DatasetSinkSource task; /** * Creates a new instance. * * @param taskId * A unique identifier for the task. This is used to produce * meaningful errors when errors occur. * @param task * The task instance to be managed. * @param pipeArgs * The arguments defining input and output pipes for the task, * pipes are a logical concept for identifying how the tasks are * connected together. */ public DatasetSinkSourceManager(String taskId, DatasetSinkSource task, Map pipeArgs) { super(taskId, pipeArgs); this.task = task; } /** * {@inheritDoc} */ @Override public void connect(PipeTasks pipeTasks) { DatasetSource source; // Get the input task. A sink only has one input, this corresponds to // pipe index 0. source = (DatasetSource) getInputTask(pipeTasks, 0, DatasetSource.class); // Cast the input feed to the correct type. // Connect the tasks. source.setDatasetSink(task); // Register the task as an output. A source only has one output, this // corresponds to pipe index 0. setOutputTask(pipeTasks, task, 0); } } MultiChangeSinkRunnableChangeSourceManager.java000066400000000000000000000041461253404521400421210ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.ActiveTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.PipeTasks; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSource; import org.openstreetmap.osmosis.core.task.v0_6.MultiChangeSinkRunnableChangeSource; /** * A task manager implementation for MultiChangeSinkRunnableChangeSource task implementations. * * @author Brett Henderson */ public class MultiChangeSinkRunnableChangeSourceManager extends ActiveTaskManager { private MultiChangeSinkRunnableChangeSource task; /** * Creates a new instance. * * @param taskId * A unique identifier for the task. This is used to produce * meaningful errors when errors occur. * @param task * The task instance to be managed. * @param pipeArgs * The arguments defining input and output pipes for the task, * pipes are a logical concept for identifying how the tasks are * connected together. */ public MultiChangeSinkRunnableChangeSourceManager( String taskId, MultiChangeSinkRunnableChangeSource task, Map pipeArgs) { super(taskId, pipeArgs); this.task = task; } /** * {@inheritDoc} */ @Override public void connect(PipeTasks pipeTasks) { // A multi sink receives multiple streams of data, so we must connect // them up one by one. for (int i = 0; i < task.getChangeSinkCount(); i++) { ChangeSink sink; ChangeSource source; // Retrieve the next sink. sink = task.getChangeSink(i); // Retrieve the appropriate source. source = (ChangeSource) getInputTask(pipeTasks, i, ChangeSource.class); // Connect the tasks. source.setChangeSink(sink); } // Register the source as an output task. setOutputTask(pipeTasks, task, 0); } /** * {@inheritDoc} */ @Override protected Runnable getTask() { return task; } } MultiSinkMultiChangeSinkRunnableSourceManager.java000066400000000000000000000052401253404521400426470ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.ActiveTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.PipeTasks; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSource; import org.openstreetmap.osmosis.core.task.v0_6.MultiSinkMultiChangeSinkRunnableSource; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.task.v0_6.Source; /** * A task manager implementation for SinkChangeSinkSource task implementations. * * @author Brett Henderson */ public class MultiSinkMultiChangeSinkRunnableSourceManager extends ActiveTaskManager { private MultiSinkMultiChangeSinkRunnableSource task; /** * Creates a new instance. * * @param taskId * A unique identifier for the task. This is used to produce * meaningful errors when errors occur. * @param task * The task instance to be managed. * @param pipeArgs * The arguments defining input and output pipes for the task, * pipes are a logical concept for identifying how the tasks are * connected together. */ public MultiSinkMultiChangeSinkRunnableSourceManager( String taskId, MultiSinkMultiChangeSinkRunnableSource task, Map pipeArgs) { super(taskId, pipeArgs); this.task = task; } /** * {@inheritDoc} */ @Override public void connect(PipeTasks pipeTasks) { // A multi sink receives multiple streams of data, so we must connect // them up one by one. In this case we will connect the sinks and then // the change sinks. for (int i = 0; i < task.getSinkCount(); i++) { Sink sink; Source source; // Retrieve the next sink. sink = task.getSink(i); // Retrieve the appropriate source. source = (Source) getInputTask(pipeTasks, i, Source.class); // Connect the tasks. source.setSink(sink); } for (int i = 0; i < task.getChangeSinkCount(); i++) { ChangeSink changeSink; ChangeSource changeSource; // Retrieve the next sink. changeSink = task.getChangeSink(i); // Retrieve the appropriate source. changeSource = (ChangeSource) getInputTask( pipeTasks, i + task.getSinkCount(), ChangeSource.class ); // Connect the tasks. changeSource.setChangeSink(changeSink); } // Register the change source as an output task. setOutputTask(pipeTasks, task, 0); } /** * {@inheritDoc} */ @Override protected Runnable getTask() { return task; } } MultiSinkRunnableChangeSourceManager.java000066400000000000000000000040231253404521400410050ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.ActiveTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.PipeTasks; import org.openstreetmap.osmosis.core.task.v0_6.MultiSinkRunnableChangeSource; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.task.v0_6.Source; /** * A task manager implementation for MultiSinkRunnableChangeSource task implementations. * * @author Brett Henderson */ public class MultiSinkRunnableChangeSourceManager extends ActiveTaskManager { private MultiSinkRunnableChangeSource task; /** * Creates a new instance. * * @param taskId * A unique identifier for the task. This is used to produce * meaningful errors when errors occur. * @param task * The task instance to be managed. * @param pipeArgs * The arguments defining input and output pipes for the task, * pipes are a logical concept for identifying how the tasks are * connected together. */ public MultiSinkRunnableChangeSourceManager( String taskId, MultiSinkRunnableChangeSource task, Map pipeArgs) { super(taskId, pipeArgs); this.task = task; } /** * {@inheritDoc} */ @Override public void connect(PipeTasks pipeTasks) { // A multi sink receives multiple streams of data, so we must connect // them up one by one. for (int i = 0; i < task.getSinkCount(); i++) { Sink sink; Source source; // Retrieve the next sink. sink = task.getSink(i); // Retrieve the appropriate source. source = (Source) getInputTask(pipeTasks, i, Source.class); // Connect the tasks. source.setSink(sink); } // Register the change source as an output task. setOutputTask(pipeTasks, task, 0); } /** * {@inheritDoc} */ @Override protected Runnable getTask() { return task; } } MultiSinkRunnableSourceManager.java000066400000000000000000000037441253404521400377100ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.ActiveTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.PipeTasks; import org.openstreetmap.osmosis.core.task.v0_6.MultiSinkRunnableSource; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.task.v0_6.Source; /** * A task manager implementation for MultiSinkRunnableSource task implementations. * * @author Brett Henderson */ public class MultiSinkRunnableSourceManager extends ActiveTaskManager { private MultiSinkRunnableSource task; /** * Creates a new instance. * * @param taskId * A unique identifier for the task. This is used to produce * meaningful errors when errors occur. * @param task * The task instance to be managed. * @param pipeArgs * The arguments defining input and output pipes for the task, * pipes are a logical concept for identifying how the tasks are * connected together. */ public MultiSinkRunnableSourceManager(String taskId, MultiSinkRunnableSource task, Map pipeArgs) { super(taskId, pipeArgs); this.task = task; } /** * {@inheritDoc} */ @Override public void connect(PipeTasks pipeTasks) { // A multi sink receives multiple streams of data, so we must connect // them up one by one. for (int i = 0; i < task.getSinkCount(); i++) { Sink sink; Source source; // Retrieve the next sink. sink = task.getSink(i); // Retrieve the appropriate source. source = (Source) getInputTask(pipeTasks, i, Source.class); // Connect the tasks. source.setSink(sink); } // Register the source as an output task. setOutputTask(pipeTasks, task, 0); } /** * {@inheritDoc} */ @Override protected Runnable getTask() { return task; } } RunnableChangeSourceManager.java000066400000000000000000000030161253404521400371460ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.ActiveTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.PipeTasks; import org.openstreetmap.osmosis.core.task.v0_6.RunnableChangeSource; /** * A task manager implementation for RunnableChangeSource task implementations. * * @author Brett Henderson */ public class RunnableChangeSourceManager extends ActiveTaskManager { private RunnableChangeSource task; /** * Creates a new instance. * * @param taskId * A unique identifier for the task. This is used to produce * meaningful errors when errors occur. * @param task * The task instance to be managed. * @param pipeArgs * The arguments defining input and output pipes for the task, * pipes are a logical concept for identifying how the tasks are * connected together. */ public RunnableChangeSourceManager(String taskId, RunnableChangeSource task, Map pipeArgs) { super(taskId, pipeArgs); this.task = task; } /** * {@inheritDoc} */ @Override public void connect(PipeTasks pipeTasks) { // Register the task as an output. A source only has one output, this // corresponds to pipe index 0. setOutputTask(pipeTasks, task, 0); } /** * {@inheritDoc} */ @Override protected Runnable getTask() { return task; } } RunnableDatasetSourceManager.java000066400000000000000000000030241253404521400373450ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.ActiveTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.PipeTasks; import org.openstreetmap.osmosis.core.task.v0_6.RunnableDatasetSource; /** * A task manager implementation for RunnableDatasetSource task implementations. * * @author Brett Henderson */ public class RunnableDatasetSourceManager extends ActiveTaskManager { private RunnableDatasetSource task; /** * Creates a new instance. * * @param taskId * A unique identifier for the task. This is used to produce * meaningful errors when errors occur. * @param task * The task instance to be managed. * @param pipeArgs * The arguments defining input and output pipes for the task, * pipes are a logical concept for identifying how the tasks are * connected together. */ public RunnableDatasetSourceManager(String taskId, RunnableDatasetSource task, Map pipeArgs) { super(taskId, pipeArgs); this.task = task; } /** * {@inheritDoc} */ @Override public void connect(PipeTasks pipeTasks) { // Register the task as an output. A source only has one output, this // corresponds to pipe index 0. setOutputTask(pipeTasks, task, 0); } /** * {@inheritDoc} */ @Override protected Runnable getTask() { return task; } } RunnableSourceManager.java000066400000000000000000000027521253404521400360460ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.ActiveTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.PipeTasks; import org.openstreetmap.osmosis.core.task.v0_6.RunnableSource; /** * A task manager implementation for RunnableSource task implementations. * * @author Brett Henderson */ public class RunnableSourceManager extends ActiveTaskManager { private RunnableSource task; /** * Creates a new instance. * * @param taskId * A unique identifier for the task. This is used to produce * meaningful errors when errors occur. * @param task * The task instance to be managed. * @param pipeArgs * The arguments defining input and output pipes for the task, * pipes are a logical concept for identifying how the tasks are * connected together. */ public RunnableSourceManager(String taskId, RunnableSource task, Map pipeArgs) { super(taskId, pipeArgs); this.task = task; } /** * {@inheritDoc} */ @Override public void connect(PipeTasks pipeTasks) { // Register the task as an output. A source only has one output, this // corresponds to pipe index 0. setOutputTask(pipeTasks, task, 0); } /** * {@inheritDoc} */ @Override protected Runnable getTask() { return task; } } SinkDatasetSourceManager.java000066400000000000000000000033711253404521400365100ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.PassiveTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.PipeTasks; import org.openstreetmap.osmosis.core.task.v0_6.SinkDatasetSource; import org.openstreetmap.osmosis.core.task.v0_6.Source; /** * A task manager implementation for task performing sink and dataset source * functionality. * * @author Brett Henderson */ public class SinkDatasetSourceManager extends PassiveTaskManager { private SinkDatasetSource task; /** * Creates a new instance. * * @param taskId * A unique identifier for the task. This is used to produce * meaningful errors when errors occur. * @param task * The task instance to be managed. * @param pipeArgs * The arguments defining input and output pipes for the task, * pipes are a logical concept for identifying how the tasks are * connected together. */ public SinkDatasetSourceManager(String taskId, SinkDatasetSource task, Map pipeArgs) { super(taskId, pipeArgs); this.task = task; } /** * {@inheritDoc} */ @Override public void connect(PipeTasks pipeTasks) { Source source; // Get the input task. A sink only has one input, this corresponds to // pipe index 0. source = (Source) getInputTask(pipeTasks, 0, Source.class); // Cast the input feed to the correct type. // Connect the tasks. source.setSink(task); // Register the task as an output. A source only has one output, this // corresponds to pipe index 0. setOutputTask(pipeTasks, task, 0); } } SinkManager.java000066400000000000000000000030071253404521400340150ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.PassiveTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.PipeTasks; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.task.v0_6.Source; /** * A task manager implementation for Sink task implementations. * * @author Brett Henderson */ public class SinkManager extends PassiveTaskManager { private Sink task; /** * Creates a new instance. * * @param taskId * A unique identifier for the task. This is used to produce * meaningful errors when errors occur. * @param task * The task instance to be managed. * @param pipeArgs * The arguments defining input and output pipes for the task, * pipes are a logical concept for identifying how the tasks are * connected together. */ public SinkManager(String taskId, Sink task, Map pipeArgs) { super(taskId, pipeArgs); this.task = task; } /** * {@inheritDoc} */ @Override public void connect(PipeTasks pipeTasks) { Source source; // Get the input task. A sink only has one input, this corresponds to // pipe index 0. source = (Source) getInputTask(pipeTasks, 0, Source.class); // Cast the input feed to the correct type. // Connect the tasks. source.setSink(task); } } SinkMultiSourceManager.java000066400000000000000000000035051253404521400362140ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.PassiveTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.PipeTasks; import org.openstreetmap.osmosis.core.task.v0_6.SinkMultiSource; import org.openstreetmap.osmosis.core.task.v0_6.Source; /** * A task manager implementation for task performing sink and multi source * functionality. * * @author Brett Henderson */ public class SinkMultiSourceManager extends PassiveTaskManager { private SinkMultiSource task; /** * Creates a new instance. * * @param taskId * A unique identifier for the task. This is used to produce * meaningful errors when errors occur. * @param task * The task instance to be managed. * @param pipeArgs * The arguments defining input and output pipes for the task, * pipes are a logical concept for identifying how the tasks are * connected together. */ public SinkMultiSourceManager(String taskId, SinkMultiSource task, Map pipeArgs) { super(taskId, pipeArgs); this.task = task; } /** * {@inheritDoc} */ @Override public void connect(PipeTasks pipeTasks) { Source source; int taskSourceCount; // Get the input task. A sink only has one input, this corresponds to // pipe index 0. source = (Source) getInputTask(pipeTasks, 0, Source.class); // Cast the input feed to the correct type. // Connect the tasks. source.setSink(task); // Register all the sources provided by this task as outputs. taskSourceCount = task.getSourceCount(); for (int i = 0; i < taskSourceCount; i++) { setOutputTask(pipeTasks, task.getSource(i), i); } } } SinkRunnableSourceManager.java000066400000000000000000000034351253404521400366720ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.ActiveTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.PipeTasks; import org.openstreetmap.osmosis.core.task.v0_6.SinkRunnableSource; import org.openstreetmap.osmosis.core.task.v0_6.Source; /** * A task manager implementation for SinkRunnableSource task implementations. * * @author Brett Henderson */ public class SinkRunnableSourceManager extends ActiveTaskManager { private SinkRunnableSource task; /** * Creates a new instance. * * @param taskId * A unique identifier for the task. This is used to produce * meaningful errors when errors occur. * @param task * The task instance to be managed. * @param pipeArgs * The arguments defining input and output pipes for the task, * pipes are a logical concept for identifying how the tasks are * connected together. */ public SinkRunnableSourceManager(String taskId, SinkRunnableSource task, Map pipeArgs) { super(taskId, pipeArgs); this.task = task; } /** * {@inheritDoc} */ @Override public void connect(PipeTasks pipeTasks) { Source source; // Get the input task. A sink only has one input, this corresponds to // pipe index 0. source = (Source) getInputTask(pipeTasks, 0, Source.class); // Connect the tasks. source.setSink(task); // Register the task as an output. A source only has one output, this // corresponds to pipe index 0. setOutputTask(pipeTasks, task, 0); } /** * {@inheritDoc} */ @Override protected Runnable getTask() { return task; } } SinkSourceManager.java000066400000000000000000000033161253404521400352010ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/pipeline/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.pipeline.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.PassiveTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.PipeTasks; import org.openstreetmap.osmosis.core.task.v0_6.SinkSource; import org.openstreetmap.osmosis.core.task.v0_6.Source; /** * A task manager implementation for task performing sink and source * functionality. * * @author Brett Henderson */ public class SinkSourceManager extends PassiveTaskManager { private SinkSource task; /** * Creates a new instance. * * @param taskId * A unique identifier for the task. This is used to produce * meaningful errors when errors occur. * @param task * The task instance to be managed. * @param pipeArgs * The arguments defining input and output pipes for the task, * pipes are a logical concept for identifying how the tasks are * connected together. */ public SinkSourceManager(String taskId, SinkSource task, Map pipeArgs) { super(taskId, pipeArgs); this.task = task; } /** * {@inheritDoc} */ @Override public void connect(PipeTasks pipeTasks) { Source source; // Get the input task. A sink only has one input, this corresponds to // pipe index 0. source = (Source) getInputTask(pipeTasks, 0, Source.class); // Cast the input feed to the correct type. // Connect the tasks. source.setSink(task); // Register the task as an output. A source only has one output, this // corresponds to pipe index 0. setOutputTask(pipeTasks, task, 0); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/plugin/000077500000000000000000000000001253404521400277515ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/plugin/CorePlugin.java000066400000000000000000000007401253404521400326640ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.plugin; import org.java.plugin.Plugin; /** * The core plugin entry point. * * @author Marcus Wolschon */ public class CorePlugin extends Plugin { /** * {@inheritDoc} */ @Override protected void doStart() throws Exception { // ignored } /** * {@inheritDoc} */ @Override protected void doStop() throws Exception { // ignored } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/plugin/PluginLoader.java000066400000000000000000000012571253404521400332060ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.plugin; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; /** * Defines the methods required by a plugin loading implementation. The plugin * loader is used to define the tasks provided by a plugin. * * @author Brett Henderson */ public interface PluginLoader { /** * Loads all task factories provided by the plugin and specifies the names * to register them under. * * @return A map between task names and their factory implementations. */ Map loadTaskFactories(); } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/progress/000077500000000000000000000000001253404521400303175ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/progress/v0_6/000077500000000000000000000000001253404521400310715ustar00rootroot00000000000000ChangeProgressLogger.java000066400000000000000000000051251253404521400357320ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/progress/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.progress.v0_6; import java.util.Map; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.progress.v0_6.impl.ProgressTracker; import org.openstreetmap.osmosis.core.task.common.ChangeAction; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSinkChangeSource; /** * Logs progress information using jdk logging at info level at regular intervals. * * @author Brett Henderson */ public class ChangeProgressLogger implements ChangeSinkChangeSource { private static final Logger LOG = Logger.getLogger(ChangeProgressLogger.class.getName()); private ChangeSink changeSink; private ProgressTracker progressTracker; private String prefix; /** * Creates a new instance. * * @param interval * The interval between logging progress reports in milliseconds. * @param label * a label to prefix the logger with; may be null. */ public ChangeProgressLogger(int interval, String label) { progressTracker = new ProgressTracker(interval); if (label != null && !label.equals("")) { prefix = "[" + label + "] "; } else { prefix = ""; } } /** * {@inheritDoc} */ public void initialize(Map metaData) { progressTracker.initialize(); changeSink.initialize(metaData); } /** * {@inheritDoc} */ public void process(ChangeContainer changeContainer) { Entity entity; ChangeAction action; entity = changeContainer.getEntityContainer().getEntity(); action = changeContainer.getAction(); if (progressTracker.updateRequired()) { LOG.info( prefix + "Processing " + entity.getType() + " " + entity.getId() + " with action " + action + ", " + progressTracker.getObjectsPerSecond() + " objects/second."); } changeSink.process(changeContainer); } /** * {@inheritDoc} */ public void complete() { LOG.info("Processing completion steps."); long start = System.currentTimeMillis(); changeSink.complete(); long duration = System.currentTimeMillis() - start; LOG.info("Completion steps took " + duration / 1000d + " seconds."); LOG.info("Processing complete."); } /** * {@inheritDoc} */ public void release() { changeSink.release(); } /** * {@inheritDoc} */ public void setChangeSink(ChangeSink changeSink) { this.changeSink = changeSink; } } ChangeProgressLoggerFactory.java000066400000000000000000000025331253404521400372620ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/progress/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.progress.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.ChangeSinkChangeSourceManager; /** * The task manager factory for a change progress logger. * * @author Brett Henderson */ public class ChangeProgressLoggerFactory extends TaskManagerFactory { private static final String ARG_LOG_INTERVAL = "interval"; private static final int DEFAULT_LOG_INTERVAL = 5; private static final String ARG_LABEL = "label"; private static final String DEFAULT_LABEL = ""; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { ChangeProgressLogger task; int interval; String label; // Get the task arguments. interval = getIntegerArgument(taskConfig, ARG_LOG_INTERVAL, DEFAULT_LOG_INTERVAL); label = getStringArgument(taskConfig, ARG_LABEL, DEFAULT_LABEL); // Build the task object. task = new ChangeProgressLogger(interval * 1000, label); return new ChangeSinkChangeSourceManager(taskConfig.getId(), task, taskConfig.getPipeArgs()); } } EntityProgressLogger.java000066400000000000000000000045031253404521400360200ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/progress/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.progress.v0_6; import java.util.Map; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.progress.v0_6.impl.ProgressTracker; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.task.v0_6.SinkSource; /** * Logs progress information using jdk logging at info level at regular intervals. * * @author Brett Henderson */ public class EntityProgressLogger implements SinkSource { private static final Logger LOG = Logger.getLogger(EntityProgressLogger.class.getName()); private Sink sink; private ProgressTracker progressTracker; private String prefix; /** * Creates a new instance. * * @param interval * The interval between logging progress reports in milliseconds. * @param label * a label to prefix the logger with; may be null. */ public EntityProgressLogger(int interval, String label) { progressTracker = new ProgressTracker(interval); if (label != null && !label.equals("")) { prefix = "[" + label + "] "; } else { prefix = ""; } } /** * {@inheritDoc} */ public void initialize(Map metaData) { progressTracker.initialize(); sink.initialize(metaData); } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { Entity entity; entity = entityContainer.getEntity(); if (progressTracker.updateRequired()) { LOG.info( prefix + "Processing " + entity.getType() + " " + entity.getId() + ", " + progressTracker.getObjectsPerSecond() + " objects/second."); } sink.process(entityContainer); } /** * {@inheritDoc} */ public void complete() { LOG.info("Processing completion steps."); long start = System.currentTimeMillis(); sink.complete(); long duration = System.currentTimeMillis() - start; LOG.info("Completion steps took " + duration / 1000d + " seconds."); LOG.info("Processing complete."); } /** * {@inheritDoc} */ public void release() { sink.release(); } /** * {@inheritDoc} */ public void setSink(Sink sink) { this.sink = sink; } } EntityProgressLoggerFactory.java000066400000000000000000000025061253404521400373510ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/progress/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.progress.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkSourceManager; /** * The task manager factory for an entity progress logger. * * @author Brett Henderson */ public class EntityProgressLoggerFactory extends TaskManagerFactory { private static final String ARG_LOG_INTERVAL = "interval"; private static final int DEFAULT_LOG_INTERVAL = 5; private static final String ARG_LABEL = "label"; private static final String DEFAULT_LABEL = ""; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { EntityProgressLogger task; int interval; String label; // Get the task arguments. interval = getIntegerArgument(taskConfig, ARG_LOG_INTERVAL, DEFAULT_LOG_INTERVAL); label = getStringArgument(taskConfig, ARG_LABEL, DEFAULT_LABEL); // Build the task object. task = new EntityProgressLogger(interval * 1000, label); return new SinkSourceManager(taskConfig.getId(), task, taskConfig.getPipeArgs()); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/progress/v0_6/impl/000077500000000000000000000000001253404521400320325ustar00rootroot00000000000000ProgressTracker.java000066400000000000000000000042501253404521400357370ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/progress/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.progress.v0_6.impl; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Maintains state about execution progress. It calculates when the next update * is due, and provides statistics on execution. * * @author Brett Henderson */ public class ProgressTracker { private int interval; private boolean initialized; private long lastUpdateTimestamp; private long objectCount; private double objectsPerSecond; /** * Creates a new instance. * * @param interval * The interval between logging progress reports in milliseconds. */ public ProgressTracker(int interval) { this.interval = interval; initialized = false; } /** * Initializes interval measurement from now. */ public void initialize() { lastUpdateTimestamp = System.currentTimeMillis(); objectCount = 0; objectsPerSecond = 0; initialized = true; } /** * Indicates if an update is due. This should be called once per object that * is processed. * * @return True if an update is due. */ public boolean updateRequired() { long currentTimestamp; long duration; if (!initialized) { throw new OsmosisRuntimeException("initialize has not been called"); } // Calculate the time since the last update. currentTimestamp = System.currentTimeMillis(); duration = currentTimestamp - lastUpdateTimestamp; // Increment the processed object count. objectCount++; if (duration > interval || duration < 0) { lastUpdateTimestamp = currentTimestamp; // Calculate the number of objects processed per second. objectsPerSecond = (double) objectCount * 1000 / duration; // Reset the object count. objectCount = 0; return true; } else { return false; } } /** * Provides the number of objects processed per second. This only becomes * valid after updateRequired returns true for the first time. * * @return The number of objects processed per second in the last timing * interval. */ public double getObjectsPerSecond() { return objectsPerSecond; } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/report/000077500000000000000000000000001253404521400277665ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/report/v0_6/000077500000000000000000000000001253404521400305405ustar00rootroot00000000000000EntityReporter.java000066400000000000000000000173051253404521400343310ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/report/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.report.v0_6; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; 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 java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityProcessor; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.task.v0_6.Sink; /** * An OSM data sink that analyses the data sent to it and provides a simple * report. * * @author Brett Henderson */ public class EntityReporter implements Sink { private static final int COLUMN_WIDTH_USER_NAME = 50; private static final int COLUMN_WIDTH_NODE_COUNT = 7; private static final int COLUMN_WIDTH_WAY_COUNT = 7; private static final int COLUMN_WIDTH_RELATION_COUNT = 7; private Logger log = Logger.getLogger(EntityReporter.class.getName()); private File file; private FileWriter fileWriter; private Map userMap; private UserStatistics anonymousUser; private UserStatistics totalUser; /** * Creates a new instance. * * @param file * The file to write. */ public EntityReporter(File file) { this.file = file; userMap = new HashMap(); anonymousUser = new UserStatistics("anonymous"); totalUser = new UserStatistics("Total"); } /** * {@inheritDoc} */ public void initialize(Map metaData) { // Do nothing. } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { String userName; final UserStatistics user; // Obtain the user statistics object. userName = entityContainer.getEntity().getUser().getName(); if (userName != null && userName.length() > 0) { if (userMap.containsKey(userName)) { user = userMap.get(userName); } else { user = new UserStatistics(userName); userMap.put(userName, user); } } else { user = anonymousUser; } // Increment the relevant user statistic. entityContainer.process( new EntityProcessor() { private UserStatistics processorUser = user; public void process(BoundContainer bound) { // Do nothing. } public void process(NodeContainer node) { processorUser.incrementNodeCount(); totalUser.incrementNodeCount(); } public void process(WayContainer way) { processorUser.incrementWayCount(); totalUser.incrementWayCount(); } public void process(RelationContainer relation) { processorUser.incrementRelationCount(); totalUser.incrementRelationCount(); } } ); } /** * Writes a single value and pads it out to the correct column width. * * @param writer * The report destination. * @param data * The data to be written. * @param columnWidth * The width of the column. */ private void writeColumnValue(BufferedWriter writer, String data, int columnWidth) throws IOException { int padLength; // Calculate the required data padding. The total column width is the // specified column width plus one space. padLength = columnWidth - data.length() + 1; if (padLength < 1) { padLength = 1; } writer.write(data); for (int i = 0; i < padLength; i++) { writer.write(' '); } } /** * Writes a single line summary of the user statistics. * * @param writer * The report destination. * @param userStatistics * The user to report on. */ private void writeUserLine(BufferedWriter writer, UserStatistics userStatistics) throws IOException { writeColumnValue(writer, userStatistics.getUserName(), COLUMN_WIDTH_USER_NAME); writeColumnValue(writer, Integer.toString(userStatistics.getNodeCount()), COLUMN_WIDTH_NODE_COUNT); writeColumnValue(writer, Integer.toString(userStatistics.getWayCount()), COLUMN_WIDTH_WAY_COUNT); writeColumnValue(writer, Integer.toString(userStatistics.getRelationCount()), COLUMN_WIDTH_RELATION_COUNT); writer.newLine(); } /** * Add user information to the report file. * * @param writer * The report destination. */ private void writeUserReport(BufferedWriter writer) throws IOException { List userList; // Sort the user statistics by user id. userList = new ArrayList(userMap.values()); Collections.sort( userList, new Comparator() { public int compare(UserStatistics o1, UserStatistics o2) { return o1.getUserName().compareTo(o2.getUserName()); } } ); writer.write("********** User Report **********"); writer.newLine(); writeColumnValue(writer, "USER NAME", COLUMN_WIDTH_USER_NAME); writeColumnValue(writer, "NODES", COLUMN_WIDTH_NODE_COUNT); writeColumnValue(writer, "WAYS", COLUMN_WIDTH_WAY_COUNT); writeColumnValue(writer, "RELNS", COLUMN_WIDTH_RELATION_COUNT); writer.newLine(); writeUserLine(writer, anonymousUser); for (UserStatistics userStatistics : userList) { writeUserLine(writer, userStatistics); } writer.newLine(); writeUserLine(writer, totalUser); } /** * Flushes all changes to file. */ public void complete() { try { BufferedWriter writer; fileWriter = new FileWriter(file); writer = new BufferedWriter(fileWriter); // Produce a report on the user statistics. writeUserReport(writer); writer.close(); fileWriter = null; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write report to file " + file + "."); } } /** * Cleans up any open file handles. */ public void release() { if (fileWriter != null) { try { fileWriter.close(); } catch (IOException e) { log.log(Level.SEVERE, "Unable to close file writer for file " + file + ".", e); } finally { fileWriter = null; } } } /** * A class holding the summary information for a single user. */ private static class UserStatistics { private String userName; private int nodeCount; private int wayCount; private int relationCount; /** * Creates a new instance. * * @param userName * The name of the user that this statistics record relates * to. */ public UserStatistics(String userName) { this.userName = userName; } /** * Increments the node count by one. */ public void incrementNodeCount() { nodeCount++; } /** * Increments the way count by one. */ public void incrementWayCount() { wayCount++; } /** * Increments the relation count by one. */ public void incrementRelationCount() { relationCount++; } /** * Returns the name of the user for which this object contains data. * * @return The user name. */ public String getUserName() { return userName; } /** * Returns the node count. * * @return The node count. */ public int getNodeCount() { return nodeCount; } /** * Returns the way count. * * @return The way count. */ public int getWayCount() { return wayCount; } /** * Returns the relation count. * * @return The relation count. */ public int getRelationCount() { return relationCount; } } } EntityReporterFactory.java000066400000000000000000000024141253404521400356540ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/report/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.report.v0_6; import java.io.File; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkManager; /** * The task manager factory for an entity reporter. * * @author Brett Henderson */ public class EntityReporterFactory extends TaskManagerFactory { private static final String ARG_FILE_NAME = "file"; private static final String DEFAULT_FILE_NAME = "entity-report.txt"; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String fileName; File file; EntityReporter task; // Get the task arguments. fileName = getStringArgument( taskConfig, ARG_FILE_NAME, getDefaultStringArgument(taskConfig, DEFAULT_FILE_NAME) ); // Create a file object from the file name provided. file = new File(fileName); // Build the task object. task = new EntityReporter(file); return new SinkManager(taskConfig.getId(), task, taskConfig.getPipeArgs()); } } IntegrityReporter.java000066400000000000000000000133171253404521400350320ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/report/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.report.v0_6; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityProcessor; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.openstreetmap.osmosis.core.filter.common.DynamicIdTracker; import org.openstreetmap.osmosis.core.filter.common.IdTracker; import org.openstreetmap.osmosis.core.task.v0_6.Sink; /** * A sink that verifies the referential integrity of all data passing through * it. * * @author Brett Henderson */ public class IntegrityReporter implements Sink, EntityProcessor { private static final Logger LOG = Logger.getLogger(IntegrityReporter.class.getName()); private File file; private boolean initialized; private BufferedWriter writer; private IdTracker nodeBitSet; private IdTracker wayBitSet; /** * Creates a new instance. * * @param file * The file to write. */ public IntegrityReporter(File file) { this.file = file; initialized = false; nodeBitSet = new DynamicIdTracker(); wayBitSet = new DynamicIdTracker(); } /** * Writes data to the output file. * * @param data * The data to be written. */ private void write(String data) { try { writer.write(data); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write data.", e); } } /** * Writes a new line in the output file. */ private void writeNewLine() { try { writer.newLine(); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write data.", e); } } /** * Initialises the output file for writing. This must be called by * sub-classes before any writing is performed. This method may be called * multiple times without adverse affect allowing sub-classes to invoke it * every time they perform processing. */ protected void initialize() { if (!initialized) { OutputStream outStream = null; try { outStream = new FileOutputStream(file); writer = new BufferedWriter(new OutputStreamWriter(outStream, "UTF-8")); outStream = null; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to open file " + file + " for writing.", e); } finally { if (outStream != null) { try { outStream.close(); } catch (Exception e) { LOG.log(Level.SEVERE, "Unable to close output stream for file " + file + ".", e); } outStream = null; } } initialized = true; write("Entity Type, Entity Id, Referred Type, Referred Id"); writeNewLine(); } } /** * {@inheritDoc} */ public void initialize(Map metaData) { // Do nothing. } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { entityContainer.process(this); } /** * {@inheritDoc} */ public void process(BoundContainer bound) { // Do nothing. } /** * {@inheritDoc} */ public void process(NodeContainer node) { nodeBitSet.set(node.getEntity().getId()); } /** * {@inheritDoc} */ public void process(WayContainer wayContainer) { Way way; way = wayContainer.getEntity(); wayBitSet.set(way.getId()); for (WayNode wayNode : way.getWayNodes()) { if (!nodeBitSet.get(wayNode.getNodeId())) { initialize(); write("Way," + way.getId() + ",Node," + wayNode.getNodeId()); writeNewLine(); } } } /** * {@inheritDoc} */ public void process(RelationContainer relationContainer) { Relation relation; relation = relationContainer.getEntity(); for (RelationMember relationMember : relation.getMembers()) { EntityType memberType; memberType = relationMember.getMemberType(); if (EntityType.Node.equals(memberType)) { if (!nodeBitSet.get(relationMember.getMemberId())) { initialize(); write("Relation," + relation.getId() + ",Node," + relationMember.getMemberId()); writeNewLine(); } } else if (EntityType.Way.equals(memberType)) { if (!wayBitSet.get(relationMember.getMemberId())) { initialize(); write("Relation," + relation.getId() + ",Way," + relationMember.getMemberId()); writeNewLine(); } } } } /** * Flushes all changes to file. */ public void complete() { try { if (writer != null) { writer.close(); } } catch (IOException e) { throw new OsmosisRuntimeException("Unable to complete writing to the file " + file + ".", e); } finally { initialized = false; writer = null; } } /** * Cleans up any open file handles. */ public void release() { try { try { if (writer != null) { writer.close(); } } catch (IOException e) { LOG.log(Level.SEVERE, "Unable to close writer.", e); } } finally { initialized = false; writer = null; } } } IntegrityReporterFactory.java000066400000000000000000000024331253404521400363570ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/report/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.report.v0_6; import java.io.File; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkManager; /** * The task manager factory for an integrity reporter. * * @author Brett Henderson */ public class IntegrityReporterFactory extends TaskManagerFactory { private static final String ARG_FILE_NAME = "file"; private static final String DEFAULT_FILE_NAME = "integrity-report.txt"; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String fileName; File file; IntegrityReporter task; // Get the task arguments. fileName = getStringArgument( taskConfig, ARG_FILE_NAME, getDefaultStringArgument(taskConfig, DEFAULT_FILE_NAME) ); // Create a file object from the file name provided. file = new File(fileName); // Build the task object. task = new IntegrityReporter(file); return new SinkManager(taskConfig.getId(), task, taskConfig.getPipeArgs()); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/000077500000000000000000000000001253404521400274425ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/common/000077500000000000000000000000001253404521400307325ustar00rootroot00000000000000FileBasedSort.java000066400000000000000000000216641253404521400342150ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.common; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import org.openstreetmap.osmosis.core.lifecycle.Releasable; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.store.ChunkedObjectStore; import org.openstreetmap.osmosis.core.store.ObjectSerializationFactory; import org.openstreetmap.osmosis.core.store.PersistentIterator; import org.openstreetmap.osmosis.core.store.Storeable; /** * Allows a large number of objects to be sorted by writing them all to disk * then sorting using a merge sort algorithm. * * @param * The object type to be sorted. * @author Brett Henderson */ public class FileBasedSort implements Releasable { /** * The maximum number of entities to perform memory-based sorting on, * amounts larger than this will be split into chunks of this size, the * chunks sorted in memory before writing to file, and all the results * merged using the merge sort algorithm. */ private static final int MAX_MEMORY_SORT_COUNT = 16384; /** * The maximum number of sources to merge together at a single level of the * merge sort hierarchy. Must be 2 or higher. A standard merge sort is 2. */ private static final int MAX_MERGE_SOURCE_COUNT = 2; /** * The number of levels in the merge sort hierarchy to perform in memory * before persisting to a file. By persisting to file at regular hierarchy * levels, the number of file handles is minimised. File handle count is * likely to be an issue before memory usage due to the small number of * in-flight objects at any point in time. *

* The number of file handles will be MAX_MERGE_SOURCE_COUNT raised to the * power of MAX_MEMORY_SORT_DEPTH. */ private static final int MAX_MEMORY_SORT_DEPTH = 8; private ObjectSerializationFactory serializationFactory; private Comparator comparator; private ChunkedObjectStore chunkedEntityStore; private List addBuffer; private boolean useCompression; /** * Creates a new instance. * * @param serializationFactory * The factory defining the object serialisation implementation. * @param comparator * The comparator to be used for sorting the results. * @param useCompression * If true, the storage files will be compressed. */ public FileBasedSort( ObjectSerializationFactory serializationFactory, Comparator comparator, boolean useCompression) { this.serializationFactory = serializationFactory; this.comparator = comparator; this.useCompression = useCompression; chunkedEntityStore = new ChunkedObjectStore(serializationFactory, "emta", "idx", useCompression); addBuffer = new ArrayList(MAX_MEMORY_SORT_COUNT); } /** * Sorts the data currently in the add buffer, writes it to the object * store, and clears the buffer. */ private void flushAddBuffer() { if (addBuffer.size() >= 0) { // Sort the chunk prior to writing. Collections.sort(addBuffer, comparator); // Write all entities in the buffer to entity storage. for (T entity : addBuffer) { chunkedEntityStore.add(entity); } addBuffer.clear(); // Close the chunk in the underlying data store so that it can be // read separately. chunkedEntityStore.closeChunk(); } } /** * Adds a new object to be sorted. * * @param value * The data object. */ public void add(T value) { // Add the new data entity to the add buffer. addBuffer.add(value); // If the add buffer is full, it must be sorted and written to entity // storage. if (addBuffer.size() >= MAX_MEMORY_SORT_COUNT) { flushAddBuffer(); } } /** * This is a wrapper method around the iterate method with the same argument * list that persists the sort results prior to returning. This forces all * sorting by nested recursive method calls to be performed allowing all * associated memory can be freed. * * @param nestLevel * The current recursive nesting level of the merge sort * operation. * @param beginChunkIndex * The initial chunk to begin sorting from. * @param chunkCount * The number of chunks to sort. * @return An iterator providing access to the sort result. */ private ReleasableIterator iteratePersisted(int nestLevel, long beginChunkIndex, long chunkCount) { ReleasableIterator persistentIterator; // Create a persistent iterator based on the requested underlying chunk // iterator. persistentIterator = new PersistentIterator( serializationFactory, iterate(nestLevel, beginChunkIndex, chunkCount), "emtb", useCompression ); // Prime the persistent iterator so that all underlying iterator data is // written to file. try { ReleasableIterator result; result = persistentIterator; // This will cause all data to be read from the underlying iterator // into the persistent store. persistentIterator.hasNext(); persistentIterator = null; return result; } finally { // This will release the persistent iterator and its underlying // source iterator if the persistence operations failed. if (persistentIterator != null) { persistentIterator.release(); } } } /** * Sorts the specified sub-section of the overall storage contents. This * result list is not backed by a file and should be persisted prior to * being incorporated into a higher level merge operation. * * @param nestLevel * The current recursive nesting level of the merge sort * operation. * @param beginChunkIndex * The initial chunk to begin sorting from. * @param chunkCount * The number of chunks to sort. * @return An iterator providing access to the sort result. */ private ReleasableIterator iterate(int nestLevel, long beginChunkIndex, long chunkCount) { List> sources; sources = new ArrayList>(); try { MergingIterator mergingIterator; // If we are down to a small number of entities, we retrieve each source from file. // Otherwise we recurse and split the number of entities down into smaller chunks. if (chunkCount <= MAX_MERGE_SOURCE_COUNT) { for (int i = 0; i < chunkCount; i++) { sources.add( chunkedEntityStore.iterate(beginChunkIndex + i) ); } } else { long maxChunkIndex; long subChunkCount; /* * The current chunk count must be divided by * MAX_MERGE_SOURCE_COUNT and we must recurse for each of those * sub chunk counts. Where the result isn't exact, we round up * to the nearest multiple of MAX_MERGE_SOURCE_COUNT to ensure * we don't end up with more than MAX_MERGE_SOURCE_COUNT * sources. */ subChunkCount = chunkCount / MAX_MERGE_SOURCE_COUNT; subChunkCount += chunkCount % MAX_MERGE_SOURCE_COUNT; // We can never pass beyond the chunk boundaries specified for // this function. maxChunkIndex = beginChunkIndex + chunkCount; for ( long subFirstChunk = beginChunkIndex; subFirstChunk < maxChunkIndex; subFirstChunk += subChunkCount) { // The chunk count passed to the nested function should not // make the nested function exceed this function's boundaries. if (subFirstChunk + subChunkCount > maxChunkIndex) { subChunkCount = maxChunkIndex - subFirstChunk; } /* * Either call the persistent or standard version of the * recursive iterate based on whether this nesting level * requires persistence. If we only have one chunk left at * this point we make an exception and skip persistence * because it will only result in a single file being opened * anyway. */ if (((nestLevel + 1) % MAX_MEMORY_SORT_DEPTH) == 0 && subChunkCount > 1) { sources.add( iteratePersisted(nestLevel + 1, subFirstChunk, subChunkCount) ); } else { sources.add( iterate(nestLevel + 1, subFirstChunk, subChunkCount) ); } } } // Create a merging iterator to merge all of the sources. mergingIterator = new MergingIterator(sources, comparator); // The merging iterator owns the sources now, so we clear our copy // of them to prevent them being released on method exit. sources.clear(); return mergingIterator; } finally { for (ReleasableIterator source : sources) { source.release(); } } } /** * Sorts and returns the contents of the sorter. * * @return An iterator providing access to the sorted entities. */ public ReleasableIterator iterate() { flushAddBuffer(); return iterate(0, 0, chunkedEntityStore.getChunkCount()); } /** * {@inheritDoc} */ public void release() { chunkedEntityStore.release(); } } MergingIterator.java000066400000000000000000000060431253404521400346230ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.common; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.NoSuchElementException; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; /** * This iterator examines a list of sorted input sources and merges them into a * single sorted list. * * @param * The object type to be sorted. * @author Brett Henderson */ public class MergingIterator implements ReleasableIterator { private List> sources; private Comparator comparator; private List sourceData; /** * Creates a new instance. * * @param sources * The list of data sources. * @param comparator * The comparator to be used for sorting. */ public MergingIterator(List> sources, Comparator comparator) { this.sources = new ArrayList>(sources); this.comparator = comparator; } /** * Primes the sorting collections. */ private void initialize() { if (sourceData == null) { // Get the first entity from each source. Delete any empty sources. sourceData = new ArrayList(sources.size()); for (int sourceIndex = 0; sourceIndex < sources.size();) { ReleasableIterator source; source = sources.get(sourceIndex); if (source.hasNext()) { sourceData.add(source.next()); sourceIndex++; } else { sources.remove(sourceIndex).release(); } } } } /** * {@inheritDoc} */ public boolean hasNext() { initialize(); return sourceData.size() > 0; } /** * {@inheritDoc} */ public DataType next() { DataType dataMinimum; int indexMinimum; ReleasableIterator source; initialize(); if (!hasNext()) { throw new NoSuchElementException(); } dataMinimum = sourceData.get(0); indexMinimum = 0; // Find the minimum entity. for (int indexCurrent = 1; indexCurrent < sources.size(); indexCurrent++) { DataType dataCurrent = sourceData.get(indexCurrent); // Check if the current data entity is less than the existing minimum. if (comparator.compare(dataMinimum, dataCurrent) > 0) { dataMinimum = dataCurrent; indexMinimum = indexCurrent; } } // Get the next entity from the source if available. // Otherwise remove the source and its current data. source = sources.get(indexMinimum); if (source.hasNext()) { sourceData.set(indexMinimum, source.next()); } else { sources.remove(indexMinimum).release(); sourceData.remove(indexMinimum); } return dataMinimum; } /** * Not supported. An UnsupportedOperationException is always thrown. */ public void remove() { throw new UnsupportedOperationException(); } /** * {@inheritDoc} */ public void release() { for (ReleasableIterator source : sources) { source.release(); } } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/v0_6/000077500000000000000000000000001253404521400302145ustar00rootroot00000000000000ChangeAsEntityComparator.java000066400000000000000000000021001253404521400356670ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.v0_6; import java.util.Comparator; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; /** * Allows an entity comparator to be used for making change comparisons. It extracts the two * entities from the changes and compares them using the underlying entity comparator. */ public class ChangeAsEntityComparator implements Comparator { private Comparator entityComparator; /** * Creates a new instance. * * @param entityComparator * The entity comparator to use for comparisons. */ public ChangeAsEntityComparator(Comparator entityComparator) { this.entityComparator = entityComparator; } /** * {@inheritDoc} */ @Override public int compare(ChangeContainer o1, ChangeContainer o2) { return entityComparator.compare(o1.getEntityContainer(), o2.getEntityContainer()); } } ChangeForSeekableApplierComparator.java000066400000000000000000000056631253404521400376470ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.v0_6; import java.util.Comparator; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; import org.openstreetmap.osmosis.core.task.common.ChangeAction; /** * Orders changes in such a way that they can be applied to a data store while * maintaining data integrity (ie. a database). For example, the ordering * prevents a way being added before the underlying nodes are created. The * changes are ordered as follows: *

    *
  • Bound creation
  • *
  • Node creation
  • *
  • Way creation
  • *
  • Relation creation
  • *
  • Relation modification
  • *
  • Way modification
  • *
  • Node modification
  • *
  • Bound modification
  • *
  • Relation deletion
  • *
  • Way deletion
  • *
  • Node deletion
  • *
  • Bound deletion
  • *
* * @author Brett Henderson */ public class ChangeForSeekableApplierComparator implements Comparator { /** * Create a weighting for the change. The weighting is the index into the * sorting list implemented by this class. * * @param changeEntity * The change to be analysed. * @return The sort weighting. */ private int calculateSortWeight(ChangeContainer changeEntity) { ChangeAction action = changeEntity.getAction(); Entity entity = changeEntity.getEntityContainer().getEntity(); if (entity.getType().equals(EntityType.Bound)) { if (action.equals(ChangeAction.Create)) { return 1; } if (action.equals(ChangeAction.Modify)) { return 8; } if (action.equals(ChangeAction.Delete)) { return 12; } } else if (entity.getType().equals(EntityType.Node)) { if (action.equals(ChangeAction.Create)) { return 2; } if (action.equals(ChangeAction.Modify)) { return 7; } if (action.equals(ChangeAction.Delete)) { return 11; } } else if (entity.getType().equals(EntityType.Way)) { if (action.equals(ChangeAction.Create)) { return 3; } if (action.equals(ChangeAction.Modify)) { return 6; } if (action.equals(ChangeAction.Delete)) { return 10; } } else if (entity.getType().equals(EntityType.Relation)) { if (action.equals(ChangeAction.Create)) { return 4; } if (action.equals(ChangeAction.Modify)) { return 5; } if (action.equals(ChangeAction.Delete)) { return 9; } } throw new OsmosisRuntimeException( "The change entity with action " + action + " type " + entity.getType() + " and id " + entity.getId() + " was not recognised." ); } /** * {@inheritDoc} */ public int compare(ChangeContainer o1, ChangeContainer o2) { return calculateSortWeight(o1) - calculateSortWeight(o2); } } ChangeForStreamableApplierComparator.java000066400000000000000000000024231253404521400402020ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.v0_6; import java.util.Comparator; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; /** * Orders changes in such a way that they can be applied to an ordered data * stream without requiring seeking throughout the data stream. (ie. an xml * dump). The change action to be performed (eg. Create) doesn't affect the sort * order. The changes are ordered as follows: *
    *
  • Nodes ordered by id and version
  • *
  • Ways ordered by id and version
  • *
  • Relations ordered by id and version
  • *
* * @author Brett Henderson */ public class ChangeForStreamableApplierComparator implements Comparator { private Comparator comparator; /** * Creates a new instance. */ public ChangeForStreamableApplierComparator() { // We have an existing entity comparator that performs the same ordering so simply adapt it. comparator = new ChangeAsEntityComparator(new EntityContainerComparator( new EntityByTypeThenIdThenVersionComparator())); } /** * {@inheritDoc} */ public int compare(ChangeContainer o1, ChangeContainer o2) { return comparator.compare(o1, o2); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/v0_6/ChangeSorter.java000066400000000000000000000040231253404521400334420ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.v0_6; import java.util.Comparator; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.sort.common.FileBasedSort; import org.openstreetmap.osmosis.core.store.SingleClassObjectSerializationFactory; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSinkChangeSource; /** * A change stream filter that sorts changes. The sort order is specified by * comparator provided during instantiation. * * @author Brett Henderson */ public class ChangeSorter implements ChangeSinkChangeSource { private FileBasedSort fileBasedSort; private ChangeSink changeSink; /** * Creates a new instance. * * @param comparator * The comparator to use for sorting. */ public ChangeSorter(Comparator comparator) { fileBasedSort = new FileBasedSort( new SingleClassObjectSerializationFactory(ChangeContainer.class), comparator, true); } /** * {@inheritDoc} */ public void initialize(Map metaData) { changeSink.initialize(metaData); } /** * {@inheritDoc} */ public void process(ChangeContainer change) { fileBasedSort.add(change); } /** * {@inheritDoc} */ public void setChangeSink(ChangeSink changeSink) { this.changeSink = changeSink; } /** * {@inheritDoc} */ public void complete() { ReleasableIterator iterator = null; try { iterator = fileBasedSort.iterate(); while (iterator.hasNext()) { changeSink.process(iterator.next()); } changeSink.complete(); } finally { if (iterator != null) { iterator.release(); } } } /** * {@inheritDoc} */ public void release() { fileBasedSort.release(); changeSink.release(); } } ChangeSorterFactory.java000066400000000000000000000053431253404521400347210ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.v0_6; import java.util.Comparator; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.ChangeSinkChangeSourceManager; /** * The task manager factory for a change sorter. * * @author Brett Henderson */ public class ChangeSorterFactory extends TaskManagerFactory { private static final String ARG_COMPARATOR_TYPE = "type"; private Map> comparatorMap; private String defaultComparatorType; /** * Creates a new instance. */ public ChangeSorterFactory() { comparatorMap = new HashMap>(); } /** * Registers a new comparator. * * @param comparatorType * The name of the comparator. * @param comparator * The comparator. * @param setAsDefault * If true, this will be set to be the default comparator if no * comparator is specified. */ public void registerComparator( String comparatorType, Comparator comparator, boolean setAsDefault) { if (comparatorMap.containsKey(comparatorType)) { throw new OsmosisRuntimeException("Comparator type \"" + comparatorType + "\" already exists."); } if (setAsDefault) { defaultComparatorType = comparatorType; } comparatorMap.put(comparatorType, comparator); } /** * Retrieves the comparator identified by the specified type. * * @param comparatorType * The comparator to be retrieved. * @return The comparator. */ private Comparator getComparator(String comparatorType) { if (!comparatorMap.containsKey(comparatorType)) { throw new OsmosisRuntimeException("Comparator type " + comparatorType + " doesn't exist."); } return comparatorMap.get(comparatorType); } /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { Comparator comparator; // Get the comparator. comparator = getComparator( getStringArgument( taskConfig, ARG_COMPARATOR_TYPE, getDefaultStringArgument(taskConfig, defaultComparatorType) ) ); return new ChangeSinkChangeSourceManager( taskConfig.getId(), new ChangeSorter(comparator), taskConfig.getPipeArgs() ); } } ChangeTagSorter.java000066400000000000000000000043661253404521400340310ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.v0_6; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSinkChangeSource; /** * A data stream filter that sorts tags on changes. This is useful for testing * to allow two sets of data to be compared for equality. * * @author Brett Henderson */ public class ChangeTagSorter implements ChangeSinkChangeSource { private ChangeSink changeSink; /** * {@inheritDoc} */ public void initialize(Map metaData) { changeSink.initialize(metaData); } /** * {@inheritDoc} */ public void process(ChangeContainer changeContainer) { EntityContainer readOnlyContainer; EntityContainer writeableContainer; Entity entity; Collection sortedTags; readOnlyContainer = changeContainer.getEntityContainer(); writeableContainer = readOnlyContainer.getWriteableInstance(); entity = writeableContainer.getEntity(); sortedTags = sortTags(entity.getTags()); entity.getTags().clear(); entity.getTags().addAll(sortedTags); changeSink.process(new ChangeContainer(writeableContainer, changeContainer.getAction())); } /** * Sorts the specified tag list. * * @param tagList * The tag list to be sorted. * @return A new list containing the sorted tags. */ private List sortTags(Collection tagList) { List sortedTagList; sortedTagList = new ArrayList(tagList); Collections.sort(sortedTagList); return sortedTagList; } /** * {@inheritDoc} */ public void setChangeSink(ChangeSink changeSink) { this.changeSink = changeSink; } /** * {@inheritDoc} */ public void complete() { changeSink.complete(); } /** * {@inheritDoc} */ public void release() { changeSink.release(); } } ChangeTagSorterFactory.java000066400000000000000000000015121253404521400353470ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.ChangeSinkChangeSourceManager; /** * The task manager factory for a change tag sorter. * * @author Brett Henderson */ public class ChangeTagSorterFactory extends TaskManagerFactory { /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { return new ChangeSinkChangeSourceManager( taskConfig.getId(), new ChangeTagSorter(), taskConfig.getPipeArgs() ); } } EntityByIdComparator.java000066400000000000000000000012361253404521400350560ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.v0_6; import java.util.Comparator; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; /** * Compares two entities and sorts them by their identifier. * * @author Brett Henderson */ public class EntityByIdComparator implements Comparator { /** * {@inheritDoc} */ public int compare(Entity o1, Entity o2) { long idDiff; // Perform an identifier comparison. idDiff = o1.getId() - o2.getId(); if (idDiff > 0) { return 1; } else if (idDiff < 0) { return -1; } else { return 0; } } } EntityByTypeComparator.java000066400000000000000000000011051253404521400354360ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.v0_6; import java.util.Comparator; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; /** * Compares two entities and sorts them by by their type (Nodes, then Segments, then Ways). * * @author Brett Henderson */ public class EntityByTypeComparator implements Comparator { /** * {@inheritDoc} */ public int compare(Entity o1, Entity o2) { // Perform a type comparison. return o1.getType().compareTo(o2.getType()); } } EntityByTypeThenIdComparator.java000066400000000000000000000021411253404521400365330ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.v0_6; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; /** * Orders entities first by their type (bound, node, way and relation), then their identifer. * * @author Brett Henderson */ public class EntityByTypeThenIdComparator implements Comparator { private Comparator comparator; /** * Creates a new instance. */ public EntityByTypeThenIdComparator() { List> entityComparators; // Build the sequence of entity comparisons. entityComparators = new ArrayList>(); entityComparators.add(new EntityByTypeComparator()); entityComparators.add(new EntityByIdComparator()); // Combine all entity comparisons into a single logical comparison. comparator = new StackableComparator(entityComparators); } /** * {@inheritDoc} */ public int compare(Entity o1, Entity o2) { return comparator.compare(o1, o2); } } EntityByTypeThenIdThenVersionComparator.java000066400000000000000000000023101253404521400407160ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.v0_6; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; /** * Orders entities first by their type (bound, node, way and relation), then their identifer, then * their version. * * @author Brett Henderson */ public class EntityByTypeThenIdThenVersionComparator implements Comparator { private Comparator comparator; /** * Creates a new instance. */ public EntityByTypeThenIdThenVersionComparator() { List> entityComparators; // Build the sequence of entity comparisons. entityComparators = new ArrayList>(); entityComparators.add(new EntityByTypeComparator()); entityComparators.add(new EntityByIdComparator()); entityComparators.add(new EntityByVersionComparator()); // Combine all entity comparisons into a single logical comparison. comparator = new StackableComparator(entityComparators); } /** * {@inheritDoc} */ public int compare(Entity o1, Entity o2) { return comparator.compare(o1, o2); } } EntityByVersionComparator.java000066400000000000000000000012331253404521400361440ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.v0_6; import java.util.Comparator; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; /** * Compares two entities and sorts them by their version. * * @author Brett Henderson */ public class EntityByVersionComparator implements Comparator { /** * {@inheritDoc} */ public int compare(Entity o1, Entity o2) { long verDiff; // Compare the version. verDiff = o1.getVersion() - o2.getVersion(); if (verDiff > 0) { return 1; } else if (verDiff < 0) { return -1; } else { return 0; } } } EntityContainerComparator.java000066400000000000000000000020761253404521400361540ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.v0_6; import java.util.Comparator; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; /** * An entity container comparator utilising an inner entity comparator. This allows entity * containers to be directly compared instead of having to extract the entities first. * * @author Brett Henderson */ public class EntityContainerComparator implements Comparator { private Comparator entityComparator; /** * Creates a new instance. * * @param entityComparator * The comparator to use for comparing the contained entities. */ public EntityContainerComparator(Comparator entityComparator) { this.entityComparator = entityComparator; } /** * {@inheritDoc} */ @Override public int compare(EntityContainer o1, EntityContainer o2) { return entityComparator.compare(o1.getEntity(), o2.getEntity()); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/v0_6/EntitySorter.java000066400000000000000000000036361253404521400335420ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.v0_6; import java.util.Comparator; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.sort.common.FileBasedSort; import org.openstreetmap.osmosis.core.store.GenericObjectSerializationFactory; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.task.v0_6.SinkSource; /** * A data stream filter that sorts entities. The sort order is specified by * comparator provided during instantiation. * * @author Brett Henderson */ public class EntitySorter implements SinkSource { private FileBasedSort fileBasedSort; private Sink sink; /** * Creates a new instance. * * @param comparator * The comparator to use for sorting. */ public EntitySorter(Comparator comparator) { fileBasedSort = new FileBasedSort(new GenericObjectSerializationFactory(), comparator, true); } /** * {@inheritDoc} */ public void initialize(Map metaData) { sink.initialize(metaData); } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { fileBasedSort.add(entityContainer); } /** * {@inheritDoc} */ public void setSink(Sink sink) { this.sink = sink; } /** * {@inheritDoc} */ public void complete() { ReleasableIterator iterator = null; try { iterator = fileBasedSort.iterate(); while (iterator.hasNext()) { sink.process(iterator.next()); } sink.complete(); } finally { if (iterator != null) { iterator.release(); } } } /** * {@inheritDoc} */ public void release() { fileBasedSort.release(); sink.release(); } } EntitySorterFactory.java000066400000000000000000000053141253404521400350060ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.v0_6; import java.util.Comparator; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkSourceManager; /** * The task manager factory for an entity sorter. * * @author Brett Henderson */ public class EntitySorterFactory extends TaskManagerFactory { private static final String ARG_COMPARATOR_TYPE = "type"; private Map> comparatorMap; private String defaultComparatorType; /** * Creates a new instance. */ public EntitySorterFactory() { comparatorMap = new HashMap>(); } /** * Registers a new comparator. * * @param comparatorType * The name of the comparator. * @param comparator * The comparator. * @param setAsDefault * If true, this will be set to be the default comparator if no * comparator is specified. */ public void registerComparator( String comparatorType, Comparator comparator, boolean setAsDefault) { if (comparatorMap.containsKey(comparatorType)) { throw new OsmosisRuntimeException("Comparator type \"" + comparatorType + "\" already exists."); } if (setAsDefault) { defaultComparatorType = comparatorType; } comparatorMap.put(comparatorType, comparator); } /** * Retrieves the comparator identified by the specified type. * * @param comparatorType * The comparator to be retrieved. * @return The comparator. */ private Comparator getComparator(String comparatorType) { if (!comparatorMap.containsKey(comparatorType)) { throw new OsmosisRuntimeException("Comparator type " + comparatorType + " doesn't exist."); } return comparatorMap.get(comparatorType); } /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { Comparator comparator; // Get the comparator. comparator = getComparator( getStringArgument( taskConfig, ARG_COMPARATOR_TYPE, getDefaultStringArgument(taskConfig, defaultComparatorType) ) ); return new SinkSourceManager( taskConfig.getId(), new EntitySorter(comparator), taskConfig.getPipeArgs() ); } } EntitySubClassComparator.java000066400000000000000000000016031253404521400357440ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.v0_6; import java.util.Comparator; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; /** * Allows a comparator for a specific entity type to be created. This is necessary in some generic classes. * * @author Brett Henderson * * @param * The entity type to be supported. */ public class EntitySubClassComparator implements Comparator { private Comparator comparator; /** * Creates a new instance. * * @param comparator * The underlying entity comparator. */ public EntitySubClassComparator(Comparator comparator) { this.comparator = comparator; } /** * {@inheritDoc} */ @Override public int compare(T o1, T o2) { return comparator.compare(o1, o2); } } SortedDeltaChangePipeValidator.java000066400000000000000000000051031253404521400370030ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.v0_6; import java.util.Comparator; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSinkChangeSource; /** * Validates that change data in a pipeline is sorted by entity type then id thus only allowing * delta style changes (ie. not full history). It accepts input data from a Source and passes all * data to a downstream Sink. * * @author Brett Henderson */ public class SortedDeltaChangePipeValidator implements ChangeSinkChangeSource { private ChangeSink changeSink; private Comparator comparator; private ChangeContainer previousChangeContainer; /** * Creates a new instance. */ public SortedDeltaChangePipeValidator() { comparator = new ChangeAsEntityComparator(new EntityContainerComparator(new EntityByTypeThenIdComparator())); } /** * {@inheritDoc} */ public void initialize(Map metaData) { changeSink.initialize(metaData); } /** * {@inheritDoc} */ public void complete() { changeSink.complete(); } /** * {@inheritDoc} */ public void process(ChangeContainer changeContainer) { // If this is not the first entity in the pipeline, make sure this // entity is greater than the previous. if (previousChangeContainer != null) { if (comparator.compare(previousChangeContainer, changeContainer) >= 0) { throw new OsmosisRuntimeException( "Pipeline entities are not sorted or contain multiple versions of a single entity" + ", previous entity type=" + previousChangeContainer.getEntityContainer().getEntity().getType() + ", id=" + previousChangeContainer.getEntityContainer().getEntity().getId() + ", version=" + previousChangeContainer.getEntityContainer().getEntity().getVersion() + " current entity type=" + changeContainer.getEntityContainer().getEntity().getType() + ", id=" + changeContainer.getEntityContainer().getEntity().getId() + ", version=" + changeContainer.getEntityContainer().getEntity().getVersion() + "." ); } } changeSink.process(changeContainer); previousChangeContainer = changeContainer; } /** * {@inheritDoc} */ public void release() { changeSink.release(); } /** * {@inheritDoc} */ public void setChangeSink(ChangeSink changeSink) { this.changeSink = changeSink; } } SortedDuplicateEntityPipeValidator.java000066400000000000000000000043601253404521400377570ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.task.v0_6.SinkSource; /** * Validates that entity data in a pipeline is sorted by entity type then id. It * allows duplicates. It accepts input data from a Source and passes all data to * a downstream Sink. * * @author Brett Henderson */ public class SortedDuplicateEntityPipeValidator implements SinkSource { private Sink sink; private EntityContainerComparator comparator; private EntityContainer previousEntityContainer; /** * Creates a new instance. */ public SortedDuplicateEntityPipeValidator() { comparator = new EntityContainerComparator(new EntityByTypeThenIdComparator()); } /** * {@inheritDoc} */ public void initialize(Map metaData) { sink.initialize(metaData); } /** * {@inheritDoc} */ public void complete() { sink.complete(); } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { // If this is not the first entity in the pipeline, make sure this // entity is greater than the previous. if (previousEntityContainer != null) { if (comparator.compare(previousEntityContainer, entityContainer) > 0) { throw new OsmosisRuntimeException( "Pipeline entities are not sorted, previous entity type=" + previousEntityContainer.getEntity().getType() + ", id=" + previousEntityContainer.getEntity().getId() + ", version=" + previousEntityContainer.getEntity().getVersion() + " current entity type=" + entityContainer.getEntity().getType() + ", id=" + entityContainer.getEntity().getId() + ", version=" + entityContainer.getEntity().getVersion() + "." ); } } sink.process(entityContainer); previousEntityContainer = entityContainer; } /** * {@inheritDoc} */ public void release() { sink.release(); } /** * {@inheritDoc} */ public void setSink(Sink sink) { this.sink = sink; } } SortedEntityPipeValidator.java000066400000000000000000000043061253404521400361240ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.task.v0_6.SinkSource; /** * Validates that entity data in a pipeline is sorted by entity type then id. It * accepts input data from a Source and passes all data to a downstream Sink. * * @author Brett Henderson */ public class SortedEntityPipeValidator implements SinkSource { private Sink sink; private EntityContainerComparator comparator; private EntityContainer previousEntityContainer; /** * Creates a new instance. */ public SortedEntityPipeValidator() { comparator = new EntityContainerComparator(new EntityByTypeThenIdComparator()); } /** * {@inheritDoc} */ public void initialize(Map metaData) { sink.initialize(metaData); } /** * {@inheritDoc} */ public void complete() { sink.complete(); } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { // If this is not the first entity in the pipeline, make sure this // entity is greater than the previous. if (previousEntityContainer != null) { if (comparator.compare(previousEntityContainer, entityContainer) >= 0) { throw new OsmosisRuntimeException( "Pipeline entities are not sorted, previous entity type=" + previousEntityContainer.getEntity().getType() + ", id=" + previousEntityContainer.getEntity().getId() + ", version=" + previousEntityContainer.getEntity().getVersion() + " current entity type=" + entityContainer.getEntity().getType() + ", id=" + entityContainer.getEntity().getId() + ", version=" + entityContainer.getEntity().getVersion() + "." ); } } sink.process(entityContainer); previousEntityContainer = entityContainer; } /** * {@inheritDoc} */ public void release() { sink.release(); } /** * {@inheritDoc} */ public void setSink(Sink sink) { this.sink = sink; } } SortedHistoryChangePipeValidator.java000066400000000000000000000050211253404521400374120ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.v0_6; import java.util.Comparator; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSinkChangeSource; /** * Validates that change data in a pipeline is sorted by entity type, then id, then version allowing * full history changes. It accepts input data from a Source and passes all data to a downstream * Sink. * * @author Brett Henderson */ public class SortedHistoryChangePipeValidator implements ChangeSinkChangeSource { private ChangeSink changeSink; private Comparator comparator; private ChangeContainer previousChangeContainer; /** * Creates a new instance. */ public SortedHistoryChangePipeValidator() { comparator = new ChangeAsEntityComparator(new EntityContainerComparator( new EntityByTypeThenIdThenVersionComparator())); } /** * {@inheritDoc} */ public void initialize(Map metaData) { changeSink.initialize(metaData); } /** * {@inheritDoc} */ public void complete() { changeSink.complete(); } /** * {@inheritDoc} */ public void process(ChangeContainer changeContainer) { // If this is not the first entity in the pipeline, make sure this // entity is greater than the previous. if (previousChangeContainer != null) { if (comparator.compare(previousChangeContainer, changeContainer) >= 0) { throw new OsmosisRuntimeException( "Pipeline entities are not sorted, previous entity type=" + previousChangeContainer.getEntityContainer().getEntity().getType() + ", id=" + previousChangeContainer.getEntityContainer().getEntity().getId() + ", version=" + previousChangeContainer.getEntityContainer().getEntity().getVersion() + " current entity type=" + changeContainer.getEntityContainer().getEntity().getType() + ", id=" + changeContainer.getEntityContainer().getEntity().getId() + ", version=" + changeContainer.getEntityContainer().getEntity().getVersion() + "." ); } } changeSink.process(changeContainer); previousChangeContainer = changeContainer; } /** * {@inheritDoc} */ public void release() { changeSink.release(); } /** * {@inheritDoc} */ public void setChangeSink(ChangeSink changeSink) { this.changeSink = changeSink; } } StackableComparator.java000066400000000000000000000023301253404521400347170ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.v0_6; import java.util.ArrayList; import java.util.Comparator; import java.util.List; /** * A comparator implementation that allows multiple comparators to be combined together. It invokes * each comparator in order, and returns the first non-zero result. If all comparators return 0, the * result is 0. * * @param * The type of data to be compared. */ public class StackableComparator implements Comparator { private List> comparators; /** * Creates a new instance. * * @param comparators * The comparators to use for comparisons. */ public StackableComparator(List> comparators) { this.comparators = new ArrayList>(comparators); } /** * {@inheritDoc} */ @Override public int compare(T o1, T o2) { // Compare using each comparator in turn. Stop if a comparator detects a difference and // return the result. for (Comparator comparator : comparators) { int result; result = comparator.compare(o1, o2); if (result != 0) { return result; } } return 0; } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/v0_6/TagSorter.java000066400000000000000000000036661253404521400330040ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.v0_6; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.task.v0_6.SinkSource; /** * A data stream filter that sorts tags on entities. This is useful for testing * to allow two sets of data to be compared for equality. * * @author Brett Henderson */ public class TagSorter implements SinkSource { private Sink sink; /** * {@inheritDoc} */ public void initialize(Map metaData) { sink.initialize(metaData); } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { EntityContainer writeableContainer; Entity entity; Collection sortedTags; writeableContainer = entityContainer.getWriteableInstance(); entity = writeableContainer.getEntity(); sortedTags = sortTags(entity.getTags()); entity.getTags().clear(); entity.getTags().addAll(sortedTags); sink.process(writeableContainer); } /** * Sorts the specified tag list. * * @param tagList * The tag list to be sorted. * @return A new list containing the sorted tags. */ private List sortTags(Collection tagList) { List sortedTagList; sortedTagList = new ArrayList(tagList); Collections.sort(sortedTagList); return sortedTagList; } /** * {@inheritDoc} */ public void setSink(Sink sink) { this.sink = sink; } /** * {@inheritDoc} */ public void complete() { sink.complete(); } /** * {@inheritDoc} */ public void release() { sink.release(); } } TagSorterFactory.java000066400000000000000000000014371253404521400342470ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/sort/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkSourceManager; /** * The task manager factory for a tag sorter. * * @author Brett Henderson */ public class TagSorterFactory extends TaskManagerFactory { /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { return new SinkSourceManager( taskConfig.getId(), new TagSorter(), taskConfig.getPipeArgs() ); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store/000077500000000000000000000000001253404521400276075ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store/BaseObjectReader.java000066400000000000000000000051071253404521400336010ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Provides functionality common to all object reader implementations. * * @author Brett Henderson */ public abstract class BaseObjectReader implements ObjectReader { private StoreReader storeReader; private StoreClassRegister storeClassRegister; private StoreableConstructorCache constructorCache; /** * Creates a new instance. * * @param storeReader * The store writer to read all serialised data from. * @param storeClassRegister * The register for class to identifier mappings. */ public BaseObjectReader(StoreReader storeReader, StoreClassRegister storeClassRegister) { this.storeReader = storeReader; this.storeClassRegister = storeClassRegister; constructorCache = new StoreableConstructorCache(); } /** * Identifies the class using data from the underlying stream. * * @param sr * The store reader to read all serialised data from. * @param scr * The register for class to identifier mappings. * @return The next class type in the data stream. */ protected abstract Class readClassFromIdentifier(StoreReader sr, StoreClassRegister scr); /** * Reads an object from storage using identifiers embedded in the stream to * determine the correct class type to instantiate. * * @return The re-instantiated object. */ public Storeable readObject() { Class clazz; Constructor constructor; clazz = readClassFromIdentifier(storeReader, storeClassRegister); constructor = constructorCache.getStoreableConstructor(clazz); try { return (Storeable) constructor.newInstance(new Object[] {storeReader, storeClassRegister}); } catch (IllegalAccessException e) { throw new OsmosisRuntimeException( "The class " + constructor.getDeclaringClass().getName() + " could not be instantiated.", e); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); if (cause instanceof EndOfStoreException) { throw (EndOfStoreException) cause; } throw new OsmosisRuntimeException( "The class " + constructor.getDeclaringClass().getName() + " could not be instantiated.", e); } catch (InstantiationException e) { throw new OsmosisRuntimeException( "The class " + constructor.getDeclaringClass().getName() + " could not be instantiated.", e); } } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store/BaseObjectWriter.java000066400000000000000000000035541253404521400336570ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; /** * Provides functionality common to all object writer implementations. * * @author Brett Henderson */ public abstract class BaseObjectWriter implements ObjectWriter { private StoreWriter storeWriter; private StoreClassRegister storeClassRegister; private StoreableConstructorCache constructorCache; /** * Creates a new instance. * * @param storeWriter * The store writer to write all serialised data to. * @param storeClassRegister * The register for class to identifier mappings. */ protected BaseObjectWriter(StoreWriter storeWriter, StoreClassRegister storeClassRegister) { this.storeWriter = storeWriter; this.storeClassRegister = storeClassRegister; constructorCache = new StoreableConstructorCache(); } /** * Writes the class identifier to the underlying data stream to allow it to * be identified when reading in again. * * @param sw * The store writer to write all serialised data to. * @param scr * The register for class to identifier mappings. * @param clazz * The class to be written. */ protected abstract void writeClassIdentifier(StoreWriter sw, StoreClassRegister scr, Class clazz); /** * Writes an object to storage in a way that allows its type to be * automatically determined when read back in. * * @param value * The object to be written. */ public void writeObject(Storeable value) { Class clazz; clazz = value.getClass(); // Verify that the class has the appropriate constructor for de-serialization. constructorCache.getStoreableConstructor(clazz); writeClassIdentifier(storeWriter, storeClassRegister, clazz); value.store(storeWriter, storeClassRegister); } } BaseStoreClassRegister.java000066400000000000000000000041551253404521400347620ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Provides common functionality to store class register implementations. */ public class BaseStoreClassRegister implements StoreClassRegister { private Map, Byte> classToByteMap; private Map> byteToClassMap; /** * Creates a new instance. */ public BaseStoreClassRegister() { classToByteMap = new HashMap, Byte>(); byteToClassMap = new HashMap>(); } /** * Indicates if the class is recognized by the current register. * * @param clazz * The class to be checked. * @return True if the class is recognized, false otherwise. */ protected boolean isClassRecognized(Class clazz) { return classToByteMap.containsKey(clazz); } /** * Registers the class with the specified id. * * @param clazz * The class to be registered. * @param id * The unique identifier for the class. */ protected void registerClass(Class clazz, byte id) { Byte objId; objId = Byte.valueOf(id); classToByteMap.put(clazz, objId); byteToClassMap.put(objId, clazz); } /** * {@inheritDoc} */ public void storeIdentifierForClass(StoreWriter storeWriter, Class clazz) { byte id; if (classToByteMap.containsKey(clazz)) { id = classToByteMap.get(clazz).byteValue(); } else { throw new OsmosisRuntimeException("The class " + clazz + " is not supported by this store class register."); } storeWriter.writeByte(id); } /** * {@inheritDoc} */ public Class getClassFromIdentifier(StoreReader storeReader) { byte classId; Byte idObj; classId = storeReader.readByte(); idObj = Byte.valueOf(classId); if (!byteToClassMap.containsKey(idObj)) { throw new OsmosisRuntimeException( "Byte " + classId + " is not a recognised class identifier, the data stream may be corrupt."); } return byteToClassMap.get(idObj); } } BufferedRandomAccessFileInputStream.java000066400000000000000000000266061253404521400374060ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.util.LinkedList; import java.util.List; /** * Wraps a random access file adding buffered input stream capabilities. This * allows a file to be randomly accessed while providing performance * improvements over the non-buffered random access file implementation. * * @author Brett Henderson */ public class BufferedRandomAccessFileInputStream extends InputStream { private static final int DEFAULT_BUFFER_COUNT = 4; private static final int DEFAULT_INITIAL_BUFFER_SIZE = 16; private static final int DEFAULT_MAXIMUM_BUFFER_SIZE = 4096; private static final float DEFAULT_BUFFER_INCREASE_FACTOR = 2; private RandomAccessFile randomFile; private int bufferCount; private List readerList; /** * Creates a new instance. * * @param file * The file to be read. * @throws FileNotFoundException * if the file cannot be opened. */ public BufferedRandomAccessFileInputStream(File file) throws FileNotFoundException { this( file, DEFAULT_BUFFER_COUNT, DEFAULT_INITIAL_BUFFER_SIZE, DEFAULT_MAXIMUM_BUFFER_SIZE, DEFAULT_BUFFER_INCREASE_FACTOR); } /** * Creates a new instance. * * @param file * The file to be read. * @param bufferCount * The number of buffers to use. Use of multiple buffers allows * some random seeks to occur without losing existing buffered * data that might be returned to. * @param initialBufferSize * After a seek, this is the number of bytes that will be * initially read. * @param maxBufferSize * This is the maximum number of bytes that will ever be read * from the underlying file at a time. * @param bufferIncreaseFactor * During sequential reads, if the buffer is exhausted the next * read will be longer than the previous read according to this * factor. A value of 1 means the buffer never gets larger. The * buffer will never get larger than maxBufferSize. * @throws FileNotFoundException * if the file cannot be opened. */ public BufferedRandomAccessFileInputStream( File file, int bufferCount, int initialBufferSize, int maxBufferSize, float bufferIncreaseFactor) throws FileNotFoundException { this.bufferCount = bufferCount; randomFile = new RandomAccessFile(file, "r"); readerList = new LinkedList(); for (int i = 0; i < bufferCount; i++) { readerList.add(new BufferedReader(randomFile, initialBufferSize, maxBufferSize, bufferIncreaseFactor)); } } /** * {@inheritDoc} */ @Override public int read() throws IOException { return readerList.get(0).read(); } /** * {@inheritDoc} */ @Override public int read(byte[] b) throws IOException { return read(b, 0, b.length); } /** * {@inheritDoc} */ @Override public int read(byte[] b, int off, int len) throws IOException { return readerList.get(0).read(b, off, len); } /** * Seeks to the specified position in the file. * * @param pos * The position within the file to seek to. * @throws IOException * if an error occurs during seeking. */ public void seek(long pos) throws IOException { BufferedReader reader; reader = null; for (int i = 0; i < bufferCount; i++) { BufferedReader tmpReader; tmpReader = readerList.get(i); if (tmpReader.containsPosition(pos)) { reader = tmpReader; if (i > 0) { readerList.remove(i); readerList.add(0, reader); } break; } } if (reader == null) { reader = readerList.remove(bufferCount - 1); readerList.add(0, reader); } reader.seek(pos); } /** * Returns the length of the data file. * * @return The file length in bytes. * @throws IOException * if an error occurs during the length operation. */ public long length() throws IOException { return randomFile.length(); } /** * Returns the current read position in the data file. * * @return The current file offset in bytes. * @throws IOException * if an error occurs during the position operation. */ public long position() throws IOException { return readerList.get(0).position(); } /** * {@inheritDoc} */ @Override public void close() throws IOException { randomFile.close(); } private static class BufferedReader { private RandomAccessFile randomFile; private int initialBufferSize; private int maxBufferSize; private float bufferIncreaseFactor; private byte[] buffer; private long bufferFilePosition; private int currentBufferSize; private int currentBufferByteCount; private int currentBufferOffset; /** * Creates a new instance. * * @param randomFile * The file to be read. * @param initialBufferSize * After a seek, this is the number of bytes that will be * initially read. * @param maxBufferSize * This is the maximum number of bytes that will ever be read * from the underlying file at a time. * @param bufferIncreaseFactor * During sequential reads, if the buffer is exhausted the next * read will be longer than the previous read according to this * factor. A value of 1 means the buffer never gets larger. The * buffer will never get larger than maxBufferSize. * @throws FileNotFoundException * if the file cannot be opened. */ public BufferedReader( RandomAccessFile randomFile, int initialBufferSize, int maxBufferSize, float bufferIncreaseFactor) { this.randomFile = randomFile; this.initialBufferSize = initialBufferSize; this.maxBufferSize = maxBufferSize; this.bufferIncreaseFactor = bufferIncreaseFactor; buffer = new byte[maxBufferSize]; bufferFilePosition = 0; currentBufferSize = 0; currentBufferByteCount = 0; currentBufferOffset = 0; } /** * Returns the current read position in the data file. * * @return The current file offset in bytes. * @throws IOException * if an error occurs during the position operation. */ public long position() throws IOException { return bufferFilePosition + currentBufferOffset; } /** * Indicates if the specified position is contained within the current * buffer. Note that the requested position may not be currently loaded * in the buffer, it may be within maxBufferSize bytes of the buffer * start position. * * @param position * The requested file position. * @return True if the position is within maxBufferSize bytes of the * buffer start. */ public boolean containsPosition(long position) { return (position >= bufferFilePosition) && (position < (bufferFilePosition + maxBufferSize)); } /** * Seeks to the specified position in the file. * * @param pos * The position within the file to seek to. * @throws IOException * if an error occurs during seeking. */ public void seek(long pos) throws IOException { long bufferBeginFileOffset; long bufferEndFileOffset; bufferBeginFileOffset = bufferFilePosition; bufferEndFileOffset = bufferFilePosition + currentBufferByteCount; // If the requested position is within the current buffer just move to // that position. if ((pos >= bufferBeginFileOffset) && pos <= (bufferEndFileOffset)) { // The request position is within the current buffer so just move to // that position. currentBufferOffset = (int) (pos - bufferBeginFileOffset); } else if ((pos < bufferBeginFileOffset) && (bufferBeginFileOffset - pos) <= maxBufferSize) { // The request position is within a max buffer size of the beginning // of the buffer so just move there without resetting the current // buffer size. randomFile.seek(pos); bufferFilePosition = pos; // Mark the current buffer as empty so that the next read will read // from disk. currentBufferByteCount = 0; } else if ((pos > bufferEndFileOffset) && (pos - bufferEndFileOffset) <= maxBufferSize) { // The request position is within a max buffer size of the end // of the buffer so just move there without resetting the current // buffer size. randomFile.seek(pos); bufferFilePosition = pos; // Mark the current buffer as empty so that the next read will read // from disk. currentBufferByteCount = 0; } else { // The request position is not close to the current position so move // there and reset the buffer completely. randomFile.seek(pos); bufferFilePosition = pos; currentBufferSize = 0; currentBufferByteCount = 0; currentBufferOffset = 0; } } /** * Ensures data is available in the buffer. * * @return True if data is available. False indicates that the end of stream * has been reached. */ private boolean populateBuffer() throws IOException { if (currentBufferOffset >= currentBufferByteCount) { // If another buffered reader has moved the file position, we need // to move it back. if (randomFile.getFilePointer() != (bufferFilePosition + currentBufferByteCount)) { randomFile.seek(bufferFilePosition + currentBufferByteCount); } // Update the current buffer file position to be at the // beginning of the next read location. bufferFilePosition += currentBufferByteCount; currentBufferOffset = 0; if (currentBufferSize == 0) { currentBufferSize = initialBufferSize; } else if (currentBufferSize < maxBufferSize) { currentBufferSize = (int) (currentBufferSize * bufferIncreaseFactor); if (currentBufferSize > maxBufferSize) { currentBufferSize = maxBufferSize; } } currentBufferByteCount = randomFile.read(buffer, 0, currentBufferSize); if (currentBufferByteCount < 0) { return false; } } return true; } /** * Reads the next byte from the underlying stream. * * @return The next byte. * @throws IOException * if an error occurs. */ public int read() throws IOException { if (populateBuffer()) { return buffer[currentBufferOffset++] & 0xff; } else { return -1; } } /** * Reads an array of bytes from the underlying stream. * * @param b * The buffer to fill. * @param off * The offset to fill the buffer from. * @param len * The number of bytes to read. * @return The number of bytes read. * @throws IOException * if an error occurs. */ public int read(byte[] b, int off, int len) throws IOException { if (populateBuffer()) { int readLength; // Determine how many bytes to read from the current buffer. readLength = currentBufferByteCount - currentBufferOffset; if (readLength > len) { readLength = len; } // Copy the bytes into the output buffer and update the current buffer position. System.arraycopy(buffer, currentBufferOffset, b, off, readLength); currentBufferOffset += readLength; return readLength; } else { return -1; } } } } ChunkedObjectStore.java000066400000000000000000000113111253404521400341150ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import org.openstreetmap.osmosis.core.lifecycle.Completable; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; /** * Adds indexed chunking capabilities to a basic object store allowing groups of * objects to be written and retrieved later by their chunk index. The number of * objects and the size of the index is limited only by disk space. *

* This store is only suitable for single-threaded use because it does not * provide per-thread readers. * * @param * The class type to be stored. * @author Brett Henderson */ public class ChunkedObjectStore implements Completable { /** * Stores all the objects written to this store. */ private SegmentedObjectStore objectStore; /** * Maintains both the file positions of each chunk and the number of objects * within each chunk. The file position is written when a new chunk is * started, and the object count is written when a chunk is completed. */ private IndexStore indexStore; private IndexStoreReader indexStoreReader; private long chunkCount; private boolean chunkInProgress; private long newChunkFilePosition; private long chunkObjectCount; /** * Creates a new instance. * * @param serializationFactory * The factory defining the object serialisation implementation. * @param storageFilePrefix * The prefix of the storage file name. * @param indexFilePrefix * The prefix of the index file name. * @param useCompression * If true, the storage file will be compressed. */ public ChunkedObjectStore( ObjectSerializationFactory serializationFactory, String storageFilePrefix, String indexFilePrefix, boolean useCompression) { objectStore = new SegmentedObjectStore(serializationFactory, storageFilePrefix, useCompression); indexStore = new IndexStore( LongLongIndexElement.class, new ComparableComparator(), indexFilePrefix ); chunkCount = 0; chunkInProgress = false; newChunkFilePosition = 0; chunkObjectCount = 0; } /** * Adds the specified object to the store. * * @param data * The object to be added. */ public void add(T data) { objectStore.add(data); chunkObjectCount++; if (!chunkInProgress) { // Write the file index of the new chunk. indexStore.write(new LongLongIndexElement((chunkCount * 2), newChunkFilePosition)); chunkInProgress = true; } } /** * Stops the current writing operation and begins a new one saving the * current position against a new interval index. */ public void closeChunk() { // We can only close a chunk if one is in progress. if (chunkInProgress) { // Create an interval in the underlying object store and note the // current position. newChunkFilePosition = objectStore.closeChunk(); // Flag that no chunk is in progress so that the next add will store // the start file index. chunkInProgress = false; // Write then reset the object count of the current chunk. indexStore.write(new LongLongIndexElement((chunkCount * 2) + 1, chunkObjectCount)); chunkObjectCount = 0; // Increment the chunk count. chunkCount++; } } /** * Returns the number of chunks managed by this store. This count will * include the in progress chunk if one exists. * * @return The number of chunks. */ public long getChunkCount() { // If a chunk is in progress, the chunk count won't have been updated yet. if (chunkInProgress) { return chunkCount + 1; } else { return chunkCount; } } /** * Provides access to the contents of this store. * * @param chunk * The chunk to read objects from. * @return An iterator providing access to contents of the store. */ public ReleasableIterator iterate(long chunk) { complete(); if (indexStoreReader == null) { indexStoreReader = indexStore.createReader(); } // Retrieve the file position and number of objects for the specified // chunk and iterate. return objectStore.iterate( indexStoreReader.get(chunk * 2).getValue(), indexStoreReader.get(chunk * 2 + 1).getValue() ); } /** * {@inheritDoc} */ @Override public void complete() { // Any outstanding chunks must be closed before we can complete. closeChunk(); indexStore.complete(); } /** * {@inheritDoc} */ public void release() { objectStore.release(); if (indexStoreReader != null) { indexStoreReader.release(); indexStoreReader = null; } indexStore.release(); } } ComparableComparator.java000066400000000000000000000010661253404521400344730ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import java.util.Comparator; /** * A simple utility class for providing comparator functionality for class types * that are directly comparable. * * @param * The class type to be compared. * @author Brett Henderson */ public class ComparableComparator> implements Comparator { /** * {@inheritDoc} */ @Override public int compare(T o1, T o2) { return o1.compareTo(o2); } } DataInputStoreReader.java000066400000000000000000000064261253404521400344340ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import java.io.DataInput; import java.io.EOFException; import java.io.IOException; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Allows persisted input to be read from a DataInput implementation. * * @author Brett Henderson */ public class DataInputStoreReader implements StoreReader { private DataInput input; /** * Creates a new instance. * * @param input * The data input to read data from. */ public DataInputStoreReader(DataInput input) { this.input = input; } /** * {@inheritDoc} */ @Override public boolean readBoolean() { try { return input.readBoolean(); } catch (EOFException e) { throw new EndOfStoreException( "End of stream was reached while attempting to read a boolean from the store.", e); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to read a boolean from the store.", e); } } /** * {@inheritDoc} */ @Override public byte readByte() { try { return input.readByte(); } catch (EOFException e) { throw new EndOfStoreException( "End of stream was reached while attempting to read a byte from the store.", e); } catch (IOException e) { throw new OsmosisRuntimeException( "Unable to read a byte from the store.", e); } } /** * {@inheritDoc} */ @Override public char readCharacter() { try { return input.readChar(); } catch (EOFException e) { throw new EndOfStoreException( "End of stream was reached while attempting to read a character from the store.", e); } catch (IOException e) { throw new OsmosisRuntimeException( "Unable to read a character from the store.", e); } } /** * {@inheritDoc} */ @Override public int readInteger() { try { return input.readInt(); } catch (EOFException e) { throw new EndOfStoreException( "End of stream was reached while attempting to read an integer from the store.", e); } catch (IOException e) { throw new OsmosisRuntimeException( "Unable to read an integer from the store.", e); } } /** * {@inheritDoc} */ @Override public long readLong() { try { return input.readLong(); } catch (EOFException e) { throw new EndOfStoreException( "End of stream was reached while attempting to read a long from the store.", e); } catch (IOException e) { throw new OsmosisRuntimeException( "Unable to read a long from the store.", e); } } /** * {@inheritDoc} */ @Override public double readDouble() { try { return input.readDouble(); } catch (EOFException e) { throw new EndOfStoreException( "End of stream was reached while attempting to read a double from the store.", e); } catch (IOException e) { throw new OsmosisRuntimeException( "Unable to read a double from the store.", e); } } /** * {@inheritDoc} */ @Override public String readString() { try { return input.readUTF(); } catch (EOFException e) { throw new EndOfStoreException( "End of stream was reached while attempting to read a String from the store.", e); } catch (IOException e) { throw new OsmosisRuntimeException( "Unable to read a String from the store.", e); } } } DataOutputStoreWriter.java000066400000000000000000000044441253404521400347050ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import java.io.DataOutput; import java.io.IOException; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Allows persisted output to be written to a DataOutput implementation. * * @author Brett Henderson */ public class DataOutputStoreWriter implements StoreWriter { private DataOutput output; /** * Creates a new instance. * * @param output * The destination to write the data to. */ public DataOutputStoreWriter(DataOutput output) { this.output = output; } /** * {@inheritDoc} */ public void writeBoolean(boolean value) { try { output.writeBoolean(value); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write boolean " + value + " to the store.", e); } } /** * {@inheritDoc} */ public void writeByte(byte value) { try { output.writeByte(value); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write byte " + value + " to the store.", e); } } /** * {@inheritDoc} */ @Override public void writeCharacter(char value) { try { output.writeChar(value); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write character " + ((int) value) + " to the store.", e); } } /** * {@inheritDoc} */ public void writeInteger(int value) { try { output.writeInt(value); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write integer " + value + " to the store.", e); } } /** * {@inheritDoc} */ public void writeLong(long value) { try { output.writeLong(value); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write long " + value + " to the store.", e); } } /** * {@inheritDoc} */ public void writeDouble(double value) { try { output.writeDouble(value); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write double " + value + " to the store.", e); } } /** * {@inheritDoc} */ public void writeString(String value) { try { output.writeUTF(value); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write String (" + value + ") to the store.", e); } } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store/DataPostbox.java000066400000000000000000000322541253404521400327100ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; import java.util.Map; import java.util.Queue; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.task.v0_6.Initializable; /** *

* This class provides a mechanism for a thread to pass data to another thread. * Both threads will block until the other is ready. It supports a single * writing thread, and a single reading thread. Multiple reading or writing * threads are NOT supported. *

* The input thread must call methods in the following sequence: *

*
    *
  • initialize - Called during successful startup, can be skipped in failure * condition
  • *
  • put - Called from zero to N times until input data is exhausted
  • *
  • complete - Only called if input processing completed successfully
  • *
  • release - Called once at the end of processing regardless of success or * failure
  • *
*

* The output thread must call methods in the following sequence: *

*
    *
  • outputInitialize - Called during successful startup, can be skipped in * failure condition
  • *
  • hasNext/getNext - Both called until hasNext returns false in which case * no more data is available
  • *
  • outputComplete - Only called if output processing completed successfully
  • *
  • outputRelease - Called once at the end of processing regardless of * success or failure
  • *
*

* The input thread will block in the following situations: *

*
    *
  • initialize has been called, but outputInitialize has not yet been called
  • *
  • put has been called, and the buffer is full
  • *
  • The complete method has been called, and outputComplete has not yet been * called
  • *
  • The release method has been called, and outputRelease has not yet been * called. This wait must occur to support the scenario where both threads * subsequently wish to initialize again.
  • *
*

* The output thread will block in the following situations: *

*
    *
  • The outputInitialize method has been called, and initialize has not yet * been called
  • *
  • hasNext has been called, the buffer is empty, and complete has not yet * been called
  • *
  • The outputComplete method has been called, but complete has not yet been * called (Should never happen because hasNext won't return false until complete * has been called).
  • *
  • The outputRelease method has been called, but release has not yet been * called.
  • *
*

* This class may be re-used multiple times. For this to work, both input and * output methods must be called an equal number of times or deadlock will * occur. Re-use may occur after input or output threads fail, however in all * cases calls to release and outputRelease must be matched. * * @param * The type of data held in the postbox. */ public class DataPostbox implements Initializable { private int bufferCapacity; private int chunkSize; private Lock lock; private Condition dataWaitCondition; private Map processingMetaData; private Collection centralQueue; private Collection inboundQueue; private Queue outboundQueue; private boolean inputInitialized; private boolean outputInitialized; private boolean inputComplete; private boolean outputComplete; private boolean inputReleased; private boolean outputReleased; private boolean inputExit; private boolean outputExit; private boolean inputOkay; private boolean outputOkay; /** * Creates a new instance. * * @param capacity * The maximum number of objects to hold in the postbox before * blocking. */ public DataPostbox(int capacity) { if (capacity <= 0) { throw new OsmosisRuntimeException("A capacity of " + capacity + " is invalid, must be greater than 0."); } this.bufferCapacity = capacity; // Use a chunk size one quarter of total buffer size. This is a magic // number but performance isn't highly sensitive to this parameter. chunkSize = bufferCapacity / 4; if (chunkSize <= 0) { chunkSize = 1; } // Create the thread synchronisation primitives. lock = new ReentrantLock(); dataWaitCondition = lock.newCondition(); // Thread synchronisation flags. Each thread moves in lockstep through // each of these phases. Only initialize and or complete flags may be // skipped which trigger error conditions and the setting of the okay // flags. inputInitialized = false; outputInitialized = false; inputComplete = false; outputComplete = false; inputReleased = false; outputReleased = false; inputExit = true; outputExit = true; inputOkay = true; outputOkay = true; // Create the inter-thread data transfer queues. initializeQueues(); } private void initializeQueues() { // Create buffer objects. centralQueue = new ArrayList(); inboundQueue = new ArrayList(); outboundQueue = new ArrayDeque(); } /** * This is called by the input thread to validate that no errors have * occurred on the output thread. */ private void checkForOutputErrors() { // Check for reading thread error. if (!outputOkay) { throw new OsmosisRuntimeException("An output error has occurred, aborting."); } } /** * This is called by the output thread to validate that no errors have * occurred on the input thread. */ private void checkForInputErrors() { // Check for writing thread error. if (!inputOkay) { throw new OsmosisRuntimeException("An input error has occurred, aborting."); } } /** * Either thread can call this method when they wish to wait until an update * has been performed by the other thread. */ private void waitForUpdate() { try { dataWaitCondition.await(); } catch (InterruptedException e) { throw new OsmosisRuntimeException("Thread was interrupted.", e); } } /** * Either thread can call this method when they wish to signal the other * thread that an update has occurred. */ private void signalUpdate() { dataWaitCondition.signal(); } /** * Adds a group of objects to the central queue ready for consumption by the * receiver. * * @param o * The objects to be added. */ private void populateCentralQueue() { lock.lock(); try { checkForOutputErrors(); // Wait until the currently posted data is cleared. while (centralQueue.size() >= bufferCapacity) { waitForUpdate(); checkForOutputErrors(); } // Post the new data. centralQueue.addAll(inboundQueue); inboundQueue.clear(); signalUpdate(); } finally { lock.unlock(); } } /** * Empties the contents of the central queue into the outbound queue. */ private void consumeCentralQueue() { lock.lock(); try { checkForInputErrors(); // Wait until data is available. while (!((centralQueue.size() > 0) || inputComplete)) { waitForUpdate(); checkForInputErrors(); } outboundQueue.addAll(centralQueue); centralQueue.clear(); signalUpdate(); } finally { lock.unlock(); } } /** * {@inheritDoc} */ @Override public void initialize(Map metaData) { if (inputInitialized) { throw new OsmosisRuntimeException("initialize has already been called"); } lock.lock(); try { checkForOutputErrors(); // Set the processing metadata, and flag that we have initialized. processingMetaData = metaData; inputInitialized = true; signalUpdate(); // Now we must wait until the output thread initializes or // encounters an error. while (!outputInitialized) { waitForUpdate(); checkForOutputErrors(); } } finally { lock.unlock(); } } /** * Adds a new object to the postbox. * * @param o * The object to be added. */ public void put(T o) { if (!inputInitialized) { throw new OsmosisRuntimeException("initialize has not been called"); } inboundQueue.add(o); if (inboundQueue.size() >= chunkSize) { populateCentralQueue(); } } /** * {@inheritDoc} */ @Override public void complete() { if (!inputInitialized) { throw new OsmosisRuntimeException("initialize has not been called"); } lock.lock(); try { populateCentralQueue(); inputComplete = true; signalUpdate(); // Now we must wait until the output thread completes or // encounters an error. while (!outputComplete) { waitForUpdate(); checkForOutputErrors(); } } finally { lock.unlock(); } } /** * This method conforms to the * {@link org.openstreetmap.osmosis.core.lifecycle.Releasable} contract, * however there are limitations around calling it multiple times. Each call * to this method must be matched by a call to the outputRelease method in a * separate thread or deadlock will occur. */ @Override public void release() { lock.lock(); try { // If release is being called without having completed successfully, // it is an error condition. if (!inputComplete) { inputOkay = false; } inputReleased = true; inputExit = false; signalUpdate(); // Wait until the output thread releases. while (!outputReleased) { waitForUpdate(); } // At this point both threads have reached a release state so we can // reset our state. initializeQueues(); inputInitialized = false; inputComplete = false; inputReleased = false; inputExit = true; inputOkay = true; signalUpdate(); // Wait for the output thread to exit. while (!outputExit) { waitForUpdate(); } } finally { lock.unlock(); } } /** * Notifies that the output thread has begun processing, and gets the * initialization data set by the input thread. This will block until either * the input thread has called initialize, or an input error occurs. * * @return The initialization data. */ public Map outputInitialize() { if (outputInitialized) { throw new OsmosisRuntimeException("outputInitialize has already been called"); } lock.lock(); try { checkForInputErrors(); // We must wait until the input thread initializes or // encounters an error. while (!inputInitialized) { waitForUpdate(); checkForInputErrors(); } outputInitialized = true; signalUpdate(); return processingMetaData; } finally { lock.unlock(); } } /** * Indicates if data is available for output. This will block until either * data is available, input processing has completed, or an input error * occurs. * * @return True if data is available. */ public boolean hasNext() { int queueSize; if (!outputInitialized) { throw new OsmosisRuntimeException("outputInitialize has not been called"); } queueSize = outboundQueue.size(); if (queueSize <= 0) { consumeCentralQueue(); queueSize = outboundQueue.size(); } return queueSize > 0; } /** * Returns the next available object from the postbox. This should be * preceeded by a call to hasNext. * * @return The next available object. */ public T getNext() { if (hasNext()) { T result; result = outboundQueue.remove(); return result; } else { throw new OsmosisRuntimeException("No data is available, should call hasNext first."); } } /** * Notifies that the output thread has completed processing. This will block * until either the input thread has called complete, or an input error * occurs. */ public void outputComplete() { if (!outputInitialized) { throw new OsmosisRuntimeException("outputInitialize has not been called"); } lock.lock(); try { checkForInputErrors(); // We must wait until the input thread completes or encounters an // error. while (!inputComplete) { waitForUpdate(); checkForInputErrors(); } outputComplete = true; signalUpdate(); } finally { lock.unlock(); } } /** * Notifies that the output thread has released. This will block until the * input thread has also released and the object has been reset. */ public void outputRelease() { lock.lock(); try { // If release is being called without having completed successfully, // it is an error condition. if (!outputComplete) { outputOkay = false; signalUpdate(); } // Wait until the input thread is released. while (!inputReleased) { waitForUpdate(); } // At this point both threads have reached a release state so we can // set out state as released but waiting for exit. outputInitialized = false; outputComplete = false; outputReleased = true; outputExit = false; outputOkay = true; signalUpdate(); // Wait until the input thread has reached the exit point. while (!inputExit) { waitForUpdate(); } // The input thread has reached exit, so now we can clear the // release flag (required so that subsequent iterations if they // exist must go through the same handshake sequence) and flag that // we've reached exit. outputReleased = false; outputExit = true; signalUpdate(); } finally { lock.unlock(); } } } DataPostboxLoadInjector.java000066400000000000000000000040031253404521400351160ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import java.util.Date; import org.openstreetmap.osmosis.core.buffer.v0_6.EntityBuffer; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.misc.v0_6.NullWriter; import org.openstreetmap.osmosis.core.progress.v0_6.EntityProgressLogger; /** * Very simple class for applying load to the DataPostbox class and measuring * performance. * * @author Brett Henderson */ public final class DataPostboxLoadInjector implements Runnable { private EntityBuffer buffer; private EntityProgressLogger progressLogger; private NullWriter nullWriter; /** * Launches the application. * * @param args * The program arguments. */ public static void main(String[] args) { new DataPostboxLoadInjector().run(); } private DataPostboxLoadInjector() { buffer = new EntityBuffer(10000); progressLogger = new EntityProgressLogger(5000, null); buffer.setSink(progressLogger); nullWriter = new NullWriter(); progressLogger.setSink(nullWriter); } /** * {@inheritDoc} */ public void run() { Thread t1; Thread t2; t1 = new Thread(new Writer(), "input"); t2 = new Thread(buffer, "output"); t1.start(); t2.start(); try { t1.join(); } catch (InterruptedException e) { e.printStackTrace(); } try { t2.join(); } catch (InterruptedException e) { e.printStackTrace(); } } private class Writer implements Runnable { private Node node; private NodeContainer nodeContainer; public Writer() { node = new Node(new CommonEntityData(1, 2, new Date(), OsmUser.NONE, 3), 10, 10); nodeContainer = new NodeContainer(node); } public void run() { while (true) { buffer.process(nodeContainer); } } } } DynamicStoreClassRegister.java000066400000000000000000000015451253404521400354740ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; /** * This store class register dynamically allocates identifiers for classes as they are encountered * while writing to the store. These identifiers are maintained in memory and used while reading * back from the store. */ public class DynamicStoreClassRegister extends BaseStoreClassRegister { private byte idSequence; /** * Creates a new instance. */ public DynamicStoreClassRegister() { super(); idSequence = 0; } /** * {@inheritDoc} */ @Override public void storeIdentifierForClass(StoreWriter storeWriter, Class clazz) { if (!isClassRecognized(clazz)) { byte id; id = idSequence++; registerClass(clazz, id); } super.storeIdentifierForClass(storeWriter, clazz); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store/EmptyIterator.java000066400000000000000000000017641253404521400332720ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; /** * Provides an iterator which returns no data. This is returned by iterator * methods that have no data to be returned. * * @author Brett Henderson * @param * The type of data to be returned by the iterator. */ public class EmptyIterator implements ReleasableIterator { /** * {@inheritDoc} */ public boolean hasNext() { // No data can be returned. return false; } /** * {@inheritDoc} */ public DataType next() { throw new OsmosisRuntimeException("This iterator contains no data."); } /** * {@inheritDoc} */ public void remove() { throw new UnsupportedOperationException(); } /** * {@inheritDoc} */ public void release() { // Nothing to do. } } EndOfStoreException.java000066400000000000000000000030211253404521400342560ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * A runtime exception indicating that the end of the store has been reached while reading. * * @author Brett Henderson */ public class EndOfStoreException extends OsmosisRuntimeException { private static final long serialVersionUID = 1L; /** * Constructs a new exception with null as its detail message. */ public EndOfStoreException() { super(); } /** * Constructs a new exception with the specified detail message. The * cause is not initialized, and may subsequently be initialized by * a call to {@link #initCause}. * * @param message the detail message. */ public EndOfStoreException(String message) { super(message); } /** * Constructs a new exception with the specified cause and a detail * message of (cause==null ? null : cause.toString()) (which * typically contains the class and detail message of cause). * * @param cause the cause. */ public EndOfStoreException(Throwable cause) { super(cause); } /** * Constructs a new exception with the specified detail message and * cause. * * @param message the detail message. * @param cause the cause. */ public EndOfStoreException(String message, Throwable cause) { super(message, cause); } } GenericObjectReader.java000066400000000000000000000016311253404521400342220ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; /** * Provides functionality to deserialise a Storeable implementation from a * store. This implementation supports the loading of any Storeable object. * * @author Brett Henderson */ public class GenericObjectReader extends BaseObjectReader { /** * Creates a new instance. * * @param storeReader * The store writer to read all serialised data from. * @param storeClassRegister * The register for class to identifier mappings. */ public GenericObjectReader(StoreReader storeReader, StoreClassRegister storeClassRegister) { super(storeReader, storeClassRegister); } /** * {@inheritDoc} */ @Override protected Class readClassFromIdentifier(StoreReader sr, StoreClassRegister scr) { return scr.getClassFromIdentifier(sr); } } GenericObjectSerializationFactory.java000066400000000000000000000015341253404521400371670ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; /** * An object reader and writer factory providing generic object serialisation * capabilities capable of storing and loading any Storeable class * implementations. * * @author Brett Henderson */ public class GenericObjectSerializationFactory implements ObjectSerializationFactory { /** * {@inheritDoc} */ @Override public ObjectReader createObjectReader(StoreReader storeReader, StoreClassRegister storeClassRegister) { return new GenericObjectReader(storeReader, storeClassRegister); } /** * {@inheritDoc} */ @Override public ObjectWriter createObjectWriter(StoreWriter storeWriter, StoreClassRegister storeClassRegister) { return new GenericObjectWriter(storeWriter, storeClassRegister); } } GenericObjectWriter.java000066400000000000000000000016361253404521400343010ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; /** * Provides functionality to serialise a Storeable implementation to a store. * This implementation supports the storing of any Storeable object. * * @author Brett Henderson */ public class GenericObjectWriter extends BaseObjectWriter { /** * Creates a new instance. * * @param storeWriter * The store writer to write all serialised data to. * @param storeClassRegister * The register for class to identifier mappings. */ public GenericObjectWriter(StoreWriter storeWriter, StoreClassRegister storeClassRegister) { super(storeWriter, storeClassRegister); } /** * {@inheritDoc} */ @Override protected void writeClassIdentifier(StoreWriter sw, StoreClassRegister scr, Class clazz) { scr.storeIdentifierForClass(sw, clazz); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store/IndexElement.java000066400000000000000000000014361253404521400330370ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; /** * Defines the methods to be implemented by data classes stored within an index. *

* Classes implementing this interface provide Storeable functionality with * restrictions. *

    *
  • All instances must persist using an identical number of bytes.
  • *
  • The key must be persisted first allowing a key instance to be loaded * independently.
  • *
* * @param * The index key type. * @author Brett Henderson */ public interface IndexElement extends Storeable { /** * Returns the key associated with this element for the purposes of * indexing. * * @return The key of the index element. */ K getKey(); } IndexRangeIterator.java000066400000000000000000000043361253404521400341370ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import java.util.Comparator; import java.util.Iterator; import java.util.NoSuchElementException; /** * Iterates over specific range within an index source. It will skip records until * it reaches the beginning of the range, and stop when it reaches the end of * the range. * * @param * The index key type. * @param * The index record being stored. * @author Brett Henderson */ public class IndexRangeIterator> implements Iterator { private Iterator source; private K beginKey; private K endKey; private Comparator ordering; private boolean nextRecordAvailable; private T nextRecord; /** * Creates a new instance. * * @param source * The input index source. * @param beginKey * The first key for which to return data. * @param endKey * The last key for which to return data. * @param ordering * The index key ordering to be used for comparing keys. */ public IndexRangeIterator(Iterator source, K beginKey, K endKey, Comparator ordering) { this.source = source; this.beginKey = beginKey; this.endKey = endKey; this.ordering = ordering; nextRecordAvailable = false; } /** * {@inheritDoc} */ @Override public boolean hasNext() { while (!nextRecordAvailable) { K key; if (!source.hasNext()) { break; } // Get the next record and its key. nextRecord = source.next(); key = nextRecord.getKey(); // Skip over records with a key lower than beginKey. if (ordering.compare(key, beginKey) >= 0) { // No more data is available if we've passed endKey. if (ordering.compare(nextRecord.getKey(), endKey) > 0) { break; } nextRecordAvailable = true; } } return nextRecordAvailable; } /** * {@inheritDoc} */ @Override public T next() { if (!hasNext()) { throw new NoSuchElementException(); } nextRecordAvailable = false; return nextRecord; } /** * {@inheritDoc} */ @Override public void remove() { throw new UnsupportedOperationException(); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store/IndexStore.java000066400000000000000000000144331253404521400325430ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import java.io.File; import java.util.Comparator; import java.util.Iterator; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.lifecycle.Completable; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.sort.common.FileBasedSort; /** * Writes data into an index file and sorts it if input data is unordered. The * data must be fixed width to allow index values to be randomly accessed later. * * @param * The index key type. * @param * The index element type to be stored. * @author Brett Henderson */ public class IndexStore> implements Completable { private ObjectSerializationFactory serializationFactory; private RandomAccessObjectStore indexStore; private Comparator ordering; private String tempFilePrefix; private File indexFile; private K previousKey; private boolean sorted; private long elementCount; private long elementSize; private boolean complete; /** * Creates a new instance. * * @param elementType * The type of index element to be stored in the index. * @param ordering * A comparator that sorts index elements desired index key * ordering. * @param indexFile * The file to use for storing the index. */ public IndexStore(Class elementType, Comparator ordering, File indexFile) { this.ordering = ordering; this.indexFile = indexFile; serializationFactory = new SingleClassObjectSerializationFactory(elementType); indexStore = new RandomAccessObjectStore(serializationFactory, indexFile); sorted = true; elementCount = 0; elementSize = -1; complete = false; } /** * Creates a new instance. * * * @param elementType * The type of index element to be stored in the index. * @param ordering * A comparator that sorts index elements desired index key * ordering. * @param tempFilePrefix * The prefix of the temporary file. */ public IndexStore(Class elementType, Comparator ordering, String tempFilePrefix) { this.ordering = ordering; this.tempFilePrefix = tempFilePrefix; serializationFactory = new SingleClassObjectSerializationFactory(elementType); indexStore = new RandomAccessObjectStore(serializationFactory, tempFilePrefix); sorted = true; elementCount = 0; elementSize = -1; complete = false; } /** * Writes the specified element to the index. * * @param element * The index element which includes the identifier when stored. */ public void write(T element) { K key; long fileOffset; if (complete) { throw new OsmosisRuntimeException("Cannot write new data once reading has begun."); } fileOffset = indexStore.add(element); key = element.getKey(); // If the new element contains a key that is not sequential, we need to // mark the index as unsorted so we can perform a sort prior to reading. if (previousKey != null) { if (ordering.compare(previousKey, key) > 0) { sorted = false; } } previousKey = key; elementCount++; // Calculate and verify the element size. This index requires all keys to be the same length // to allow sorting and searching to occur. The first element has a file offset of 0 so we // ignore that one. The second element offset will tell us the size of the first element. // From that point on we verify that all elements have the same size. if (elementCount == 2) { elementSize = fileOffset; } else if (elementCount > 2) { long expectedOffset; expectedOffset = (elementCount - 1) * elementSize; if (expectedOffset != fileOffset) { throw new OsmosisRuntimeException( "Inconsistent element sizes, new file offset=" + fileOffset + ", expected offset=" + expectedOffset + ", element size=" + elementSize + ", element count=" + elementCount ); } } } /** * Creates a new reader capable of accessing the contents of this store. The * reader must be explicitly released when no longer required. Readers must * be released prior to this store. * * @return A store reader. */ public IndexStoreReader createReader() { return new IndexStoreReader(indexStore.createReader(), ordering); } /** * {@inheritDoc} */ public void complete() { if (!complete) { indexStore.complete(); if (!sorted) { final Comparator keyOrdering = ordering; FileBasedSort fileSort; // Create a new file based sort instance ordering elements by their // identifiers. fileSort = new FileBasedSort( serializationFactory, new Comparator() { private Comparator elementKeyOrdering = keyOrdering; @Override public int compare(T o1, T o2) { return elementKeyOrdering.compare(o1.getKey(), o2.getKey()); } }, true ); try { RandomAccessObjectStoreReader indexStoreReader; ReleasableIterator sortIterator; // Read all data from the index store into the sorting store. indexStoreReader = indexStore.createReader(); try { Iterator indexIterator; indexIterator = indexStoreReader.iterate(); while (indexIterator.hasNext()) { fileSort.add(indexIterator.next()); } } finally { indexStoreReader.release(); } // Release the existing index store and create a new one. indexStore.release(); if (indexFile != null) { indexStore = new RandomAccessObjectStore(serializationFactory, indexFile); } else { indexStore = new RandomAccessObjectStore(serializationFactory, tempFilePrefix); } // Read all data from the sorting store back into the index store. sortIterator = fileSort.iterate(); try { while (sortIterator.hasNext()) { indexStore.add(sortIterator.next()); } } finally { sortIterator.release(); } } finally { fileSort.release(); } } complete = true; } } /** * {@inheritDoc} */ public void release() { indexStore.release(); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store/IndexStoreReader.java000066400000000000000000000166221253404521400336700ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import java.util.ArrayList; import java.util.Comparator; import java.util.Iterator; import java.util.List; import org.openstreetmap.osmosis.core.lifecycle.Releasable; /** * Provides read-only access to an index store. Each thread accessing the object * store must create its own reader. The reader maintains all references to * heavyweight resources such as file handles used to access the store * eliminating the need for objects such as object iterators to be cleaned up * explicitly. * * @param * The index key type. * @param * The object type being stored. * @author Brett Henderson */ public class IndexStoreReader> implements Releasable { private RandomAccessObjectStoreReader indexStoreReader; private Comparator ordering; private boolean elementDetailsInitialized; private long elementCount; private long elementSize; private long binarySearchElementCount; private int binarySearchDepth; private List> binarySearchCache; /** * Creates a new instance. * * @param indexStoreReader * Provides access to the index data. * @param ordering * A comparator that sorts index elements desired index key * ordering. */ public IndexStoreReader(RandomAccessObjectStoreReader indexStoreReader, Comparator ordering) { this.indexStoreReader = indexStoreReader; this.ordering = ordering; elementDetailsInitialized = false; } /** * Initialises the element count and element size required for performing * binary searches within the index. */ private void initializeElementDetails() { long dataLength; dataLength = indexStoreReader.length(); if (dataLength <= 0) { elementCount = 0; elementSize = 0; } else { indexStoreReader.get(0); elementSize = indexStoreReader.position(); elementCount = dataLength / elementSize; } // Determine how many levels of a binary tree must be traversed to reach a result. binarySearchDepth = 0; binarySearchElementCount = 1; // Must add 1 here because we search from offset -1 to elementCount while (binarySearchElementCount < (elementCount + 1)) { binarySearchDepth++; binarySearchElementCount *= 2; } // Initialise the binary search cache. binarySearchCache = new ArrayList>(binarySearchDepth); for (int i = 0; i < binarySearchDepth; i++) { binarySearchCache.add(null); } elementDetailsInitialized = true; } /** * Returns the index of the first index element with a key greater than or * equal to the specified key. * * @param searchKey * The key to search for. * @return The matching index. */ private long getKeyIndex(K searchKey) { long intervalBegin; long intervalEnd; int currentSearchDepth; boolean useCache; boolean higherThanPrevious; // The element details must be initialised before searching. if (!elementDetailsInitialized) { initializeElementDetails(); } intervalBegin = -1; intervalEnd = binarySearchElementCount; currentSearchDepth = 0; useCache = true; higherThanPrevious = true; while ((intervalBegin + 1) < intervalEnd) { long intervalMid; // Calculate the mid point of the current interval. intervalMid = (intervalBegin + intervalEnd) / 2; // We can only perform a comparison if the mid point of the current // search interval is within the data set. if (intervalMid < elementCount) { K intervalMidKey = null; ComparisonElement searchElement; boolean comparisonHigher; // Attempt to retrieve the key for the mid point from the search // cache. if (useCache) { searchElement = binarySearchCache.get(currentSearchDepth); if (searchElement != null && searchElement.getIndexOffset() == intervalMid) { intervalMidKey = searchElement.getKey(); } else { useCache = false; } } // If the value couldn't be retrieved from cache, load it from // the underlying dataset. if (!useCache) { intervalMidKey = indexStoreReader.get(intervalMid * elementSize).getKey(); } // Compare the current key for equality with the desired key. comparisonHigher = ordering.compare(searchKey, intervalMidKey) > 0; if (!useCache) { binarySearchCache.set(currentSearchDepth, new ComparisonElement(intervalMid, intervalMidKey)); } higherThanPrevious = comparisonHigher; } else { higherThanPrevious = false; } // Update binary search attributes based on recent comparison. currentSearchDepth++; if (higherThanPrevious) { intervalBegin = intervalMid; } else { intervalEnd = intervalMid; } } return intervalEnd; } /** * Returns the index element identified by id. * * @param key * The identifier for the index element to be retrieved. * @return The requested object. */ public T get(K key) { long keyIndex; // Determine the location of the key within the index. keyIndex = getKeyIndex(key); if (keyIndex < elementCount) { T element; K locatedKey; element = indexStoreReader.get(keyIndex * elementSize); locatedKey = element.getKey(); if (ordering.compare(key, locatedKey) == 0) { return element; } } throw new NoSuchIndexElementException("Requested key " + key + " does not exist."); } /** * Returns all elements in the range specified by the begin and end keys. * All elements with keys matching and lying between the two keys will be * returned. * * @param beginKey * The key marking the beginning of the required index elements. * @param endKey * The key marking the end of the required index elements. The * identifier for the index element to be retrieved. * @return An iterator pointing to the requested range. */ public Iterator getRange(K beginKey, K endKey) { long keyIndex; // Determine the location of the begin key within the index. keyIndex = getKeyIndex(beginKey); // Iterate across the range. return new IndexRangeIterator( indexStoreReader.iterate(keyIndex * elementSize), beginKey, endKey, ordering ); } /** * {@inheritDoc} */ @Override public void release() { indexStoreReader.release(); } /** * Maintains the state associated with a single index search comparison. The * complete path to the previously searched element is maintained using a * list of these elements between searches, improving performance for * searches on keys that are closely located. */ private static class ComparisonElement { private long indexOffset; private K key; /** * Creates a new instance. * * @param indexOffset * The offset of the current key within the index. * @param key * The key of the index element compared against. */ public ComparisonElement(long indexOffset, K key) { this.indexOffset = indexOffset; this.key = key; } /** * Returns the index offset this key is located at. * * @return The offset of the key within the index. */ public long getIndexOffset() { return indexOffset; } /** * Returns the key associated with this comparison. * * @return The comparison key. */ public K getKey() { return key; } } } IndexedObjectStore.java000066400000000000000000000064541253404521400341300ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import java.io.File; import org.openstreetmap.osmosis.core.lifecycle.Completable; /** * Provides a store for objects that can be located by a long identifier. * * @param * The object type to be stored. * @author Brett Henderson */ public class IndexedObjectStore implements Completable { private RandomAccessObjectStore objectStore; private IndexStore indexStore; /** * Creates a new instance. * * @param serializationFactory * The factory defining the object serialisation implementation. * @param tmpFilePrefix * The prefix of the storage file. */ public IndexedObjectStore(ObjectSerializationFactory serializationFactory, String tmpFilePrefix) { objectStore = new RandomAccessObjectStore(serializationFactory, tmpFilePrefix + "d"); indexStore = new IndexStore( LongLongIndexElement.class, new ComparableComparator(), tmpFilePrefix + "i" ); } /** * Creates a new instance. * * @param serializationFactory * The factory defining the object serialisation implementation. * @param objectStorageFile * The storage file to use for objects. * @param indexStorageFile * The storage file to use for the index. */ public IndexedObjectStore( ObjectSerializationFactory serializationFactory, File objectStorageFile, File indexStorageFile) { objectStore = new RandomAccessObjectStore(serializationFactory, objectStorageFile); indexStore = new IndexStore( LongLongIndexElement.class, new ComparableComparator(), indexStorageFile ); } /** * Adds the specified object to the store. * * @param id * The identifier allowing the object to be retrieved. * @param data * The object to be added. */ public void add(long id, T data) { long objectOffset; // Write the object to the object store. objectOffset = objectStore.add(data); // Write the object offset keyed by the id to the index store. indexStore.write(new LongLongIndexElement(id, objectOffset)); } /** * Creates a new reader capable of accessing the contents of this store. The * reader must be explicitly released when no longer required. Readers must * be released prior to this store. * * @return A store reader. */ public IndexedObjectStoreReader createReader() { RandomAccessObjectStoreReader objectStoreReader = null; objectStoreReader = objectStore.createReader(); try { IndexStoreReader indexStoreReader; IndexedObjectStoreReader reader; indexStoreReader = indexStore.createReader(); reader = new IndexedObjectStoreReader(objectStoreReader, indexStoreReader); objectStoreReader = null; return reader; } finally { if (objectStoreReader != null) { objectStoreReader.release(); } } } /** * {@inheritDoc} */ @Override public void complete() { objectStore.complete(); indexStore.complete(); } /** * {@inheritDoc} */ public void release() { objectStore.release(); indexStore.release(); } } IndexedObjectStoreReader.java000066400000000000000000000034741253404521400352520ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import org.openstreetmap.osmosis.core.lifecycle.Releasable; /** * Provides read-only access to an indexed object store. Each thread accessing * the object store must create its own reader. The reader maintains all * references to heavyweight resources such as file handles used to access the * store eliminating the need for objects such as object iterators to be cleaned * up explicitly. * * @param * The object type being stored. * @author Brett Henderson */ public class IndexedObjectStoreReader implements Releasable { private RandomAccessObjectStoreReader objectStoreReader; private IndexStoreReader indexStoreReader; /** * Creates a new instance. * * @param objectStoreReader * Provides access to the object data. * @param indexStoreReader * Provides access to the index data. */ public IndexedObjectStoreReader( RandomAccessObjectStoreReader objectStoreReader, IndexStoreReader indexStoreReader) { this.objectStoreReader = objectStoreReader; this.indexStoreReader = indexStoreReader; } /** * Returns the object identified by id. * * @param id * The identifier for the object to be retrieved. * @return The requested object. */ public T get(long id) { long objectOffset; T data; // Get the object offset from the index store. objectOffset = indexStoreReader.get(id).getValue(); // Read the object from the object store. data = objectStoreReader.get(objectOffset); return data; } /** * {@inheritDoc} */ @Override public void release() { objectStoreReader.release(); indexStoreReader.release(); } } IntegerLongIndexElement.java000066400000000000000000000031261253404521400351140ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; /** * A single index element for an int-long index. * * @author Brett Henderson */ public class IntegerLongIndexElement implements IndexElement { /** * The value identifier. */ private int id; /** * The data value. */ private long value; /** * Creates a new instance. * * @param id * The value identifier. * @param value * The data value. */ public IntegerLongIndexElement(int id, long value) { this.id = id; this.value = value; } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers * within the store. */ public IntegerLongIndexElement(StoreReader sr, StoreClassRegister scr) { this(sr.readInteger(), sr.readLong()); } /** * {@inheritDoc} */ public void store(StoreWriter writer, StoreClassRegister storeClassRegister) { writer.writeInteger(id); writer.writeLong(value); } /** * {@inheritDoc} */ @Override public Integer getKey() { // This will cause the sign of the identifier to be ignored resulting in // unsigned ordering of index values. return id; } /** * Returns the id of this index element. * * @return The index id. */ public int getId() { return id; } /** * Returns the value of this index element. * * @return The index value. */ public long getValue() { return value; } } LongLongIndexElement.java000066400000000000000000000027211253404521400344160ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; /** * A single index element for a long-long index. * * @author Brett Henderson */ public class LongLongIndexElement implements IndexElement { /** * The value identifier. */ private long id; /** * The data value. */ private long value; /** * Creates a new instance. * * @param id * The value identifier. * @param value * The data value. */ public LongLongIndexElement(long id, long value) { this.id = id; this.value = value; } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers * within the store. */ public LongLongIndexElement(StoreReader sr, StoreClassRegister scr) { this(sr.readLong(), sr.readLong()); } /** * {@inheritDoc} */ public void store(StoreWriter writer, StoreClassRegister storeClassRegister) { writer.writeLong(id); writer.writeLong(value); } /** * {@inheritDoc} */ @Override public Long getKey() { return id; } /** * Returns the id of this index element. * * @return The index id. */ public long getId() { return id; } /** * Returns the value of this index element. * * @return The index value. */ public long getValue() { return value; } } MultipleSourceIterator.java000066400000000000000000000027411253404521400350650ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import java.util.LinkedList; import java.util.List; import java.util.NoSuchElementException; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; /** * Allows the contents of several iterators to be combined into a single * iterator. * * @param * The type of data to be iterated over. * @author Brett Henderson */ public class MultipleSourceIterator implements ReleasableIterator { private List> sources; /** * Creates a new instance. * * @param sources * The input iterators. */ public MultipleSourceIterator(List> sources) { this.sources = new LinkedList>(sources); } /** * {@inheritDoc} */ @Override public boolean hasNext() { while (sources.size() > 0) { if (sources.get(0).hasNext()) { return true; } else { sources.remove(0).release(); } } return false; } /** * {@inheritDoc} */ @Override public T next() { if (!hasNext()) { throw new NoSuchElementException(); } return sources.get(0).next(); } /** * {@inheritDoc} */ @Override public void remove() { throw new UnsupportedOperationException(); } /** * {@inheritDoc} */ @Override public void release() { for (ReleasableIterator source : sources) { source.release(); } } } NoSuchIndexElementException.java000066400000000000000000000030561253404521400357570ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * A runtime exception indicating that the requested index value does not exist. * * @author Brett Henderson */ public class NoSuchIndexElementException extends OsmosisRuntimeException { private static final long serialVersionUID = 1L; /** * Constructs a new exception with null as its detail message. */ public NoSuchIndexElementException() { super(); } /** * Constructs a new exception with the specified detail message. The * cause is not initialized, and may subsequently be initialized by * a call to {@link #initCause}. * * @param message the detail message. */ public NoSuchIndexElementException(String message) { super(message); } /** * Constructs a new exception with the specified cause and a detail * message of (cause==null ? null : cause.toString()) (which * typically contains the class and detail message of cause). * * @param cause the cause. */ public NoSuchIndexElementException(Throwable cause) { super(cause); } /** * Constructs a new exception with the specified detail message and * cause. * * @param message the detail message. * @param cause the cause. */ public NoSuchIndexElementException(String message, Throwable cause) { super(message, cause); } } ObjectDataInputIterator.java000066400000000000000000000025031253404521400351250ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import java.util.Iterator; import java.util.NoSuchElementException; /** * Provides functionality common to all object iterators. * * @param * The type of data to be returned by the iterator. * @author Brett Henderson */ public class ObjectDataInputIterator implements Iterator { private ObjectReader objectReader; private T nextElement; /** * Creates a new instance. * * @param objectReader * The reader containing the objects to be deserialized. */ public ObjectDataInputIterator(ObjectReader objectReader) { this.objectReader = objectReader; } /** * {@inheritDoc} */ @SuppressWarnings("unchecked") public boolean hasNext() { if (nextElement != null) { return true; } try { nextElement = (T) objectReader.readObject(); } catch (EndOfStoreException e) { return false; } return true; } /** * {@inheritDoc} */ public T next() { if (hasNext()) { T result; result = nextElement; nextElement = null; return result; } else { throw new NoSuchElementException(); } } /** * {@inheritDoc} */ public void remove() { throw new UnsupportedOperationException(); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store/ObjectReader.java000066400000000000000000000006441253404521400330070ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; /** * Implementations provide functionality to deserialise a Storeable * implementation from a store. * * @author Brett Henderson */ public interface ObjectReader { /** * Reads an object from storage. * * @return The re-instantiated object. */ Storeable readObject(); } ObjectSerializationFactory.java000066400000000000000000000021251253404521400356670ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; /** * Implementations of this factory provide methods for creating object readers * and writers for storing and loading objects from data stores. * * @author Brett Henderson */ public interface ObjectSerializationFactory { /** * Creates a new object reader. * * @param storeReader * The store writer to write all serialised data to. * @param storeClassRegister * The register for class to identifier mappings. * @return The newly created object reader. */ ObjectReader createObjectReader(StoreReader storeReader, StoreClassRegister storeClassRegister); /** * Creates a new object writer. * * @param storeWriter * The store writer to write all serialised data to. * @param storeClassRegister * The register for class to identifier mappings. * @return The newly created object writer. */ ObjectWriter createObjectWriter(StoreWriter storeWriter, StoreClassRegister storeClassRegister); } ObjectStreamIterator.java000066400000000000000000000026201253404521400344670ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import java.io.DataInputStream; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; /** * This class reads objects from an ObjectInputStream until the end of stream is * reached. * * @param * The type of data to be returned by the iterator. * @author Brett Henderson */ public class ObjectStreamIterator extends ObjectDataInputIterator implements ReleasableIterator { private static final Logger LOG = Logger.getLogger(ObjectStreamIterator.class.getName()); private DataInputStream inStream; /** * Creates a new instance. * * @param inStream * The stream to read objects from. * @param objectReader * The reader containing the objects to be deserialized. */ public ObjectStreamIterator(DataInputStream inStream, ObjectReader objectReader) { super(objectReader); this.inStream = inStream; } /** * {@inheritDoc} */ public void release() { if (inStream != null) { try { inStream.close(); } catch (IOException e) { // We cannot throw an exception within a release method. LOG.log(Level.WARNING, "Unable to close input stream.", e); } inStream = null; } } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store/ObjectWriter.java000066400000000000000000000006731253404521400330630ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; /** * Implementations provide functionality to serialise a Storeable implementation * to a store. * * @author Brett Henderson */ public interface ObjectWriter { /** * Writes an object to storage. * * @param value * The object to be written. */ void writeObject(Storeable value); } OffsetTrackingOutputStream.java000066400000000000000000000026301253404521400357020ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import java.io.IOException; import java.io.OutputStream; /** * Tracks the number of bytes written so far to the stream. * * @author Brett Henderson */ public class OffsetTrackingOutputStream extends OutputStream { private OutputStream out; private long byteCount; /** * Creates a new instance. * * @param out * The destination stream for all written data. */ public OffsetTrackingOutputStream(OutputStream out) { this.out = out; byteCount = 0; } /** * Returns the number of bytes written to this stream so far. * * @return The current byte count. */ public long getByteCount() { return byteCount; } /** * {@inheritDoc} */ @Override public void write(int b) throws IOException { byteCount++; out.write(b); } /** * {@inheritDoc} */ @Override public void write(byte[] b, int off, int len) throws IOException { byteCount += len; out.write(b, off, len); } /** * {@inheritDoc} */ @Override public void write(byte[] b) throws IOException { byteCount += b.length; out.write(b); } /** * {@inheritDoc} */ @Override public void flush() throws IOException { out.flush(); } /** * {@inheritDoc} */ @Override public void close() throws IOException { out.close(); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store/PeekableIterator.java000066400000000000000000000032711253404521400336770ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; /** * Wraps a releasable iterator and adds the ability to peek at the next value * without moving to the next record. * * @author Brett Henderson * * @param * The type of entity to retrieved. */ public class PeekableIterator implements ReleasableIterator { private ReleasableIterator sourceIterator; private T nextValue; private boolean nextValueAvailable; /** * Creates a new instance. * * @param sourceIterator * The underlying iterator providing source data. This will be * owned and released by this object. */ public PeekableIterator(ReleasableIterator sourceIterator) { this.sourceIterator = sourceIterator; nextValue = null; nextValueAvailable = false; } /** * {@inheritDoc} */ public boolean hasNext() { return nextValueAvailable || sourceIterator.hasNext(); } /** * Returns the next available entity without advancing to the next record. * * @return The next available entity. */ public T peekNext() { if (!nextValueAvailable) { nextValue = sourceIterator.next(); nextValueAvailable = true; } return nextValue; } /** * {@inheritDoc} */ public T next() { T result; result = peekNext(); nextValue = null; nextValueAvailable = false; return result; } /** * {@inheritDoc} */ public void release() { sourceIterator.release(); } /** * {@inheritDoc} */ public void remove() { throw new UnsupportedOperationException(); } } PersistentIterator.java000066400000000000000000000050331253404521400342460ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import java.util.NoSuchElementException; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; /** * Wraps an underlying iterator implementation so that all data is read from the * underlying reader and written to a temporary file before being returned. This * allows underlying resources such as database connections to be closed sooner * than otherwise possible. This object will own the wrapped source iterator and * release it along with all other resources. * * @author Brett Henderson * @param * The type of entity to retrieved. */ public class PersistentIterator implements ReleasableIterator { private ReleasableIterator sourceIterator; private SimpleObjectStore store; private ReleasableIterator storeIterator; private boolean initialized; /** * Creates a new instance. * * @param serializationFactory * The factory defining the object serialisation implementation. * @param sourceIterator * The source of data. * @param storageFilePrefix * The prefix of the storage file. * @param useCompression * If true, the storage file will be compressed. */ public PersistentIterator( ObjectSerializationFactory serializationFactory, ReleasableIterator sourceIterator, String storageFilePrefix, boolean useCompression) { this.sourceIterator = sourceIterator; store = new SimpleObjectStore(serializationFactory, storageFilePrefix, useCompression); initialized = false; } private void initialize() { if (!initialized) { while (sourceIterator.hasNext()) { store.add(sourceIterator.next()); } sourceIterator.release(); sourceIterator = null; storeIterator = store.iterate(); initialized = true; } } /** * {@inheritDoc} */ public boolean hasNext() { initialize(); return storeIterator.hasNext(); } /** * {@inheritDoc} */ public T next() { if (!hasNext()) { throw new NoSuchElementException(); } return storeIterator.next(); } /** * {@inheritDoc} */ public void release() { if (storeIterator != null) { storeIterator.release(); storeIterator = null; } store.release(); if (sourceIterator != null) { sourceIterator.release(); sourceIterator = null; } } /** * {@inheritDoc} */ public void remove() { throw new UnsupportedOperationException(); } } RandomAccessObjectStore.java000066400000000000000000000160701253404521400351050ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.lifecycle.Completable; /** * Provides a store for writing objects to a file for later retrieval. The * number of objects is limited only by disk space. * * @param * The object type to be stored. * @author Brett Henderson */ public class RandomAccessObjectStore implements Completable { private static final Logger LOG = Logger.getLogger(RandomAccessObjectStore.class.getName()); private ObjectSerializationFactory serializationFactory; private StorageStage stage; private String tempFilePrefix; private File tempFile; private File storageFile; private OffsetTrackingOutputStream offsetTrackingStream; private StoreClassRegister storeClassRegister; private ObjectWriter objectWriter; /** * Creates a new instance. * * @param serializationFactory * The factory defining the object serialisation implementation. * @param tempFilePrefix * The prefix of the temporary file. */ public RandomAccessObjectStore(ObjectSerializationFactory serializationFactory, String tempFilePrefix) { this.serializationFactory = serializationFactory; this.tempFilePrefix = tempFilePrefix; storeClassRegister = new DynamicStoreClassRegister(); stage = StorageStage.NotStarted; } /** * Creates a new instance. * * @param serializationFactory * The factory defining the object serialisation implementation. * @param storageFile * The storage file to use. */ public RandomAccessObjectStore(ObjectSerializationFactory serializationFactory, File storageFile) { this.serializationFactory = serializationFactory; this.storageFile = storageFile; storeClassRegister = new DynamicStoreClassRegister(); stage = StorageStage.NotStarted; } /** * Initialises the output file and configures the class for adding data. */ private void initializeAddStage() { // We can't add if we've passed the add stage. if (stage.compareTo(StorageStage.Add) > 0) { throw new OsmosisRuntimeException("Cannot add to storage in stage " + stage + "."); } // If we're not up to the add stage, initialise for adding. if (stage.compareTo(StorageStage.Add) < 0) { FileOutputStream fileStream = null; try { if (storageFile == null) { tempFile = File.createTempFile(tempFilePrefix, null); storageFile = tempFile; } fileStream = new FileOutputStream(storageFile); offsetTrackingStream = new OffsetTrackingOutputStream(new BufferedOutputStream(fileStream, 65536)); // Clear reference so that the stream doesn't get closed at the end of this method. fileStream = null; objectWriter = serializationFactory.createObjectWriter( new DataOutputStoreWriter(new DataOutputStream(offsetTrackingStream)), storeClassRegister ); stage = StorageStage.Add; } catch (IOException e) { throw new OsmosisRuntimeException( "Unable to create object stream writing to file " + storageFile + ".", e); } finally { if (fileStream != null) { try { fileStream.close(); } catch (IOException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to close file stream.", e); } } } } } /** * Adds the specified object to the store. * * @param data * The object to be added. * @return The offset within the output file of the object written. */ public long add(T data) { long objectFileOffset; initializeAddStage(); objectFileOffset = offsetTrackingStream.getByteCount(); // Write the object to the store. objectWriter.writeObject(data); return objectFileOffset; } /** * Configures the state of this object instance for reading mode. If the * current state doesn't allow reading, an exception will be thrown. */ private void initializeReadingStage() { // If we're already in the reading stage there's nothing to do. if (stage.equals(StorageStage.Reading)) { return; } if (stage.equals(StorageStage.Add)) { throw new OsmosisRuntimeException( "Cannot begin reading in " + StorageStage.Add + " stage, must call complete first."); } // If we haven't reached the reading stage yet, configure for output // first to ensure a file is available for reading. if (stage.compareTo(StorageStage.Reading) < 0) { stage = StorageStage.Reading; } // If we've passed the reading stage, we can't continue. if (stage.compareTo(StorageStage.Reading) > 0) { throw new OsmosisRuntimeException("Cannot read from storage once we've reached stage " + stage + "."); } } /** * Creates a new reader capable of accessing the contents of this store. The * reader must be explicitly released when no longer required. Readers must * be released prior to this store. * * @return A store reader. */ public RandomAccessObjectStoreReader createReader() { initializeReadingStage(); try { BufferedRandomAccessFileInputStream randomFileReader; randomFileReader = new BufferedRandomAccessFileInputStream(storageFile); return new RandomAccessObjectStoreReader( randomFileReader, serializationFactory.createObjectReader( new DataInputStoreReader( new DataInputStream(randomFileReader)), storeClassRegister) ); } catch (FileNotFoundException e) { throw new OsmosisRuntimeException( "Unable to create object stream reading from file " + storageFile + ".", e); } } /** * {@inheritDoc} */ @Override public void complete() { // If we're already in the reading stage, we don't need to perform a // complete. if (stage.compareTo(StorageStage.Reading) != 0) { // We need to make sure we pass through the add stage to ensure an // output file is created. initializeAddStage(); try { offsetTrackingStream.close(); offsetTrackingStream = null; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to close the file " + storageFile + "."); } stage = StorageStage.Reading; } } /** * {@inheritDoc} */ public void release() { if (offsetTrackingStream != null) { try { offsetTrackingStream.close(); } catch (Exception e) { // We cannot throw an exception within a release statement. LOG.log(Level.WARNING, "Unable to close offset tracking output stream.", e); } offsetTrackingStream = null; } if (tempFile != null) { if (!tempFile.delete()) { // We cannot throw an exception within a release statement. LOG.warning("Unable to delete file " + tempFile); } tempFile = null; } stage = StorageStage.Released; } } RandomAccessObjectStoreReader.java000066400000000000000000000071471253404521400362350ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import java.io.IOException; import java.util.Iterator; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.lifecycle.Releasable; /** * Provides read-only access to a random access object store. Each thread * accessing the object store must create its own reader. The reader maintains * all references to heavyweight resources such as file handles used to access * the store eliminating the need for objects such as object iterators to be * cleaned up explicitly. * * @param * The object type being stored. * @author Brett Henderson */ public class RandomAccessObjectStoreReader implements Releasable { private static final Logger LOG = Logger.getLogger(RandomAccessObjectStoreReader.class.getName()); private BufferedRandomAccessFileInputStream randomFile; private ObjectReader objectReader; /** * Creates a new instance. * * @param randomFile * A read-only random access file opened on the store file. * @param objectReader * The reader containing the objects to be deserialized. */ public RandomAccessObjectStoreReader(BufferedRandomAccessFileInputStream randomFile, ObjectReader objectReader) { this.randomFile = randomFile; this.objectReader = objectReader; } /** * Seeks to the specified location in the storage file. * * @param offset * The file offset to seek to. */ private void seek(long offset) { try { randomFile.seek(offset); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to seek to position " + offset + " in the storage file.", e); } } /** * Reads the object at the specified file offset. * * @param offset * The file offset to read an object from. * @return The requested object. */ @SuppressWarnings("unchecked") public T get(long offset) { seek(offset); return (T) objectReader.readObject(); } /** * Returns the length of data. * * @return The data length in bytes. */ public long length() { try { return randomFile.length(); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to obtain the length of the storage file.", e); } } /** * Returns the current read position. * * @return The current offset offset in bytes. */ public long position() { try { return randomFile.position(); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to obtain the current position in the storage file.", e); } } /** * Iterates over the entire stream of data. * * @param offset * The location in the storage file to begin reading. * @return An iterator for reading objects from the data store. This * iterator must be released after use. */ public Iterator iterate(long offset) { seek(offset); return new ObjectDataInputIterator(objectReader); } /** * Iterates over the entire stream of data. * * @return An iterator for reading objects from the data store. This * iterator must be released after use. */ public Iterator iterate() { return iterate(0); } /** * {@inheritDoc} */ @Override public void release() { if (randomFile != null) { try { randomFile.close(); } catch (IOException e) { // We cannot throw an exception within a release statement. LOG.log(Level.WARNING, "Unable to close random access file.", e); } randomFile = null; } } } ReleasableAdaptorForIterator.java000066400000000000000000000020631253404521400361270ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import java.util.Iterator; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; /** * Simple wrapper around a standard iterator to allow it to be used as a * releasable iterator. * * @param * The iterator type. * @author Brett Henderson */ public class ReleasableAdaptorForIterator implements ReleasableIterator { private Iterator source; /** * Creates a new instance. * * @param source * The input source. */ public ReleasableAdaptorForIterator(Iterator source) { this.source = source; } /** * {@inheritDoc} */ @Override public boolean hasNext() { return source.hasNext(); } /** * {@inheritDoc} */ @Override public T next() { return source.next(); } /** * {@inheritDoc} */ @Override public void remove() { source.remove(); } /** * {@inheritDoc} */ @Override public void release() { // Do nothing. } } SegmentedObjectStore.java000066400000000000000000000233171253404521400344600ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import java.util.zip.GZIPOutputStream; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.lifecycle.Completable; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.util.MultiMemberGZIPInputStream; /** * Provides a store for writing objects to a file for later retrieval. The * number of objects is limited only by disk space. *

* This class supports chunking where the stream is broken into segments. This * is achieved by calling the closeChunk method between add calls. *

* This store is only suitable for single-threaded use because it does not * provide per-thread readers. * * @param * The object type to be stored. * @author Brett Henderson */ public class SegmentedObjectStore implements Completable { private static final Logger LOG = Logger.getLogger(SegmentedObjectStore.class.getName()); private ObjectSerializationFactory serializationFactory; private StorageStage stage; private String storageFilePrefix; private File file; private FileOutputStream fileOutStream; private DataOutputStream dataOutStream; private ByteArrayOutputStream arrayOutStream; private StoreClassRegister storeClassRegister; private ObjectWriter objectWriter; private boolean chunkActive; private boolean useCompression; private long fileSize; /** * Creates a new instance. * * @param serializationFactory * The factory defining the object serialisation implementation. * @param storageFilePrefix * The prefix of the storage file. * @param useCompression * If true, the storage file will be compressed. */ public SegmentedObjectStore( ObjectSerializationFactory serializationFactory, String storageFilePrefix, boolean useCompression) { this.serializationFactory = serializationFactory; this.storageFilePrefix = storageFilePrefix; this.useCompression = useCompression; storeClassRegister = new DynamicStoreClassRegister(); stage = StorageStage.NotStarted; fileSize = 0; chunkActive = false; } /** * Adds the specified object to the store. * * @param data * The object to be added. */ public void add(T data) { // We can't add if we've passed the add stage. if (stage.compareTo(StorageStage.Add) > 0) { throw new OsmosisRuntimeException("Cannot add to storage in stage " + stage + "."); } // If we're not up to the add stage, initialise for adding. if (stage.compareTo(StorageStage.Add) < 0) { try { file = File.createTempFile(storageFilePrefix, null); fileOutStream = new FileOutputStream(file); stage = StorageStage.Add; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to open temporary file " + file + " for writing.", e); } } // Initialise the current chunk if it isn't already. if (!chunkActive) { try { arrayOutStream = new ByteArrayOutputStream(); if (useCompression) { dataOutStream = new DataOutputStream( new BufferedOutputStream( new GZIPOutputStream(arrayOutStream), 65536)); } else { dataOutStream = new DataOutputStream(new BufferedOutputStream(arrayOutStream, 65536)); } objectWriter = serializationFactory.createObjectWriter( new DataOutputStoreWriter(dataOutStream), storeClassRegister); chunkActive = true; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to create object stream.", e); } } // Write the object to the store. objectWriter.writeObject(data); // Update the file position based on the buffer size. fileSize += arrayOutStream.size(); // Write the buffer to file, and clear the buffer. try { arrayOutStream.writeTo(fileOutStream); arrayOutStream.reset(); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write object to file.", e); } } /** * Closes the current object stream and creates a new one. This allows read * operations to begin at offsets within the file. This can only be called * while adding to the store, not once reads are begun. Read operations must * begin at offsets created by this method. * * @return The start position of the new chunk within the file. */ public long closeChunk() { // We can only create an interval if we are in add mode. if (stage.compareTo(StorageStage.Add) != 0) { throw new OsmosisRuntimeException("Cannot create interval in stage " + stage + "."); } // Nothing needs to be done if the chunk is not yet active. if (chunkActive) { try { dataOutStream.close(); fileSize += arrayOutStream.size(); arrayOutStream.writeTo(fileOutStream); arrayOutStream.reset(); // Subsequent writes must begin a new object stream. arrayOutStream = null; dataOutStream = null; chunkActive = false; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to create a new interval.", e); } } return fileSize; } /** * Configures the state of this object instance for iterating or reading * mode. If the current state doesn't allow iterating, an exception will be * thrown. * * @return true if data is available, false otherwise. */ private boolean initializeIteratingStage() { // If we've been released, we can't iterate. if (stage.compareTo(StorageStage.Released) >= 0) { throw new OsmosisRuntimeException("Cannot iterate over storage in stage " + stage + "."); } // If no data was written, an empty iterator should be returned. if (stage.compareTo(StorageStage.NotStarted) <= 0) { return false; } // If we're in the add stage, close the current chunk and overall file stream. if (stage.compareTo(StorageStage.Add) == 0) { closeChunk(); try { fileOutStream.close(); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to close output stream.", e); } finally { fileOutStream = null; } stage = StorageStage.Reading; } // Data is available. return true; } /** * Returns an iterator for reading objects from the underlying data store. * * @return An iterator for reading objects from the data store. This * iterator must be released after use. */ public ReleasableIterator iterate() { return iterate(0, -1); } /** * Returns an iterator for reading objects from the underlying data store. * * @param streamOffset * The location in the underlying stream to begin reading. * @param maxObjectCount * The maximum number of objects to be returned, -1 for * unlimited. * @return An iterator for reading objects from the data store. This * iterator must be released after use. */ public ReleasableIterator iterate(long streamOffset, long maxObjectCount) { FileInputStream fileStream = null; try { DataInputStream dataInStream; ObjectReader objectReader; if (!initializeIteratingStage()) { return new EmptyIterator(); } // If we've reached this far, we have a file containing data to be read. Open a file stream on the file. try { fileStream = new FileInputStream(file); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to open file for reading.", e); } // Seek to the required starting point in the file. if (streamOffset > 0) { try { fileStream.skip(streamOffset); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to skip to specified location in file.", e); } } // Create the object input stream. try { if (useCompression) { dataInStream = new DataInputStream( new BufferedInputStream( new MultiMemberGZIPInputStream(fileStream), 65536)); } else { dataInStream = new DataInputStream(new BufferedInputStream(fileStream, 65536)); } } catch (IOException e) { throw new OsmosisRuntimeException("Unable to open object stream.", e); } // The stream will be owned by the caller, therefore we must clear // the reference now so it isn't closed on method exit. fileStream = null; objectReader = serializationFactory.createObjectReader( new DataInputStoreReader(dataInStream), storeClassRegister); if (maxObjectCount >= 0) { return new SubObjectStreamIterator(dataInStream, objectReader, maxObjectCount); } else { return new ObjectStreamIterator(dataInStream, objectReader); } } finally { if (fileStream != null) { try { fileStream.close(); } catch (IOException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to close result set.", e); } } } } /** * {@inheritDoc} */ @Override public void complete() { // Do nothing. } /** * {@inheritDoc} */ public void release() { if (fileOutStream != null) { try { fileOutStream.close(); } catch (Exception e) { // We cannot throw an exception within a release statement. LOG.log(Level.WARNING, "Unable to file output stream.", e); } fileOutStream = null; } if (file != null) { if (!file.delete()) { LOG.warning("Unable to delete file " + file); } file = null; } stage = StorageStage.Released; } } SimpleObjectStore.java000066400000000000000000000152001253404521400337660ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import java.util.zip.GZIPOutputStream; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.lifecycle.Completable; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.util.MultiMemberGZIPInputStream; /** * Provides a store for writing objects to a file for later retrieval. The * number of objects is limited only by disk space. * * @param * The object type to be stored. * @author Brett Henderson */ public class SimpleObjectStore implements Completable { private static final Logger LOG = Logger.getLogger(SimpleObjectStore.class.getName()); private ObjectSerializationFactory serializationFactory; private StorageStage stage; private String storageFilePrefix; private File file; private FileOutputStream fileOutStream; private DataOutputStream dataOutStream; private StoreClassRegister storeClassRegister; private ObjectWriter objectWriter; private boolean useCompression; /** * Creates a new instance. * * @param serializationFactory * The factory defining the object serialisation implementation. * @param storageFilePrefix * The prefix of the storage file. * @param useCompression * If true, the storage file will be compressed. */ public SimpleObjectStore( ObjectSerializationFactory serializationFactory, String storageFilePrefix, boolean useCompression) { this.serializationFactory = serializationFactory; this.storageFilePrefix = storageFilePrefix; this.useCompression = useCompression; storeClassRegister = new DynamicStoreClassRegister(); stage = StorageStage.NotStarted; } /** * Adds the specified object to the store. * * @param data * The object to be added. */ public void add(T data) { // We can't add if we've passed the add stage. if (stage.compareTo(StorageStage.Add) > 0) { throw new OsmosisRuntimeException("Cannot add to storage in stage " + stage + "."); } // If we're not up to the add stage, initialise for adding. if (stage.compareTo(StorageStage.Add) < 0) { try { file = File.createTempFile(storageFilePrefix, null); fileOutStream = new FileOutputStream(file); if (useCompression) { dataOutStream = new DataOutputStream( new BufferedOutputStream(new GZIPOutputStream(fileOutStream), 65536)); } else { dataOutStream = new DataOutputStream( new BufferedOutputStream(fileOutStream, 65536)); } objectWriter = serializationFactory.createObjectWriter( new DataOutputStoreWriter(dataOutStream), storeClassRegister); stage = StorageStage.Add; } catch (IOException e) { throw new OsmosisRuntimeException( "Unable to create object stream writing to temporary file " + file + ".", e); } } // Write the object to the store. objectWriter.writeObject(data); } /** * Configures the state of this object instance for iterating or reading * mode. If the current state doesn't allow iterating, an exception will be * thrown. * * @return true if data is available, false otherwise. */ private boolean initializeIteratingStage() { // If we've been released, we can't iterate. if (stage.compareTo(StorageStage.Released) >= 0) { throw new OsmosisRuntimeException("Cannot iterate over storage in stage " + stage + "."); } // If no data was written, an empty iterator should be returned. if (stage.compareTo(StorageStage.NotStarted) <= 0) { return false; } // If we're in the add stage, close the output streams. if (stage.compareTo(StorageStage.Add) == 0) { try { dataOutStream.close(); fileOutStream.close(); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to close output stream.", e); } finally { dataOutStream = null; fileOutStream = null; } stage = StorageStage.Reading; } // Data is available. return true; } /** * Returns an iterator for reading objects from the underlying data store. * * @return An iterator for reading objects from the data store. This * iterator must be released after use. */ public ReleasableIterator iterate() { FileInputStream fileStream = null; try { DataInputStream dataInStream; if (!initializeIteratingStage()) { return new EmptyIterator(); } // If we've reached this far, we have a file containing data to be read. Open a file stream on the file. try { fileStream = new FileInputStream(file); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to open file for reading.", e); } // Create the object input stream. try { if (useCompression) { dataInStream = new DataInputStream( new BufferedInputStream(new MultiMemberGZIPInputStream(fileStream), 65536)); } else { dataInStream = new DataInputStream( new BufferedInputStream(fileStream, 65536)); } } catch (IOException e) { throw new OsmosisRuntimeException("Unable to open object stream.", e); } // The stream will be owned by the caller, therefore we must clear // the reference now so it isn't closed on method exit. fileStream = null; return new ObjectStreamIterator( dataInStream, serializationFactory.createObjectReader( new DataInputStoreReader(dataInStream), storeClassRegister)); } finally { if (fileStream != null) { try { fileStream.close(); } catch (IOException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to close file input stream.", e); } } } } /** * {@inheritDoc} */ @Override public void complete() { // Do nothing. } /** * {@inheritDoc} */ public void release() { if (fileOutStream != null) { try { fileOutStream.close(); } catch (IOException e) { // We cannot throw an exception within a release statement. LOG.log(Level.WARNING, "Unable to close file output stream.", e); } fileOutStream = null; } if (file != null) { if (!file.delete()) { LOG.warning("Unable to delete file " + file); } file = null; } stage = StorageStage.Released; } } SingleClassObjectReader.java000066400000000000000000000021361253404521400350560ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; /** * Provides object reading functionality where only a single class type will be * loaded. * * @author Brett Henderson */ public class SingleClassObjectReader extends BaseObjectReader { private Class storeableType; /** * Creates a new instance. * * @param storeReader * The store writer to read all serialised data from. * @param storeClassRegister * The register for class to identifier mappings. * @param storeableType * The type of class to be stored. */ protected SingleClassObjectReader( StoreReader storeReader, StoreClassRegister storeClassRegister, Class storeableType) { super(storeReader, storeClassRegister); this.storeableType = storeableType; } /** * {@inheritDoc} */ @Override protected Class readClassFromIdentifier(StoreReader sr, StoreClassRegister scr) { // This implementation only stores a single type so no data read is // required. return storeableType; } } SingleClassObjectSerializationFactory.java000066400000000000000000000021631253404521400400210ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; /** * An object reader and writer factory providing object serialisation * capabilities where only a single class type will be stored. * * @author Brett Henderson */ public class SingleClassObjectSerializationFactory implements ObjectSerializationFactory { private Class storeableType; /** * Creates a new instance. * * @param storeableType * The class type to be supported. */ public SingleClassObjectSerializationFactory(Class storeableType) { this.storeableType = storeableType; } /** * {@inheritDoc} */ @Override public ObjectReader createObjectReader(StoreReader storeReader, StoreClassRegister storeClassRegister) { return new SingleClassObjectReader(storeReader, storeClassRegister, storeableType); } /** * {@inheritDoc} */ @Override public ObjectWriter createObjectWriter(StoreWriter storeWriter, StoreClassRegister storeClassRegister) { return new SingleClassObjectWriter(storeWriter, storeClassRegister, storeableType); } } SingleClassObjectWriter.java000066400000000000000000000025231253404521400351300ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Provides object writing functionality where only a single class type will be * stored. * * @author Brett Henderson */ public class SingleClassObjectWriter extends BaseObjectWriter { private Class storeableType; /** * Creates a new instance. * * @param storeWriter * The store writer to write all serialised data to. * @param storeClassRegister * The register for class to identifier mappings. * @param storeableType * The type of class to be stored. */ protected SingleClassObjectWriter( StoreWriter storeWriter, StoreClassRegister storeClassRegister, Class storeableType) { super(storeWriter, storeClassRegister); this.storeableType = storeableType; } /** * {@inheritDoc} */ @Override protected void writeClassIdentifier(StoreWriter sw, StoreClassRegister scr, Class clazz) { // We don't need to write anything, we just need to verify that the // class is of the correct type. if (!storeableType.equals(clazz)) { throw new OsmosisRuntimeException( "Received class " + clazz.getName() + ", expected class " + storeableType.getName() + "."); } } } StaticStoreClassRegister.java000066400000000000000000000013531253404521400353340ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; /** * This store class register dynamically allocates identifiers for classes as they are encountered * while writing to the store. These identifiers are maintained in memory and used while reading * back from the store. */ public class StaticStoreClassRegister extends BaseStoreClassRegister { /** * Creates a new instance. * * @param classes * The classes to be supported by this register. */ public StaticStoreClassRegister(Class[] classes) { super(); byte currentId; currentId = 0; for (Class clazz : classes) { registerClass(clazz, currentId++); } } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store/StorageStage.java000066400000000000000000000011221253404521400330360ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; /** * Each class used for managing storage has a lifecycle. The values of this enum * represent each state in that lifecycle. * * @author Brett Henderson */ public enum StorageStage { /** * No data has yet been written to storage. */ NotStarted, /** * Data is being written to storage. */ Add, /** * Data is being read from storage. */ Reading, /** * All resources associated with the storage have been released. */ Released } StoreClassRegister.java000066400000000000000000000021001253404521400341530ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; /** * Writes class identifiers to a store allowing the class to be identified when the store data is * being read back again. This provides the basis for multiple classes to be written to a single * store location. */ public interface StoreClassRegister { /** * Stores the unique identifier for the specified class to the store. * * @param storeWriter * The store to write class identification data to. * @param clazz * The class for which an identifier is required. */ void storeIdentifierForClass(StoreWriter storeWriter, Class clazz); /** * Returns the class associated with the unique identifier in the store. An * exception will be thrown if the identifier is not recognised. * * @param storeReader * The store to read class identification information from. * @return The class associated with the identifier. */ Class getClassFromIdentifier(StoreReader storeReader); } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store/StoreReader.java000066400000000000000000000017701253404521400326760ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; /** * Implementations of this interface are used by Storeable classes to load their * state. * * @author Brett Henderson */ public interface StoreReader { /** * Reads a boolean from storage. * * @return The loaded value. */ boolean readBoolean(); /** * Reads a byte from storage. * * @return The loaded value. */ byte readByte(); /** * Reads a character from storage. * * @return The loaded value. */ char readCharacter(); /** * Reads an integer from storage. * * @return The loaded value. */ int readInteger(); /** * Reads a long from storage. * * @return The loaded value. */ long readLong(); /** * Reads a double from storage. * * @return The loaded value. */ double readDouble(); /** * Reads a String from storage. * * @return The loaded value. */ String readString(); } StoreReleasingIterator.java000066400000000000000000000036231253404521400350370ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.lifecycle.Releasable; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; /** * This class allows an underlying store to be released along with the iterator * accessing it. As such it acts as an iterator delegating all calls to a * provided iterator, but during release it also releases the data store. * * @param * The type of data to be returned by the iterator. * @author Brett Henderson */ public class StoreReleasingIterator implements ReleasableIterator { private Releasable store; private ReleasableIterator iterator; /** * Creates a new instance. * * @param iterator * The underlying iterator to read from. * @param store * The store to be released after use. */ public StoreReleasingIterator(ReleasableIterator iterator, Releasable store) { this.iterator = iterator; this.store = store; } /** * {@inheritDoc} */ public boolean hasNext() { if (iterator == null) { throw new OsmosisRuntimeException("Iterator has been released."); } return iterator.hasNext(); } /** * {@inheritDoc} */ public DataType next() { if (iterator == null) { throw new OsmosisRuntimeException("Iterator has been released."); } return iterator.next(); } /** * {@inheritDoc} */ public void remove() { if (iterator == null) { throw new OsmosisRuntimeException("Iterator has been released."); } iterator.remove(); } /** * {@inheritDoc} */ public void release() { if (iterator != null) { iterator.release(); iterator = null; } if (store != null) { store.release(); store = null; } } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store/StoreWriter.java000066400000000000000000000023731253404521400327500ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; /** * Implementations of this interface are used by Storeable classes to persist * their state. * * @author Brett Henderson */ public interface StoreWriter { /** * Writes a boolean to storage. * * @param value * The value to be written. */ void writeBoolean(boolean value); /** * Writes a byte to storage. * * @param value * The value to be written. */ void writeByte(byte value); /** * Writes a character to storage. * * @param value * The value to be written. */ void writeCharacter(char value); /** * Writes an integer to storage. * * @param value * The value to be written. */ void writeInteger(int value); /** * Writes a long to storage. * * @param value * The value to be written. */ void writeLong(long value); /** * Writes a double to storage. * * @param value * The value to be written. */ void writeDouble(double value); /** * Writes a String to storage. * * @param value * The value to be written. */ void writeString(String value); } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store/Storeable.java000066400000000000000000000014361253404521400323760ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; /** * This interface defines the methods supporting custom serialisation. This * custom serialisation provides performance improvements over default java * serialisation at the expense of having to be supported explicitly by classes. * * @author Brett Henderson */ public interface Storeable { /** * Stores all state to the specified store writer. * * @param writer * The writer that persists data to an underlying store. * @param storeClassRegister * Maintains the mapping between classes and their identifiers * within the store. */ void store(StoreWriter writer, StoreClassRegister storeClassRegister); } StoreableConstructorCache.java000066400000000000000000000034011253404521400355030ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import java.lang.reflect.Constructor; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Provides a cache mapping between classes and storeable constructors. A * storeable constructor is a constructor accepting a StoreReader and * StoreClassRegister as arguments. This class uses reflection to obtain the * required constructor and is suitable for validating classes being written to * a store as well as obtaining suitable constructors when reading from a store. * * @author Brett Henderson */ public class StoreableConstructorCache { private Map, Constructor> cache; /** * Creates a new instance. */ public StoreableConstructorCache() { cache = new HashMap, Constructor>(); } /** * Returns the constructor on the specified class that is used for loading * state from a data store. * * @param clazz * The class with the storeable constructor. * @return The storeable class constructor. */ public Constructor getStoreableConstructor(Class clazz) { Constructor constructor; if (cache.containsKey(clazz)) { constructor = cache.get(clazz); } else { try { constructor = clazz.getConstructor(new Class [] {StoreReader.class, StoreClassRegister.class}); } catch (NoSuchMethodException e) { throw new OsmosisRuntimeException( "Class " + clazz.getName() + " does not have a constructor accepting a " + StoreReader.class.getName() + " argument, this is required for all Storeable classes.", e); } cache.put(clazz, constructor); } return constructor; } } SubObjectStreamIterator.java000066400000000000000000000025261253404521400351460ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import java.io.DataInputStream; /** * This class reads objects from an ObjectInputStream until the end of stream is * reached or a maximum number of objects is reached. * * @param * The type of data to be returned by the iterator. * @author Brett Henderson */ public class SubObjectStreamIterator extends ObjectStreamIterator { private long maxObjectCount; private long objectCount; /** * Creates a new instance. * * @param inStream * The stream to read objects from. * @param objectReader * The reader containing the objects to be deserialized. * @param maxObjectCount * The maximum number of objects to read. */ public SubObjectStreamIterator(DataInputStream inStream, ObjectReader objectReader, long maxObjectCount) { super(inStream, objectReader); this.maxObjectCount = maxObjectCount; objectCount = 0; } /** * {@inheritDoc} */ @Override public boolean hasNext() { if (objectCount >= maxObjectCount) { return false; } return super.hasNext(); } /** * {@inheritDoc} */ @Override public T next() { T result; result = super.next(); objectCount++; return result; } } UnsignedIntegerComparator.java000066400000000000000000000014401253404521400355140ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import java.util.Comparator; /** * Compares two Integers as unsigned values. * * @author Brett Henderson */ public class UnsignedIntegerComparator implements Comparator { /** * {@inheritDoc} */ @Override public int compare(Integer o1, Integer o2) { long value1; long value2; long comparison; // Convert the two integers to longs using an unsigned conversion and // perform the comparison on those. value1 = o1.intValue() & 0xFFFFFFFFL; value2 = o2.intValue() & 0xFFFFFFFFL; comparison = value1 - value2; if (comparison == 0) { return 0; } else if (comparison > 0) { return 1; } else { return -1; } } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/store/UpcastIterator.java000066400000000000000000000022361253404521400334260ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; /** * A simple pass-through iterator that changes an object from a specific class * type to a more general class type. * * @param * The generic class type of the destination data. * @param * The more specific class type of the source data. * @author Brett Henderson */ public class UpcastIterator implements ReleasableIterator { private ReleasableIterator source; /** * Creates a new instance. * * @param source * The input source. */ public UpcastIterator(ReleasableIterator source) { this.source = source; } /** * {@inheritDoc} */ @Override public boolean hasNext() { return source.hasNext(); } /** * {@inheritDoc} */ @Override public X next() { return source.next(); } /** * {@inheritDoc} */ @Override public void remove() { source.remove(); } /** * {@inheritDoc} */ @Override public void release() { source.release(); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/000077500000000000000000000000001253404521400274155ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/common/000077500000000000000000000000001253404521400307055ustar00rootroot00000000000000ChangeAction.java000066400000000000000000000010001253404521400340030ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.common; /** * Represents all the actions that can be performed on a data type when * performing a change. * * @author Brett Henderson */ public enum ChangeAction { /** * Represents the creation of a new entity. */ Create, /** * Represents the modification of an existing entity. */ Modify, /** * Represents the deletion of an existing entity. */ Delete } RunnableTask.java000066400000000000000000000006101253404521400340570ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.common; /** * Extends the basic Task interface with the Runnable capability. * * @author Brett Henderson */ public interface RunnableTask extends Task, Runnable { // This interface combines Task and Runnable but doesn't introduce // methods of its own. } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/common/Task.java000066400000000000000000000005561253404521400324600ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.common; /** * Defines the root of the interface inheritance hierarchy for all task types. * * @author Brett Henderson */ public interface Task { // Interface only exists to provide a common hierarchy root for all task // types. } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6/000077500000000000000000000000001253404521400301675ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6/ChangeSink.java000066400000000000000000000010731253404521400330450ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.task.common.Task; /** * Defines the interface for all tasks consuming OSM changes to data. * * @author Brett Henderson */ public interface ChangeSink extends Task, Initializable { /** * Process the change. * * @param change * The change to be processed. */ void process(ChangeContainer change); } ChangeSinkChangeSource.java000066400000000000000000000011301253404521400352470ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; /** * Defines the interface for combining change sink and change source * functionality. This is typically used by classes performing some form of * translation on an input change source before sending along to the output. * This includes filtering tasks and modification tasks. * * @author Brett Henderson */ public interface ChangeSinkChangeSource extends ChangeSink, ChangeSource { // Interface only combines functionality of its extended interfaces. } ChangeSinkMultiChangeSource.java000066400000000000000000000010451253404521400362670ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; /** * Defines the interface for combining ChangeSink and MultiChangeSource * functionality. This is primarily intended for tasks splitting change data to * multiple destinations. * * @author Brett Henderson */ public interface ChangeSinkMultiChangeSource extends ChangeSink, MultiChangeSource { // This interface combines ChangeSink and MultiChangeSource but doesn't // introduce // methods of its own. } ChangeSinkRunnableChangeSource.java000066400000000000000000000010661253404521400367460ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; /** * Defines the interface for combining ChangeSink and RunnableChangeSource functionality. * This is primarily intended for buffering tasks splitting processing across * multiple threads. * * @author Brett Henderson */ public interface ChangeSinkRunnableChangeSource extends ChangeSink, RunnableChangeSource { // This interface combines ChangeSink and RunnableChangeSource but doesn't introduce // methods of its own. } ChangeSinkSource.java000066400000000000000000000007171253404521400341530ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; /** * Defines the interface for combining change sink and source functionality. * This is used by classes converting a change stream into an entity stream. * * @author Brett Henderson */ public interface ChangeSinkSource extends ChangeSink, Source { // Interface only combines functionality of its extended interfaces. } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6/ChangeSource.java000066400000000000000000000010221253404521400333730ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; import org.openstreetmap.osmosis.core.task.common.Task; /** * Defines the interface for all tasks producing OSM changes to data. * * @author Brett Henderson */ public interface ChangeSource extends Task { /** * Sets the change sink to send data to. * * @param changeSink * The sink for receiving all produced data. */ void setChangeSink(ChangeSink changeSink); } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6/DatasetSink.java000066400000000000000000000013471253404521400332510ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; import org.openstreetmap.osmosis.core.container.v0_6.Dataset; import org.openstreetmap.osmosis.core.lifecycle.Releasable; import org.openstreetmap.osmosis.core.task.common.Task; /** * Defines the interface for tasks consuming datasets. * * @author Brett Henderson */ public interface DatasetSink extends Task, Releasable { /** * Process the dataset. This must only be called once. This will perform all * finalisation tasks such as database commits as necessary to complete the * task. * * @param dataset * The dataset to be processed. */ void process(Dataset dataset); } DatasetSinkSource.java000066400000000000000000000007731253404521400343550ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; /** * Defines the interface for combining dataset sink and source functionality. * This is typically used by classes performing some data extraction from a * dataset and producing a subset output. * * @author Brett Henderson */ public interface DatasetSinkSource extends DatasetSink, Source { // Interface only combines functionality of its extended interfaces. } DatasetSource.java000066400000000000000000000010111253404521400335120ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; import org.openstreetmap.osmosis.core.task.common.Task; /** * Defines the interface for tasks producing datasets. * * @author Brett Henderson */ public interface DatasetSource extends Task { /** * Sets the dataset sink to send data to. * * @param datasetSink * The sink for receiving all produced data. */ void setDatasetSink(DatasetSink datasetSink); } Initializable.java000066400000000000000000000021331253404521400335320ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.lifecycle.Completable; /** * This interface defines methods required to manage class lifecycles. All * clients must first call the initialize method, then the implementation * specific processing methods, then complete, and finally the release method. * It may be possible to call initialize multiple times, but each call must be * matched by a call to complete. Release must be called at the completion of * all processing. It may be possible to call release multiple times, but * initialize must be called again before processing can proceed. * * @author Brett Henderson */ public interface Initializable extends Completable { /** * Initialize the object. Any global information applicable to this * processing phase can be generically set as meta data. * * @param metaData * Meta data applicable to this pipeline invocation. */ void initialize(Map metaData); } MultiChangeSink.java000066400000000000000000000015111253404521400337760ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; /** * Defines the interface for tasks consuming multiple streams of data. It allows * a task to expose multiple change sinks. Classes may choose to combine this * with other multi sink style interfaces where data streams of different types * are to be consumed. * * @author Brett Henderson */ public interface MultiChangeSink { /** * Obtains one of the change sinks exposed by the task. * * @param instance * The index of the change sink to be returned. * @return The change sink. */ ChangeSink getChangeSink(int instance); /** * Returns the number of change sinks provided by this task. * * @return The number of change sinks. */ int getChangeSinkCount(); } MultiChangeSinkRunnableChangeSource.java000066400000000000000000000010131253404521400377510ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; /** * Defines the interface for combining multi change sink and change source * functionality. This is typically used by classes combining the contents of * two change sources. * * @author Brett Henderson */ public interface MultiChangeSinkRunnableChangeSource extends MultiChangeSink, RunnableChangeSource { // Interface only combines functionality of its extended interfaces. } MultiChangeSource.java000066400000000000000000000014101253404521400343300ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; import org.openstreetmap.osmosis.core.task.common.Task; /** * Defines the interface for tasks producing multiple change streams of OSM data. * * @author Brett Henderson */ public interface MultiChangeSource extends Task { /** * Retrieves a specific change source that can then have a change sink * attached. * * @param index * The index of the change source to retrieve. * @return The requested index. */ ChangeSource getChangeSource(int index); /** * Indicates the number of change sources that the task provides. * * @return The number of change sources. */ int getChangeSourceCount(); } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6/MultiSink.java000066400000000000000000000014071253404521400327530ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; /** * Defines the interface for tasks consuming multiple streams of data. It allows * a task to expose multiple sinks. Classes may choose to combine this with * other multi sink style interfaces where data streams of different types are * to be consumed. * * @author Brett Henderson */ public interface MultiSink { /** * Obtains one of the sinks exposed by the task. * * @param instance * The index of the sink to be returned. * @return The sink. */ Sink getSink(int instance); /** * Returns the number of sinks provided by this task. * * @return The number of sinks. */ int getSinkCount(); } MultiSinkMultiChangeSinkRunnableSource.java000066400000000000000000000010271253404521400405100ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; /** * Defines the interface for combining sink, change sink and source * functionality. This is typically used by classes adding a change set to an * input to produce a new output. * * @author Brett Henderson */ public interface MultiSinkMultiChangeSinkRunnableSource extends MultiSink, MultiChangeSink, RunnableSource { // Interface only combines functionality of its extended interfaces. } MultiSinkRunnableChangeSource.java000066400000000000000000000007761253404521400366620ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; /** * Defines the interface for combining multi sink and change source * functionality. This is typically used by classes performing difference * analysis of two data sources. * * @author Brett Henderson */ public interface MultiSinkRunnableChangeSource extends MultiSink, RunnableChangeSource { // Interface only combines functionality of its extended interfaces. } MultiSinkRunnableSource.java000066400000000000000000000007401253404521400355430ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; /** * Defines the interface for combining multi sink and source functionality. This * is typically used by classes combining the contents of two data sources. * * @author Brett Henderson */ public interface MultiSinkRunnableSource extends MultiSink, RunnableSource { // Interface only combines functionality of its extended interfaces. } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6/MultiSource.java000066400000000000000000000012741253404521400333110ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; import org.openstreetmap.osmosis.core.task.common.Task; /** * Defines the interface for tasks producing multiple streams of OSM data. * * @author Brett Henderson */ public interface MultiSource extends Task { /** * Retrieves a specific source that can then have a sink attached. * * @param index * The index of the source to retrieve. * @return The requested index. */ Source getSource(int index); /** * Indicates the number of sources that the task provides. * * @return The number of sources. */ int getSourceCount(); } RunnableChangeSource.java000066400000000000000000000010471253404521400350120ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; /** * Extends the basic ChangeSource interface with the Runnable capability. * Runnable is not applied to the ChangeSource interface because tasks that act * as filters do not require Runnable capability. * * @author Brett Henderson */ public interface RunnableChangeSource extends ChangeSource, Runnable { // This interface combines ChangeSource and Runnable but doesn't introduce // methods of its own. } RunnableDatasetSource.java000066400000000000000000000010541253404521400352100ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; /** * Extends the basic DatasetSource interface with the Runnable capability. * Runnable is not applied to the DatasetSource interface because tasks that act * as filters do not require Runnable capability. * * @author Brett Henderson */ public interface RunnableDatasetSource extends DatasetSource, Runnable { // This interface combines DatasetSource and Runnable but doesn't introduce // methods of its own. } RunnableSource.java000066400000000000000000000010111253404521400336730ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; /** * Extends the basic Source interface with the Runnable capability. Runnable * is not applied to the Source interface because tasks that act as filters * do not require Runnable capability. * * @author Brett Henderson */ public interface RunnableSource extends Source, Runnable { // This interface combines Source and Runnable but doesn't introduce // methods of its own. } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6/Sink.java000066400000000000000000000010761253404521400317420ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.task.common.Task; /** * Defines the interface for tasks consuming OSM data types. * * @author Brett Henderson */ public interface Sink extends Task, Initializable { /** * Process the entity. * * @param entityContainer * The entity to be processed. */ void process(EntityContainer entityContainer); } SinkDatasetSource.java000066400000000000000000000007641253404521400343550ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; /** * Defines the interface for combining sink and dataset source functionality. This is * typically implemented by classes converting a stream of data into an indexed random access dataset. * * @author Brett Henderson */ public interface SinkDatasetSource extends Sink, DatasetSource { // Interface only combines functionality of its extended interfaces. } SinkMultiSource.java000066400000000000000000000007471253404521400340630ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; /** * Defines the interface for combining Sink and MultiSource functionality. This * is primarily intended for tasks splitting data to multiple destinations. * * @author Brett Henderson */ public interface SinkMultiSource extends Sink, MultiSource { // This interface combines Sink and MultiSource but doesn't introduce // methods of its own. } SinkRunnableSource.java000066400000000000000000000010061253404521400345240ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; /** * Defines the interface for combining Sink and RunnableSource functionality. * This is primarily intended for buffering tasks splitting processing across * multiple threads. * * @author Brett Henderson */ public interface SinkRunnableSource extends Sink, RunnableSource { // This interface combines Sink and RunnableSource but doesn't introduce // methods of its own. } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6/SinkSource.java000066400000000000000000000010531253404521400331160ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; /** * Defines the interface for combining sink and source functionality. This is * typically used by classes performing some form of translation on an input * source before sending along to the output. This includes filtering tasks and * modification tasks. * * @author Brett Henderson */ public interface SinkSource extends Sink, Source { // Interface only combines functionality of its extended interfaces. } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/task/v0_6/Source.java000066400000000000000000000007501253404521400322740ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.task.v0_6; import org.openstreetmap.osmosis.core.task.common.Task; /** * Defines the interface for tasks producing OSM data types. * * @author Brett Henderson */ public interface Source extends Task { /** * Sets the osm sink to send data to. * * @param sink * The sink for receiving all produced data. */ void setSink(Sink sink); } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/tee/000077500000000000000000000000001253404521400272305ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/tee/v0_6/000077500000000000000000000000001253404521400300025ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/tee/v0_6/ChangeTee.java000066400000000000000000000063631253404521400325000ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.tee.v0_6; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSinkChangeSource; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSinkMultiChangeSource; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSource; /** * Sends input change data to two output destinations. * * @author Brett Henderson */ public class ChangeTee implements ChangeSinkMultiChangeSource { private List sinkList; /** * Creates a new instance. * * @param outputCount * The number of output destinations to write to. */ public ChangeTee(int outputCount) { sinkList = new ArrayList(); for (int i = 0; i < outputCount; i++) { sinkList.add(new ProxyChangeSinkChangeSource()); } } /** * {@inheritDoc} */ public ChangeSource getChangeSource(int index) { if (index < 0 || index >= sinkList.size()) { throw new OsmosisRuntimeException("Source index " + index + " is in the range 0 to " + (sinkList.size() - 1) + "."); } return sinkList.get(index); } /** * {@inheritDoc} */ public int getChangeSourceCount() { return sinkList.size(); } /** * {@inheritDoc} */ public void initialize(Map metaData) { for (ProxyChangeSinkChangeSource sink : sinkList) { sink.initialize(metaData); } } /** * {@inheritDoc} */ public void process(ChangeContainer change) { for (ProxyChangeSinkChangeSource sink : sinkList) { // We're passing the data to multiple downstream tasks therefore should make the entity // read-only to prevent multiple threads impacting each other. change.getEntityContainer().getEntity().makeReadOnly(); sink.process(change); } } /** * {@inheritDoc} */ public void complete() { for (ProxyChangeSinkChangeSource sink : sinkList) { sink.complete(); } } /** * {@inheritDoc} */ public void release() { for (ProxyChangeSinkChangeSource sink : sinkList) { sink.release(); } } /** * Instances of this class are returned via the parent class getSource method. * * @author Brett Henderson */ private static class ProxyChangeSinkChangeSource implements ChangeSinkChangeSource { private ChangeSink changeSink; /** * Creates a new instance. */ public ProxyChangeSinkChangeSource() { // Nothing to do. } /** * {@inheritDoc} */ public void setChangeSink(ChangeSink changeSink) { this.changeSink = changeSink; } /** * {@inheritDoc} */ public void initialize(Map metaData) { changeSink.initialize(metaData); } /** * {@inheritDoc} */ public void process(ChangeContainer change) { changeSink.process(change); } /** * {@inheritDoc} */ public void complete() { changeSink.complete(); } /** * {@inheritDoc} */ public void release() { changeSink.release(); } } } ChangeTeeFactory.java000066400000000000000000000021771253404521400337500ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/tee/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.tee.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.ChangeSinkMultiChangeSourceManager; /** * The task manager factory for a change tee. * * @author Brett Henderson */ public class ChangeTeeFactory extends TaskManagerFactory { private static final String ARG_OUTPUT_COUNT = "outputCount"; private static final int DEFAULT_OUTPUT_COUNT = 2; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { int outputCount; // Get the task arguments. outputCount = getIntegerArgument( taskConfig, ARG_OUTPUT_COUNT, getDefaultIntegerArgument(taskConfig, DEFAULT_OUTPUT_COUNT) ); return new ChangeSinkMultiChangeSourceManager( taskConfig.getId(), new ChangeTee(outputCount), taskConfig.getPipeArgs() ); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/tee/v0_6/EntityTee.java000066400000000000000000000060121253404521400325560ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.tee.v0_6; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.task.v0_6.SinkMultiSource; import org.openstreetmap.osmosis.core.task.v0_6.SinkSource; import org.openstreetmap.osmosis.core.task.v0_6.Source; /** * Sends input data to two output destinations. * * @author Brett Henderson */ public class EntityTee implements SinkMultiSource { private List sinkList; /** * Creates a new instance. * * @param outputCount * The number of output destinations to write to. */ public EntityTee(int outputCount) { sinkList = new ArrayList(); for (int i = 0; i < outputCount; i++) { sinkList.add(new ProxySinkSource()); } } /** * {@inheritDoc} */ public Source getSource(int index) { if (index < 0 || index >= sinkList.size()) { throw new OsmosisRuntimeException("Source index " + index + " is in the range 0 to " + (sinkList.size() - 1) + "."); } return sinkList.get(index); } /** * {@inheritDoc} */ public int getSourceCount() { return sinkList.size(); } /** * {@inheritDoc} */ public void initialize(Map metaData) { for (ProxySinkSource sink : sinkList) { sink.initialize(metaData); } } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { for (ProxySinkSource sink : sinkList) { // We're passing the data to multiple downstream tasks therefore should make the entity // read-only to prevent multiple threads impacting each other. entityContainer.getEntity().makeReadOnly(); sink.process(entityContainer); } } /** * {@inheritDoc} */ public void complete() { for (ProxySinkSource sink : sinkList) { sink.complete(); } } /** * {@inheritDoc} */ public void release() { for (ProxySinkSource sink : sinkList) { sink.release(); } } /** * Instances of this class are returned via the parent class getSource method. * * @author Brett Henderson */ private static class ProxySinkSource implements SinkSource { private Sink sink; /** * Creates a new instance. */ public ProxySinkSource() { // Nothing to do. } /** * {@inheritDoc} */ public void setSink(Sink sink) { this.sink = sink; } /** * {@inheritDoc} */ public void initialize(Map metaData) { sink.initialize(metaData); } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { sink.process(entityContainer); } /** * {@inheritDoc} */ public void complete() { sink.complete(); } /** * {@inheritDoc} */ public void release() { sink.release(); } } } EntityTeeFactory.java000066400000000000000000000021501253404521400340260ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/tee/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.tee.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkMultiSourceManager; /** * The task manager factory for an entity tee. * * @author Brett Henderson */ public class EntityTeeFactory extends TaskManagerFactory { private static final String ARG_OUTPUT_COUNT = "outputCount"; private static final int DEFAULT_OUTPUT_COUNT = 2; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { int outputCount; // Get the task arguments. outputCount = getIntegerArgument( taskConfig, ARG_OUTPUT_COUNT, getDefaultIntegerArgument(taskConfig, DEFAULT_OUTPUT_COUNT) ); return new SinkMultiSourceManager( taskConfig.getId(), new EntityTee(outputCount), taskConfig.getPipeArgs() ); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/time/000077500000000000000000000000001253404521400274115ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/time/DateFormatter.java000066400000000000000000000032461253404521400330220ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.time; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.TimeZone; /** * Outputs a date in a format suitable for an OSM XML file. * * @author Brett Henderson */ public class DateFormatter { private GregorianCalendar calendar; /** * Creates a new instance. */ public DateFormatter() { calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC")); } /** * Formats a date in XML format. * * @param date * The date to be formatted. * @return The string representing the date. */ public String format(Date date) { StringBuilder result; int year; int month; int day; int hour; int minute; int second; calendar.setTime(date); result = new StringBuilder(20); year = calendar.get(Calendar.YEAR); month = calendar.get(Calendar.MONTH) + 1; day = calendar.get(Calendar.DATE); hour = calendar.get(Calendar.HOUR_OF_DAY); minute = calendar.get(Calendar.MINUTE); second = calendar.get(Calendar.SECOND); result.append(year); result.append('-'); if (month < 10) { result.append('0'); } result.append(month); result.append('-'); if (day < 10) { result.append('0'); } result.append(day); result.append('T'); if (hour < 10) { result.append('0'); } result.append(hour); result.append(':'); if (minute < 10) { result.append('0'); } result.append(minute); result.append(':'); if (second < 10) { result.append('0'); } result.append(second); result.append('Z'); return result.toString(); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/time/DateParser.java000066400000000000000000000145341253404521400323150ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.time; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.TimeZone; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; //1970-01-12T13:46:40.000Z //1970-01-12T13:46:40Z /** * Handles a number of different date formats encountered in OSM. This is built * based on similar code in JOSM. This class is not threadsafe, a separate * instance must be created per thread. * * @author Brett Henderson */ public class DateParser { private DatatypeFactory datatypeFactory; private FallbackDateParser fallbackDateParser; private Calendar calendar; /** * Creates a new instance. */ public DateParser() { // Build an xml data type factory. try { datatypeFactory = DatatypeFactory.newInstance(); } catch (DatatypeConfigurationException e) { throw new OsmosisRuntimeException("Unable to instantiate xml datatype factory.", e); } fallbackDateParser = new FallbackDateParser(); calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC")); } private boolean isDateInShortStandardFormat(String date) { char[] dateChars; // We can only parse the date if it is in a very specific format. // eg. 2007-09-23T08:25:43Z if (date.length() != 20) { return false; } dateChars = date.toCharArray(); // Make sure any fixed characters are in the correct place. if (dateChars[4] != '-') { return false; } if (dateChars[7] != '-') { return false; } if (dateChars[10] != 'T') { return false; } if (dateChars[13] != ':') { return false; } if (dateChars[16] != ':') { return false; } if (dateChars[19] != 'Z') { return false; } // Ensure all remaining characters are numbers. for (int i = 0; i < 4; i++) { if (dateChars[i] < '0' || dateChars[i] > '9') { return false; } } for (int i = 5; i < 7; i++) { if (dateChars[i] < '0' || dateChars[i] > '9') { return false; } } for (int i = 8; i < 10; i++) { if (dateChars[i] < '0' || dateChars[i] > '9') { return false; } } for (int i = 11; i < 13; i++) { if (dateChars[i] < '0' || dateChars[i] > '9') { return false; } } for (int i = 14; i < 16; i++) { if (dateChars[i] < '0' || dateChars[i] > '9') { return false; } } for (int i = 17; i < 19; i++) { if (dateChars[i] < '0' || dateChars[i] > '9') { return false; } } // No problems found so it is in the special case format. return true; } private boolean isDateInLongStandardFormat(String date) { char[] dateChars; // We can only parse the date if it is in a very specific format. // eg. 2007-09-23T08:25:43.000Z if (date.length() != 24) { return false; } dateChars = date.toCharArray(); // Make sure any fixed characters are in the correct place. if (dateChars[4] != '-') { return false; } if (dateChars[7] != '-') { return false; } if (dateChars[10] != 'T') { return false; } if (dateChars[13] != ':') { return false; } if (dateChars[16] != ':') { return false; } if (dateChars[19] != '.') { return false; } if (dateChars[23] != 'Z') { return false; } // Ensure all remaining characters are numbers. for (int i = 0; i < 4; i++) { if (dateChars[i] < '0' || dateChars[i] > '9') { return false; } } for (int i = 5; i < 7; i++) { if (dateChars[i] < '0' || dateChars[i] > '9') { return false; } } for (int i = 8; i < 10; i++) { if (dateChars[i] < '0' || dateChars[i] > '9') { return false; } } for (int i = 11; i < 13; i++) { if (dateChars[i] < '0' || dateChars[i] > '9') { return false; } } for (int i = 14; i < 16; i++) { if (dateChars[i] < '0' || dateChars[i] > '9') { return false; } } for (int i = 17; i < 19; i++) { if (dateChars[i] < '0' || dateChars[i] > '9') { return false; } } for (int i = 20; i < 23; i++) { if (dateChars[i] < '0' || dateChars[i] > '9') { return false; } } // No problems found so it is in the special case format. return true; } private Date parseShortStandardDate(String date) { int year; int month; int day; int hour; int minute; int second; year = Integer.parseInt(date.substring(0, 4)); month = Integer.parseInt(date.substring(5, 7)); day = Integer.parseInt(date.substring(8, 10)); hour = Integer.parseInt(date.substring(11, 13)); minute = Integer.parseInt(date.substring(14, 16)); second = Integer.parseInt(date.substring(17, 19)); calendar.clear(); calendar.set(Calendar.YEAR, year); calendar.set(Calendar.MONTH, month - 1); calendar.set(Calendar.DAY_OF_MONTH, day); calendar.set(Calendar.HOUR_OF_DAY, hour); calendar.set(Calendar.MINUTE, minute); calendar.set(Calendar.SECOND, second); return calendar.getTime(); } private Date parseLongStandardDate(String date) { int year; int month; int day; int hour; int minute; int second; int millisecond; year = Integer.parseInt(date.substring(0, 4)); month = Integer.parseInt(date.substring(5, 7)); day = Integer.parseInt(date.substring(8, 10)); hour = Integer.parseInt(date.substring(11, 13)); minute = Integer.parseInt(date.substring(14, 16)); second = Integer.parseInt(date.substring(17, 19)); millisecond = Integer.parseInt(date.substring(20, 23)); calendar.clear(); calendar.set(Calendar.YEAR, year); calendar.set(Calendar.MONTH, month - 1); calendar.set(Calendar.DAY_OF_MONTH, day); calendar.set(Calendar.HOUR_OF_DAY, hour); calendar.set(Calendar.MINUTE, minute); calendar.set(Calendar.SECOND, second); calendar.set(Calendar.MILLISECOND, millisecond); return calendar.getTime(); } /** * Attempts to parse the specified date. * * @param date * The date to parse. * @return The date. */ public Date parse(String date) { try { if (isDateInShortStandardFormat(date)) { return parseShortStandardDate(date); } else if (isDateInLongStandardFormat(date)) { return parseLongStandardDate(date); } else { return datatypeFactory.newXMLGregorianCalendar(date).toGregorianCalendar().getTime(); } } catch (IllegalArgumentException e) { return fallbackDateParser.parse(date); } } } FallbackDateParser.java000066400000000000000000000061271253404521400336550ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/time// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.time; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Handles a number of different date FORMATS encountered in OSM. This is built * based on similar code in JOSM. This class is not threadsafe, a separate * instance must be created per thread. * * @author Brett Henderson */ public class FallbackDateParser { private static final Logger LOG = Logger.getLogger(FallbackDateParser.class.getName()); private static final String[] FORMATS = { "yyyy-MM-dd'T'HH:mm:ss'Z'", "yyyy-MM-dd'T'HH:mm:ssZ", "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd HH:mm:ss", "MM/dd/yyyy HH:mm:ss", "MM/dd/yyyy'T'HH:mm:ss.SSS'Z'", "MM/dd/yyyy'T'HH:mm:ss.SSSZ", "MM/dd/yyyy'T'HH:mm:ss.SSS", "MM/dd/yyyy'T'HH:mm:ssZ", "MM/dd/yyyy'T'HH:mm:ss", "yyyy:MM:dd HH:mm:ss" }; private List dateParsers; private int activeDateParser; /** * Creates a new instance. */ public FallbackDateParser() { // Build a list of candidate date parsers. dateParsers = new ArrayList(FORMATS.length); for (int i = 0; i < FORMATS.length; i++) { dateParsers.add(new SimpleDateFormat(FORMATS[i])); } // We haven't selected a date parser yet. activeDateParser = -1; } /** * Attempts to parse the specified date. * * @param date * The date to parse. * @return The date. */ public Date parse(String date) { String correctedDate; // Try to fix ruby's broken xmlschema - format // Replace this: // 2007-02-12T18:43:01+00:00 // With this: // 2007-02-12T18:43:01+0000 if (date.length() == 25 && date.charAt(22) == ':') { correctedDate = date.substring(0, 22) + date.substring(23, 25); } else { correctedDate = date; } // If we have previously successfully used a date parser, we'll try it // first. if (activeDateParser >= 0) { try { return dateParsers.get(activeDateParser).parse(correctedDate); } catch (ParseException e) { // The currently active parser didn't work, so we must clear it // and find a new appropriate parser. activeDateParser = -1; } } // Try the date parsers one by one until a suitable format is found. for (int i = 0; i < dateParsers.size(); i++) { try { Date result; // Attempt to parse with the current parser, if successful we // store its index for next time. result = dateParsers.get(i).parse(correctedDate); activeDateParser = i; return result; } catch (ParseException e) { LOG.log(Level.FINER, "Pattern " + i + " could not parse the date.", e); // Ignore parsing errors and try the next pattern. } } throw new OsmosisRuntimeException("The date string (" + date + ") could not be parsed."); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/util/000077500000000000000000000000001253404521400274305ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/util/AtomicFileCreator.java000066400000000000000000000044201253404521400336270ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.util; import java.io.File; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Supports the creation of files in an atomic fashion. Internally it creates files using a * temporary filename, then renames them to the final file name. */ public class AtomicFileCreator { private File file; private File tmpFile; /** * Creates a new instance. * * @param file * The file to be created. */ public AtomicFileCreator(File file) { this.file = file; this.tmpFile = new File(file.getPath() + ".tmp"); } /** * Checks if either one of the main or temporary files currently exists. * * @return True if a file exists, false otherwise. */ public boolean exists() { // We're checking both files because there is a small window where only the new file exists // after the main state file is deleted before the new file being renamed. // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4017593 for more details. return file.exists() || tmpFile.exists(); } /** * Renames the new temporary file to the current file deleting the current file if it exists. */ public void renameTmpFileToCurrent() { // Make sure we have a new file. if (!tmpFile.exists()) { throw new OsmosisRuntimeException("Can't rename non-existent file " + tmpFile + "."); } // Delete the existing file if it exists. if (file.exists()) { if (!file.delete()) { throw new OsmosisRuntimeException("Unable to delete file " + file + "."); } } // Rename the new file to the existing file. if (!tmpFile.renameTo(file)) { throw new OsmosisRuntimeException( "Unable to rename file " + tmpFile + " to " + file + "."); } } /** * Returns the temporary file used during file generation. This file is written first, and then * renamed to the real file name when complete. * * @return The temporary file name. */ public File getTmpFile() { return tmpFile; } /** * Returns the file represented by this class. This file is not written directly, instead a * temporary file is created and then renamed to this file. * * @return The file name. */ public File getFile() { return file; } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/util/CollectionWrapper.java000066400000000000000000000047011253404521400337310ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.util; import java.util.Collection; import java.util.Iterator; /** * Wraps an existing collection and delegates all calls to it. This is not useful on its own but can * be extended as necessary by classes that delegate most functionality to an underlying collection * implementation but extend or modify it in some ways. * * @author Brett Henderson * * @param The type of data stored within the collection. */ public class CollectionWrapper implements Collection { private Collection wrappedCollection; /** * Creates a new instance. * * @param wrappedCollection * The collection to be wrapped. This collection will not be copied, it will be used * directly. */ public CollectionWrapper(Collection wrappedCollection) { this.wrappedCollection = wrappedCollection; } /** * {@inheritDoc} */ @Override public boolean add(E e) { return wrappedCollection.add(e); } /** * {@inheritDoc} */ @Override public boolean addAll(Collection c) { return wrappedCollection.addAll(c); } /** * {@inheritDoc} */ @Override public void clear() { wrappedCollection.clear(); } /** * {@inheritDoc} */ @Override public boolean contains(Object o) { return wrappedCollection.contains(o); } /** * {@inheritDoc} */ @Override public boolean containsAll(Collection c) { return wrappedCollection.containsAll(c); } /** * {@inheritDoc} */ @Override public boolean isEmpty() { return wrappedCollection.isEmpty(); } /** * {@inheritDoc} */ @Override public Iterator iterator() { return wrappedCollection.iterator(); } /** * {@inheritDoc} */ @Override public boolean remove(Object o) { return wrappedCollection.remove(o); } /** * {@inheritDoc} */ @Override public boolean removeAll(Collection c) { return wrappedCollection.removeAll(c); } /** * {@inheritDoc} */ @Override public boolean retainAll(Collection c) { return wrappedCollection.retainAll(c); } /** * {@inheritDoc} */ @Override public int size() { return wrappedCollection.size(); } /** * {@inheritDoc} */ @Override public Object[] toArray() { return wrappedCollection.toArray(); } /** * {@inheritDoc} */ @Override public T[] toArray(T[] a) { return wrappedCollection.toArray(a); } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/util/FileBasedLock.java000066400000000000000000000053101253404521400327210ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.util; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.nio.channels.FileChannel; import java.nio.channels.FileLock; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.lifecycle.Releasable; /** * This class provides a mechanism to use simple files as locks to prevent * multiple threads or processes from updating common files. * * @author Brett Henderson */ public class FileBasedLock implements Releasable { private static final Logger LOG = Logger.getLogger(FileBasedLock.class.getName()); private File lockFile; private FileOutputStream outputStream; private FileChannel fileChannel; private FileLock fileLock; private boolean initialized; /** * Creates a new instance. * * @param lockFile * The file to use for locking. */ public FileBasedLock(File lockFile) { this.lockFile = lockFile; initialized = false; } /** * Creates the file resources used internally for implementing the lock. */ private void initialize() { if (!initialized) { try { outputStream = new FileOutputStream(lockFile); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to open lock file " + lockFile + "."); } fileChannel = outputStream.getChannel(); initialized = true; } } /** * Obtain an exclusive lock. This will fail if another thread or process * already has a lock. */ public void lock() { initialize(); if (fileLock != null) { throw new OsmosisRuntimeException("A lock has already been obtained on file " + lockFile + "."); } try { fileLock = fileChannel.tryLock(); if (fileLock == null) { throw new OsmosisRuntimeException("A exclusive lock already exists on file " + lockFile + "."); } } catch (IOException e) { throw new OsmosisRuntimeException( "An error occurred while trying to obtain an exclusive lock on file " + lockFile + "."); } } /** * Release the lock. */ public void unlock() { initialize(); try { fileLock.release(); fileLock = null; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to release lock on file " + lockFile + "."); } } /** * {@inheritDoc} */ public void release() { if (outputStream != null) { try { outputStream.close(); } catch (Exception e) { LOG.warning("Unable to close lock stream on file " + lockFile + "."); } finally { outputStream = null; fileChannel = null; fileLock = null; initialized = false; } } } } FixedPrecisionCoordinateConvertor.java000066400000000000000000000031611253404521400370420ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/util// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.util; /** * Converts a double coordinate value into an equivalent integer with fixed * precision. * * @author Brett Henderson */ public final class FixedPrecisionCoordinateConvertor { private static final int PRECISION = 7; private static final int MULTIPLICATION_FACTOR = calculateMultiplicationFactor(); /** * This class cannot be instantiated. */ private FixedPrecisionCoordinateConvertor() { // Do nothing. } /** * Generates the multiplication factor that the double coordinate must be * multiplied by to turn it into a fixed precision integer. * * @return The double to fixed multiplication factor. */ private static int calculateMultiplicationFactor() { int result; result = 1; for (int i = 0; i < PRECISION; i++) { result *= 10; } return result; } /** * Converts the requested coordinate from double to fixed precision. * * @param coordinate * The double coordinate value. * @return The fixed coordinate value. */ public static int convertToFixed(double coordinate) { int result; result = (int) Math.round(coordinate * MULTIPLICATION_FACTOR); return result; } /** * Converts the requested coordinate from fixed to double precision. * * @param coordinate * The fixed coordinate value. * @return The double coordinate value. */ public static double convertToDouble(int coordinate) { double result; result = ((double) coordinate) / MULTIPLICATION_FACTOR; return result; } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/util/IntAsChar.java000066400000000000000000000017611253404521400321140ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.util; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Contains utility methods supporting storage of ints as chars. * * @author Brett Henderson */ public final class IntAsChar { /** * This class cannot be constructed. */ private IntAsChar() { // Do nothing. } /** * Converts the specified int to an char and verifies that it is legal. * * @param value * The identifier to be converted. * @return The integer representation of the id. */ public static char intToChar(int value) { // Verify that the bit can be safely cast to an integer. if (value > Character.MAX_VALUE) { throw new OsmosisRuntimeException("Cannot represent " + value + " as a char."); } if (value < Character.MIN_VALUE) { throw new OsmosisRuntimeException("Cannot represent " + value + " as a char."); } return (char) value; } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/util/LazyHashMap.java000066400000000000000000000054731253404521400324650ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.util; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Set; /** * This map uses a HashMap internally, but only instantiates it after values are * added. This is intended for cases where most instances of the map will remain * empty and avoids the instantiation overhead of creating the full map. * * @author Brett Henderson * * @param * the type of keys maintained by this map * @param * the type of mapped values */ public class LazyHashMap implements Map { private Map internalMap; /** * {@inheritDoc} */ @Override public void clear() { if (internalMap != null) { internalMap.clear(); } } /** * {@inheritDoc} */ @Override public boolean containsKey(Object key) { if (internalMap != null) { return internalMap.containsKey(key); } else { return false; } } /** * {@inheritDoc} */ @Override public boolean containsValue(Object value) { if (internalMap != null) { return internalMap.containsValue(value); } else { return false; } } /** * {@inheritDoc} */ @Override public Set> entrySet() { if (internalMap != null) { return internalMap.entrySet(); } else { return Collections.emptySet(); } } /** * {@inheritDoc} */ @Override public V get(Object key) { if (internalMap != null) { return internalMap.get(key); } else { return null; } } /** * {@inheritDoc} */ @Override public boolean isEmpty() { if (internalMap != null) { return internalMap.isEmpty(); } else { return true; } } /** * {@inheritDoc} */ @Override public Set keySet() { if (internalMap != null) { return internalMap.keySet(); } else { return Collections.emptySet(); } } /** * {@inheritDoc} */ @Override public V put(K key, V value) { if (internalMap == null) { internalMap = new HashMap(); } return internalMap.put(key, value); } /** * {@inheritDoc} */ @Override public void putAll(Map m) { if (internalMap == null) { internalMap = new HashMap(); } internalMap.putAll(m); } /** * {@inheritDoc} */ @Override public V remove(Object key) { if (internalMap != null) { return internalMap.remove(key); } else { return null; } } /** * {@inheritDoc} */ @Override public int size() { if (internalMap != null) { return internalMap.size(); } else { return 0; } } /** * {@inheritDoc} */ @Override public Collection values() { if (internalMap != null) { return internalMap.values(); } else { return Collections.emptyMap().values(); } } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/util/LongAsInt.java000066400000000000000000000020771253404521400321370ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.util; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Contains utility methods supporting storage of longs as integers. This is * only useful while OSM ids remain below Integer.MAX_VALUE. * * @author Brett Henderson */ public final class LongAsInt { /** * This class cannot be constructed. */ private LongAsInt() { // Do nothing. } /** * Converts the specified long to an int and verifies that it is legal. * * @param value * The identifier to be converted. * @return The integer representation of the id. */ public static int longToInt(long value) { // Verify that the value can be safely cast to an integer. if (value > Integer.MAX_VALUE) { throw new OsmosisRuntimeException("Cannot represent " + value + " as an integer."); } if (value < Integer.MIN_VALUE) { throw new OsmosisRuntimeException("Cannot represent " + value + " as an integer."); } return (int) value; } } MultiMemberGZIPInputStream.java000066400000000000000000000067331253404521400353350ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/util// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.util; import java.io.InputStream; import java.io.PushbackInputStream; import java.io.IOException; import java.util.zip.GZIPInputStream; /** * This class was copied directly from the workaround class provided in * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4691425. */ public class MultiMemberGZIPInputStream extends GZIPInputStream { /** * Creates a new instance. * * @param in * The input stream. * @param size * The buffer size. * @throws IOException * if an IO exception occurs. */ public MultiMemberGZIPInputStream(InputStream in, int size) throws IOException { // Wrap the stream in a PushbackInputStream... super(new PushbackInputStream(in, size), size); this.size = size; } /** * Creates a new instance. * * @param in * The input stream. * @throws IOException * if an IO exception occurs. */ public MultiMemberGZIPInputStream(InputStream in) throws IOException { // Wrap the stream in a PushbackInputStream... super(new PushbackInputStream(in, 1024)); this.size = -1; } private MultiMemberGZIPInputStream(MultiMemberGZIPInputStream parent) throws IOException { super(parent.in); this.size = -1; if (parent.parent == null) { this.parent = parent; } else { this.parent = parent.parent; } this.parent.child = this; } private MultiMemberGZIPInputStream(MultiMemberGZIPInputStream parent, int size) throws IOException { super(parent.in, size); this.size = size; if (parent.parent == null) { this.parent = parent; } else { this.parent = parent.parent; } this.parent.child = this; } private MultiMemberGZIPInputStream parent; private MultiMemberGZIPInputStream child; private int size; private boolean eos; /** * {@inheritDoc} */ @Override public int read(byte[] inputBuffer, int inputBufferOffset, int inputBufferLen) throws IOException { if (eos) { return -1; } if (this.child != null) { return this.child.read(inputBuffer, inputBufferOffset, inputBufferLen); } int charsRead = super.read(inputBuffer, inputBufferOffset, inputBufferLen); if (charsRead == -1) { // Push any remaining buffered data back onto the stream // If the stream is then not empty, use it to construct // a new instance of this class and delegate this and any // future calls to it... int n = inf.getRemaining() - 8; if (n > 0) { // More than 8 bytes remaining in deflater // First 8 are gzip trailer. Add the rest to // any un-read data... ((PushbackInputStream) this.in).unread(buf, len - n, n); } else { // Nothing in the buffer. We need to know whether or not // there is unread data available in the underlying stream // since the base class will not handle an empty file. // Read a byte to see if there is data and if so, // push it back onto the stream... byte[] b = new byte[1]; int ret = in.read(b, 0, 1); if (ret == -1) { eos = true; return -1; } else { ((PushbackInputStream) this.in).unread(b, 0, 1); } } MultiMemberGZIPInputStream tmpChild; if (this.size == -1) { tmpChild = new MultiMemberGZIPInputStream(this); } else { tmpChild = new MultiMemberGZIPInputStream(this, this.size); } return tmpChild.read(inputBuffer, inputBufferOffset, inputBufferLen); } else { return charsRead; } } } PropertiesPersister.java000066400000000000000000000073621253404521400342610ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/util// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.util; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.Writer; import java.nio.charset.Charset; import java.util.HashMap; import java.util.Map; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Allows Properties objects to be loaded and stored to file. */ public class PropertiesPersister { private static final Logger LOG = Logger.getLogger(PropertiesPersister.class.getName()); private AtomicFileCreator atomicFileCreator; /** * Creates a new instance. * * @param propertiesFile * The location of the file containing the persisted data. */ public PropertiesPersister(File propertiesFile) { atomicFileCreator = new AtomicFileCreator(propertiesFile); } /** * Loads the properties from the file. * * @return The properties. */ public Properties load() { FileInputStream fileInputStream = null; try { Reader reader; Properties properties; fileInputStream = new FileInputStream(atomicFileCreator.getFile()); reader = new InputStreamReader(new BufferedInputStream(fileInputStream), Charset.forName("UTF-8")); properties = new Properties(); properties.load(reader); fileInputStream.close(); fileInputStream = null; return properties; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to read the properties from file " + atomicFileCreator.getFile() + ".", e); } finally { if (fileInputStream != null) { try { fileInputStream.close(); } catch (Exception e) { LOG.log(Level.WARNING, "Unable to close properties file " + atomicFileCreator.getFile() + ".", e); } } } } /** * Load the properties from a file as a strongly typed Map. * * @return The properties. */ @SuppressWarnings({ "rawtypes", "unchecked" }) public Map loadMap() { return new HashMap((Map) load()); } /** * Stores the properties to the file overwriting any existing file contents. * * @param properties * The properties. */ public void store(Properties properties) { FileOutputStream fileOutputStream = null; try { Writer writer; fileOutputStream = new FileOutputStream(atomicFileCreator.getTmpFile()); writer = new OutputStreamWriter(new BufferedOutputStream(fileOutputStream)); properties.store(writer, null); writer.close(); atomicFileCreator.renameTmpFileToCurrent(); } catch (IOException e) { throw new OsmosisRuntimeException( "Unable to write the properties to temporary file " + atomicFileCreator.getTmpFile() + ".", e); } finally { if (fileOutputStream != null) { try { fileOutputStream.close(); } catch (Exception e) { LOG.log(Level.WARNING, "Unable to close temporary state file " + atomicFileCreator.getTmpFile() + ".", e); } } } } /** * Stores the properties to the file overwriting any existing file contents. * * @param propertiesMap * The properties. */ public void store(Map propertiesMap) { Properties properties = new Properties(); properties.putAll(propertiesMap); store(properties); } /** * Checks if the properties file exists. * * @return True if a file exists, false otherwise. */ public boolean exists() { return atomicFileCreator.exists(); } } ResourceFileManager.java000066400000000000000000000042621253404521400341020ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/util// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.util; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Contains utility methods for dealing with resource files packaged within the application. * * @author Brett Henderson */ public class ResourceFileManager { private static final Logger LOG = Logger.getLogger(ResourceFileManager.class.getName()); /** * Copies a packaged resource to a file on the file system. * * @param callingClass * The calling class is used to load the resource, this allows * resources to be loaded with paths relative to the caller. * @param sourceResource * The input resource. * @param destinationFile * The output file. */ public void copyResourceToFile(Class callingClass, String sourceResource, File destinationFile) { InputStream is = null; OutputStream os = null; try { byte[] buffer; int bytesRead; buffer = new byte[4096]; is = callingClass.getResourceAsStream(sourceResource); os = new FileOutputStream(destinationFile); if (is == null) { throw new FileNotFoundException("Could not find " + sourceResource); } while (true) { bytesRead = is.read(buffer); // Stop reading if no more data is available. if (bytesRead < 0) { break; } os.write(buffer, 0, bytesRead); } is.close(); os.close(); } catch (IOException e) { throw new OsmosisRuntimeException( "Unable to copy resource " + sourceResource + " to file " + destinationFile); } finally { if (is != null) { try { is.close(); } catch (Exception e) { LOG.warning("Unable to close input stream for resource " + sourceResource); } } if (os != null) { try { os.close(); } catch (Exception e) { LOG.warning("Unable to close output stream for file " + destinationFile); } } } } } osmosis-0.44.1/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/util/TileCalculator.java000066400000000000000000000023311253404521400332010ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.util; /** * Calculates a tile index based upon coordinate values. Note that this class * returns a signed integer due to the lack of an unsigned integer type in java. * The result is a 32-bit unsigned integer but stored in a long value for ease * of use. *

* The result can be cast directly to an int, but converting back to an unsigned * long value must be performed like: * long tile = intTile & 0xFFFFFFFFl; * * * @author Brett Henderson */ public class TileCalculator { /** * Calculates a tile index based upon the supplied coordinates. * * @param latitude * The coordinate latitude. * @param longitude * The coordinate longitude. * @return The tile index value. */ public long calculateTile(double latitude, double longitude) { int x; int y; long tile; x = (int) Math.round((longitude + 180) * 65535 / 360); y = (int) Math.round((latitude + 90) * 65535 / 180); tile = 0; for (int i = 15; i >= 0; i--) { tile = (tile << 1) | ((x >> i) & 1); tile = (tile << 1) | ((y >> i) & 1); } return tile; } } osmosis-0.44.1/osmosis-core/src/main/resources/000077500000000000000000000000001253404521400214435ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/resources/org/000077500000000000000000000000001253404521400222325ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/resources/org/openstreetmap/000077500000000000000000000000001253404521400251205ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/resources/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400266145ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/resources/org/openstreetmap/osmosis/core/000077500000000000000000000000001253404521400275445ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/resources/org/openstreetmap/osmosis/core/plugin/000077500000000000000000000000001253404521400310425ustar00rootroot00000000000000plugin.xml.template000066400000000000000000000006331253404521400346170ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/main/resources/org/openstreetmap/osmosis/core/plugin osmosis-0.44.1/osmosis-core/src/main/resources/osmosis-plugins.conf000066400000000000000000000000571253404521400254670ustar00rootroot00000000000000org.openstreetmap.osmosis.core.CorePluginLoaderosmosis-0.44.1/osmosis-core/src/site/000077500000000000000000000000001253404521400174515ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/site/site.xml000066400000000000000000000014031253404521400211350ustar00rootroot00000000000000 Osmosis OpenStreetMap

osmosis-0.44.1/osmosis-core/src/test/000077500000000000000000000000001253404521400174645ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/java/000077500000000000000000000000001253404521400204055ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/java/org/000077500000000000000000000000001253404521400211745ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/000077500000000000000000000000001253404521400240625ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400255565ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/core/000077500000000000000000000000001253404521400265065ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/core/MyPluginLoader.java000066400000000000000000000016711253404521400322510ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.misc.v0_6.NullChangeWriterFactory; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.plugin.PluginLoader; /** * A simple plugin loader to validate plugin functionality. * * @author Brett Henderson */ public class MyPluginLoader implements PluginLoader { /** * {@inheritDoc} */ @Override public Map loadTaskFactories() { Map taskFactories; taskFactories = new HashMap(); // Register a task under a new name. We can use an existing task implementation for simplicity. taskFactories.put("my-plugin-task", new NullChangeWriterFactory()); return taskFactories; } } osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/core/bound/000077500000000000000000000000001253404521400276155ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/core/bound/v0_6/000077500000000000000000000000001253404521400303675ustar00rootroot00000000000000BoundComputerTest.java000066400000000000000000000062161253404521400346060ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/core/bound/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.bound.v0_6; import java.util.Date; import java.util.Iterator; import org.junit.Assert; import org.junit.Test; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.testutil.v0_6.SinkEntityInspector; /** * Unit tests for the bound computer. * * @author Igor Podolskiy */ public class BoundComputerTest { /** * Tests the bound computation if no nodes are upstream. */ @Test public void computeBoundNoNodes() { SinkEntityInspector inspector = new SinkEntityInspector(); BoundComputer bc = new BoundComputer("NewBound"); bc.setSink(inspector); bc.complete(); bc.release(); Assert.assertNull(inspector.getLastEntityContainer()); } /** * Tests the bound computation if no nodes but a bound entity is upstream. */ @Test public void computeBoundNoNodesWithBound() { SinkEntityInspector inspector = new SinkEntityInspector(); BoundComputer bc = new BoundComputer("NewBound"); bc.setSink(inspector); bc.process(new BoundContainer(new Bound("Test"))); bc.complete(); bc.release(); Assert.assertNull(inspector.getLastEntityContainer()); } /** * Tests the bound computation when no bound entity is upstream. */ @Test public void computeBoundNoUpstreamBound() { SinkEntityInspector inspector = new SinkEntityInspector(); BoundComputer bc = new BoundComputer("NewBound"); bc.setSink(inspector); bc.process(new NodeContainer(new Node(new CommonEntityData(1, 1, new Date(), OsmUser.NONE, 1), 1, 1))); bc.process(new NodeContainer(new Node(new CommonEntityData(2, 2, new Date(), OsmUser.NONE, 1), 2, 2))); bc.complete(); bc.release(); EntityContainer ec = inspector.getProcessedEntities().iterator().next(); Assert.assertEquals(new Bound(2, 1, 2, 1, "NewBound"), ec.getEntity()); } /** * Tests the bound computation when there is bound entity is upstream. */ @Test public void computeBoundWithUpstreamBound() { SinkEntityInspector inspector = new SinkEntityInspector(); BoundComputer bc = new BoundComputer("NewBound"); bc.setSink(inspector); bc.process(new NodeContainer(new Node(new CommonEntityData(1, 1, new Date(), OsmUser.NONE, 1), 1, 1))); bc.process(new NodeContainer(new Node(new CommonEntityData(2, 2, new Date(), OsmUser.NONE, 1), 2, 2))); bc.complete(); bc.release(); Iterator iterator = inspector.getProcessedEntities().iterator(); EntityContainer ec = iterator.next(); Assert.assertEquals(new Bound(2, 1, 2, 1, "NewBound"), ec.getEntity()); // Ensure there is no second bound. ec = iterator.next(); Assert.assertEquals(EntityType.Node, ec.getEntity().getType()); } } BoundSetterTest.java000066400000000000000000000070751253404521400342620ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/core/bound/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.bound.v0_6; import java.util.Date; import java.util.Iterator; import org.junit.Assert; import org.junit.Test; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.testutil.v0_6.SinkEntityInspector; /** * Test for the bound setter task. * * @author Igor Podolskiy */ public class BoundSetterTest { /** * Tests the bound removal. */ @Test public void removeExistingBoundTest() { SinkEntityInspector inspector = new SinkEntityInspector(); BoundSetter setter = new BoundSetter(null); setter.setSink(inspector); setter.process(new BoundContainer(new Bound("Test"))); setter.process(new NodeContainer(new Node( new CommonEntityData(1, 1, new Date(), OsmUser.NONE, 1), 1, 1))); setter.complete(); setter.release(); EntityContainer ec = inspector.getProcessedEntities().iterator().next(); Assert.assertEquals(EntityType.Node, ec.getEntity().getType()); } /** * Tests the bound removal when there is no bound upstream. */ @Test public void removeNoBoundTest() { SinkEntityInspector inspector = new SinkEntityInspector(); BoundSetter setter = new BoundSetter(null); setter.setSink(inspector); setter.process(new NodeContainer(new Node( new CommonEntityData(1, 1, new Date(), OsmUser.NONE, 1), 1, 1))); setter.complete(); setter.release(); EntityContainer ec = inspector.getProcessedEntities().iterator().next(); Assert.assertEquals(EntityType.Node, ec.getEntity().getType()); } /** * Tests the bound setting. */ @Test public void overwriteBoundTest() { SinkEntityInspector inspector = new SinkEntityInspector(); Bound newBound = new Bound(2, 1, 4, 3, "NewBound"); BoundSetter setter = new BoundSetter(newBound); setter.setSink(inspector); setter.process(new BoundContainer(new Bound("Test"))); setter.process(new NodeContainer(new Node( new CommonEntityData(1, 1, new Date(), OsmUser.NONE, 1), 1, 1))); setter.complete(); setter.release(); Iterator iterator = inspector.getProcessedEntities().iterator(); EntityContainer ec = iterator.next(); Assert.assertEquals(EntityType.Bound, ec.getEntity().getType()); Bound bound = (Bound) ec.getEntity(); Assert.assertEquals(bound, newBound); // Ensure there is no second bound ec = iterator.next(); Assert.assertEquals(EntityType.Node, ec.getEntity().getType()); } /** * Tests the bound setting when there is no bound upstream. */ @Test public void setNewBoundTest() { SinkEntityInspector inspector = new SinkEntityInspector(); Bound newBound = new Bound(2, 1, 4, 3, "NewBound"); BoundSetter setter = new BoundSetter(newBound); setter.setSink(inspector); setter.process(new NodeContainer(new Node( new CommonEntityData(1, 1, new Date(), OsmUser.NONE, 1), 1, 1))); setter.complete(); setter.release(); EntityContainer ec = inspector.getProcessedEntities().iterator().next(); Assert.assertEquals(EntityType.Bound, ec.getEntity().getType()); Bound bound = (Bound) ec.getEntity(); Assert.assertEquals(bound, newBound); } } osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/core/cli/000077500000000000000000000000001253404521400272555ustar00rootroot00000000000000CommandLineParserTest.java000066400000000000000000000111511253404521400342430ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/core/cli// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.cli; import java.util.Arrays; import java.util.logging.Level; import org.junit.Assert; import org.junit.Test; import org.openstreetmap.osmosis.core.LogLevels; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Tests the CommandLineParser class. * * @author Brett Henderson */ public class CommandLineParserTest { /** * Validates the quiet option. */ @Test public void testQuietOption() { CommandLineParser commandLineParser; commandLineParser = new CommandLineParser(); commandLineParser.parse(new String [] {}); Assert.assertEquals("Incorrect default log level.", Level.INFO, LogLevels.getLogLevel(commandLineParser.getLogLevelIndex())); commandLineParser = new CommandLineParser(); commandLineParser.parse(new String [] {"-q"}); Assert.assertEquals("Incorrect quiet log level.", Level.WARNING, LogLevels.getLogLevel(commandLineParser.getLogLevelIndex())); commandLineParser = new CommandLineParser(); commandLineParser.parse(new String [] {"-q", "1"}); Assert.assertEquals("Incorrect very quiet log level.", Level.SEVERE, LogLevels.getLogLevel(commandLineParser.getLogLevelIndex())); commandLineParser = new CommandLineParser(); commandLineParser.parse(new String [] {"-q", "2"}); Assert.assertEquals("Incorrect very very quiet log level.", Level.OFF, LogLevels.getLogLevel(commandLineParser.getLogLevelIndex())); } /** * Validates the verbose option. */ @Test public void testVerboseOption() { CommandLineParser commandLineParser; commandLineParser = new CommandLineParser(); commandLineParser.parse(new String [] {}); Assert.assertEquals("Incorrect default log level.", Level.INFO, LogLevels.getLogLevel(commandLineParser.getLogLevelIndex())); commandLineParser = new CommandLineParser(); commandLineParser.parse(new String [] {"-v"}); Assert.assertEquals("Incorrect verbose log level.", Level.FINE, LogLevels.getLogLevel(commandLineParser.getLogLevelIndex())); commandLineParser = new CommandLineParser(); commandLineParser.parse(new String [] {"-v", "1"}); Assert.assertEquals("Incorrect very verbose log level.", Level.FINER, LogLevels.getLogLevel(commandLineParser.getLogLevelIndex())); commandLineParser = new CommandLineParser(); commandLineParser.parse(new String [] {"-v", "2"}); Assert.assertEquals("Incorrect very very verbose log level.", Level.FINEST, LogLevels.getLogLevel(commandLineParser.getLogLevelIndex())); commandLineParser = new CommandLineParser(); commandLineParser.parse(new String [] {"-v", "3"}); Assert.assertEquals( "Incorrect very very very verbose log level.", Level.FINEST, LogLevels.getLogLevel(commandLineParser.getLogLevelIndex())); } /** * Validates the quiet and verbose options in combination. */ @Test public void testQuietAndVerboseOption() { CommandLineParser commandLineParser; commandLineParser = new CommandLineParser(); commandLineParser.parse(new String [] {}); Assert.assertEquals("Incorrect default log level.", Level.INFO, LogLevels.getLogLevel(commandLineParser.getLogLevelIndex())); commandLineParser = new CommandLineParser(); commandLineParser.parse(new String [] {"-v", "-q"}); Assert.assertEquals("Incorrect default log level.", Level.INFO, LogLevels.getLogLevel(commandLineParser.getLogLevelIndex())); commandLineParser = new CommandLineParser(); commandLineParser.parse(new String [] {"-v", "1", "-q", "1"}); Assert.assertEquals("Incorrect default log level.", Level.INFO, LogLevels.getLogLevel(commandLineParser.getLogLevelIndex())); commandLineParser = new CommandLineParser(); commandLineParser.parse(new String [] {"-v", "1", "-q", "2"}); Assert.assertEquals("Incorrect quiet log level.", Level.WARNING, LogLevels.getLogLevel(commandLineParser.getLogLevelIndex())); } /** * Validates the quiet and verbose options in combination. */ @Test public void testPluginOption() { CommandLineParser commandLineParser; commandLineParser = new CommandLineParser(); commandLineParser.parse(new String [] {"-p", "plugin1", "-p", "plugin2"}); Assert.assertEquals( "Incorrect plugin list.", Arrays.asList("plugin1", "plugin2"), commandLineParser.getPlugins()); } /** * Validates failure when an unknown option is specified. */ @Test (expected = OsmosisRuntimeException.class) public void testUnknownOption() { CommandLineParser commandLineParser; commandLineParser = new CommandLineParser(); commandLineParser.parse(new String [] {"-a"}); } } osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/core/domain/000077500000000000000000000000001253404521400277555ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/core/domain/v0_6/000077500000000000000000000000001253404521400305275ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/core/domain/v0_6/BoundTest.java000066400000000000000000000437711253404521400333150ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.domain.v0_6; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import org.junit.Test; /** * Tests the Bound entity class. * * @author Karl Newman */ public class BoundTest { /** * Test the constructor with right > 180. */ @Test(expected = IllegalArgumentException.class) public final void testConstructor1() { new Bound(181.0000000000001, -20, 20, -20, "not null"); fail("Expected to throw an exception"); } /** * Test the constructor with right < -180. */ @Test(expected = IllegalArgumentException.class) public final void testConstructor2() { new Bound(-181.0000000000001, -20, 20, -20, "not null"); fail("Expected to throw an exception"); } /** * Test the constructor with left > 180. */ @Test(expected = IllegalArgumentException.class) public final void testConstructor3() { new Bound(20, 181.0000000000001, 20, -20, "not null"); fail("Expected to throw an exception"); } /** * Test the constructor with left < -180. */ @Test(expected = IllegalArgumentException.class) public final void testConstructor4() { new Bound(20, -181.0000000000001, 20, -20, "not null"); fail("Expected to throw an exception"); } /** * Test the constructor with top > 90. */ @Test(expected = IllegalArgumentException.class) public final void testConstructor5() { new Bound(20, -20, 91.0000000000001, -20, "not null"); fail("Expected to throw an exception"); } /** * Test the constructor with top < -90. */ @Test(expected = IllegalArgumentException.class) public final void testConstructor6() { new Bound(20, -20, -91.0000000000001, -20, "not null"); fail("Expected to throw an exception"); } /** * Test the constructor with bottom > 90. */ @Test(expected = IllegalArgumentException.class) public final void testConstructor7() { new Bound(20, -20, 20, 91.0000000000001, "not null"); fail("Expected to throw an exception"); } /** * Test the constructor with bottom < -90. */ @Test(expected = IllegalArgumentException.class) public final void testConstructor8() { new Bound(20, -20, 20, -91.0000000000001, "not null"); fail("Expected to throw an exception"); } /** * Test the constructor with top < bottom. */ @Test(expected = IllegalArgumentException.class) public final void testConstructor9() { new Bound(20, -20, -20, 20, "not null"); fail("Expected to throw an exception"); } /** * Test a valid constructor with only the origin string provided (covers full planet). */ @Test public final void testConstructor11() { Bound b = new Bound("not null"); assertTrue(Double.compare(b.getRight(), 180) == 0 && Double.compare(b.getLeft(), -180) == 0 && Double.compare(b.getTop(), 90) == 0 && Double.compare(b.getBottom(), -90) == 0 && b.getOrigin().equals("not null")); } /** * Test a valid constructor with all values provided. */ @Test public final void testConstructor12() { Bound b = new Bound(20, -20, 21, -21, "not null"); assertTrue(Double.compare(b.getRight(), 20) == 0 && Double.compare(b.getLeft(), -20) == 0 && Double.compare(b.getTop(), 21) == 0 && Double.compare(b.getBottom(), -21) == 0 && b.getOrigin().equals("not null")); } /** * Test a simple intersection. */ @Test public final void testIntersect1() { final double right1 = 20.0; final double left1 = 10.0; final double top1 = 40.0; final double bottom1 = 30.0; final double right2 = 30.0; final double left2 = 15.0; final double top2 = 45.0; final double bottom2 = 20.0; Bound b1 = new Bound(right1, left1, top1, bottom1, "this"); Bound b2 = new Bound(right2, left2, top2, bottom2, "that"); Bound b = b1.intersect(b2); assertTrue(Double.compare(b.getRight(), right1) == 0 && Double.compare(b.getLeft(), left2) == 0 && Double.compare(b.getTop(), top1) == 0 && Double.compare(b.getBottom(), bottom1) == 0 && b.getOrigin().equals("this")); // Test it with arguments swapped b = b2.intersect(b1); assertTrue(Double.compare(b.getRight(), right1) == 0 && Double.compare(b.getLeft(), left2) == 0 && Double.compare(b.getTop(), top1) == 0 && Double.compare(b.getBottom(), bottom1) == 0 && b.getOrigin().equals("that")); } /** * Test an intersect with no top-bottom overlapping areas. */ @Test public final void testIntersect2() { final double right1 = 20.0; final double left1 = 10.0; final double top1 = 40.0; final double bottom1 = 30.0; final double right2 = 30.0; final double left2 = 15.0; final double top2 = 25.0; final double bottom2 = 20.0; Bound b = new Bound(right1, left1, top1, bottom1, "").intersect(new Bound( right2, left2, top2, bottom2, "")); assertNull(b); } /** * Test an intersect with no left-right overlapping areas. */ @Test public final void testIntersect3() { final double right1 = 20.0; final double left1 = 10.0; final double top1 = 40.0; final double bottom1 = 30.0; final double right2 = 30.0; final double left2 = 21.0; final double top2 = 45.0; final double bottom2 = 20.0; Bound b = new Bound(right1, left1, top1, bottom1, "").intersect(new Bound( right2, left2, top2, bottom2, "")); assertNull(b); } /** * Test an intersect with 1 Bound crossing the antimeridian. */ @Test public final void testIntersect4() { final double right1 = 20.0; final double left1 = 60.0; final double top1 = 40.0; final double bottom1 = 30.0; final double right2 = 30.0; final double left2 = 15.0; final double top2 = 45.0; final double bottom2 = 20.0; Bound b1 = new Bound(right1, left1, top1, bottom1, ""); Bound b2 = new Bound(right2, left2, top2, bottom2, "that"); Bound b = b1.intersect(b2); assertTrue(Double.compare(b.getRight(), right1) == 0 && Double.compare(b.getLeft(), left2) == 0 && Double.compare(b.getTop(), top1) == 0 && Double.compare(b.getBottom(), bottom1) == 0 && b.getOrigin().equals("that")); // Test it with arguments swapped b = b2.intersect(b1); assertTrue(Double.compare(b.getRight(), right1) == 0 && Double.compare(b.getLeft(), left2) == 0 && Double.compare(b.getTop(), top1) == 0 && Double.compare(b.getBottom(), bottom1) == 0 && b.getOrigin().equals("that")); } /** * Test an intersection where one Bound crosses the antimeridian (but doesn't cover the planet) * and both ends overlap with the intersecting Bound. A strict intersection would result in two * Bound areas, so just expect the smaller (longitudinally) of the Bound as the result. */ @Test public final void testIntersect5() { final double right1 = 150.0; final double left1 = 170.0; final double top1 = 40.0; final double bottom1 = 30.0; final double right2 = 175.0; final double left2 = 145.0; final double top2 = 45.0; final double bottom2 = 25.0; Bound b1 = new Bound(right1, left1, top1, bottom1, ""); Bound b2 = new Bound(right2, left2, top2, bottom2, ""); Bound b = b1.intersect(b2); assertTrue(Double.compare(b.getRight(), right2) == 0 && Double.compare(b.getLeft(), left2) == 0 && Double.compare(b.getTop(), top1) == 0 && Double.compare(b.getBottom(), bottom1) == 0); // Test it with arguments swapped b = b2.intersect(b1); assertTrue(Double.compare(b.getRight(), right2) == 0 && Double.compare(b.getLeft(), left2) == 0 && Double.compare(b.getTop(), top1) == 0 && Double.compare(b.getBottom(), bottom1) == 0); } /** * Test an intersect with both Bound crossing the antimeridian. */ @Test public final void testIntersect6() { final double right1 = 20.0; final double left1 = 60.0; final double top1 = 40.0; final double bottom1 = 30.0; final double right2 = 30.0; final double left2 = 50.0; final double top2 = 45.0; final double bottom2 = 35.0; Bound b = new Bound(right1, left1, top1, bottom1, "").intersect(new Bound( right2, left2, top2, bottom2, "")); assertTrue(Double.compare(b.getRight(), right1) == 0 && Double.compare(b.getLeft(), left1) == 0 && Double.compare(b.getTop(), top1) == 0 && Double.compare(b.getBottom(), bottom2) == 0); } /** * Test a simple union on opposite sides of the planet with exactly the same distance between * them on both sides. The smallest resulting union could wrap around the planet either way, so * expect a simple Bound which does not cross the antimeridian. */ @Test public final void testUnion1() { final double right1 = 90.0; final double left1 = 80.0; final double top1 = 40.0; final double bottom1 = 30.0; final double right2 = -90.0; final double left2 = -100.0; final double top2 = 45.0; final double bottom2 = 35.0; Bound b1 = new Bound(right1, left1, top1, bottom1, "this"); Bound b2 = new Bound(right2, left2, top2, bottom2, "that"); Bound b = b1.union(b2); assertTrue(Double.compare(b.getRight(), right1) == 0 && Double.compare(b.getLeft(), left2) == 0 && Double.compare(b.getTop(), top2) == 0 && Double.compare(b.getBottom(), bottom1) == 0 && b.getOrigin().equals("this")); // Test it with arguments swapped b = b2.union(b1); assertTrue(Double.compare(b.getRight(), right1) == 0 && Double.compare(b.getLeft(), left2) == 0 && Double.compare(b.getTop(), top2) == 0 && Double.compare(b.getBottom(), bottom1) == 0 && b.getOrigin().equals("that")); } /** * Test a union where one Bound is entirely contained by another. */ @Test public final void testUnion2() { final double right1 = 20.0; final double left1 = 10.0; final double top1 = 40.0; final double bottom1 = 30.0; final double right2 = 15.0; final double left2 = 12.0; final double top2 = 35.0; final double bottom2 = 32.0; Bound b1 = new Bound(right1, left1, top1, bottom1, ""); Bound b2 = new Bound(right2, left2, top2, bottom2, "that"); Bound b = b1.union(b2); assertTrue(Double.compare(b.getRight(), right1) == 0 && Double.compare(b.getLeft(), left1) == 0 && Double.compare(b.getTop(), top1) == 0 && Double.compare(b.getBottom(), bottom1) == 0 && b.getOrigin().equals("that")); // Test it with arguments swapped b = b2.union(b1); assertTrue(Double.compare(b.getRight(), right1) == 0 && Double.compare(b.getLeft(), left1) == 0 && Double.compare(b.getTop(), top1) == 0 && Double.compare(b.getBottom(), bottom1) == 0 && b.getOrigin().equals("that")); } /** * Test a union of two simple Bound where the resulting Bound crosses the antimeridian. */ @Test public final void testUnion3() { final double right1 = 91.0; final double left1 = 80.0; final double top1 = 40.0; final double bottom1 = 30.0; final double right2 = -90.0; final double left2 = -100.0; final double top2 = 45.0; final double bottom2 = 35.0; Bound b1 = new Bound(right1, left1, top1, bottom1, ""); Bound b2 = new Bound(right2, left2, top2, bottom2, ""); Bound b = b1.union(b2); assertTrue(Double.compare(b.getRight(), right2) == 0 && Double.compare(b.getLeft(), left1) == 0 && Double.compare(b.getTop(), top2) == 0 && Double.compare(b.getBottom(), bottom1) == 0); // Test it with arguments swapped b = b2.union(b1); assertTrue(Double.compare(b.getRight(), right2) == 0 && Double.compare(b.getLeft(), left1) == 0 && Double.compare(b.getTop(), top2) == 0 && Double.compare(b.getBottom(), bottom1) == 0); } /** * Test a union where one Bound crosses the antimeridian but there is still a gap such that the * union does not cover the planet. */ @Test public final void testUnion4() { final double right1 = 10.0; final double left1 = 20.0; final double top1 = 40.0; final double bottom1 = 30.0; final double right2 = 15.0; final double left2 = 12.0; final double top2 = 35.0; final double bottom2 = 32.0; Bound b1 = new Bound(right1, left1, top1, bottom1, ""); Bound b2 = new Bound(right2, left2, top2, bottom2, ""); Bound b = b1.union(b2); assertTrue(Double.compare(b.getRight(), right2) == 0 && Double.compare(b.getLeft(), left1) == 0 && Double.compare(b.getTop(), top1) == 0 && Double.compare(b.getBottom(), bottom1) == 0); // Test it with arguments swapped b = b2.union(b1); assertTrue(Double.compare(b.getRight(), right2) == 0 && Double.compare(b.getLeft(), left1) == 0 && Double.compare(b.getTop(), top1) == 0 && Double.compare(b.getBottom(), bottom1) == 0); } /** * Test a union where both Bound cross the antimeridian but do not cover the planet. */ @Test public final void testUnion5() { final double right1 = -170.0; final double left1 = 175.0; final double top1 = 40.0; final double bottom1 = 30.0; final double right2 = -175.0; final double left2 = 170.0; final double top2 = 35.0; final double bottom2 = 25.0; Bound b1 = new Bound(right1, left1, top1, bottom1, ""); Bound b2 = new Bound(right2, left2, top2, bottom2, ""); Bound b = b1.union(b2); assertTrue(Double.compare(b.getRight(), right1) == 0 && Double.compare(b.getLeft(), left2) == 0 && Double.compare(b.getTop(), top1) == 0 && Double.compare(b.getBottom(), bottom2) == 0); // Test it with arguments swapped b = b2.union(b1); assertTrue(Double.compare(b.getRight(), right1) == 0 && Double.compare(b.getLeft(), left2) == 0 && Double.compare(b.getTop(), top1) == 0 && Double.compare(b.getBottom(), bottom2) == 0); } /** * Test a union where one Bound covers the planet left-right. */ @Test public final void testUnion6() { final double right1 = 180.0; final double left1 = -180.0; final double top1 = 40.0; final double bottom1 = 30.0; final double right2 = 15.0; final double left2 = 12.0; final double top2 = 45.0; final double bottom2 = 32.0; Bound b1 = new Bound(right1, left1, top1, bottom1, ""); Bound b2 = new Bound(right2, left2, top2, bottom2, ""); Bound b = b1.union(b2); assertTrue(Double.compare(b.getRight(), right1) == 0 && Double.compare(b.getLeft(), left1) == 0 && Double.compare(b.getTop(), top2) == 0 && Double.compare(b.getBottom(), bottom1) == 0); // Test it with arguments swapped b = b2.union(b1); assertTrue(Double.compare(b.getRight(), right1) == 0 && Double.compare(b.getLeft(), left1) == 0 && Double.compare(b.getTop(), top2) == 0 && Double.compare(b.getBottom(), bottom1) == 0); } /** * Test a union where the Bound overlap and the resulting union covers the planet left-right. */ @Test public final void testUnion7() { final double right1 = 150.0; final double left1 = 170.0; final double top1 = 40.0; final double bottom1 = 30.0; final double right2 = 175.0; final double left2 = 145.0; final double top2 = 45.0; final double bottom2 = 25.0; final double minLongitude = -180.0; final double maxLongitude = 180.0; Bound b1 = new Bound(right1, left1, top1, bottom1, ""); Bound b2 = new Bound(right2, left2, top2, bottom2, ""); Bound b = b1.union(b2); assertTrue(Double.compare(b.getRight(), maxLongitude) == 0 && Double.compare(b.getLeft(), minLongitude) == 0 && Double.compare(b.getTop(), top2) == 0 && Double.compare(b.getBottom(), bottom2) == 0); // Test it with arguments swapped b = b2.union(b1); assertTrue(Double.compare(b.getRight(), maxLongitude) == 0 && Double.compare(b.getLeft(), minLongitude) == 0 && Double.compare(b.getTop(), top2) == 0 && Double.compare(b.getBottom(), bottom2) == 0); } /** * Test the case where the Bound is already "simple" (i.e., doesn't cross the antimeridian). */ @Test public final void testToSimpleBound1() { final double left = -179.0; final double right = 179.0; final double top = 1.0; final double bottom = -1.0; boolean expected1found = false; int cnt = 0; Bound expected1 = new Bound(right, left, top, bottom, ""); for (Bound b : new Bound(right, left, top, bottom, "").toSimpleBound()) { cnt++; if (Double.compare(b.getRight(), expected1.getRight()) == 0 && Double.compare(b.getLeft(), expected1.getLeft()) == 0 && Double.compare(b.getTop(), expected1.getTop()) == 0 && Double.compare(b.getBottom(), expected1.getBottom()) == 0) { expected1found = true; } } assertTrue(cnt == 1); assertTrue(expected1found); } /** * Test the case where the Bound is split into two simple Bound elements, one on either side * of the antimeridian. */ @Test public final void testToSimpleBound2() { final double left = 179.0; final double right = -179.0; final double top = 1.0; final double bottom = -1.0; final double minLongitude = -180.0; final double maxLongitude = 180.0; boolean expected1found = false, expected2found = false; int cnt = 0; Bound expected1 = new Bound(maxLongitude, left, top, bottom, ""); Bound expected2 = new Bound(right, minLongitude, top, bottom, ""); for (Bound b : new Bound(right, left, top, bottom, "").toSimpleBound()) { cnt++; if (Double.compare(b.getRight(), expected1.getRight()) == 0 && Double.compare(b.getLeft(), expected1.getLeft()) == 0 && Double.compare(b.getTop(), expected1.getTop()) == 0 && Double.compare(b.getBottom(), expected1.getBottom()) == 0) { expected1found = true; } if (Double.compare(b.getRight(), expected2.getRight()) == 0 && Double.compare(b.getLeft(), expected2.getLeft()) == 0 && Double.compare(b.getTop(), expected2.getTop()) == 0 && Double.compare(b.getBottom(), expected2.getBottom()) == 0) { expected2found = true; } } assertTrue(cnt == 2); assertTrue(expected1found); assertTrue(expected2found); } } osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/core/domain/v0_6/CloneTest.java000066400000000000000000000050761253404521400333020ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.domain.v0_6; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.junit.Assert; import org.junit.Test; /** * Verifies that read-only entities can be cloned. * * @author Brett Henderson * */ public class CloneTest { /** * Node cloning test. */ @Test public void testNodeClone() { // Build the original entity. List tags = new ArrayList(); tags.add(new Tag("myKey", "myValue")); Node entity = new Node(new CommonEntityData(1, 2, new Date(0), OsmUser.NONE, 3, tags), 4, 5); // Cloning a writeable object should return the original object. Assert.assertSame("Entity was cloned", entity, entity.getWriteableInstance()); // Get a cloned entity. entity.makeReadOnly(); Node clonedEntity = entity.getWriteableInstance(); // Make sure we weren't assigned the original entity. Assert.assertNotSame("Entity was not cloned", entity, clonedEntity); } /** * Way cloning test. */ @Test public void testWayClone() { // Build the original entity. List tags = new ArrayList(); tags.add(new Tag("myKey", "myValue")); List wayNodes = new ArrayList(); wayNodes.add(new WayNode(1)); Way entity = new Way(new CommonEntityData(1, 2, new Date(0), OsmUser.NONE, 3, tags), wayNodes); // Cloning a writeable object should return the original object. Assert.assertSame("Entity was cloned", entity, entity.getWriteableInstance()); // Get a cloned entity. entity.makeReadOnly(); Way clonedEntity = entity.getWriteableInstance(); // Make sure we weren't assigned the original entity. Assert.assertNotSame("Entity was not cloned", entity, clonedEntity); } /** * Relation cloning test. */ @Test public void testRelationClone() { // Build the original entity. List tags = new ArrayList(); tags.add(new Tag("myKey", "myValue")); List members = new ArrayList(); members.add(new RelationMember(1, EntityType.Node, "myRole")); Relation entity = new Relation(new CommonEntityData(1, 2, new Date(0), OsmUser.NONE, 3, tags), members); // Cloning a writeable object should return the original object. Assert.assertSame("Entity was cloned", entity, entity.getWriteableInstance()); // Get a cloned entity. entity.makeReadOnly(); Relation clonedEntity = entity.getWriteableInstance(); // Make sure we weren't assigned the original entity. Assert.assertNotSame("Entity was not cloned", entity, clonedEntity); } } OsmUserTest.java000066400000000000000000000051031253404521400335470ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/core/domain/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.domain.v0_6; import static org.junit.Assert.assertEquals; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import org.junit.Test; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.store.DataInputStoreReader; import org.openstreetmap.osmosis.core.store.DataOutputStoreWriter; import org.openstreetmap.osmosis.core.store.DynamicStoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; /** * Tests the OsmUser class. * * @author Karl Newman * @author Brett Henderson */ public class OsmUserTest { /** * Verify the details of the NONE user. */ @Test public final void testGetInstanceNoUser() { assertEquals("None user id is incorrect.", -1, OsmUser.NONE.getId()); assertEquals("None user name is incorrect.", "", OsmUser.NONE.getName()); } /** * Ensure that the class doesn't allow a null user name. */ @Test(expected = NullPointerException.class) public final void testGetInstancePreventsNullUser() { new OsmUser(1, null); } /** * Ensure that the class doesn't allow the reserved "NONE" user id to be specified. */ @Test(expected = OsmosisRuntimeException.class) public final void testGetInstancePreventsNoneUser() { new OsmUser(OsmUser.NONE.getId(), "MyNoneUser"); } /** * Ensure the instance is correctly written to and read from the store. */ @Test public final void testGetInstanceFromStore() { ByteArrayOutputStream out = new ByteArrayOutputStream(); StoreWriter sw = new DataOutputStoreWriter(new DataOutputStream(out)); StoreClassRegister scr = new DynamicStoreClassRegister(); OsmUser user1 = new OsmUser(12, "aUser"); OsmUser user3 = new OsmUser(13, "aUser2"); OsmUser user5 = new OsmUser(14, ""); user1.store(sw, scr); user3.store(sw, scr); user5.store(sw, scr); StoreReader sr = new DataInputStoreReader(new DataInputStream(new ByteArrayInputStream(out.toByteArray()))); OsmUser user2 = new OsmUser(sr, scr); OsmUser user4 = new OsmUser(sr, scr); OsmUser user6 = new OsmUser(sr, scr); assertEquals("Object not equal after retrieval from store", user1, user2); assertEquals("Object not equal after retrieval from store", user3, user4); assertEquals("Object not equal after retrieval from store", user5, user6); } } osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/core/filter/000077500000000000000000000000001253404521400277735ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/core/filter/common/000077500000000000000000000000001253404521400312635ustar00rootroot00000000000000BitSetIdTrackerTest.java000066400000000000000000000005621253404521400356750ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/core/filter/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.filter.common; /** * Tests the bitset id tracker implementation. */ public class BitSetIdTrackerTest extends IdTrackerBase { /** * {@inheritDoc} */ @Override protected IdTracker getImplementation() { return new BitSetIdTracker(); } } DynamicIdTrackerTest.java000066400000000000000000000005651253404521400360720ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/core/filter/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.filter.common; /** * Tests the dynamic id tracker implementation. */ public class DynamicIdTrackerTest extends IdTrackerBase { /** * {@inheritDoc} */ @Override protected IdTracker getImplementation() { return new DynamicIdTracker(); } } IdTrackerBase.java000066400000000000000000000073701253404521400345210ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/core/filter/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.filter.common; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; /** * Tests an id tracker implementation. Sub-classes provide the actual implementation to be tested. */ public abstract class IdTrackerBase { private static final int TEST_VAL_1 = -100; private static final int TEST_VAL_2 = 0; private static final int TEST_VAL_3 = 100; private static final int TEST_VAL_4 = 10000; private static final int TEST_VAL_5 = 10000; private IdTracker idt; /** * Performs pre-test activities. */ @Before public final void setUp() { idt = getImplementation(); } /** * Performs post-test activities. */ @After public final void tearDown() { idt = null; } /** * Gets an object which implements the interface under test. * * @return The implementation of this interface to test. */ protected abstract IdTracker getImplementation(); /** * Simple test of a single value. */ @Test public final void testSet1() { idt.set(TEST_VAL_1); assertTrue(idt.get(TEST_VAL_1)); } /** * Test three values, added in order of increasing value. */ @Test public final void testSet2() { idt.set(TEST_VAL_1); idt.set(TEST_VAL_2); idt.set(TEST_VAL_3); idt.set(TEST_VAL_4); idt.set(TEST_VAL_5); assertTrue(idt.get(TEST_VAL_1)); assertTrue(idt.get(TEST_VAL_2)); assertTrue(idt.get(TEST_VAL_3)); assertTrue(idt.get(TEST_VAL_4)); assertTrue(idt.get(TEST_VAL_5)); } /** * Test three values, added in order of decreasing value. */ @Test public final void testSet3() { idt.set(TEST_VAL_5); idt.set(TEST_VAL_4); idt.set(TEST_VAL_3); idt.set(TEST_VAL_2); idt.set(TEST_VAL_1); assertTrue(idt.get(TEST_VAL_1)); assertTrue(idt.get(TEST_VAL_2)); assertTrue(idt.get(TEST_VAL_3)); assertTrue(idt.get(TEST_VAL_4)); assertTrue(idt.get(TEST_VAL_5)); } /** * Test three values, added in random (not sorted) order. */ @Test public final void testSet4() { idt.set(TEST_VAL_2); idt.set(TEST_VAL_5); idt.set(TEST_VAL_3); idt.set(TEST_VAL_4); idt.set(TEST_VAL_1); assertTrue(idt.get(TEST_VAL_1)); assertTrue(idt.get(TEST_VAL_2)); assertTrue(idt.get(TEST_VAL_3)); assertTrue(idt.get(TEST_VAL_4)); assertTrue(idt.get(TEST_VAL_5)); } /** * Test duplicate values added. */ @Test public final void testSet5() { idt.set(TEST_VAL_1); idt.set(TEST_VAL_2); idt.set(TEST_VAL_3); idt.set(TEST_VAL_4); idt.set(TEST_VAL_5); idt.set(TEST_VAL_1); assertTrue(idt.get(TEST_VAL_1)); assertTrue(idt.get(TEST_VAL_2)); assertTrue(idt.get(TEST_VAL_3)); assertTrue(idt.get(TEST_VAL_4)); assertTrue(idt.get(TEST_VAL_5)); } /** * Test set after get. */ @Test public final void testSet6() { idt.set(TEST_VAL_2); assertTrue(idt.get(TEST_VAL_2)); idt.set(TEST_VAL_1); idt.set(TEST_VAL_3); idt.set(TEST_VAL_4); idt.set(TEST_VAL_5); assertTrue(idt.get(TEST_VAL_1)); assertTrue(idt.get(TEST_VAL_2)); assertTrue(idt.get(TEST_VAL_3)); assertTrue(idt.get(TEST_VAL_4)); assertTrue(idt.get(TEST_VAL_5)); } /** * Test a large number of values added to trigger a growth in the list size. */ @Test public final void testSet7() { final int listSize = 1024; for (int i = listSize - 1; i >= 0; i--) { idt.set(i); } // This one should trigger the list growth idt.set(TEST_VAL_3); assertTrue(idt.get(TEST_VAL_3)); for (int i = 0; i < listSize; i++) { assertTrue(idt.get(i)); } } /** * Tests the setAll method of the id tracker. */ @Ignore @Test public final void testSetAll() { fail("Not yet implemented"); // TODO } } ListIdTrackerTest.java000066400000000000000000000005541253404521400354170ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/core/filter/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.filter.common; /** * Tests the list id tracker implementation. */ public class ListIdTrackerTest extends IdTrackerBase { /** * {@inheritDoc} */ @Override protected IdTracker getImplementation() { return new ListIdTracker(); } } osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/core/mysql/000077500000000000000000000000001253404521400276535ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/core/mysql/common/000077500000000000000000000000001253404521400311435ustar00rootroot00000000000000TileCalculatorTest.java000066400000000000000000000010551253404521400354770ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/core/mysql/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.mysql.common; import org.junit.Assert; import org.junit.Test; import org.openstreetmap.osmosis.core.util.TileCalculator; /** * Tests the quad tile calculator. * * @author Brett Henderson */ public class TileCalculatorTest { /** * Basic test. */ @Test public void test() { Assert.assertEquals( "Incorrect tile value generated.", 2062265654, new TileCalculator().calculateTile(51.4781325, -0.1474929)); } } osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/core/sort/000077500000000000000000000000001253404521400274755ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/core/sort/common/000077500000000000000000000000001253404521400307655ustar00rootroot00000000000000FileBasedSortTest.java000066400000000000000000000045651253404521400351110ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/core/sort/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.common; import java.util.Comparator; import java.util.Random; import org.junit.Assert; import org.junit.Test; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.store.SingleClassObjectSerializationFactory; /** * Tests the {@link FileBasedSort} class. */ public class FileBasedSortTest { /** * Stores a large number of items into the file-based sorter and verifies * that they are returned in the correct sequence. It exceeds the in-memory * sorting limit, but doesn't trigger additional persistence at sub-levels * in the merge sort to minimise file handles as this would take too much * time for a unit test. The item count must be greater than * (MAX_MEMORY_SORT_COUNT * (MAX_MERGE_SOURCE_COUNT ^ * MAX_MEMORY_SORT_DEPTH)) to trigger intermediate persistence. */ @Test public void test() { final long itemCount = 10000; // Create a new file-based sorter for the TestStoreable type. SingleClassObjectSerializationFactory objectFactory = new SingleClassObjectSerializationFactory( SampleStoreable.class); Comparator comparator = new Comparator() { @Override public int compare(SampleStoreable o1, SampleStoreable o2) { long value1 = o1.getValue(); long value2 = o2.getValue(); if (value1 > value2) { return 1; } else if (value1 < value2) { return -1; } else { return 0; } } }; FileBasedSort fileBasedSort = new FileBasedSort(objectFactory, comparator, true); try { // Add randomly generated test values into the sorter. Random random = new Random(); for (long i = 0; i < itemCount; i++) { fileBasedSort.add(new SampleStoreable(random.nextInt())); } // Read back all values in the sorter and verify that they are // sorted correctly. ReleasableIterator resultIterator = fileBasedSort.iterate(); try { int lastValue = Integer.MIN_VALUE; while (resultIterator.hasNext()) { int currentValue = resultIterator.next().getValue(); Assert.assertTrue(currentValue >= lastValue); lastValue = currentValue; } } finally { resultIterator.release(); } } finally { fileBasedSort.release(); } } } SampleStoreable.java000066400000000000000000000023541253404521400346370ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/core/sort/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.sort.common; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; import org.openstreetmap.osmosis.core.store.Storeable; /** * A simple storeable class for testing {@link FileBasedSort}. */ public class SampleStoreable implements Storeable { private int value; /** * Constructs a new instance. * * @param value * See {@link #getValue()}. */ public SampleStoreable(int value) { this.value = value; } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers * within the store. */ public SampleStoreable(StoreReader sr, StoreClassRegister scr) { this.value = sr.readInteger(); } @Override public void store(StoreWriter writer, StoreClassRegister storeClassRegister) { writer.writeInteger(value); } /** * The value used for sorting. * * @return The sort value. */ public int getValue() { return value; } } osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/testutil/000077500000000000000000000000001253404521400274335ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/testutil/v0_6/000077500000000000000000000000001253404521400302055ustar00rootroot00000000000000SinkEntityInspector.java000066400000000000000000000034631253404521400347670ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/java/org/openstreetmap/osmosis/testutil/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.testutil.v0_6; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.task.v0_6.Sink; /** * Mock object for inspecting the resulting entities after passing through a pipeline task. * * @author Karl Newman */ public class SinkEntityInspector implements Sink { private List processedEntities; /** * Creates a new instance. */ public SinkEntityInspector() { processedEntities = new LinkedList(); } /** * {@inheritDoc} */ public void initialize(Map metaData) { // Nothing to do here } /** * {@inheritDoc} */ @Override public void complete() { // Nothing to do here } /** * Catch all passed entities and save them for later inspection. * * @param entityContainer * The entity to be processed. */ @Override public void process(EntityContainer entityContainer) { processedEntities.add(entityContainer); } /** * {@inheritDoc} */ @Override public void release() { // Nothing to do here } /** * Shortcut method if you only care about the most recent EntityContainer. * * @return the lastEntityContainer */ public EntityContainer getLastEntityContainer() { if (processedEntities.isEmpty()) { return null; } else { return processedEntities.get(processedEntities.size() - 1); } } /** * Retrieve an Iterable of all the processed EntityContainers. * * @return the processedEntities */ public Iterable getProcessedEntities() { return Collections.unmodifiableList(processedEntities); } } osmosis-0.44.1/osmosis-core/src/test/resources/000077500000000000000000000000001253404521400214765ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/resources/data/000077500000000000000000000000001253404521400224075ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/resources/data/template/000077500000000000000000000000001253404521400242225ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/resources/data/template/readme.txt000066400000000000000000000002351253404521400262200ustar00rootroot00000000000000The following substitutions are performed on files in this directory. %VERSION% - Replaced with the current osmosis version, useful for updating xml files. osmosis-0.44.1/osmosis-core/src/test/resources/data/template/v0_6/000077500000000000000000000000001253404521400247745ustar00rootroot00000000000000osmosis-0.44.1/osmosis-core/src/test/resources/data/template/v0_6/compressor-bzip2-test.osm.bz2000066400000000000000000000007641253404521400324140ustar00rootroot00000000000000BZh91AY&SY{_@@q[`0+%d4К20#2444S3JcBiLE! h=M"9% LoOb=nۮѝsm{`Az r]fY7YM6 1bÊvQ,fe$ 4e{D^"FUZ7%L0&]zú I'8z;1R6Gq&A $ihx&ߛ^iG> .26aAdЍ<<x)J osmosis-0.44.1/osmosis-core/src/test/resources/data/template/v0_6/migration-expected.osm000066400000000000000000000023211253404521400313020ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-core/src/test/resources/data/template/v0_6/rep-changeset.osc000066400000000000000000000025011253404521400302250ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-core/src/test/resources/data/template/v0_6/repdb-authfile.txt000066400000000000000000000001141253404521400304240ustar00rootroot00000000000000host=localhost database=replicosis user=osm password=password db=postgresql osmosis-0.44.1/osmosis-dataset/000077500000000000000000000000001253404521400164135ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/.checkstyle000066400000000000000000000010051253404521400205460ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-dataset/.gitignore000066400000000000000000000000531253404521400204010ustar00rootroot00000000000000.classpath .project .settings /bin /build osmosis-0.44.1/osmosis-dataset/build.gradle000066400000000000000000000002131253404521400206660ustar00rootroot00000000000000dependencies { compile project(':osmosis-core') testCompile project(':osmosis-xml') testCompile project(':osmosis-testutil') } osmosis-0.44.1/osmosis-dataset/src/000077500000000000000000000000001253404521400172025ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/000077500000000000000000000000001253404521400201265ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/000077500000000000000000000000001253404521400210475ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/000077500000000000000000000000001253404521400216365ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/000077500000000000000000000000001253404521400245245ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400262205ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/000077500000000000000000000000001253404521400276455ustar00rootroot00000000000000DatasetPluginLoader.java000066400000000000000000000033101253404521400343210ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.dataset; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.plugin.PluginLoader; import org.openstreetmap.osmosis.dataset.v0_6.DatasetBoundingBoxFilterFactory; import org.openstreetmap.osmosis.dataset.v0_6.DumpDatasetFactory; import org.openstreetmap.osmosis.dataset.v0_6.ReadDatasetFactory; import org.openstreetmap.osmosis.dataset.v0_6.WriteDatasetFactory; /** * The plugin loader for the dataset tasks. * * @author Brett Henderson */ public class DatasetPluginLoader implements PluginLoader { /** * {@inheritDoc} */ @Override public Map loadTaskFactories() { Map factoryMap; factoryMap = new HashMap(); factoryMap.put("write-customdb", new WriteDatasetFactory()); factoryMap.put("wc", new WriteDatasetFactory()); factoryMap.put("dataset-dump", new DumpDatasetFactory()); factoryMap.put("dd", new DumpDatasetFactory()); factoryMap.put("read-customdb", new ReadDatasetFactory()); factoryMap.put("rc", new ReadDatasetFactory()); factoryMap.put("dataset-bounding-box", new DatasetBoundingBoxFilterFactory()); factoryMap.put("dbb", new DatasetBoundingBoxFilterFactory()); factoryMap.put("write-customdb-0.6", new WriteDatasetFactory()); factoryMap.put("dataset-dump-0.6", new DumpDatasetFactory()); factoryMap.put("read-customdb-0.6", new ReadDatasetFactory()); factoryMap.put("dataset-bounding-box-0.6", new DatasetBoundingBoxFilterFactory()); return factoryMap; } } osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/v0_6/000077500000000000000000000000001253404521400304175ustar00rootroot00000000000000DatasetBoundingBoxFilter.java000066400000000000000000000055631253404521400361060ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.dataset.v0_6; import java.util.Collections; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.Dataset; import org.openstreetmap.osmosis.core.container.v0_6.DatasetContext; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.task.v0_6.DatasetSinkSource; import org.openstreetmap.osmosis.core.task.v0_6.Sink; /** * Provides a filter utilising a dataset to extract all entities that lie within * a specific geographical box identified by latitude and longitude coordinates. * * @author Brett Henderson */ public class DatasetBoundingBoxFilter implements DatasetSinkSource { private Sink sink; private double left; private double right; private double top; private double bottom; private boolean completeWays; private DatasetContext datasetReader; /** * Creates a new instance with the specified geographical coordinates. When * filtering, nodes right on the left and bottom edges of the box will be * included, nodes on the top and right edges will be excluded. * * @param left * The longitude marking the left edge of the bounding box. * @param right * The longitude marking the right edge of the bounding box. * @param top * The latitude marking the top edge of the bounding box. * @param bottom * The latitude marking the bottom edge of the bounding box. * @param completeWays * Include all nodes for ways which have some portion inside the * filtered area. */ public DatasetBoundingBoxFilter(double left, double right, double top, double bottom, boolean completeWays) { this.left = left; this.right = right; this.top = top; this.bottom = bottom; this.completeWays = completeWays; } /** * {@inheritDoc} */ @Override public void setSink(Sink sink) { this.sink = sink; } /** * {@inheritDoc} */ @Override public void process(Dataset dataset) { ReleasableIterator bboxData; if (datasetReader != null) { throw new OsmosisRuntimeException("process may only be invoked once."); } datasetReader = dataset.createReader(); // Pass all data within the bounding box to the sink. bboxData = datasetReader.iterateBoundingBox(left, right, top, bottom, completeWays); try { sink.initialize(Collections.emptyMap()); while (bboxData.hasNext()) { sink.process(bboxData.next()); } sink.complete(); } finally { bboxData.release(); } } /** * {@inheritDoc} */ @Override public void release() { sink.release(); if (datasetReader != null) { datasetReader.release(); } } } DatasetBoundingBoxFilterFactory.java000066400000000000000000000035471253404521400374360ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.dataset.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.DatasetSinkSourceManager; /** * The task manager factory for a dataset based bounding box filter. * * @author Brett Henderson */ public class DatasetBoundingBoxFilterFactory extends TaskManagerFactory { private static final String ARG_LEFT = "left"; private static final String ARG_RIGHT = "right"; private static final String ARG_TOP = "top"; private static final String ARG_BOTTOM = "bottom"; private static final double DEFAULT_LEFT = -180; private static final double DEFAULT_RIGHT = 180; private static final double DEFAULT_TOP = 90; private static final double DEFAULT_BOTTOM = -90; private static final String ARG_COMPLETE_WAYS = "completeWays"; private static final boolean DEFAULT_COMPLETE_WAYS = false; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { double left; double right; double top; double bottom; boolean completeWays; // Get the task arguments. left = getDoubleArgument(taskConfig, ARG_LEFT, DEFAULT_LEFT); right = getDoubleArgument(taskConfig, ARG_RIGHT, DEFAULT_RIGHT); top = getDoubleArgument(taskConfig, ARG_TOP, DEFAULT_TOP); bottom = getDoubleArgument(taskConfig, ARG_BOTTOM, DEFAULT_BOTTOM); completeWays = getBooleanArgument(taskConfig, ARG_COMPLETE_WAYS, DEFAULT_COMPLETE_WAYS); return new DatasetSinkSourceManager( taskConfig.getId(), new DatasetBoundingBoxFilter(left, right, top, bottom, completeWays), taskConfig.getPipeArgs() ); } } osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/v0_6/DumpDataset.java000066400000000000000000000031741253404521400335020ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.dataset.v0_6; import java.util.Collections; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.Dataset; import org.openstreetmap.osmosis.core.container.v0_6.DatasetContext; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.task.v0_6.DatasetSinkSource; import org.openstreetmap.osmosis.core.task.v0_6.Sink; /** * Reads all data from a dataset. * * @author Brett Henderson */ public class DumpDataset implements DatasetSinkSource { private Sink sink; private DatasetContext datasetReader; /** * {@inheritDoc} */ @Override public void setSink(Sink sink) { this.sink = sink; } /** * {@inheritDoc} */ @Override public void process(Dataset dataset) { ReleasableIterator bboxData; if (datasetReader != null) { throw new OsmosisRuntimeException("process may only be invoked once."); } datasetReader = dataset.createReader(); // Pass all data within the dataset to the sink. bboxData = datasetReader.iterate(); try { sink.initialize(Collections.emptyMap()); while (bboxData.hasNext()) { sink.process(bboxData.next()); } sink.complete(); } finally { bboxData.release(); } } /** * {@inheritDoc} */ @Override public void release() { sink.release(); if (datasetReader != null) { datasetReader.release(); } } } DumpDatasetFactory.java000066400000000000000000000015101253404521400347430ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.dataset.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.DatasetSinkSourceManager; /** * The task manager factory for reading the entire contents of a dataset. * * @author Brett Henderson */ public class DumpDatasetFactory extends TaskManagerFactory { /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { return new DatasetSinkSourceManager( taskConfig.getId(), new DumpDataset(), taskConfig.getPipeArgs() ); } } osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/v0_6/ReadDataset.java000066400000000000000000000030511253404521400334420ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.dataset.v0_6; import java.io.File; import org.openstreetmap.osmosis.dataset.v0_6.impl.DatasetStore; import org.openstreetmap.osmosis.dataset.v0_6.impl.DatasetStoreFileManager; import org.openstreetmap.osmosis.dataset.v0_6.impl.PermanentFileDatasetStoreFileManager; import org.openstreetmap.osmosis.core.task.v0_6.DatasetSink; import org.openstreetmap.osmosis.core.task.v0_6.RunnableDatasetSource; /** * An OSM dataset source exposing read-only access to a custom DB database. * * @author Brett Henderson */ public class ReadDataset implements RunnableDatasetSource { private DatasetSink datasetSink; private DatasetStoreFileManager fileManager; private DatasetStore store; /** * Creates a new instance. * * @param directory * The directory to store all data files in. * @param enableWayTileIndex * If true a tile index is created for ways, otherwise a node-way * index is used. */ public ReadDataset(File directory, boolean enableWayTileIndex) { fileManager = new PermanentFileDatasetStoreFileManager(directory); store = new DatasetStore(fileManager, enableWayTileIndex); } /** * {@inheritDoc} */ @Override public void setDatasetSink(DatasetSink datasetSink) { this.datasetSink = datasetSink; } /** * {@inheritDoc} */ @Override public void run() { try { datasetSink.process(store); } finally { datasetSink.release(); store.release(); } } } ReadDatasetFactory.java000066400000000000000000000032501253404521400347140ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.dataset.v0_6; import java.io.File; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.RunnableDatasetSourceManager; /** * The task manager factory for a custom database reader. * * @author Brett Henderson */ public class ReadDatasetFactory extends TaskManagerFactory { private static final String ARG_DIRECTORY_NAME = "directory"; private static final String ARG_ENABLE_WAY_TILE_INDEX = "enableWayTileIndex"; private static final String DEFAULT_DIRECTORY_NAME = "dataset"; private static final boolean DEFAULT_ENABLE_WAY_TILE_INDEX = false; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String directoryName; File directory; boolean enableWayTileIndex; ReadDataset task; // Get the task arguments. directoryName = getStringArgument( taskConfig, ARG_DIRECTORY_NAME, getDefaultStringArgument(taskConfig, DEFAULT_DIRECTORY_NAME) ); enableWayTileIndex = getBooleanArgument( taskConfig, ARG_ENABLE_WAY_TILE_INDEX, DEFAULT_ENABLE_WAY_TILE_INDEX ); // Create a file object from the directory name provided. directory = new File(directoryName); // Build the task object. task = new ReadDataset(directory, enableWayTileIndex); return new RunnableDatasetSourceManager( taskConfig.getId(), task, taskConfig.getPipeArgs() ); } } WriteDataset.java000066400000000000000000000035471253404521400336140ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.dataset.v0_6; import java.io.File; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.dataset.v0_6.impl.DatasetStore; import org.openstreetmap.osmosis.dataset.v0_6.impl.DatasetStoreFileManager; import org.openstreetmap.osmosis.dataset.v0_6.impl.PermanentFileDatasetStoreFileManager; import org.openstreetmap.osmosis.core.task.v0_6.Sink; /** * Receives input data as a stream and builds a dataset containing all of the * data. * * @author Brett Henderson */ public class WriteDataset implements Sink { private DatasetStoreFileManager fileManager; private DatasetStore store; /** * Creates a new instance. * * @param directory * The directory to store all data files in. * @param enableWayTileIndex * If true a tile index is created for ways, otherwise a node-way * index is used. */ public WriteDataset(File directory, boolean enableWayTileIndex) { fileManager = new PermanentFileDatasetStoreFileManager(directory); store = new DatasetStore(fileManager, enableWayTileIndex); } /** * {@inheritDoc} */ public void initialize(Map metaData) { store.initialize(metaData); } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { store.process(entityContainer); } /** * {@inheritDoc} */ public void complete() { store.complete(); } /** * {@inheritDoc} */ public void release() { // We must release the store last because downstream tasks must be able // to release store readers first. store.release(); // We must release the file manager after the store to ensure all open // files are closed. fileManager.release(); } } WriteDatasetFactory.java000066400000000000000000000032261253404521400351360ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.dataset.v0_6; import java.io.File; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkManager; /** * The task manager factory for writing an entity stream to a dataset. * * @author Brett Henderson */ public class WriteDatasetFactory extends TaskManagerFactory { private static final String ARG_DIRECTORY_NAME = "directory"; private static final String ARG_ENABLE_WAY_TILE_INDEX = "enableWayTileIndex"; private static final String DEFAULT_DIRECTORY_NAME = "dataset"; private static final boolean DEFAULT_ENABLE_WAY_TILE_INDEX = false; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String directoryName; File directory; boolean enableWayTileIndex; WriteDataset task; // Get the task arguments. directoryName = getStringArgument( taskConfig, ARG_DIRECTORY_NAME, getDefaultStringArgument(taskConfig, DEFAULT_DIRECTORY_NAME) ); enableWayTileIndex = getBooleanArgument( taskConfig, ARG_ENABLE_WAY_TILE_INDEX, DEFAULT_ENABLE_WAY_TILE_INDEX ); // Create a file object from the directory name provided. directory = new File(directoryName); // Build the task object. task = new WriteDataset(directory, enableWayTileIndex); return new SinkManager( taskConfig.getId(), task, taskConfig.getPipeArgs() ); } } osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/v0_6/impl/000077500000000000000000000000001253404521400313605ustar00rootroot00000000000000BoundingBoxContext.java000066400000000000000000000077221253404521400357370ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.dataset.v0_6.impl; import java.awt.geom.Rectangle2D; import java.util.Comparator; import org.openstreetmap.osmosis.core.filter.common.DynamicIdTracker; import org.openstreetmap.osmosis.core.filter.common.IdTracker; import org.openstreetmap.osmosis.core.store.UnsignedIntegerComparator; import org.openstreetmap.osmosis.core.util.TileCalculator; /** * Contains the data associated with a bounding box iteration call on a dataset. * * @author Brett Henderson */ public class BoundingBoxContext { /** * The coordinates of the box represented as an AWT box for use in AWT API * calls. */ public final Rectangle2D boundingBox; /** * The maximum tile value for the box. */ public final int maximumTile; /** * The minimum tile value for the box. */ public final int minimumTile; /** * All node ids are stored within this tracker. */ public final IdTracker nodeIdTracker; /** * All way ids are stored within this tracker. */ public final IdTracker wayIdTracker; /** * All relation ids are stored within this tracker. */ public final IdTracker relationIdTracker; /** * All nodes outside the bounding box are stored within this tracker. */ public final IdTracker externalNodeIdTracker; /** * Creates a new instance. This initialises all internal variables so that * no public variables require initialisation by external code. * * @param left * The longitude marking the left edge of the bounding box. * @param right * The longitude marking the right edge of the bounding box. * @param top * The latitude marking the top edge of the bounding box. * @param bottom * The latitude marking the bottom edge of the bounding box. */ public BoundingBoxContext(double left, double right, double top, double bottom) { TileCalculator tileCalculator; Comparator tileOrdering; int calculatedTile; int tmpMinimumTile; int tmpMaximumTile; // Create utility objects. tileCalculator = new TileCalculator(); tileOrdering = new UnsignedIntegerComparator(); // Create a rectangle representing the bounding box. boundingBox = new Rectangle2D.Double(left, bottom, right - left, top - bottom); // Calculate the maximum and minimum tile values for the bounding box. calculatedTile = (int) tileCalculator.calculateTile(top, left); tmpMaximumTile = calculatedTile; tmpMinimumTile = calculatedTile; calculatedTile = (int) tileCalculator.calculateTile(top, right); if (tileOrdering.compare(calculatedTile, tmpMinimumTile) < 0) { tmpMinimumTile = calculatedTile; } if (tileOrdering.compare(calculatedTile, tmpMaximumTile) > 0) { tmpMaximumTile = calculatedTile; } calculatedTile = (int) tileCalculator.calculateTile(bottom, left); if (tileOrdering.compare(calculatedTile, tmpMinimumTile) < 0) { tmpMinimumTile = calculatedTile; } if (tileOrdering.compare(calculatedTile, tmpMaximumTile) > 0) { tmpMaximumTile = calculatedTile; } calculatedTile = (int) tileCalculator.calculateTile(bottom, right); if (tileOrdering.compare(calculatedTile, tmpMinimumTile) < 0) { tmpMinimumTile = calculatedTile; } if (tileOrdering.compare(calculatedTile, tmpMaximumTile) > 0) { tmpMaximumTile = calculatedTile; } // The tile values at the corners are all zero. If max tile is 0 but if // the maximum longitude and latitude are above minimum values set the // maximum tile to the maximum value. if (tmpMaximumTile == 0) { if (right > -180 || top > -90) { tmpMaximumTile = 0xFFFFFFFF; } } // Set the "final" versions of tile variables with the results. maximumTile = tmpMaximumTile; minimumTile = tmpMinimumTile; // Create the id trackers. nodeIdTracker = new DynamicIdTracker(); wayIdTracker = new DynamicIdTracker(); relationIdTracker = new DynamicIdTracker(); externalNodeIdTracker = new DynamicIdTracker(); } } DatasetStore.java000066400000000000000000000332041253404521400345500ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.dataset.v0_6.impl; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.Dataset; import org.openstreetmap.osmosis.core.container.v0_6.DatasetContext; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityProcessor; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.openstreetmap.osmosis.core.lifecycle.CompletableContainer; import org.openstreetmap.osmosis.core.lifecycle.ReleasableContainer; import org.openstreetmap.osmosis.core.sort.v0_6.SortedEntityPipeValidator; import org.openstreetmap.osmosis.core.store.ComparableComparator; import org.openstreetmap.osmosis.core.store.IndexStore; import org.openstreetmap.osmosis.core.store.IndexStoreReader; import org.openstreetmap.osmosis.core.store.IntegerLongIndexElement; import org.openstreetmap.osmosis.core.store.LongLongIndexElement; import org.openstreetmap.osmosis.core.store.NoSuchIndexElementException; import org.openstreetmap.osmosis.core.store.RandomAccessObjectStore; import org.openstreetmap.osmosis.core.store.RandomAccessObjectStoreReader; import org.openstreetmap.osmosis.core.store.SingleClassObjectSerializationFactory; import org.openstreetmap.osmosis.core.store.UnsignedIntegerComparator; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.util.TileCalculator; /** * Provides a file based storage mechanism for implementing a dataset. * * @author Brett Henderson */ public class DatasetStore implements Sink, EntityProcessor, Dataset { private static final Logger LOG = Logger.getLogger(DatasetStore.class.getName()); private SortedEntityPipeValidator sortedPipeValidator; private TileCalculator tileCalculator; private UnsignedIntegerComparator uintComparator; private boolean enableWayTileIndex; private CompletableContainer storeContainer; private RandomAccessObjectStore nodeObjectStore; private IndexStore nodeObjectOffsetIndexWriter; private IndexStore nodeTileIndexWriter; private RandomAccessObjectStore wayObjectStore; private IndexStore wayObjectOffsetIndexWriter; private WayTileAreaIndex wayTileIndexWriter; private IndexStore nodeWayIndexWriter; private RandomAccessObjectStore relationObjectStore; private IndexStore relationObjectOffsetIndexWriter; private IndexStore nodeRelationIndexWriter; private IndexStore wayRelationIndexWriter; private IndexStore relationRelationIndexWriter; private RandomAccessObjectStoreReader nodeObjectReader; private IndexStoreReader nodeObjectOffsetIndexReader; /** * Creates a new instance. * * @param fileManager * The manager providing access to store files. * @param enableWayTileIndex * If true a tile index is created for ways, otherwise a node-way * index is used. */ public DatasetStore(DatasetStoreFileManager fileManager, boolean enableWayTileIndex) { this.enableWayTileIndex = enableWayTileIndex; storeContainer = new CompletableContainer(); // Validate all input data to ensure it is sorted. sortedPipeValidator = new SortedEntityPipeValidator(); sortedPipeValidator.setSink(new Sink() { @Override public void initialize(Map metaData) { throw new UnsupportedOperationException(); } @Override public void complete() { throw new UnsupportedOperationException(); } @Override public void process(EntityContainer entityContainer) { processImpl(entityContainer); } @Override public void release() { throw new UnsupportedOperationException(); } }); tileCalculator = new TileCalculator(); uintComparator = new UnsignedIntegerComparator(); // Create node store and indexes. nodeObjectStore = storeContainer.add( new RandomAccessObjectStore( new SingleClassObjectSerializationFactory(Node.class), fileManager.getNodeObjectFile() ) ); nodeObjectOffsetIndexWriter = storeContainer.add( new IndexStore( LongLongIndexElement.class, new ComparableComparator(), fileManager.getNodeObjectOffsetIndexFile() ) ); nodeTileIndexWriter = storeContainer.add( new IndexStore( IntegerLongIndexElement.class, uintComparator, fileManager.getNodeTileIndexFile() ) ); // Create way store and indexes. wayObjectStore = storeContainer.add( new RandomAccessObjectStore( new SingleClassObjectSerializationFactory(Way.class), fileManager.getWayObjectFile() ) ); wayObjectOffsetIndexWriter = storeContainer.add( new IndexStore( LongLongIndexElement.class, new ComparableComparator(), fileManager.getWayObjectOffsetIndexFile() ) ); wayTileIndexWriter = storeContainer.add(new WayTileAreaIndex(fileManager)); nodeWayIndexWriter = storeContainer.add( new IndexStore( LongLongIndexElement.class, new ComparableComparator(), fileManager.getNodeWayIndexFile() ) ); // Create relation store and indexes. relationObjectStore = storeContainer.add( new RandomAccessObjectStore( new SingleClassObjectSerializationFactory(Relation.class), fileManager.getRelationObjectFile() ) ); relationObjectOffsetIndexWriter = storeContainer.add( new IndexStore( LongLongIndexElement.class, new ComparableComparator(), fileManager.getRelationObjectOffsetIndexFile() ) ); nodeRelationIndexWriter = storeContainer.add( new IndexStore( LongLongIndexElement.class, new ComparableComparator(), fileManager.getNodeRelationIndexFile() ) ); wayRelationIndexWriter = storeContainer.add( new IndexStore( LongLongIndexElement.class, new ComparableComparator(), fileManager.getWayRelationIndexFile() ) ); relationRelationIndexWriter = storeContainer.add( new IndexStore( LongLongIndexElement.class, new ComparableComparator(), fileManager.getRelationRelationIndexFile() ) ); } /** * {@inheritDoc} */ public void initialize(Map metaData) { // Do nothing. } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { sortedPipeValidator.process(entityContainer); } /** * The entity processing implementation. This must not be called directly, * it is called by the internal sorted pipe validator. * * @param entityContainer * The entity to be processed. */ protected void processImpl(EntityContainer entityContainer) { entityContainer.process(this); } /** * {@inheritDoc} */ @Override public void process(BoundContainer bound) { // Do nothing. } /** * {@inheritDoc} */ public void process(NodeContainer nodeContainer) { Node node; long nodeId; long objectOffset; node = nodeContainer.getEntity(); nodeId = node.getId(); // Write the node to the object store and save the file offset in an // index keyed by node id. objectOffset = nodeObjectStore.add(node); nodeObjectOffsetIndexWriter.write( new LongLongIndexElement(nodeId, objectOffset) ); // Write the node id to an index keyed by tile. nodeTileIndexWriter.write( new IntegerLongIndexElement((int) tileCalculator.calculateTile(node.getLatitude(), node.getLongitude()), nodeId) ); } /** * {@inheritDoc} */ public void process(WayContainer wayContainer) { Way way; long wayId; long objectOffset; int minimumTile; int maximumTile; boolean tilesFound; if (nodeObjectReader == null) { nodeObjectStore.complete(); nodeObjectReader = nodeObjectStore.createReader(); } if (nodeObjectOffsetIndexReader == null) { nodeObjectOffsetIndexWriter.complete(); nodeObjectOffsetIndexReader = nodeObjectOffsetIndexWriter.createReader(); } way = wayContainer.getEntity(); wayId = way.getId(); // Write the way to the object store and save the file offset in an // index keyed by way id. objectOffset = wayObjectStore.add(way); wayObjectOffsetIndexWriter.write( new LongLongIndexElement(wayId, objectOffset) ); if (enableWayTileIndex) { // Calculate the minimum and maximum tile indexes for the way. tilesFound = false; minimumTile = 0; maximumTile = 0; for (WayNode wayNode : way.getWayNodes()) { long nodeId; Node node; int tile; nodeId = wayNode.getNodeId(); try { node = nodeObjectReader.get( nodeObjectOffsetIndexReader.get(nodeId).getValue() ); tile = (int) tileCalculator.calculateTile(node.getLatitude(), node.getLongitude()); if (tilesFound) { if (uintComparator.compare(tile, minimumTile) < 0) { minimumTile = tile; } if (uintComparator.compare(maximumTile, tile) < 0) { maximumTile = tile; } } else { minimumTile = tile; maximumTile = tile; tilesFound = true; } } catch (NoSuchIndexElementException e) { // Ignore any referential integrity problems. if (LOG.isLoggable(Level.FINER)) { LOG.finest( "Ignoring referential integrity problem where way " + wayId + " refers to non-existent node " + nodeId + "." ); } } } // Write the way id to an index keyed by tile but only if tiles were // actually found. if (tilesFound) { wayTileIndexWriter.write(wayId, minimumTile, maximumTile); } } else { for (WayNode wayNode : way.getWayNodes()) { long nodeId; nodeId = wayNode.getNodeId(); nodeWayIndexWriter.write(new LongLongIndexElement(nodeId, wayId)); } } } /** * {@inheritDoc} */ public void process(RelationContainer relationContainer) { Relation relation; long relationId; long objectOffset; relation = relationContainer.getEntity(); relationId = relation.getId(); // Write the relation to the object store and save the file offset in an // index keyed by relation id. objectOffset = relationObjectStore.add(relation); relationObjectOffsetIndexWriter.write( new LongLongIndexElement(relationId, objectOffset) ); // Write the relation id to indexes keyed by each of the relation members. for (RelationMember member : relation.getMembers()) { EntityType memberType; memberType = member.getMemberType(); if (memberType.equals(EntityType.Node)) { nodeRelationIndexWriter.write(new LongLongIndexElement(member.getMemberId(), relationId)); } else if (memberType.equals(EntityType.Way)) { wayRelationIndexWriter.write(new LongLongIndexElement(member.getMemberId(), relationId)); } else if (memberType.equals(EntityType.Relation)) { relationRelationIndexWriter.write(new LongLongIndexElement(member.getMemberId(), relationId)); } else { throw new OsmosisRuntimeException("Member type " + memberType + " is not recognised."); } } } /** * {@inheritDoc} */ public void complete() { // Complete all the stores to ensure their data is fully persisted. storeContainer.complete(); } /** * {@inheritDoc} */ @Override public DatasetContext createReader() { ReleasableContainer releasableContainer = new ReleasableContainer(); try { DatasetContext reader; reader = new DatasetStoreReader( new NodeStorageContainer( releasableContainer.add(nodeObjectStore.createReader()), releasableContainer.add(nodeObjectOffsetIndexWriter.createReader()), releasableContainer.add(nodeTileIndexWriter.createReader()), releasableContainer.add(nodeWayIndexWriter.createReader()), releasableContainer.add(nodeRelationIndexWriter.createReader())), new WayStorageContainer( releasableContainer.add(wayObjectStore.createReader()), releasableContainer.add(wayObjectOffsetIndexWriter.createReader()), releasableContainer.add(wayTileIndexWriter.createReader()), releasableContainer.add(wayRelationIndexWriter.createReader())), new RelationStorageContainer( releasableContainer.add(relationObjectStore.createReader()), releasableContainer.add(relationObjectOffsetIndexWriter.createReader()), releasableContainer.add(relationRelationIndexWriter.createReader())), enableWayTileIndex ); // Stop the release of all created objects. releasableContainer.clear(); return reader; } finally { releasableContainer.release(); } } /** * {@inheritDoc} */ public void release() { if (nodeObjectReader != null) { nodeObjectReader.release(); } if (nodeObjectOffsetIndexReader != null) { nodeObjectOffsetIndexReader.release(); } storeContainer.release(); } } DatasetStoreFileManager.java000066400000000000000000000051551253404521400366470ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.dataset.v0_6.impl; import java.io.File; import org.openstreetmap.osmosis.core.lifecycle.Releasable; /** * Defines the operations required for a manager of dataset store files. * * @author Brett Henderson */ public interface DatasetStoreFileManager extends Releasable { /** * Returns the file to be used for storing node objects. * * @return The node object file. */ File getNodeObjectFile(); /** * Returns the file to be used for storing node object offsets against their * id. * * @return The node object offset index file. */ File getNodeObjectOffsetIndexFile(); /** * Returns the file to be used for storing node ids against tile ids. * * @return The node tile index file. */ File getNodeTileIndexFile(); /** * Returns the file to be used for storing way objects. * * @return The way object file. */ File getWayObjectFile(); /** * Returns the file to be used for storing way object offsets against their * id. * * @return The way object offset index file. */ File getWayObjectOffsetIndexFile(); /** * Returns the file to be used for storing way ids against tile ids. Because * multiple files are used for storing way tile indexes, the implementation * must support an arbitrary number of index files to be returned. * * @param instance * The index file number. * @return The way tile index file. */ File getWayTileIndexFile(int instance); /** * Returns the file to be used for storing relationships between nodes and * ways. * * @return The node way index file. */ File getNodeWayIndexFile(); /** * Returns the file to be used for storing relation objects. * * @return The relation object file. */ File getRelationObjectFile(); /** * Returns the file to be used for storing relation object offsets against * their id. * * @return The relation object offset index file. */ File getRelationObjectOffsetIndexFile(); /** * Returns the file to be used for storing relationships between nodes and * relations. * * @return The node relation index file. */ File getNodeRelationIndexFile(); /** * Returns the file to be used for storing relationships between ways and * relations. * * @return The way relation index file. */ File getWayRelationIndexFile(); /** * Returns the file to be used for storing relationships between relations * and relations. * * @return The relation relation index file. */ File getRelationRelationIndexFile(); } DatasetStoreReader.java000066400000000000000000000423621253404521400357000ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.dataset.v0_6.impl; import java.awt.geom.Rectangle2D; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.container.v0_6.DatasetContext; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityManager; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainerIterator; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainerIterator; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainerIterator; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.openstreetmap.osmosis.core.filter.common.DynamicIdTracker; import org.openstreetmap.osmosis.core.filter.common.IdTracker; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.store.EmptyIterator; import org.openstreetmap.osmosis.core.store.MultipleSourceIterator; import org.openstreetmap.osmosis.core.store.NoSuchIndexElementException; import org.openstreetmap.osmosis.core.store.ReleasableAdaptorForIterator; import org.openstreetmap.osmosis.core.store.UpcastIterator; /** * Provides read-only access to a dataset store. Each thread accessing the store * must create its own reader. The reader maintains all references to * heavyweight resources such as file handles used to access the store * eliminating the need for objects such as object iterators to be cleaned up * explicitly. * * @author Brett Henderson */ public class DatasetStoreReader implements DatasetContext { private static final Logger LOG = Logger.getLogger(DatasetStoreReader.class.getName()); private NodeStorageContainer nodeStorageContainer; private WayStorageContainer wayStorageContainer; private RelationStorageContainer relationStorageContainer; private NodeManager nodeManager; private WayManager wayManager; private RelationManager relationManager; private boolean enableWayTileIndex; /** * Creates a new instance. * * @param nodeStorageContainer * The node storages. * @param wayStorageContainer * The way storages. * @param relationStorageContainer * The relation storages. * @param enableWayTileIndex * If true a tile index is created for ways, otherwise a node-way * index is used. */ public DatasetStoreReader( NodeStorageContainer nodeStorageContainer, WayStorageContainer wayStorageContainer, RelationStorageContainer relationStorageContainer, boolean enableWayTileIndex) { this.nodeStorageContainer = nodeStorageContainer; this.wayStorageContainer = wayStorageContainer; this.relationStorageContainer = relationStorageContainer; this.enableWayTileIndex = enableWayTileIndex; nodeManager = new NodeManager(nodeStorageContainer); wayManager = new WayManager(wayStorageContainer); relationManager = new RelationManager(relationStorageContainer); } /** * {@inheritDoc} */ private ReleasableIterator getNodeIdsForTileRange(int minimumTile, int maximumTile) { return new TileIndexValueIdIterator( nodeStorageContainer.getNodeTileIndexReader().getRange(minimumTile, maximumTile)); } /** * {@inheritDoc} */ private ReleasableIterator getWayIdsForTileRange(int minimumTile, int maximumTile) { return new ReleasableAdaptorForIterator( wayStorageContainer.getWayTileIndexReader().getRange(minimumTile, maximumTile)); } /** * {@inheritDoc} */ private ReleasableIterator getWayIdsOwningNode(long nodeId) { return new RelationalIndexValueIdIterator( nodeStorageContainer.getNodeWayIndexReader().getRange(nodeId, nodeId)); } /** * {@inheritDoc} */ private ReleasableIterator getRelationIdsOwningNode(long nodeId) { return new RelationalIndexValueIdIterator( nodeStorageContainer.getNodeRelationIndexReader().getRange(nodeId, nodeId)); } /** * {@inheritDoc} */ private ReleasableIterator getRelationIdsOwningWay(long wayId) { return new RelationalIndexValueIdIterator( wayStorageContainer.getWayRelationIndexReader().getRange(wayId, wayId)); } /** * {@inheritDoc} */ private ReleasableIterator getRelationIdsOwningRelation(long relationId) { return new RelationalIndexValueIdIterator( relationStorageContainer.getRelationRelationIndexReader().getRange(relationId, relationId)); } /** * {@inheritDoc} */ private boolean isTileWayIndexAvailable() { return enableWayTileIndex; } /** * {@inheritDoc} */ @Override @Deprecated public Node getNode(long id) { return nodeManager.getEntity(id); } /** * {@inheritDoc} */ @Override @Deprecated public Way getWay(long id) { return wayManager.getEntity(id); } /** * {@inheritDoc} */ @Override @Deprecated public Relation getRelation(long id) { return relationManager.getEntity(id); } /** * {@inheritDoc} */ @Override public EntityManager getNodeManager() { return nodeManager; } /** * {@inheritDoc} */ @Override public EntityManager getWayManager() { return wayManager; } /** * {@inheritDoc} */ @Override public EntityManager getRelationManager() { return relationManager; } /** * {@inheritDoc} */ @Override public ReleasableIterator iterate() { List> sources; sources = new ArrayList>(); sources.add( new UpcastIterator( new NodeContainerIterator(nodeManager.iterate()))); sources.add( new UpcastIterator( new WayContainerIterator(wayManager.iterate()))); sources.add( new UpcastIterator( new RelationContainerIterator(relationManager.iterate()))); return new MultipleSourceIterator(sources); } /** * Determines if a node lies within the bounding box. * * @param boundingBox * The bounding box. * @param node * The node to be checked. * @return True if the node lies within the box. */ private boolean isNodeInsideBox(Rectangle2D boundingBox, Node node) { return boundingBox.contains(node.getLongitude(), node.getLatitude()); } /** * Determines if a way lies within the bounding box. * * @param boundingBox * The bounding box. * @param nodes * The ordered nodes of the way in order. * @return True if the way is at least partially within the box. */ private boolean isWayInsideBox(Rectangle2D boundingBox, List nodes) { // If at least one node lies within the box, the way is inside the box. for (Node node : nodes) { if (isNodeInsideBox(boundingBox, node)) { return true; } } // Now we need to check if any of the segments cross the box. for (int i = 0; i < nodes.size() - 1; i++) { Node nodeA; Node nodeB; nodeA = nodes.get(i); nodeB = nodes.get(i + 1); if (boundingBox.intersectsLine(nodeA.getLongitude(), nodeA.getLatitude(), nodeB.getLongitude(), nodeB.getLatitude())) { return true; } } return false; } /** * Retrieves all nodes for the bounding box and populates the node id * tracker. * * @param bboxCtx * The bounding box data. */ private void populateNodeIds(BoundingBoxContext bboxCtx) { ReleasableIterator nodeIdsForTileset; IdTracker idTracker; idTracker = new DynamicIdTracker(); // Search through all nodes in the tile range and add them to a // temporary id tracker. This temporary id tracker allows all node ids // to be sorted ascendingly prior to retrieving the nodes themselves // which improves index performance. nodeIdsForTileset = getNodeIdsForTileRange(bboxCtx.minimumTile, bboxCtx.maximumTile); try { while (nodeIdsForTileset.hasNext()) { idTracker.set(nodeIdsForTileset.next()); } } finally { nodeIdsForTileset.release(); } // Check to see whether each applicable node lies within the bounding // box and add them to the result id list if they are. for (long nodeId : idTracker) { Node node = getNode(nodeId); // Determine if the node lies within the required bounding box. if (isNodeInsideBox(bboxCtx.boundingBox, node)) { bboxCtx.nodeIdTracker.set(nodeId); } } } /** * Retrieves all ways for the bounding box, populates the way id tracker, * and updates the external node tracker with any nodes outside the box if * complete ways are required. * * @param bboxCtx * The bounding box data. */ private void populateWayIdsUsingTileWayIndex(BoundingBoxContext bboxCtx, boolean completeWays) { ReleasableIterator tileWayIndexValues; // Search through all ways in the tile range and store the ids of those // within the bounding box. tileWayIndexValues = getWayIdsForTileRange(bboxCtx.minimumTile, bboxCtx.maximumTile); try { while (tileWayIndexValues.hasNext()) { long wayId; Way way; List nodes; // Load the current way. wayId = tileWayIndexValues.next(); way = getWay(wayId); // Load the nodes within the way. nodes = new ArrayList(); for (WayNode wayNode : way.getWayNodes()) { try { nodes.add(getNode(wayNode.getNodeId())); } catch (NoSuchIndexElementException e) { // Ignore any referential integrity problems. if (LOG.isLoggable(Level.FINER)) { LOG.finest( "Ignoring referential integrity problem where way " + wayId + " refers to non-existent node " + wayNode.getNodeId() + "." ); } } } // Determine if the way lies within the required bounding box. if (isWayInsideBox(bboxCtx.boundingBox, nodes)) { bboxCtx.wayIdTracker.set(wayId); // If we want complete ways, we need to check the list of nodes // adding any nodes that haven't already been selected (ie. // those that are outside the box). if (completeWays) { for (WayNode wayNode : way.getWayNodes()) { long nodeId; nodeId = wayNode.getNodeId(); if (!bboxCtx.nodeIdTracker.get(nodeId)) { bboxCtx.externalNodeIdTracker.set(nodeId); } } } } } } finally { tileWayIndexValues.release(); } } /** * Retrieves all ways for the currently selected nodes, populates the way id * tracker, and updates the external node tracker with any nodes outside the * box if complete ways are required. * * @param bboxCtx * The bounding box data. */ private void populateWayIdsUsingNodeWayIndex(BoundingBoxContext bboxCtx, boolean completeWays) { // Select all ways that contain the currently selected nodes. for (Long nodeId : bboxCtx.nodeIdTracker) { ReleasableIterator wayIdIterator = getWayIdsOwningNode(nodeId); try { while (wayIdIterator.hasNext()) { bboxCtx.wayIdTracker.set(wayIdIterator.next()); } } finally { wayIdIterator.release(); } } // If we want complete ways, we need to load each way and // check the list of nodes adding any nodes that haven't // already been selected (ie. those that are outside the box). // This is done outside the main loop so that ways are loaded // in ascending order which utilises index caching more effectively if (completeWays) { for (Long wayId : bboxCtx.wayIdTracker) { Way way; way = getWay(wayId); for (WayNode wayNode : way.getWayNodes()) { long externalNodeId; externalNodeId = wayNode.getNodeId(); if (!bboxCtx.nodeIdTracker.get(externalNodeId)) { bboxCtx.externalNodeIdTracker.set(externalNodeId); } } } } } /** * Retrieves all relations for the currently selected nodes and ways, * populates the relation id tracker, and recursively includes all parents * of selected relations. * * @param bboxCtx * The bounding box data. */ private void populateRelationIds(BoundingBoxContext bboxCtx) { // Select all relations that contain the currently selected nodes, ways and relations. for (Long nodeId : bboxCtx.nodeIdTracker) { ReleasableIterator relationIdIterator = getRelationIdsOwningNode(nodeId); try { while (relationIdIterator.hasNext()) { bboxCtx.relationIdTracker.set(relationIdIterator.next()); } } finally { relationIdIterator.release(); } } for (Long wayId : bboxCtx.wayIdTracker) { ReleasableIterator relationIdIterator = getRelationIdsOwningWay(wayId); try { while (relationIdIterator.hasNext()) { bboxCtx.relationIdTracker.set(relationIdIterator.next()); } } finally { relationIdIterator.release(); } } for (boolean moreParents = true; moreParents;) { // If parents of current relations are found, this flag will be set // triggering another round of searching. moreParents = false; for (Long relationId : bboxCtx.relationIdTracker) { ReleasableIterator relationIdIterator = getRelationIdsOwningRelation(relationId); try { while (relationIdIterator.hasNext()) { long parentRelationId; parentRelationId = relationIdIterator.next(); if (!bboxCtx.relationIdTracker.get(parentRelationId)) { bboxCtx.relationIdTracker.set(parentRelationId); moreParents = true; } } } finally { relationIdIterator.release(); } } } } /** * {@inheritDoc} */ @Override public ReleasableIterator iterateBoundingBox( double left, double right, double top, double bottom, boolean completeWays) { BoundingBoxContext bboxCtx; LOG.fine("Beginning bounding box iteration."); // Create the bounding box context to manage the data associated with // this call. bboxCtx = new BoundingBoxContext(left, right, top, bottom); // Verify that the input coordinates create a positive box, if not just // return an empty result set. if (left > right || bottom > top) { LOG.fine("Bounding box is zero size, returning an empty iterator."); return new EmptyIterator(); } LOG.fine("Populating node ids."); populateNodeIds(bboxCtx); if (isTileWayIndexAvailable()) { LOG.fine("Populating way ids using tile-way index."); populateWayIdsUsingTileWayIndex(bboxCtx, completeWays); } else { LOG.fine("Populating way ids using node-way index."); populateWayIdsUsingNodeWayIndex(bboxCtx, completeWays); } LOG.fine("Populating relation ids."); populateRelationIds(bboxCtx); // Now we need to add any external nodes that might have been included outside the bounding box. bboxCtx.nodeIdTracker.setAll(bboxCtx.externalNodeIdTracker); LOG.fine("Iterating all entities matching result ids."); return new ResultIterator(bboxCtx.nodeIdTracker, bboxCtx.wayIdTracker, bboxCtx.relationIdTracker); } /** * Returns a complete result set of matching records based on lists of * entity ids. It will return the nodes, followed by the ways, followed by * the relations. * * @author Brett Henderson */ private class ResultIterator implements ReleasableIterator { private Iterator nodeIds; private Iterator wayIds; private Iterator relationIds; /** * Creates a new instance. * * @param nodeIdList * The set of nodes to be returned. * @param wayIdList * The set of ways to be returned. * @param relationIdList * The set of relations to be returned. */ public ResultIterator(IdTracker nodeIdList, IdTracker wayIdList, IdTracker relationIdList) { nodeIds = nodeIdList.iterator(); wayIds = wayIdList.iterator(); relationIds = relationIdList.iterator(); } /** * {@inheritDoc} */ @Override public boolean hasNext() { return (nodeIds.hasNext() || wayIds.hasNext() || relationIds.hasNext()); } /** * {@inheritDoc} */ @Override public EntityContainer next() { if (nodeIds.hasNext()) { return new NodeContainer(getNode(nodeIds.next())); } if (wayIds.hasNext()) { return new WayContainer(getWay(wayIds.next())); } if (relationIds.hasNext()) { return new RelationContainer(getRelation(relationIds.next())); } throw new NoSuchElementException(); } /** * {@inheritDoc} */ @Override public void remove() { throw new UnsupportedOperationException(); } /** * {@inheritDoc} */ @Override public void release() { // Do nothing. } } /** * {@inheritDoc} */ @Override public void complete() { // This dataset is read-only so no changes need to be committed. } /** * {@inheritDoc} */ @Override public void release() { nodeStorageContainer.release(); wayStorageContainer.release(); relationStorageContainer.release(); } } NodeManager.java000066400000000000000000000037231253404521400343310ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.dataset.v0_6.impl; import org.openstreetmap.osmosis.core.container.v0_6.EntityManager; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.store.NoSuchIndexElementException; import org.openstreetmap.osmosis.core.store.ReleasableAdaptorForIterator; /** * Provides access to nodes within a dataset store. * * @author Brett Henderson */ public class NodeManager implements EntityManager { private NodeStorageContainer storageContainer; /** * Creates a new instance. * * @param storageContainer * The storage container containing the entities. */ public NodeManager(NodeStorageContainer storageContainer) { this.storageContainer = storageContainer; } /** * {@inheritDoc} */ @Override public void addEntity(Node entity) { throw new UnsupportedOperationException(); } /** * {@inheritDoc} */ @Override public boolean exists(long id) { // Check if the node id exists in the index. try { storageContainer.getNodeObjectOffsetIndexReader().get(id); return true; } catch (NoSuchIndexElementException e) { return false; } } /** * {@inheritDoc} */ @Override public Node getEntity(long id) { return storageContainer.getNodeObjectReader().get( storageContainer.getNodeObjectOffsetIndexReader().get(id).getValue() ); } /** * {@inheritDoc} */ @Override public ReleasableIterator iterate() { return new ReleasableAdaptorForIterator( storageContainer.getNodeObjectReader().iterate()); } /** * {@inheritDoc} */ @Override public void modifyEntity(Node entity) { throw new UnsupportedOperationException(); } /** * {@inheritDoc} */ @Override public void removeEntity(long entityId) { throw new UnsupportedOperationException(); } } NodeStorageContainer.java000066400000000000000000000070121253404521400362210ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.dataset.v0_6.impl; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.lifecycle.Releasable; import org.openstreetmap.osmosis.core.lifecycle.ReleasableContainer; import org.openstreetmap.osmosis.core.store.IndexStoreReader; import org.openstreetmap.osmosis.core.store.IntegerLongIndexElement; import org.openstreetmap.osmosis.core.store.LongLongIndexElement; import org.openstreetmap.osmosis.core.store.RandomAccessObjectStoreReader; /** * Holds references to all of the node storage related classes. * * @author Brett Henderson */ public class NodeStorageContainer implements Releasable { private ReleasableContainer releasableContainer; private RandomAccessObjectStoreReader nodeObjectReader; private IndexStoreReader nodeObjectOffsetIndexReader; private IndexStoreReader nodeTileIndexReader; private IndexStoreReader nodeWayIndexReader; private IndexStoreReader nodeRelationIndexReader; /** * Creates a new instance. * * @param nodeObjectReader * The raw node objects. * @param nodeObjectOffsetIndexReader * The node object offsets. * @param nodeTileIndexReader * The tile to node index. * @param nodeWayIndexReader * The node to way index. * @param nodeRelationIndexReader * The node to relation index. */ public NodeStorageContainer( RandomAccessObjectStoreReader nodeObjectReader, IndexStoreReader nodeObjectOffsetIndexReader, IndexStoreReader nodeTileIndexReader, IndexStoreReader nodeWayIndexReader, IndexStoreReader nodeRelationIndexReader) { releasableContainer = new ReleasableContainer(); this.nodeObjectReader = releasableContainer.add(nodeObjectReader); this.nodeObjectOffsetIndexReader = releasableContainer.add(nodeObjectOffsetIndexReader); this.nodeTileIndexReader = releasableContainer.add(nodeTileIndexReader); this.nodeWayIndexReader = releasableContainer.add(nodeWayIndexReader); this.nodeRelationIndexReader = releasableContainer.add(nodeRelationIndexReader); } /** * Gets the raw node reader. * * @return The raw node reader. */ public RandomAccessObjectStoreReader getNodeObjectReader() { return nodeObjectReader; } /** * Gets the node object offset reader. * * @return The node object offset reader. */ public IndexStoreReader getNodeObjectOffsetIndexReader() { return nodeObjectOffsetIndexReader; } /** * Gets the tile to node index reader. * * @return The tile to node index reader. */ public IndexStoreReader getNodeTileIndexReader() { return nodeTileIndexReader; } /** * Gets the node to way index reader. * * @return The node to way index reader. */ public IndexStoreReader getNodeWayIndexReader() { return nodeWayIndexReader; } /** * Gets the node to relation index reader. * * @return The node to relation index reader. */ public IndexStoreReader getNodeRelationIndexReader() { return nodeRelationIndexReader; } /** * {@inheritDoc} */ @Override public void release() { releasableContainer.release(); } } PermanentFileDatasetStoreFileManager.java000066400000000000000000000102111253404521400413060ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.dataset.v0_6.impl; import java.io.File; import java.util.HashMap; import java.util.Map; /** * Implements a dataset store file manager using permanent files stored in a specified directory. * * @author Brett Henderson */ public class PermanentFileDatasetStoreFileManager implements DatasetStoreFileManager { private File directory; private File nodeObjectFile; private File nodeObjectOffsetIndexFile; private File nodeTileIndexFile; private File wayObjectFile; private File wayObjectOffsetIndexFile; private Map wayTileIndexFileMap; private File nodeWayIndexFile; private File relationObjectFile; private File relationObjectOffsetIndexFile; private File nodeRelationIndexFile; private File wayRelationIndexFile; private File relationRelationIndexFile; /** * Creates a new instance. * * @param directory * The directory to store all datafiles in. */ public PermanentFileDatasetStoreFileManager(File directory) { this.directory = directory; wayTileIndexFileMap = new HashMap(); } /** * Creates a file object with the specified file name. It will be located in * the data directory. * * @param fileName * The name of the data file. * @return A file object representing the data file. */ private File createDataFile(String fileName) { return new File(directory, fileName); } /** * {@inheritDoc} */ @Override public File getNodeObjectFile() { if (nodeObjectFile == null) { nodeObjectFile = createDataFile("dsno"); } return nodeObjectFile; } /** * {@inheritDoc} */ @Override public File getNodeObjectOffsetIndexFile() { if (nodeObjectOffsetIndexFile == null) { nodeObjectOffsetIndexFile = createDataFile("dsnooi"); } return nodeObjectOffsetIndexFile; } /** * {@inheritDoc} */ @Override public File getNodeTileIndexFile() { if (nodeTileIndexFile == null) { nodeTileIndexFile = createDataFile("dsnti"); } return nodeTileIndexFile; } /** * {@inheritDoc} */ @Override public File getWayObjectFile() { if (wayObjectFile == null) { wayObjectFile = createDataFile("dswo"); } return wayObjectFile; } /** * {@inheritDoc} */ @Override public File getWayObjectOffsetIndexFile() { if (wayObjectOffsetIndexFile == null) { wayObjectOffsetIndexFile = createDataFile("dswooi"); } return wayObjectOffsetIndexFile; } /** * {@inheritDoc} */ @Override public File getWayTileIndexFile(int instance) { if (!wayTileIndexFileMap.containsKey(instance)) { wayTileIndexFileMap.put(instance, createDataFile("dswti" + instance)); } return wayTileIndexFileMap.get(instance); } /** * {@inheritDoc} */ @Override public File getNodeWayIndexFile() { if (nodeWayIndexFile == null) { nodeWayIndexFile = createDataFile("dsnwi"); } return nodeWayIndexFile; } /** * {@inheritDoc} */ @Override public File getRelationObjectFile() { if (relationObjectFile == null) { relationObjectFile = createDataFile("dsro"); } return relationObjectFile; } /** * {@inheritDoc} */ @Override public File getRelationObjectOffsetIndexFile() { if (relationObjectOffsetIndexFile == null) { relationObjectOffsetIndexFile = createDataFile("dsrooi"); } return relationObjectOffsetIndexFile; } /** * {@inheritDoc} */ @Override public File getNodeRelationIndexFile() { if (nodeRelationIndexFile == null) { nodeRelationIndexFile = createDataFile("dsnri"); } return nodeRelationIndexFile; } /** * {@inheritDoc} */ @Override public File getWayRelationIndexFile() { if (wayRelationIndexFile == null) { wayRelationIndexFile = createDataFile("dswri"); } return wayRelationIndexFile; } /** * {@inheritDoc} */ @Override public File getRelationRelationIndexFile() { if (relationRelationIndexFile == null) { relationRelationIndexFile = createDataFile("dsrri"); } return relationRelationIndexFile; } /** * {@inheritDoc} */ @Override public void release() { // Do nothing. } } RelationManager.java000066400000000000000000000040231253404521400352130ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.dataset.v0_6.impl; import org.openstreetmap.osmosis.core.container.v0_6.EntityManager; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.store.NoSuchIndexElementException; import org.openstreetmap.osmosis.core.store.ReleasableAdaptorForIterator; /** * Provides access to relations within a dataset store. * * @author Brett Henderson */ public class RelationManager implements EntityManager { private RelationStorageContainer storageContainer; /** * Creates a new instance. * * @param storageContainer * The storage container containing the entities. */ public RelationManager(RelationStorageContainer storageContainer) { this.storageContainer = storageContainer; } /** * {@inheritDoc} */ @Override public void addEntity(Relation entity) { throw new UnsupportedOperationException(); } /** * {@inheritDoc} */ @Override public boolean exists(long id) { // Check if the node id exists in the index. try { storageContainer.getRelationObjectOffsetIndexReader().get(id); return true; } catch (NoSuchIndexElementException e) { return false; } } /** * {@inheritDoc} */ @Override public Relation getEntity(long id) { return storageContainer.getRelationObjectReader().get( storageContainer.getRelationObjectOffsetIndexReader().get(id).getValue() ); } /** * {@inheritDoc} */ @Override public ReleasableIterator iterate() { return new ReleasableAdaptorForIterator( storageContainer.getRelationObjectReader().iterate()); } /** * {@inheritDoc} */ @Override public void modifyEntity(Relation entity) { throw new UnsupportedOperationException(); } /** * {@inheritDoc} */ @Override public void removeEntity(long entityId) { throw new UnsupportedOperationException(); } } RelationStorageContainer.java000066400000000000000000000051341253404521400371140ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.dataset.v0_6.impl; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.lifecycle.Releasable; import org.openstreetmap.osmosis.core.lifecycle.ReleasableContainer; import org.openstreetmap.osmosis.core.store.IndexStoreReader; import org.openstreetmap.osmosis.core.store.LongLongIndexElement; import org.openstreetmap.osmosis.core.store.RandomAccessObjectStoreReader; /** * Holds references to all of the node storage related classes. * * @author Brett Henderson */ public class RelationStorageContainer implements Releasable { private ReleasableContainer releasableContainer; private RandomAccessObjectStoreReader relationObjectReader; private IndexStoreReader relationObjectOffsetIndexReader; private IndexStoreReader relationRelationIndexReader; /** * Creates a new instance. * * @param relationObjectReader * The raw relation objects. * @param relationObjectOffsetIndexReader * The relation object offsets. * @param relationRelationIndexReader * The relation to relation index. */ public RelationStorageContainer(RandomAccessObjectStoreReader relationObjectReader, IndexStoreReader relationObjectOffsetIndexReader, IndexStoreReader relationRelationIndexReader) { releasableContainer = new ReleasableContainer(); this.relationObjectReader = releasableContainer.add(relationObjectReader); this.relationObjectOffsetIndexReader = releasableContainer.add(relationObjectOffsetIndexReader); this.relationRelationIndexReader = releasableContainer.add(relationRelationIndexReader); } /** * Gets the raw relation reader. * * @return The raw relation reader. */ public RandomAccessObjectStoreReader getRelationObjectReader() { return relationObjectReader; } /** * Gets the relation object offset reader. * * @return The relation object offset reader. */ public IndexStoreReader getRelationObjectOffsetIndexReader() { return relationObjectOffsetIndexReader; } /** * Gets the relation to relation index reader. * * @return The relation to relation index reader. */ public IndexStoreReader getRelationRelationIndexReader() { return relationRelationIndexReader; } /** * {@inheritDoc} */ @Override public void release() { releasableContainer.release(); } } RelationalIndexValueIdIterator.java000066400000000000000000000022231253404521400402110ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.dataset.v0_6.impl; import java.util.Iterator; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.store.LongLongIndexElement; /** * Iterates over a relational index iterator and returns all the id values * stored against the index elements. * * @author Brett Henderson */ public class RelationalIndexValueIdIterator implements ReleasableIterator { private Iterator source; /** * Creates a new instance. * * @param source * The input source. */ public RelationalIndexValueIdIterator(Iterator source) { this.source = source; } /** * {@inheritDoc} */ @Override public boolean hasNext() { return source.hasNext(); } /** * {@inheritDoc} */ @Override public Long next() { return source.next().getValue(); } /** * {@inheritDoc} */ @Override public void remove() { source.remove(); } /** * {@inheritDoc} */ @Override public void release() { // Do nothing. } } TempFileDatasetStoreFileManager.java000066400000000000000000000107521253404521400402740ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.dataset.v0_6.impl; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Implements a dataset store file manager using temporary files. * * @author Brett Henderson */ public class TempFileDatasetStoreFileManager implements DatasetStoreFileManager { private static Logger log = Logger.getLogger(TempFileDatasetStoreFileManager.class.getName()); private List allFiles; private File nodeObjectFile; private File nodeObjectOffsetIndexFile; private File nodeTileIndexFile; private File wayObjectFile; private File wayObjectOffsetIndexFile; private Map wayTileIndexFileMap; private File nodeWayIndexFile; private File relationObjectFile; private File relationObjectOffsetIndexFile; private File nodeRelationIndexFile; private File wayRelationIndexFile; private File relationRelationIndexFile; /** * Creates a new instance. */ public TempFileDatasetStoreFileManager() { allFiles = new ArrayList(); wayTileIndexFileMap = new HashMap(); } /** * Creates a temporary file. * * @param prefix * The temporary file name prefix. * @return The newly created temporary file. */ private File createTempFile(String prefix) { try { File file; file = File.createTempFile(prefix, null); allFiles.add(file); return file; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to create a new temporary file.", e); } } /** * {@inheritDoc} */ @Override public File getNodeObjectFile() { if (nodeObjectFile == null) { nodeObjectFile = createTempFile("dsno"); } return nodeObjectFile; } /** * {@inheritDoc} */ @Override public File getNodeObjectOffsetIndexFile() { if (nodeObjectOffsetIndexFile == null) { nodeObjectOffsetIndexFile = createTempFile("dsnooi"); } return nodeObjectOffsetIndexFile; } /** * {@inheritDoc} */ @Override public File getNodeTileIndexFile() { if (nodeTileIndexFile == null) { nodeTileIndexFile = createTempFile("dsnti"); } return nodeTileIndexFile; } /** * {@inheritDoc} */ @Override public File getWayObjectFile() { if (wayObjectFile == null) { wayObjectFile = createTempFile("dswo"); } return wayObjectFile; } /** * {@inheritDoc} */ @Override public File getWayObjectOffsetIndexFile() { if (wayObjectOffsetIndexFile == null) { wayObjectOffsetIndexFile = createTempFile("dswooi"); } return wayObjectOffsetIndexFile; } /** * {@inheritDoc} */ @Override public File getWayTileIndexFile(int instance) { if (!wayTileIndexFileMap.containsKey(instance)) { wayTileIndexFileMap.put(instance, createTempFile("dswti")); } return wayTileIndexFileMap.get(instance); } /** * {@inheritDoc} */ @Override public File getNodeWayIndexFile() { if (nodeWayIndexFile == null) { nodeWayIndexFile = createTempFile("dsnwi"); } return nodeWayIndexFile; } /** * {@inheritDoc} */ @Override public File getRelationObjectFile() { if (relationObjectFile == null) { relationObjectFile = createTempFile("dsro"); } return relationObjectFile; } /** * {@inheritDoc} */ @Override public File getRelationObjectOffsetIndexFile() { if (relationObjectOffsetIndexFile == null) { relationObjectOffsetIndexFile = createTempFile("dsrooi"); } return relationObjectOffsetIndexFile; } /** * {@inheritDoc} */ @Override public File getNodeRelationIndexFile() { if (nodeRelationIndexFile == null) { nodeRelationIndexFile = createTempFile("dsnri"); } return nodeRelationIndexFile; } /** * {@inheritDoc} */ @Override public File getWayRelationIndexFile() { if (wayRelationIndexFile == null) { wayRelationIndexFile = createTempFile("dswri"); } return wayRelationIndexFile; } /** * {@inheritDoc} */ @Override public File getRelationRelationIndexFile() { if (relationRelationIndexFile == null) { relationRelationIndexFile = createTempFile("dsrri"); } return relationRelationIndexFile; } /** * {@inheritDoc} */ @Override public void release() { for (File file : allFiles) { if (!file.delete()) { log.warning("Unable to delete file " + file); } } } } TileIndexValueIdIterator.java000066400000000000000000000022171253404521400370170ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.dataset.v0_6.impl; import java.util.Iterator; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.store.IntegerLongIndexElement; /** * Iterates over a tile index iterator and returns all the id values stored * against the tile index elements. * * @author Brett Henderson */ public class TileIndexValueIdIterator implements ReleasableIterator { private Iterator source; /** * Creates a new instance. * * @param source * The input source. */ public TileIndexValueIdIterator(Iterator source) { this.source = source; } /** * {@inheritDoc} */ @Override public boolean hasNext() { return source.hasNext(); } /** * {@inheritDoc} */ @Override public Long next() { return source.next().getValue(); } /** * {@inheritDoc} */ @Override public void remove() { source.remove(); } /** * {@inheritDoc} */ @Override public void release() { // Do nothing. } } WayManager.java000066400000000000000000000037031253404521400342020ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.dataset.v0_6.impl; import org.openstreetmap.osmosis.core.container.v0_6.EntityManager; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.store.NoSuchIndexElementException; import org.openstreetmap.osmosis.core.store.ReleasableAdaptorForIterator; /** * Provides access to ways within a dataset store. * * @author Brett Henderson */ public class WayManager implements EntityManager { private WayStorageContainer storageContainer; /** * Creates a new instance. * * @param storageContainer * The storage container containing the entities. */ public WayManager(WayStorageContainer storageContainer) { this.storageContainer = storageContainer; } /** * {@inheritDoc} */ @Override public void addEntity(Way entity) { throw new UnsupportedOperationException(); } /** * {@inheritDoc} */ @Override public boolean exists(long id) { // Check if the node id exists in the index. try { storageContainer.getWayObjectOffsetIndexReader().get(id); return true; } catch (NoSuchIndexElementException e) { return false; } } /** * {@inheritDoc} */ @Override public Way getEntity(long id) { return storageContainer.getWayObjectReader().get( storageContainer.getWayObjectOffsetIndexReader().get(id).getValue() ); } /** * {@inheritDoc} */ @Override public ReleasableIterator iterate() { return new ReleasableAdaptorForIterator( storageContainer.getWayObjectReader().iterate()); } /** * {@inheritDoc} */ @Override public void modifyEntity(Way entity) { throw new UnsupportedOperationException(); } /** * {@inheritDoc} */ @Override public void removeEntity(long entityId) { throw new UnsupportedOperationException(); } } WayStorageContainer.java000066400000000000000000000055221253404521400361000ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.dataset.v0_6.impl; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.lifecycle.Releasable; import org.openstreetmap.osmosis.core.lifecycle.ReleasableContainer; import org.openstreetmap.osmosis.core.store.IndexStoreReader; import org.openstreetmap.osmosis.core.store.LongLongIndexElement; import org.openstreetmap.osmosis.core.store.RandomAccessObjectStoreReader; /** * Holds references to all of the node storage related classes. * * @author Brett Henderson */ public class WayStorageContainer implements Releasable { private ReleasableContainer releasableContainer; private RandomAccessObjectStoreReader wayObjectReader; private IndexStoreReader wayObjectOffsetIndexReader; private WayTileAreaIndexReader wayTileIndexReader; private IndexStoreReader wayRelationIndexReader; /** * Creates a new instance. * * @param wayObjectReader * The raw way objects. * @param wayObjectOffsetIndexReader * The way object offsets. * @param wayTileIndexReader * The tile to way index. * @param wayRelationIndexReader * The way to relation index. */ public WayStorageContainer(RandomAccessObjectStoreReader wayObjectReader, IndexStoreReader wayObjectOffsetIndexReader, WayTileAreaIndexReader wayTileIndexReader, IndexStoreReader wayRelationIndexReader) { releasableContainer = new ReleasableContainer(); this.wayObjectReader = releasableContainer.add(wayObjectReader); this.wayObjectOffsetIndexReader = releasableContainer.add(wayObjectOffsetIndexReader); this.wayTileIndexReader = releasableContainer.add(wayTileIndexReader); this.wayRelationIndexReader = releasableContainer.add(wayRelationIndexReader); } /** * Gets the raw way reader. * * @return The raw way reader. */ public RandomAccessObjectStoreReader getWayObjectReader() { return wayObjectReader; } /** * Gets the way object offset reader. * * @return The way object offset reader. */ public IndexStoreReader getWayObjectOffsetIndexReader() { return wayObjectOffsetIndexReader; } /** * Gets the tile to way index reader. * * @return The tile to way index reader. */ public WayTileAreaIndexReader getWayTileIndexReader() { return wayTileIndexReader; } /** * Gets the way to relation index reader. * * @return The way to relation index reader. */ public IndexStoreReader getWayRelationIndexReader() { return wayRelationIndexReader; } /** * {@inheritDoc} */ @Override public void release() { releasableContainer.release(); } } WayTileAreaIndex.java000066400000000000000000000070431253404521400353070ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.dataset.v0_6.impl; import java.util.ArrayList; import java.util.List; import org.openstreetmap.osmosis.core.lifecycle.Completable; import org.openstreetmap.osmosis.core.lifecycle.Releasable; import org.openstreetmap.osmosis.core.lifecycle.ReleasableContainer; import org.openstreetmap.osmosis.core.store.IndexStore; import org.openstreetmap.osmosis.core.store.IndexStoreReader; import org.openstreetmap.osmosis.core.store.IntegerLongIndexElement; import org.openstreetmap.osmosis.core.store.UnsignedIntegerComparator; /** * A class for managing a way tile index of varying granularity allowing * different sized tiles for different sized ways. */ public class WayTileAreaIndex implements Completable { private static final int[] MASKS = {0xFFFFFFFF, 0xFFFFFFF0, 0xFFFFFF00, 0xFFFF0000, 0xFF000000, 0x00000000}; private List> indexes; /** * Creates a new instance. * * @param fileManager * Manages and provides files for writing indexes to. */ public WayTileAreaIndex(DatasetStoreFileManager fileManager) { indexes = new ArrayList>(MASKS.length); for (int i = 0; i < MASKS.length; i++) { indexes.add( new IndexStore( IntegerLongIndexElement.class, new UnsignedIntegerComparator(), fileManager.getWayTileIndexFile(i) ) ); } } /** * Writes a new way tile entry to the index. * * @param wayId * The way to be added. * @param minimumTile * The minimum tile of the way. * @param maximumTile * The maximum tile of the way. */ public void write(long wayId, int minimumTile, int maximumTile) { // Write a new index element for the tile to the tile index that matches // the granularity of the way. for (int i = 0; i < MASKS.length; i++) { int mask; int maskedMinimum; int maskedMaximum; mask = MASKS[i]; maskedMinimum = mask & minimumTile; maskedMaximum = mask & maximumTile; // Write the element to the current index if the index tile // granularity allows the way to fit within a single tile value. if ((maskedMinimum) == (maskedMaximum)) { indexes.get(i).write(new IntegerLongIndexElement(maskedMinimum, wayId)); // Stop once one index has received the way. break; } } } /** * Creates a new reader capable of accessing the contents of this index. The * reader must be explicitly released when no longer required. Readers must * be released prior to this index. * * @return An index reader. */ public WayTileAreaIndexReader createReader() { ReleasableContainer releasableContainer = new ReleasableContainer(); try { List> indexReaders; indexReaders = new ArrayList>(MASKS.length); for (IndexStore index : indexes) { indexReaders.add(releasableContainer.add(index.createReader())); } releasableContainer.clear(); return new WayTileAreaIndexReader(MASKS, indexReaders); } finally { releasableContainer.release(); } } /** * {@inheritDoc} */ @Override public void complete() { for (Completable index : indexes) { index.complete(); } } /** * {@inheritDoc} */ @Override public void release() { for (Releasable index : indexes) { index.release(); } } } WayTileAreaIndexReader.java000066400000000000000000000077561253404521400364450ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/java/org/openstreetmap/osmosis/dataset/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.dataset.v0_6.impl; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import org.openstreetmap.osmosis.core.lifecycle.Releasable; import org.openstreetmap.osmosis.core.store.IndexStoreReader; import org.openstreetmap.osmosis.core.store.IntegerLongIndexElement; /** * Provides read-only access to a way tile area index store. Each thread * accessing the store must create its own reader. The reader maintains all * references to heavyweight resources such as file handles used to access the * store eliminating the need for objects such as object iterators to be cleaned * up explicitly. * * @author Brett Henderson */ public class WayTileAreaIndexReader implements Releasable { private int[] masks = {0xFFFFFFFF, 0xFFFFFFF0, 0xFFFFFF00, 0xFFFF0000, 0xFF000000, 0x00000000}; private List> indexReaders; /** * Creates a new instance. * * @param masks * The index masks. * @param indexReaders * The index readers. */ public WayTileAreaIndexReader(int[] masks, List> indexReaders) { this.masks = masks; this.indexReaders = indexReaders; } /** * Returns all elements in the range specified by the minimum and maximum * tiles. All ways with tiles matching and lying between the two values will * be returned. * * @param minimumTile * The minimum tile in the range. * @param maximumTile * The maximum tile in the range. * @return An iterator pointing to the requested range. */ public Iterator getRange(Integer minimumTile, Integer maximumTile) { List> ranges; // Loop through the masks reading way id ranges from the corresponding // indexes. ranges = new ArrayList>(masks.length); for (int i = 0; i < masks.length; i++) { int mask; int beginKey; int endKey; IndexStoreReader indexReader; mask = masks[i]; beginKey = mask & minimumTile; endKey = mask & maximumTile; indexReader = indexReaders.get(i); ranges.add(indexReader.getRange(beginKey, endKey)); } return new ResultIterator(ranges.iterator()); } /** * {@inheritDoc} */ @Override public void release() { for (IndexStoreReader indexReader : indexReaders) { indexReader.release(); } } /** * Returns a complete result set of matching index values based on iterators * from each of the internal indexes. * * @author Brett Henderson */ private static class ResultIterator implements Iterator { private Iterator> sources; private Iterator currentSource; private boolean currentSourceAvailable; /** * Creates a new instance. * * @param sources * The input sources. */ public ResultIterator(Iterator> sources) { this.sources = sources; currentSourceAvailable = false; } /** * {@inheritDoc} */ @Override public boolean hasNext() { while (true) { // Get the next available input source if required. if (!currentSourceAvailable) { if (sources.hasNext()) { currentSource = sources.next(); currentSourceAvailable = true; } else { return false; } } if (currentSource.hasNext()) { return true; } else { currentSourceAvailable = false; } } } /** * {@inheritDoc} */ @Override public Long next() { if (!hasNext()) { throw new NoSuchElementException(); } return currentSource.next().getValue(); } /** * {@inheritDoc} */ @Override public void remove() { throw new UnsupportedOperationException(); } } } osmosis-0.44.1/osmosis-dataset/src/main/resources/000077500000000000000000000000001253404521400221405ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/main/resources/osmosis-plugins.conf000066400000000000000000000000651253404521400261630ustar00rootroot00000000000000org.openstreetmap.osmosis.dataset.DatasetPluginLoaderosmosis-0.44.1/osmosis-dataset/src/test/000077500000000000000000000000001253404521400201615ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/test/java/000077500000000000000000000000001253404521400211025ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/test/java/org/000077500000000000000000000000001253404521400216715ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/test/java/org/openstreetmap/000077500000000000000000000000001253404521400245575ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/test/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400262535ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/test/java/org/openstreetmap/osmosis/dataset/000077500000000000000000000000001253404521400277005ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/test/java/org/openstreetmap/osmosis/dataset/v0_6/000077500000000000000000000000001253404521400304525ustar00rootroot00000000000000CustomDbTest.java000066400000000000000000000027411253404521400336220ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/test/java/org/openstreetmap/osmosis/dataset/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.dataset.v0_6; import java.io.File; import java.io.IOException; import org.junit.Test; import org.openstreetmap.osmosis.core.Osmosis; import org.openstreetmap.osmosis.testutil.AbstractDataTest; /** * Tests for PostgreSQL tasks. * * @author Brett Henderson */ public class CustomDbTest extends AbstractDataTest { /** * A basic test loading an osm file into a pgsql database, then dumping it * again and verifying that it is identical. * * @throws IOException * if any file operations fail. */ @Test public void testLoadAndDump() throws IOException { File inputFile; File outputFile; File dataDir; // Generate input files. inputFile = dataUtils.createDataFile("v0_6/customdb-snapshot.osm"); outputFile = File.createTempFile("test", ".osm"); dataDir = dataUtils.newFolder(); // Load the database with a dataset. Osmosis.run( new String [] { "-q", "--read-xml-0.6", inputFile.getPath(), "--write-customdb-0.6", "directory=" + dataDir } ); // Dump the database to an osm file. Osmosis.run( new String [] { "-q", "--read-customdb-0.6", "directory=" + dataDir, "--dataset-dump-0.6", "--tag-sort-0.6", "--write-xml-0.6", outputFile.getPath() } ); // Validate that the output file matches the input file. dataUtils.compareFiles(inputFile, outputFile); } } osmosis-0.44.1/osmosis-dataset/src/test/resources/000077500000000000000000000000001253404521400221735ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/test/resources/data/000077500000000000000000000000001253404521400231045ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/test/resources/data/template/000077500000000000000000000000001253404521400247175ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/test/resources/data/template/v0_6/000077500000000000000000000000001253404521400254715ustar00rootroot00000000000000osmosis-0.44.1/osmosis-dataset/src/test/resources/data/template/v0_6/customdb-snapshot.osm000066400000000000000000000033151253404521400316700ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-extract/000077500000000000000000000000001253404521400164405ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/.checkstyle000066400000000000000000000010051253404521400205730ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-extract/.gitignore000066400000000000000000000000531253404521400204260ustar00rootroot00000000000000.classpath .project .settings /bin /build osmosis-0.44.1/osmosis-extract/build.gradle000066400000000000000000000003311253404521400207140ustar00rootroot00000000000000dependencies { compile project(':osmosis-apidb') compile project(':osmosis-core') compile project(':osmosis-replication') compile project(':osmosis-xml') testCompile project(':osmosis-testutil') } osmosis-0.44.1/osmosis-extract/src/000077500000000000000000000000001253404521400172275ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/main/000077500000000000000000000000001253404521400201535ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/main/java/000077500000000000000000000000001253404521400210745ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/main/java/org/000077500000000000000000000000001253404521400216635ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/main/java/org/openstreetmap/000077500000000000000000000000001253404521400245515ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/main/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400262455ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/main/java/org/openstreetmap/osmosis/extract/000077500000000000000000000000001253404521400277175ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/main/java/org/openstreetmap/osmosis/extract/apidb/000077500000000000000000000000001253404521400307765ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/main/java/org/openstreetmap/osmosis/extract/apidb/common/000077500000000000000000000000001253404521400322665ustar00rootroot00000000000000Configuration.java000066400000000000000000000133201253404521400356600ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/main/java/org/openstreetmap/osmosis/extract/apidb/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.extract.apidb.common; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.database.DatabaseType; /** * Loads and exposes the extraction configuration properties. * * @author Brett Henderson */ public class Configuration { private static final Logger LOG = Logger.getLogger(Configuration.class.getName()); private static final String KEY_HOST = "host"; private static final String KEY_DATABASE = "database"; private static final String KEY_USER = "user"; private static final String KEY_PASSWORD = "password"; private static final String KEY_DB_TYPE = "dbType"; private static final String KEY_INTERVAL_LENGTH = "intervalLength"; private static final String KEY_LAG_LENGTH = "lagLength"; private static final String KEY_CHANGE_FILE_BEGIN_FORMAT = "changeFileBeginFormat"; private static final String KEY_CHANGE_FILE_END_FORMAT = "changeFileEndFormat"; private static final String KEY_READ_FULL_HISTORY = "readFullHistory"; private static final String KEY_VALIDATE_SCHEMA_VERSION = "validateSchemaVersion"; private static final String KEY_ALLOW_INCORRECT_SCHEMA_VERSION = "allowIncorrectSchemaVersion"; private Properties properties; /** * Creates a new instance. * * @param configFile * The configuration file to read from. */ public Configuration(File configFile) { properties = loadProperties(configFile); } private Properties loadProperties(File configFile) { FileInputStream fileInputStream = null; properties = new Properties(); try { fileInputStream = new FileInputStream(configFile); properties.load(fileInputStream); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to load properties from config file " + configFile); } finally { if (fileInputStream != null) { try { fileInputStream.close(); } catch (IOException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to close file input stream.", e); } } } return properties; } private String getProperty(String propertyName) { String value; value = properties.getProperty(propertyName); if (value == null) { throw new OsmosisRuntimeException("Property " + propertyName + " cannot be found."); } return value; } /** * Returns the database host. * * @return The database host. */ public String getHost() { return getProperty(KEY_HOST); } /** * Returns the database instance. * * @return The database instance. */ public String getDatabase() { return getProperty(KEY_DATABASE); } /** * Returns the database user. * * @return The database user. */ public String getUser() { return getProperty(KEY_USER); } /** * Returns the database password. * * @return The database password. */ public String getPassword() { // Call the properties object directly because we allow nulls for a password. return properties.getProperty(KEY_PASSWORD); } /** * Returns the database type. * * @return The database type */ public DatabaseType getDbType() { return DatabaseType.fromString(getProperty(KEY_DB_TYPE)); } /** * Returns the duration of each changeset interval. * * @return The interval length in milliseconds. */ public int getIntervalLength() { return Integer.parseInt(getProperty(KEY_INTERVAL_LENGTH)) * 1000; } /** * Returns the amount of time the extraction process lags the current time to allow the database * to stabilise to ensure consistent queries. * * @return The lag length in milliseconds. */ public int getLagLength() { return Integer.parseInt(getProperty(KEY_LAG_LENGTH)) * 1000; } /** * Returns the begin time portion of the changeset filename. * * @return The format. */ public String getChangeFileBeginFormat() { return getProperty(KEY_CHANGE_FILE_BEGIN_FORMAT); } /** * Returns the end time portion of the changeset filename. * * @return The format. */ public String getChangeFileEndFormat() { return getProperty(KEY_CHANGE_FILE_END_FORMAT); } /** * Returns the full history flag. * * @return The full history flag. */ public boolean getReadFullHistory() { return Boolean.valueOf(getProperty(KEY_READ_FULL_HISTORY)); } /** * Returns the validate schema version flag. * * @return The validate schema version flag. */ public boolean getValidateSchemaVersion() { return Boolean.valueOf(getProperty(KEY_VALIDATE_SCHEMA_VERSION)); } /** * Returns the validate schema version flag. * * @return The validate schema version flag. */ public boolean getAllowIncorrectSchemaVersion() { return Boolean.valueOf(getProperty(KEY_ALLOW_INCORRECT_SCHEMA_VERSION)); } /** * Provides a fully configured set of database login credentials based on the configuration. * * @return The database login credentials. */ public DatabaseLoginCredentials getDatabaseLoginCredentials() { return new DatabaseLoginCredentials(getHost(), getDatabase(), getUser(), getPassword(), false, false, getDbType()); } /** * Provides a fully configured set of database preferences based on the configuration. * * @return The database preferences. */ public DatabasePreferences getDatabasePreferences() { return new DatabasePreferences(getValidateSchemaVersion(), getAllowIncorrectSchemaVersion()); } } osmosis-0.44.1/osmosis-extract/src/main/java/org/openstreetmap/osmosis/extract/apidb/v0_6/000077500000000000000000000000001253404521400315505ustar00rootroot00000000000000DatabaseTimeLoader.java000066400000000000000000000042711253404521400360120ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/main/java/org/openstreetmap/osmosis/extract/apidb/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.extract.apidb.v0_6; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Date; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.apidb.common.DatabaseContext; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; /** * Loads the current time from the database. This avoids relying on the clock of this system which * may be different. If this system was to skew ahead of the database server it may be possible for * data to be missed during extraction operations. * * @author Brett Henderson */ public class DatabaseTimeLoader { private static final Logger LOG = Logger.getLogger(DatabaseTimeLoader.class.getName()); private DatabaseLoginCredentials loginCredentials; /** * Creates a new instance. * * @param loginCredentials Contains all information required to connect to the database. */ public DatabaseTimeLoader(DatabaseLoginCredentials loginCredentials) { this.loginCredentials = loginCredentials; } private Date readTimeField(ResultSet timeSet) { ResultSet rs = timeSet; try { Date dbTime; Date result; timeSet.next(); dbTime = timeSet.getTimestamp("SystemTime"); result = new Date(dbTime.getTime()); rs.close(); rs = null; return result; } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to read the time from the database server.", e); } finally { if (rs != null) { try { rs.close(); } catch (SQLException e) { LOG.log(Level.WARNING, "Unable to close result set.", e); } } } } /** * Gets the current system time according to the database server. * * @return The current system time. */ public Date getDatabaseTime() { DatabaseContext dbCtx = new DatabaseContext(loginCredentials); try { ResultSet rs; Date result; rs = dbCtx.executeQuery("SELECT now() AS SystemTime"); result = readTimeField(rs); return result; } finally { dbCtx.release(); } } } IntervalExtractor.java000066400000000000000000000067601253404521400360250ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/main/java/org/openstreetmap/osmosis/extract/apidb/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.extract.apidb.v0_6; import java.io.File; import java.util.Date; import org.openstreetmap.osmosis.apidb.v0_6.ApidbChangeReader; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.sort.v0_6.ChangeTagSorter; import org.openstreetmap.osmosis.extract.apidb.common.Configuration; import org.openstreetmap.osmosis.replication.v0_6.impl.ChangesetFileNameFormatter; import org.openstreetmap.osmosis.xml.common.CompressionMethod; import org.openstreetmap.osmosis.xml.v0_6.XmlChangeWriter; /** * Performs an extract from a database for a single time interval and writes to a change file. * * @author Brett Henderson */ public class IntervalExtractor { private static final String TMP_FILE_NAME = "tmpchangeset.osc.gz"; private final Configuration config; private final File baseDirectory; private final Date intervalBegin; private final Date intervalEnd; private final boolean fullHistory; /** * Creates a new instance. * * @param config * The configuration object defining runtime parameters. * @param baseDirectory * The root of the changeset extraction directory tree. * @param intervalBegin * The beginning of the interval to extract. * @param intervalEnd * The end of the interval to extract. * @param fullHistory * Specifies if full version history should be returned, or just a single change per * entity for the interval. */ public IntervalExtractor(Configuration config, File baseDirectory, Date intervalBegin, Date intervalEnd, boolean fullHistory) { this.baseDirectory = baseDirectory; this.config = config; this.intervalBegin = intervalBegin; this.intervalEnd = intervalEnd; this.fullHistory = fullHistory; } /** * Runs the changeset extraction. */ public void run() { ApidbChangeReader reader; XmlChangeWriter writer; ChangeTagSorter tagSorter; String fileName; File tmpFile; File file; // Generate the changeset file name. fileName = new ChangesetFileNameFormatter(config.getChangeFileBeginFormat(), config.getChangeFileEndFormat()) .generateFileName(intervalBegin, intervalEnd); // Generate the temporary output file. tmpFile = new File(baseDirectory, TMP_FILE_NAME); // Generate the changeset output file. file = new File(baseDirectory, fileName); // Create the output task to write to a compressed xml file. writer = new XmlChangeWriter(tmpFile, CompressionMethod.GZip); // Create the input task to read the change interval from the database. reader = new ApidbChangeReader(config.getDatabaseLoginCredentials(), config.getDatabasePreferences(), intervalBegin, intervalEnd, fullHistory); // Create the tag sorter to ensure that output files are consistent allowing simple // comparisons when auditing results. tagSorter = new ChangeTagSorter(); // Connect the tasks together. reader.setChangeSink(tagSorter); tagSorter.setChangeSink(writer); // Run the changeset extraction. reader.run(); // Delete the destination file if it already exists. if (file.exists()) { if (!file.delete()) { throw new OsmosisRuntimeException("Unable to delete existing file " + file + "."); } } // Rename the temporary file to the final file name. if (!tmpFile.renameTo(file)) { throw new OsmosisRuntimeException("Unable to rename temporary file " + tmpFile + " to " + file + "."); } } } OsmosisExtractApiDb.java000066400000000000000000000220601253404521400362230ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/main/java/org/openstreetmap/osmosis/extract/apidb/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.extract.apidb.v0_6; import java.io.File; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import java.util.TimeZone; import org.openstreetmap.osmosis.core.OsmosisConstants; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.util.FileBasedLock; import org.openstreetmap.osmosis.core.util.ResourceFileManager; import org.openstreetmap.osmosis.extract.apidb.common.Configuration; import org.openstreetmap.osmosis.replication.common.TimestampTracker; /** * The main entry point for the apidb change extraction application. * * @author Brett Henderson */ public class OsmosisExtractApiDb { private static final File LOCK_FILE = new File("osmosis-extract-apidb.lock"); private static final File CONFIG_FILE = new File("osmosis-extract-apidb.conf"); private static final File DATA_DIR = new File("data"); private static final File TSTAMP_FILE = new File("timestamp.txt"); private static final File TSTAMP_NEW_FILE = new File("timestampnew.txt"); private static final File DATA_TSTAMP_FILE = new File("data/timestamp.txt"); private static final File DATA_TSTAMP_NEW_FILE = new File("data/timestampnew.txt"); private static final String CONFIG_RESOURCE = "osmosis-extract-apidb.conf"; private static final String COMMAND_HELP = "help"; private static final String COMMAND_INITIALIZE = "initialize"; private static final String COMMAND_INFO = "info"; private static final String COMMAND_EXTRACT = "extract"; private static final String COMMAND_LINE_DATE_FORMAT = "yyyy-MM-dd_HH:mm:ss"; private static final Locale COMMAND_LINE_DATE_LOCALE = Locale.US; private static final TimeZone COMMAND_LINE_DATE_TIMEZONE = TimeZone.getTimeZone("UTC"); private final String[] programArgs; /** * The entry point to the application. * * @param args * The command line arguments. */ public static void main(String[] args) { FileBasedLock fileLock = new FileBasedLock(LOCK_FILE); boolean success = false; try { fileLock.lock(); new OsmosisExtractApiDb(args).run(); fileLock.unlock(); success = true; } finally { fileLock.release(); } // Indicate success or otherwise. if (success) { System.exit(0); } else { System.exit(1); } } /** * Creates a new instance. * * @param programArgs * The command line arguments. */ public OsmosisExtractApiDb(String[] programArgs) { this.programArgs = programArgs; } /** * Launches program execution. */ public void run() { int argIndex; String command; if (programArgs.length == 0) { helpCommand(); } else { argIndex = 0; command = programArgs[argIndex++]; if (COMMAND_HELP.equals(command)) { helpCommand(); } else if (COMMAND_INITIALIZE.equals(command)) { initializeCommand(programArgs, argIndex); } else if (COMMAND_INFO.equals(command)) { infoCommand(); } else if (COMMAND_EXTRACT.equals(command)) { extractCommand(); } else { System.out.println("Command " + command + " is not recognised."); } } } /** * Creates a configuration object. * * @return The configuration. */ private Configuration getConfiguration() { return new Configuration(CONFIG_FILE); } /** * Creates a timestamp tracker object for persisting the currently extracted timestamp. * * @return The timestamp tracker. */ private TimestampTracker getTimestampTracker() { return new TimestampTracker(TSTAMP_FILE, TSTAMP_NEW_FILE); } /** * Creates a timestamp tracker object for persisting the currently extracted timestamp into the * data directory for consumers to download. * * @return The timestamp tracker. */ private TimestampTracker getDataTimestampSetter() { return new TimestampTracker(DATA_TSTAMP_FILE, DATA_TSTAMP_NEW_FILE); } /** * Gets a date argument from the program arguments. * * @param args * The program arguments. * @param argIndex * The current argument index. * @return The parsed date. */ private Date getDateArgument(String[] args, int argIndex) { // Verify that the argument is available. if (args.length <= argIndex) { throw new OsmosisRuntimeException("A date argument is required at argument " + (argIndex + 1) + "."); } try { SimpleDateFormat dateFormat; dateFormat = new SimpleDateFormat(COMMAND_LINE_DATE_FORMAT, COMMAND_LINE_DATE_LOCALE); dateFormat.setTimeZone(COMMAND_LINE_DATE_TIMEZONE); return dateFormat.parse(args[argIndex]); } catch (ParseException e) { throw new OsmosisRuntimeException("Argument " + (argIndex + 1) + " must be a date in format " + COMMAND_LINE_DATE_FORMAT + ".", e); } } /** * Prints usage information to the console. */ private void helpCommand() { System.out.println("Osmosis Extract ApiDb Version " + OsmosisConstants.VERSION); System.out.println("Usage: osmosis-apidb-extract "); System.out.println("Commands:"); System.out.println("\t" + COMMAND_INITIALIZE + " <" + COMMAND_LINE_DATE_FORMAT + ">"); System.out.println("\t" + COMMAND_INFO); System.out.println("\t" + COMMAND_EXTRACT); } /** * Initialises the current working directory. * * @param args * The input arguments. * @param initialArgIndex * The current offset into the arguments. */ private void initializeCommand(String[] args, int initialArgIndex) { int currentArgIndex; Date initialExtractDate; ResourceFileManager resourceFileManager; // Get the command line arguments. currentArgIndex = initialArgIndex; initialExtractDate = getDateArgument(args, currentArgIndex++); if (CONFIG_FILE.exists()) { throw new OsmosisRuntimeException("Config file " + CONFIG_FILE + " already exists."); } resourceFileManager = new ResourceFileManager(); resourceFileManager.copyResourceToFile(getClass(), CONFIG_RESOURCE, CONFIG_FILE); if (!DATA_DIR.exists()) { if (!DATA_DIR.mkdir()) { throw new OsmosisRuntimeException("Unable to create directory " + DATA_DIR); } } if (TSTAMP_FILE.exists()) { throw new OsmosisRuntimeException("Extract timestamp file " + TSTAMP_FILE + " already exists."); } getTimestampTracker().setTime(initialExtractDate); } /** * Provides information about the state of the current working directory. */ private void infoCommand() { Configuration configuration; TimestampTracker timestampTracker; configuration = getConfiguration(); timestampTracker = getTimestampTracker(); System.out.println("Configuration"); System.out.println("\thost: " + configuration.getHost()); System.out.println("\tdatabase: " + configuration.getDatabase()); System.out.println("\tuser: " + configuration.getUser()); System.out.println("\tpassword: " + configuration.getPassword()); System.out.println("\tdb: " + configuration.getDbType()); System.out.println("\tintervalLength: " + configuration.getIntervalLength()); System.out.println("\tlagLength: " + configuration.getLagLength()); System.out.println("\tchangeSetBeginFormat: " + configuration.getChangeFileBeginFormat()); System.out.println("\tchangeSetEndFormat: " + configuration.getChangeFileEndFormat()); System.out.println(); System.out.println("Data"); System.out.println("\tCurrent Timestamp: " + timestampTracker.getTime()); } /** * Performs the extraction process. */ private void extractCommand() { Configuration configuration; DatabaseTimeLoader timeLoader; boolean fullHistory; TimestampTracker timestampTracker; TimestampTracker dataTimestampSetter; long extractTime; long maximumExtractTime; long nextExtractTime; configuration = getConfiguration(); timeLoader = new DatabaseTimeLoader(configuration.getDatabaseLoginCredentials()); fullHistory = configuration.getReadFullHistory(); timestampTracker = getTimestampTracker(); dataTimestampSetter = getDataTimestampSetter(); // Determine the last extraction time. extractTime = timestampTracker.getTime().getTime(); while (true) { Date intervalBegin; Date intervalEnd; IntervalExtractor extractor; nextExtractTime = extractTime + configuration.getIntervalLength(); // Determine the maximum extraction time. It is the current time minus the lag length. maximumExtractTime = timeLoader.getDatabaseTime().getTime() - configuration.getLagLength(); // Stop when the maximum extraction time is passed. if (nextExtractTime > maximumExtractTime) { break; } // Calculate the beginning and end of the next changeset interval. intervalBegin = new Date(extractTime); intervalEnd = new Date(nextExtractTime); // Extract a changeset for the current interval. extractor = new IntervalExtractor(configuration, DATA_DIR, intervalBegin, intervalEnd, fullHistory); extractor.run(); // Update and persist the latest extract timestamp to both the // working directory and the output data directory. extractTime = nextExtractTime; timestampTracker.setTime(new Date(extractTime)); dataTimestampSetter.setTime(new Date(extractTime)); } } } osmosis-0.44.1/osmosis-extract/src/main/resources/000077500000000000000000000000001253404521400221655ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/main/resources/org/000077500000000000000000000000001253404521400227545ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/main/resources/org/openstreetmap/000077500000000000000000000000001253404521400256425ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/main/resources/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400273365ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/main/resources/org/openstreetmap/osmosis/extract/000077500000000000000000000000001253404521400310105ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/main/resources/org/openstreetmap/osmosis/extract/apidb/000077500000000000000000000000001253404521400320675ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/main/resources/org/openstreetmap/osmosis/extract/apidb/v0_6/000077500000000000000000000000001253404521400326415ustar00rootroot00000000000000osmosis-extract-apidb.conf000066400000000000000000000021561253404521400376560ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/main/resources/org/openstreetmap/osmosis/extract/apidb/v0_6# The database host system. host=localhost # The database instance. database=osm # The database user. user=osm # The database password password=mypwd # The database type dbType=postgresql # The length of an extraction interval in seconds (86400 = 1 day). intervalLength=86400 # The time to lag the main database by in seconds (300 = 5 minutes, 1800 = 30 minutes). lagLength=1800 # If true, full history will be returned. If not, a single change per entity will be created. False is the normal setting. readFullHistory=false # Define the changeset filename format. The format is {changeFileBeginFormat}-{changeFileEndFormat}.osc. # Be careful to pick a format that won't result in duplicate names for the specified interval size. # Change file begin format changeFileBeginFormat=yyyyMMddHH changeFileEndFormat=yyyyMMddHH # The database schema version will be checked if this is set to true. validateSchemaVersion=true # Defines behaviour if the schema version is checked and found to be incorrect. # If true, a warning will be logged. If false, execution will abort. allowIncorrectSchemaVersion=false osmosis-0.44.1/osmosis-extract/src/test/000077500000000000000000000000001253404521400202065ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/test/java/000077500000000000000000000000001253404521400211275ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/test/java/org/000077500000000000000000000000001253404521400217165ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/test/java/org/openstreetmap/000077500000000000000000000000001253404521400246045ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/test/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400263005ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/test/java/org/openstreetmap/osmosis/extract/000077500000000000000000000000001253404521400277525ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/test/java/org/openstreetmap/osmosis/extract/apidb/000077500000000000000000000000001253404521400310315ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/test/java/org/openstreetmap/osmosis/extract/apidb/v0_6/000077500000000000000000000000001253404521400316035ustar00rootroot00000000000000DatabaseTimeLoaderTest.java000066400000000000000000000024551253404521400367070ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/test/java/org/openstreetmap/osmosis/extract/apidb/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.extract.apidb.v0_6; import java.io.File; import java.util.Date; import org.junit.Assert; import org.junit.Test; import org.openstreetmap.osmosis.extract.apidb.common.Configuration; import org.openstreetmap.osmosis.testutil.AbstractDataTest; /** * Tests the operation of the database system time loader. * * @author Brett Henderson */ public class DatabaseTimeLoaderTest extends AbstractDataTest { private DatabaseUtilities dbUtils = new DatabaseUtilities(dataUtils); /** * Tests getting the current time from the database. */ @Test public void testGetTime() { File authFile; Configuration config; DatabaseTimeLoader timeLoader; Date systemTime; Date databaseTime; long difference; authFile = dbUtils.getAuthorizationFile(); config = new Configuration(authFile); timeLoader = new DatabaseTimeLoader(config.getDatabaseLoginCredentials()); databaseTime = timeLoader.getDatabaseTime(); systemTime = new Date(); difference = databaseTime.getTime() - systemTime.getTime(); Assert.assertTrue("Database time is different to system time, databaseTime=" + databaseTime + ", systemTime=" + systemTime + ".", difference > -1000 && difference < 1000); } } DatabaseUtilities.java000066400000000000000000000050001253404521400357620ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/test/java/org/openstreetmap/osmosis/extract/apidb/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.extract.apidb.v0_6; import java.io.File; import org.openstreetmap.osmosis.apidb.common.DatabaseContext; import org.openstreetmap.osmosis.core.Osmosis; import org.openstreetmap.osmosis.core.database.AuthenticationPropertiesLoader; import org.openstreetmap.osmosis.core.database.DatabaseConstants; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.testutil.TestDataUtilities; /** * Contains re-usable functionality for manipulating the database during tests. * * @author Brett Henderson */ public class DatabaseUtilities { private static final String AUTHFILE = "v0_6/apidb-authfile.txt"; private static final String AUTHFILE_PROPERTY = "db.apidb.authfile"; private TestDataUtilities dataUtils; /** * Creates a new instance. * * @param dataUtils * The test data manager. */ public DatabaseUtilities(TestDataUtilities dataUtils) { this.dataUtils = dataUtils; } /** * Creates a new database context pointing at the test database. * * @return A fully configured database context. */ public DatabaseContext createDatabaseContext() { AuthenticationPropertiesLoader credentialsLoader; DatabaseLoginCredentials credentials; credentials = new DatabaseLoginCredentials(DatabaseConstants.TASK_DEFAULT_HOST, DatabaseConstants.TASK_DEFAULT_DATABASE, DatabaseConstants.TASK_DEFAULT_USER, DatabaseConstants.TASK_DEFAULT_PASSWORD, DatabaseConstants.TASK_DEFAULT_FORCE_UTF8, DatabaseConstants.TASK_DEFAULT_PROFILE_SQL, DatabaseConstants.TASK_DEFAULT_DB_TYPE); credentialsLoader = new AuthenticationPropertiesLoader(getAuthorizationFile()); credentialsLoader.updateLoginCredentials(credentials); return new DatabaseContext(credentials); } /** * Removes all data from the database. */ public void truncateDatabase() { // Remove all existing data from the database. Osmosis.run(new String[] { "-q", "--truncate-apidb-0.6", "authFile=" + getAuthorizationFile().getPath(), "allowIncorrectSchemaVersion=true" }); } /** * Returns the location of the database authorization file. * * @return The authorization file. */ public File getAuthorizationFile() { return dataUtils.createDataFile(AUTHFILE_PROPERTY, AUTHFILE); } } osmosis-0.44.1/osmosis-extract/src/test/resources/000077500000000000000000000000001253404521400222205ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/test/resources/data/000077500000000000000000000000001253404521400231315ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/test/resources/data/template/000077500000000000000000000000001253404521400247445ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/test/resources/data/template/v0_6/000077500000000000000000000000001253404521400255165ustar00rootroot00000000000000osmosis-0.44.1/osmosis-extract/src/test/resources/data/template/v0_6/apidb-authfile.txt000066400000000000000000000001201253404521400311260ustar00rootroot00000000000000host=localhost database=api06_test user=osm password=password dbType=postgresql osmosis-0.44.1/osmosis-hstore-jdbc/000077500000000000000000000000001253404521400171725ustar00rootroot00000000000000osmosis-0.44.1/osmosis-hstore-jdbc/.checkstyle000066400000000000000000000010051253404521400213250ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-hstore-jdbc/.gitignore000066400000000000000000000000531253404521400211600ustar00rootroot00000000000000.classpath .project .settings /bin /build osmosis-0.44.1/osmosis-hstore-jdbc/build.gradle000066400000000000000000000003041253404521400214460ustar00rootroot00000000000000dependencies { compile group: 'org.postgresql', name: 'postgresql', version: dependencyVersionPostgreSql } // Disable checkstyle because this is external code. checkstyleMain.enabled = false osmosis-0.44.1/osmosis-hstore-jdbc/src/000077500000000000000000000000001253404521400177615ustar00rootroot00000000000000osmosis-0.44.1/osmosis-hstore-jdbc/src/main/000077500000000000000000000000001253404521400207055ustar00rootroot00000000000000osmosis-0.44.1/osmosis-hstore-jdbc/src/main/java/000077500000000000000000000000001253404521400216265ustar00rootroot00000000000000osmosis-0.44.1/osmosis-hstore-jdbc/src/main/java/org/000077500000000000000000000000001253404521400224155ustar00rootroot00000000000000osmosis-0.44.1/osmosis-hstore-jdbc/src/main/java/org/openstreetmap/000077500000000000000000000000001253404521400253035ustar00rootroot00000000000000osmosis-0.44.1/osmosis-hstore-jdbc/src/main/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400267775ustar00rootroot00000000000000osmosis-0.44.1/osmosis-hstore-jdbc/src/main/java/org/openstreetmap/osmosis/hstore/000077500000000000000000000000001253404521400303035ustar00rootroot00000000000000osmosis-0.44.1/osmosis-hstore-jdbc/src/main/java/org/openstreetmap/osmosis/hstore/PGHStore.java000066400000000000000000000252451253404521400326110ustar00rootroot00000000000000/* * This file has been copied from the following location: * http://archives.postgresql.org/pgsql-jdbc/2009-12/msg00037.php * * PostgreSQL code is typically under a BSD licence. * http://jdbc.postgresql.org/license.html */ /*------------------------------------------------------------------------- * * A preliminary version of a custom type wrapper for hstore data. * Once it gets some testing and cleanups it will go into the official * PG JDBC driver, but stick it here for now because we need it sooner. * * Copyright (c) 2009, PostgreSQL Global Development Group * * IDENTIFICATION * $PostgreSQL$ * *------------------------------------------------------------------------- */ package org.openstreetmap.osmosis.hstore; import java.io.Serializable; import java.sql.SQLException; import java.util.Set; import java.util.Map; import java.util.HashMap; import java.util.List; import java.util.ArrayList; import java.util.Iterator; import java.util.Collection; import org.postgresql.util.PGobject; /** * This implements a class that handles the PostgreSQL contrib/hstore type */ public class PGHStore extends PGobject implements Serializable, Cloneable, Map { private final static long serialVersionUID = 1; private Map _map; /** * required by the driver */ public PGHStore() { setType("hstore"); _map = new HashMap(); } /** * Initialize a hstore with a given string representation * * @param value String representated hstore * @throws SQLException Is thrown if the string representation has an unknown format * @see #setValue(String) */ public PGHStore(String value) throws SQLException { this(); setValue(value); } public PGHStore(Map map) { this(); setValue(map); } public void setValue(Map map) { _map = map; } /** */ public void setValue(String value) throws SQLException { Parser p = new Parser(); _map = p.parse(value); } /** * Returns the stored information as a string * * @return String represented hstore */ public String getValue() { StringBuffer buf = new StringBuffer(); Iterator i = _map.keySet().iterator(); boolean first = true; while (i.hasNext()) { Object key = i.next(); Object value = _map.get(key); if (first) { first = false; } else { buf.append(','); } writeValue(buf, key); buf.append("=>"); writeValue(buf, value); } return buf.toString(); } private static void writeValue(StringBuffer buf, Object o) { if (o == null) { buf.append("NULL"); return; } String s = o.toString(); buf.append('"'); for (int i=0; i keys; private List values; private final static int GV_WAITVAL = 0; private final static int GV_INVAL = 1; private final static int GV_INESCVAL = 2; private final static int GV_WAITESCIN = 3; private final static int GV_WAITESCESCIN = 4; private final static int WKEY = 0; private final static int WVAL = 1; private final static int WEQ = 2; private final static int WGT = 3; private final static int WDEL = 4; public Parser() { } private Map parse(String value) throws SQLException { this.value = value; ptr = 0; keys = new ArrayList(); values = new ArrayList(); parseHStore(); Map map = new HashMap(); for (int i=0; i') { state = WVAL; } else if (c == '\0') { throw new SQLException("KJJ, unexpected end of string"); } else { throw new SQLException("KJJ, syntax err [" + c + "] at " + ptr); } } else if (state == WVAL) { if (!getValue(true)) { throw new SQLException("KJJ, unexpected end of string"); } String val = cur.toString(); cur = null; if (!escaped && "null".equalsIgnoreCase(val)) { val = null; } values.add(val); state = WDEL; } else if (state == WDEL) { if (c == ',') { state = WKEY; } else if (c == '\0') { return; } else if (!Character.isWhitespace(c)) { throw new SQLException("KJJ, syntax err"); } } else { throw new SQLException("KJJ unknown state"); } ptr++; } } } // Farm out all the work to the real underlying map. public void clear() { _map.clear(); } public boolean containsKey(Object key) { return _map.containsKey(key); } public boolean containsValue(Object value) { return _map.containsValue(value); } public Set> entrySet() { return _map.entrySet(); } public String get(Object key) { return _map.get(key); } public int hashCode() { return _map.hashCode(); } public boolean isEmpty() { return _map.isEmpty(); } public Set keySet() { return _map.keySet(); } public String put(String key, String value) { return _map.put(key, value); } public void putAll(Map m) { _map.putAll(m); } public String remove(Object key) { return _map.remove(key); } public int size() { return _map.size(); } public Collection values() { return _map.values(); } } osmosis-0.44.1/osmosis-osm-binary/000077500000000000000000000000001253404521400170465ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/.gitignore000066400000000000000000000000531253404521400210340ustar00rootroot00000000000000.classpath .project .settings /bin /build osmosis-0.44.1/osmosis-osm-binary/COPYING.osmpbf000066400000000000000000000167431253404521400214010ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. osmosis-0.44.1/osmosis-osm-binary/ReleaseNotes.txt000066400000000000000000000033711253404521400222040ustar00rootroot00000000000000---------------------------------------- Release notes for 1.3.3 -- 2014-03-15 ---------------------------------------- Fixed ant build file. ---------------------------------------- Release notes for 1.3.2 -- 2014-03-12 ---------------------------------------- Small bugfixes and build enhancements. Improved Debian build in coordination with Debian maintainers. ---------------------------------------- Release notes for 1.3.1 -- 2013-12-11 ---------------------------------------- Several building fixes and enhancements. ---------------------------------------- Release notes for 1.3.0 -- 2012-12-04 ---------------------------------------- Add osmosis replication fields into the header. -- Changes from Frederick Ramm ---------------------------------------- Release notes for 1.2.1 -- 2011-10-29 ---------------------------------------- -------------------------------------- Release notes for 1.2.0 -- NOT RELEASED -------------------------------------- * Bad tag, so not releasable. * Switched to the lite (non-introspective) version of protocol buffers for a smaller library. * Includes support for "visible" flag on OSM objects. This allows PBF to handle OSM history files. * Namespace and include conventions changes for the C++ library. Everything is in the OSMPBF namespace. You now do: #include * Added stuff needed to build Debian/Ubuntu libosmpbf-dev package containing the C++ library. * Added osmpbf-outline tool that shows internals of a PBF file for debugging. * Added magic file that can recognize OSM PBF files. -- Changes from Jochen Topf Peter * Added a pom.xml -- Changes from Zsombor Welker osmosis-0.44.1/osmosis-osm-binary/build.gradle000066400000000000000000000011551253404521400213270ustar00rootroot00000000000000dependencies { compile group: 'com.google.protobuf', name: 'protobuf-java', version: dependencyVersionProtobuf } // Disable checkstyle because this is external code. checkstyleMain.enabled = false sourceSets { main { // Create a separate source directory to contain protobuf generated classes. java.srcDirs 'gen-src/main/java' } } // Configure the maven plugin to upload artefacts to the Sonatype repository. uploadArchives { repositories { mavenDeployer { pom.project { licenses { license { name 'LGPL 3' url 'http://www.gnu.org/licenses/lgpl-3.0.html' } } } } } } osmosis-0.44.1/osmosis-osm-binary/gen-src/000077500000000000000000000000001253404521400204045ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/gen-src/main/000077500000000000000000000000001253404521400213305ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/gen-src/main/java/000077500000000000000000000000001253404521400222515ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/gen-src/main/java/org/000077500000000000000000000000001253404521400230405ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/gen-src/main/java/org/openstreetmap/000077500000000000000000000000001253404521400257265ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/gen-src/main/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400274225ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/gen-src/main/java/org/openstreetmap/osmosis/osmbinary/000077500000000000000000000000001253404521400314255ustar00rootroot00000000000000Fileformat.java000066400000000000000000001317601253404521400343110ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/gen-src/main/java/org/openstreetmap/osmosis/osmbinary// Generated by the protocol buffer compiler. DO NOT EDIT! // source: src/main/protobuf/fileformat.proto package org.openstreetmap.osmosis.osmbinary; public final class Fileformat { private Fileformat() {} public static void registerAllExtensions( com.google.protobuf.ExtensionRegistryLite registry) { } public interface BlobOrBuilder extends // @@protoc_insertion_point(interface_extends:OSMPBF.Blob) com.google.protobuf.MessageLiteOrBuilder { /** * optional bytes raw = 1; * *
     * No compression
     * 
*/ boolean hasRaw(); /** * optional bytes raw = 1; * *
     * No compression
     * 
*/ com.google.protobuf.ByteString getRaw(); /** * optional int32 raw_size = 2; * *
     * When compressed, the uncompressed size
     * 
*/ boolean hasRawSize(); /** * optional int32 raw_size = 2; * *
     * When compressed, the uncompressed size
     * 
*/ int getRawSize(); /** * optional bytes zlib_data = 3; * *
     * Possible compressed versions of the data.
     * 
*/ boolean hasZlibData(); /** * optional bytes zlib_data = 3; * *
     * Possible compressed versions of the data.
     * 
*/ com.google.protobuf.ByteString getZlibData(); /** * optional bytes lzma_data = 4; * *
     * PROPOSED feature for LZMA compressed data. SUPPORT IS NOT REQUIRED.
     * 
*/ boolean hasLzmaData(); /** * optional bytes lzma_data = 4; * *
     * PROPOSED feature for LZMA compressed data. SUPPORT IS NOT REQUIRED.
     * 
*/ com.google.protobuf.ByteString getLzmaData(); /** * optional bytes OBSOLETE_bzip2_data = 5 [deprecated = true]; * *
     * Formerly used for bzip2 compressed data. Depreciated in 2010.
     * 
*/ @java.lang.Deprecated boolean hasOBSOLETEBzip2Data(); /** * optional bytes OBSOLETE_bzip2_data = 5 [deprecated = true]; * *
     * Formerly used for bzip2 compressed data. Depreciated in 2010.
     * 
*/ @java.lang.Deprecated com.google.protobuf.ByteString getOBSOLETEBzip2Data(); } /** * Protobuf type {@code OSMPBF.Blob} */ public static final class Blob extends com.google.protobuf.GeneratedMessageLite implements // @@protoc_insertion_point(message_implements:OSMPBF.Blob) BlobOrBuilder { // Use Blob.newBuilder() to construct. private Blob(com.google.protobuf.GeneratedMessageLite.Builder builder) { super(builder); this.unknownFields = builder.getUnknownFields(); } private Blob(boolean noInit) { this.unknownFields = com.google.protobuf.ByteString.EMPTY;} private static final Blob defaultInstance; public static Blob getDefaultInstance() { return defaultInstance; } public Blob getDefaultInstanceForType() { return defaultInstance; } private final com.google.protobuf.ByteString unknownFields; private Blob( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { initFields(); int mutable_bitField0_ = 0; com.google.protobuf.ByteString.Output unknownFieldsOutput = com.google.protobuf.ByteString.newOutput(); com.google.protobuf.CodedOutputStream unknownFieldsCodedOutput = com.google.protobuf.CodedOutputStream.newInstance( unknownFieldsOutput); try { boolean done = false; while (!done) { int tag = input.readTag(); switch (tag) { case 0: done = true; break; default: { if (!parseUnknownField(input, unknownFieldsCodedOutput, extensionRegistry, tag)) { done = true; } break; } case 10: { bitField0_ |= 0x00000001; raw_ = input.readBytes(); break; } case 16: { bitField0_ |= 0x00000002; rawSize_ = input.readInt32(); break; } case 26: { bitField0_ |= 0x00000004; zlibData_ = input.readBytes(); break; } case 34: { bitField0_ |= 0x00000008; lzmaData_ = input.readBytes(); break; } case 42: { bitField0_ |= 0x00000010; oBSOLETEBzip2Data_ = input.readBytes(); break; } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { throw e.setUnfinishedMessage(this); } catch (java.io.IOException e) { throw new com.google.protobuf.InvalidProtocolBufferException( e.getMessage()).setUnfinishedMessage(this); } finally { try { unknownFieldsCodedOutput.flush(); } catch (java.io.IOException e) { // Should not happen } finally { unknownFields = unknownFieldsOutput.toByteString(); } makeExtensionsImmutable(); } } public static com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { public Blob parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return new Blob(input, extensionRegistry); } }; @java.lang.Override public com.google.protobuf.Parser getParserForType() { return PARSER; } private int bitField0_; public static final int RAW_FIELD_NUMBER = 1; private com.google.protobuf.ByteString raw_; /** * optional bytes raw = 1; * *
     * No compression
     * 
*/ public boolean hasRaw() { return ((bitField0_ & 0x00000001) == 0x00000001); } /** * optional bytes raw = 1; * *
     * No compression
     * 
*/ public com.google.protobuf.ByteString getRaw() { return raw_; } public static final int RAW_SIZE_FIELD_NUMBER = 2; private int rawSize_; /** * optional int32 raw_size = 2; * *
     * When compressed, the uncompressed size
     * 
*/ public boolean hasRawSize() { return ((bitField0_ & 0x00000002) == 0x00000002); } /** * optional int32 raw_size = 2; * *
     * When compressed, the uncompressed size
     * 
*/ public int getRawSize() { return rawSize_; } public static final int ZLIB_DATA_FIELD_NUMBER = 3; private com.google.protobuf.ByteString zlibData_; /** * optional bytes zlib_data = 3; * *
     * Possible compressed versions of the data.
     * 
*/ public boolean hasZlibData() { return ((bitField0_ & 0x00000004) == 0x00000004); } /** * optional bytes zlib_data = 3; * *
     * Possible compressed versions of the data.
     * 
*/ public com.google.protobuf.ByteString getZlibData() { return zlibData_; } public static final int LZMA_DATA_FIELD_NUMBER = 4; private com.google.protobuf.ByteString lzmaData_; /** * optional bytes lzma_data = 4; * *
     * PROPOSED feature for LZMA compressed data. SUPPORT IS NOT REQUIRED.
     * 
*/ public boolean hasLzmaData() { return ((bitField0_ & 0x00000008) == 0x00000008); } /** * optional bytes lzma_data = 4; * *
     * PROPOSED feature for LZMA compressed data. SUPPORT IS NOT REQUIRED.
     * 
*/ public com.google.protobuf.ByteString getLzmaData() { return lzmaData_; } public static final int OBSOLETE_BZIP2_DATA_FIELD_NUMBER = 5; private com.google.protobuf.ByteString oBSOLETEBzip2Data_; /** * optional bytes OBSOLETE_bzip2_data = 5 [deprecated = true]; * *
     * Formerly used for bzip2 compressed data. Depreciated in 2010.
     * 
*/ @java.lang.Deprecated public boolean hasOBSOLETEBzip2Data() { return ((bitField0_ & 0x00000010) == 0x00000010); } /** * optional bytes OBSOLETE_bzip2_data = 5 [deprecated = true]; * *
     * Formerly used for bzip2 compressed data. Depreciated in 2010.
     * 
*/ @java.lang.Deprecated public com.google.protobuf.ByteString getOBSOLETEBzip2Data() { return oBSOLETEBzip2Data_; } private void initFields() { raw_ = com.google.protobuf.ByteString.EMPTY; rawSize_ = 0; zlibData_ = com.google.protobuf.ByteString.EMPTY; lzmaData_ = com.google.protobuf.ByteString.EMPTY; oBSOLETEBzip2Data_ = com.google.protobuf.ByteString.EMPTY; } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized == 1) return true; if (isInitialized == 0) return false; memoizedIsInitialized = 1; return true; } public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { getSerializedSize(); if (((bitField0_ & 0x00000001) == 0x00000001)) { output.writeBytes(1, raw_); } if (((bitField0_ & 0x00000002) == 0x00000002)) { output.writeInt32(2, rawSize_); } if (((bitField0_ & 0x00000004) == 0x00000004)) { output.writeBytes(3, zlibData_); } if (((bitField0_ & 0x00000008) == 0x00000008)) { output.writeBytes(4, lzmaData_); } if (((bitField0_ & 0x00000010) == 0x00000010)) { output.writeBytes(5, oBSOLETEBzip2Data_); } output.writeRawBytes(unknownFields); } private int memoizedSerializedSize = -1; public int getSerializedSize() { int size = memoizedSerializedSize; if (size != -1) return size; size = 0; if (((bitField0_ & 0x00000001) == 0x00000001)) { size += com.google.protobuf.CodedOutputStream .computeBytesSize(1, raw_); } if (((bitField0_ & 0x00000002) == 0x00000002)) { size += com.google.protobuf.CodedOutputStream .computeInt32Size(2, rawSize_); } if (((bitField0_ & 0x00000004) == 0x00000004)) { size += com.google.protobuf.CodedOutputStream .computeBytesSize(3, zlibData_); } if (((bitField0_ & 0x00000008) == 0x00000008)) { size += com.google.protobuf.CodedOutputStream .computeBytesSize(4, lzmaData_); } if (((bitField0_ & 0x00000010) == 0x00000010)) { size += com.google.protobuf.CodedOutputStream .computeBytesSize(5, oBSOLETEBzip2Data_); } size += unknownFields.size(); memoizedSerializedSize = size; return size; } private static final long serialVersionUID = 0L; @java.lang.Override protected java.lang.Object writeReplace() throws java.io.ObjectStreamException { return super.writeReplace(); } public static org.openstreetmap.osmosis.osmbinary.Fileformat.Blob parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Fileformat.Blob parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Fileformat.Blob parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Fileformat.Blob parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Fileformat.Blob parseFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Fileformat.Blob parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Fileformat.Blob parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseDelimitedFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Fileformat.Blob parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseDelimitedFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Fileformat.Blob parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Fileformat.Blob parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static Builder newBuilder() { return Builder.create(); } public Builder newBuilderForType() { return newBuilder(); } public static Builder newBuilder(org.openstreetmap.osmosis.osmbinary.Fileformat.Blob prototype) { return newBuilder().mergeFrom(prototype); } public Builder toBuilder() { return newBuilder(this); } /** * Protobuf type {@code OSMPBF.Blob} */ public static final class Builder extends com.google.protobuf.GeneratedMessageLite.Builder< org.openstreetmap.osmosis.osmbinary.Fileformat.Blob, Builder> implements // @@protoc_insertion_point(builder_implements:OSMPBF.Blob) org.openstreetmap.osmosis.osmbinary.Fileformat.BlobOrBuilder { // Construct using org.openstreetmap.osmosis.osmbinary.Fileformat.Blob.newBuilder() private Builder() { maybeForceBuilderInitialization(); } private void maybeForceBuilderInitialization() { } private static Builder create() { return new Builder(); } public Builder clear() { super.clear(); raw_ = com.google.protobuf.ByteString.EMPTY; bitField0_ = (bitField0_ & ~0x00000001); rawSize_ = 0; bitField0_ = (bitField0_ & ~0x00000002); zlibData_ = com.google.protobuf.ByteString.EMPTY; bitField0_ = (bitField0_ & ~0x00000004); lzmaData_ = com.google.protobuf.ByteString.EMPTY; bitField0_ = (bitField0_ & ~0x00000008); oBSOLETEBzip2Data_ = com.google.protobuf.ByteString.EMPTY; bitField0_ = (bitField0_ & ~0x00000010); return this; } public Builder clone() { return create().mergeFrom(buildPartial()); } public org.openstreetmap.osmosis.osmbinary.Fileformat.Blob getDefaultInstanceForType() { return org.openstreetmap.osmosis.osmbinary.Fileformat.Blob.getDefaultInstance(); } public org.openstreetmap.osmosis.osmbinary.Fileformat.Blob build() { org.openstreetmap.osmosis.osmbinary.Fileformat.Blob result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } public org.openstreetmap.osmosis.osmbinary.Fileformat.Blob buildPartial() { org.openstreetmap.osmosis.osmbinary.Fileformat.Blob result = new org.openstreetmap.osmosis.osmbinary.Fileformat.Blob(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) == 0x00000001)) { to_bitField0_ |= 0x00000001; } result.raw_ = raw_; if (((from_bitField0_ & 0x00000002) == 0x00000002)) { to_bitField0_ |= 0x00000002; } result.rawSize_ = rawSize_; if (((from_bitField0_ & 0x00000004) == 0x00000004)) { to_bitField0_ |= 0x00000004; } result.zlibData_ = zlibData_; if (((from_bitField0_ & 0x00000008) == 0x00000008)) { to_bitField0_ |= 0x00000008; } result.lzmaData_ = lzmaData_; if (((from_bitField0_ & 0x00000010) == 0x00000010)) { to_bitField0_ |= 0x00000010; } result.oBSOLETEBzip2Data_ = oBSOLETEBzip2Data_; result.bitField0_ = to_bitField0_; return result; } public Builder mergeFrom(org.openstreetmap.osmosis.osmbinary.Fileformat.Blob other) { if (other == org.openstreetmap.osmosis.osmbinary.Fileformat.Blob.getDefaultInstance()) return this; if (other.hasRaw()) { setRaw(other.getRaw()); } if (other.hasRawSize()) { setRawSize(other.getRawSize()); } if (other.hasZlibData()) { setZlibData(other.getZlibData()); } if (other.hasLzmaData()) { setLzmaData(other.getLzmaData()); } if (other.hasOBSOLETEBzip2Data()) { setOBSOLETEBzip2Data(other.getOBSOLETEBzip2Data()); } setUnknownFields( getUnknownFields().concat(other.unknownFields)); return this; } public final boolean isInitialized() { return true; } public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { org.openstreetmap.osmosis.osmbinary.Fileformat.Blob parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { parsedMessage = (org.openstreetmap.osmosis.osmbinary.Fileformat.Blob) e.getUnfinishedMessage(); throw e; } finally { if (parsedMessage != null) { mergeFrom(parsedMessage); } } return this; } private int bitField0_; private com.google.protobuf.ByteString raw_ = com.google.protobuf.ByteString.EMPTY; /** * optional bytes raw = 1; * *
       * No compression
       * 
*/ public boolean hasRaw() { return ((bitField0_ & 0x00000001) == 0x00000001); } /** * optional bytes raw = 1; * *
       * No compression
       * 
*/ public com.google.protobuf.ByteString getRaw() { return raw_; } /** * optional bytes raw = 1; * *
       * No compression
       * 
*/ public Builder setRaw(com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } bitField0_ |= 0x00000001; raw_ = value; return this; } /** * optional bytes raw = 1; * *
       * No compression
       * 
*/ public Builder clearRaw() { bitField0_ = (bitField0_ & ~0x00000001); raw_ = getDefaultInstance().getRaw(); return this; } private int rawSize_ ; /** * optional int32 raw_size = 2; * *
       * When compressed, the uncompressed size
       * 
*/ public boolean hasRawSize() { return ((bitField0_ & 0x00000002) == 0x00000002); } /** * optional int32 raw_size = 2; * *
       * When compressed, the uncompressed size
       * 
*/ public int getRawSize() { return rawSize_; } /** * optional int32 raw_size = 2; * *
       * When compressed, the uncompressed size
       * 
*/ public Builder setRawSize(int value) { bitField0_ |= 0x00000002; rawSize_ = value; return this; } /** * optional int32 raw_size = 2; * *
       * When compressed, the uncompressed size
       * 
*/ public Builder clearRawSize() { bitField0_ = (bitField0_ & ~0x00000002); rawSize_ = 0; return this; } private com.google.protobuf.ByteString zlibData_ = com.google.protobuf.ByteString.EMPTY; /** * optional bytes zlib_data = 3; * *
       * Possible compressed versions of the data.
       * 
*/ public boolean hasZlibData() { return ((bitField0_ & 0x00000004) == 0x00000004); } /** * optional bytes zlib_data = 3; * *
       * Possible compressed versions of the data.
       * 
*/ public com.google.protobuf.ByteString getZlibData() { return zlibData_; } /** * optional bytes zlib_data = 3; * *
       * Possible compressed versions of the data.
       * 
*/ public Builder setZlibData(com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } bitField0_ |= 0x00000004; zlibData_ = value; return this; } /** * optional bytes zlib_data = 3; * *
       * Possible compressed versions of the data.
       * 
*/ public Builder clearZlibData() { bitField0_ = (bitField0_ & ~0x00000004); zlibData_ = getDefaultInstance().getZlibData(); return this; } private com.google.protobuf.ByteString lzmaData_ = com.google.protobuf.ByteString.EMPTY; /** * optional bytes lzma_data = 4; * *
       * PROPOSED feature for LZMA compressed data. SUPPORT IS NOT REQUIRED.
       * 
*/ public boolean hasLzmaData() { return ((bitField0_ & 0x00000008) == 0x00000008); } /** * optional bytes lzma_data = 4; * *
       * PROPOSED feature for LZMA compressed data. SUPPORT IS NOT REQUIRED.
       * 
*/ public com.google.protobuf.ByteString getLzmaData() { return lzmaData_; } /** * optional bytes lzma_data = 4; * *
       * PROPOSED feature for LZMA compressed data. SUPPORT IS NOT REQUIRED.
       * 
*/ public Builder setLzmaData(com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } bitField0_ |= 0x00000008; lzmaData_ = value; return this; } /** * optional bytes lzma_data = 4; * *
       * PROPOSED feature for LZMA compressed data. SUPPORT IS NOT REQUIRED.
       * 
*/ public Builder clearLzmaData() { bitField0_ = (bitField0_ & ~0x00000008); lzmaData_ = getDefaultInstance().getLzmaData(); return this; } private com.google.protobuf.ByteString oBSOLETEBzip2Data_ = com.google.protobuf.ByteString.EMPTY; /** * optional bytes OBSOLETE_bzip2_data = 5 [deprecated = true]; * *
       * Formerly used for bzip2 compressed data. Depreciated in 2010.
       * 
*/ @java.lang.Deprecated public boolean hasOBSOLETEBzip2Data() { return ((bitField0_ & 0x00000010) == 0x00000010); } /** * optional bytes OBSOLETE_bzip2_data = 5 [deprecated = true]; * *
       * Formerly used for bzip2 compressed data. Depreciated in 2010.
       * 
*/ @java.lang.Deprecated public com.google.protobuf.ByteString getOBSOLETEBzip2Data() { return oBSOLETEBzip2Data_; } /** * optional bytes OBSOLETE_bzip2_data = 5 [deprecated = true]; * *
       * Formerly used for bzip2 compressed data. Depreciated in 2010.
       * 
*/ @java.lang.Deprecated public Builder setOBSOLETEBzip2Data(com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } bitField0_ |= 0x00000010; oBSOLETEBzip2Data_ = value; return this; } /** * optional bytes OBSOLETE_bzip2_data = 5 [deprecated = true]; * *
       * Formerly used for bzip2 compressed data. Depreciated in 2010.
       * 
*/ @java.lang.Deprecated public Builder clearOBSOLETEBzip2Data() { bitField0_ = (bitField0_ & ~0x00000010); oBSOLETEBzip2Data_ = getDefaultInstance().getOBSOLETEBzip2Data(); return this; } // @@protoc_insertion_point(builder_scope:OSMPBF.Blob) } static { defaultInstance = new Blob(true); defaultInstance.initFields(); } // @@protoc_insertion_point(class_scope:OSMPBF.Blob) } public interface BlobHeaderOrBuilder extends // @@protoc_insertion_point(interface_extends:OSMPBF.BlobHeader) com.google.protobuf.MessageLiteOrBuilder { /** * required string type = 1; */ boolean hasType(); /** * required string type = 1; */ java.lang.String getType(); /** * required string type = 1; */ com.google.protobuf.ByteString getTypeBytes(); /** * optional bytes indexdata = 2; */ boolean hasIndexdata(); /** * optional bytes indexdata = 2; */ com.google.protobuf.ByteString getIndexdata(); /** * required int32 datasize = 3; */ boolean hasDatasize(); /** * required int32 datasize = 3; */ int getDatasize(); } /** * Protobuf type {@code OSMPBF.BlobHeader} */ public static final class BlobHeader extends com.google.protobuf.GeneratedMessageLite implements // @@protoc_insertion_point(message_implements:OSMPBF.BlobHeader) BlobHeaderOrBuilder { // Use BlobHeader.newBuilder() to construct. private BlobHeader(com.google.protobuf.GeneratedMessageLite.Builder builder) { super(builder); this.unknownFields = builder.getUnknownFields(); } private BlobHeader(boolean noInit) { this.unknownFields = com.google.protobuf.ByteString.EMPTY;} private static final BlobHeader defaultInstance; public static BlobHeader getDefaultInstance() { return defaultInstance; } public BlobHeader getDefaultInstanceForType() { return defaultInstance; } private final com.google.protobuf.ByteString unknownFields; private BlobHeader( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { initFields(); int mutable_bitField0_ = 0; com.google.protobuf.ByteString.Output unknownFieldsOutput = com.google.protobuf.ByteString.newOutput(); com.google.protobuf.CodedOutputStream unknownFieldsCodedOutput = com.google.protobuf.CodedOutputStream.newInstance( unknownFieldsOutput); try { boolean done = false; while (!done) { int tag = input.readTag(); switch (tag) { case 0: done = true; break; default: { if (!parseUnknownField(input, unknownFieldsCodedOutput, extensionRegistry, tag)) { done = true; } break; } case 10: { com.google.protobuf.ByteString bs = input.readBytes(); bitField0_ |= 0x00000001; type_ = bs; break; } case 18: { bitField0_ |= 0x00000002; indexdata_ = input.readBytes(); break; } case 24: { bitField0_ |= 0x00000004; datasize_ = input.readInt32(); break; } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { throw e.setUnfinishedMessage(this); } catch (java.io.IOException e) { throw new com.google.protobuf.InvalidProtocolBufferException( e.getMessage()).setUnfinishedMessage(this); } finally { try { unknownFieldsCodedOutput.flush(); } catch (java.io.IOException e) { // Should not happen } finally { unknownFields = unknownFieldsOutput.toByteString(); } makeExtensionsImmutable(); } } public static com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { public BlobHeader parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return new BlobHeader(input, extensionRegistry); } }; @java.lang.Override public com.google.protobuf.Parser getParserForType() { return PARSER; } private int bitField0_; public static final int TYPE_FIELD_NUMBER = 1; private java.lang.Object type_; /** * required string type = 1; */ public boolean hasType() { return ((bitField0_ & 0x00000001) == 0x00000001); } /** * required string type = 1; */ public java.lang.String getType() { java.lang.Object ref = type_; if (ref instanceof java.lang.String) { return (java.lang.String) ref; } else { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; java.lang.String s = bs.toStringUtf8(); if (bs.isValidUtf8()) { type_ = s; } return s; } } /** * required string type = 1; */ public com.google.protobuf.ByteString getTypeBytes() { java.lang.Object ref = type_; if (ref instanceof java.lang.String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( (java.lang.String) ref); type_ = b; return b; } else { return (com.google.protobuf.ByteString) ref; } } public static final int INDEXDATA_FIELD_NUMBER = 2; private com.google.protobuf.ByteString indexdata_; /** * optional bytes indexdata = 2; */ public boolean hasIndexdata() { return ((bitField0_ & 0x00000002) == 0x00000002); } /** * optional bytes indexdata = 2; */ public com.google.protobuf.ByteString getIndexdata() { return indexdata_; } public static final int DATASIZE_FIELD_NUMBER = 3; private int datasize_; /** * required int32 datasize = 3; */ public boolean hasDatasize() { return ((bitField0_ & 0x00000004) == 0x00000004); } /** * required int32 datasize = 3; */ public int getDatasize() { return datasize_; } private void initFields() { type_ = ""; indexdata_ = com.google.protobuf.ByteString.EMPTY; datasize_ = 0; } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized == 1) return true; if (isInitialized == 0) return false; if (!hasType()) { memoizedIsInitialized = 0; return false; } if (!hasDatasize()) { memoizedIsInitialized = 0; return false; } memoizedIsInitialized = 1; return true; } public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { getSerializedSize(); if (((bitField0_ & 0x00000001) == 0x00000001)) { output.writeBytes(1, getTypeBytes()); } if (((bitField0_ & 0x00000002) == 0x00000002)) { output.writeBytes(2, indexdata_); } if (((bitField0_ & 0x00000004) == 0x00000004)) { output.writeInt32(3, datasize_); } output.writeRawBytes(unknownFields); } private int memoizedSerializedSize = -1; public int getSerializedSize() { int size = memoizedSerializedSize; if (size != -1) return size; size = 0; if (((bitField0_ & 0x00000001) == 0x00000001)) { size += com.google.protobuf.CodedOutputStream .computeBytesSize(1, getTypeBytes()); } if (((bitField0_ & 0x00000002) == 0x00000002)) { size += com.google.protobuf.CodedOutputStream .computeBytesSize(2, indexdata_); } if (((bitField0_ & 0x00000004) == 0x00000004)) { size += com.google.protobuf.CodedOutputStream .computeInt32Size(3, datasize_); } size += unknownFields.size(); memoizedSerializedSize = size; return size; } private static final long serialVersionUID = 0L; @java.lang.Override protected java.lang.Object writeReplace() throws java.io.ObjectStreamException { return super.writeReplace(); } public static org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader parseFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseDelimitedFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseDelimitedFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static Builder newBuilder() { return Builder.create(); } public Builder newBuilderForType() { return newBuilder(); } public static Builder newBuilder(org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader prototype) { return newBuilder().mergeFrom(prototype); } public Builder toBuilder() { return newBuilder(this); } /** * Protobuf type {@code OSMPBF.BlobHeader} */ public static final class Builder extends com.google.protobuf.GeneratedMessageLite.Builder< org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader, Builder> implements // @@protoc_insertion_point(builder_implements:OSMPBF.BlobHeader) org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeaderOrBuilder { // Construct using org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader.newBuilder() private Builder() { maybeForceBuilderInitialization(); } private void maybeForceBuilderInitialization() { } private static Builder create() { return new Builder(); } public Builder clear() { super.clear(); type_ = ""; bitField0_ = (bitField0_ & ~0x00000001); indexdata_ = com.google.protobuf.ByteString.EMPTY; bitField0_ = (bitField0_ & ~0x00000002); datasize_ = 0; bitField0_ = (bitField0_ & ~0x00000004); return this; } public Builder clone() { return create().mergeFrom(buildPartial()); } public org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader getDefaultInstanceForType() { return org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader.getDefaultInstance(); } public org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader build() { org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } public org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader buildPartial() { org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader result = new org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) == 0x00000001)) { to_bitField0_ |= 0x00000001; } result.type_ = type_; if (((from_bitField0_ & 0x00000002) == 0x00000002)) { to_bitField0_ |= 0x00000002; } result.indexdata_ = indexdata_; if (((from_bitField0_ & 0x00000004) == 0x00000004)) { to_bitField0_ |= 0x00000004; } result.datasize_ = datasize_; result.bitField0_ = to_bitField0_; return result; } public Builder mergeFrom(org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader other) { if (other == org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader.getDefaultInstance()) return this; if (other.hasType()) { bitField0_ |= 0x00000001; type_ = other.type_; } if (other.hasIndexdata()) { setIndexdata(other.getIndexdata()); } if (other.hasDatasize()) { setDatasize(other.getDatasize()); } setUnknownFields( getUnknownFields().concat(other.unknownFields)); return this; } public final boolean isInitialized() { if (!hasType()) { return false; } if (!hasDatasize()) { return false; } return true; } public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { parsedMessage = (org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader) e.getUnfinishedMessage(); throw e; } finally { if (parsedMessage != null) { mergeFrom(parsedMessage); } } return this; } private int bitField0_; private java.lang.Object type_ = ""; /** * required string type = 1; */ public boolean hasType() { return ((bitField0_ & 0x00000001) == 0x00000001); } /** * required string type = 1; */ public java.lang.String getType() { java.lang.Object ref = type_; if (!(ref instanceof java.lang.String)) { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; java.lang.String s = bs.toStringUtf8(); if (bs.isValidUtf8()) { type_ = s; } return s; } else { return (java.lang.String) ref; } } /** * required string type = 1; */ public com.google.protobuf.ByteString getTypeBytes() { java.lang.Object ref = type_; if (ref instanceof String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( (java.lang.String) ref); type_ = b; return b; } else { return (com.google.protobuf.ByteString) ref; } } /** * required string type = 1; */ public Builder setType( java.lang.String value) { if (value == null) { throw new NullPointerException(); } bitField0_ |= 0x00000001; type_ = value; return this; } /** * required string type = 1; */ public Builder clearType() { bitField0_ = (bitField0_ & ~0x00000001); type_ = getDefaultInstance().getType(); return this; } /** * required string type = 1; */ public Builder setTypeBytes( com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } bitField0_ |= 0x00000001; type_ = value; return this; } private com.google.protobuf.ByteString indexdata_ = com.google.protobuf.ByteString.EMPTY; /** * optional bytes indexdata = 2; */ public boolean hasIndexdata() { return ((bitField0_ & 0x00000002) == 0x00000002); } /** * optional bytes indexdata = 2; */ public com.google.protobuf.ByteString getIndexdata() { return indexdata_; } /** * optional bytes indexdata = 2; */ public Builder setIndexdata(com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } bitField0_ |= 0x00000002; indexdata_ = value; return this; } /** * optional bytes indexdata = 2; */ public Builder clearIndexdata() { bitField0_ = (bitField0_ & ~0x00000002); indexdata_ = getDefaultInstance().getIndexdata(); return this; } private int datasize_ ; /** * required int32 datasize = 3; */ public boolean hasDatasize() { return ((bitField0_ & 0x00000004) == 0x00000004); } /** * required int32 datasize = 3; */ public int getDatasize() { return datasize_; } /** * required int32 datasize = 3; */ public Builder setDatasize(int value) { bitField0_ |= 0x00000004; datasize_ = value; return this; } /** * required int32 datasize = 3; */ public Builder clearDatasize() { bitField0_ = (bitField0_ & ~0x00000004); datasize_ = 0; return this; } // @@protoc_insertion_point(builder_scope:OSMPBF.BlobHeader) } static { defaultInstance = new BlobHeader(true); defaultInstance.initFields(); } // @@protoc_insertion_point(class_scope:OSMPBF.BlobHeader) } static { } // @@protoc_insertion_point(outer_class_scope) } Osmformat.java000066400000000000000000014644531253404521400342010ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/gen-src/main/java/org/openstreetmap/osmosis/osmbinary// Generated by the protocol buffer compiler. DO NOT EDIT! // source: src/main/protobuf/osmformat.proto package org.openstreetmap.osmosis.osmbinary; public final class Osmformat { private Osmformat() {} public static void registerAllExtensions( com.google.protobuf.ExtensionRegistryLite registry) { } public interface HeaderBlockOrBuilder extends // @@protoc_insertion_point(interface_extends:OSMPBF.HeaderBlock) com.google.protobuf.MessageLiteOrBuilder { /** * optional .OSMPBF.HeaderBBox bbox = 1; */ boolean hasBbox(); /** * optional .OSMPBF.HeaderBBox bbox = 1; */ org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox getBbox(); /** * repeated string required_features = 4; * *
     * Additional tags to aid in parsing this dataset 
     * 
*/ com.google.protobuf.ProtocolStringList getRequiredFeaturesList(); /** * repeated string required_features = 4; * *
     * Additional tags to aid in parsing this dataset 
     * 
*/ int getRequiredFeaturesCount(); /** * repeated string required_features = 4; * *
     * Additional tags to aid in parsing this dataset 
     * 
*/ java.lang.String getRequiredFeatures(int index); /** * repeated string required_features = 4; * *
     * Additional tags to aid in parsing this dataset 
     * 
*/ com.google.protobuf.ByteString getRequiredFeaturesBytes(int index); /** * repeated string optional_features = 5; */ com.google.protobuf.ProtocolStringList getOptionalFeaturesList(); /** * repeated string optional_features = 5; */ int getOptionalFeaturesCount(); /** * repeated string optional_features = 5; */ java.lang.String getOptionalFeatures(int index); /** * repeated string optional_features = 5; */ com.google.protobuf.ByteString getOptionalFeaturesBytes(int index); /** * optional string writingprogram = 16; */ boolean hasWritingprogram(); /** * optional string writingprogram = 16; */ java.lang.String getWritingprogram(); /** * optional string writingprogram = 16; */ com.google.protobuf.ByteString getWritingprogramBytes(); /** * optional string source = 17; * *
     * From the bbox field.
     * 
*/ boolean hasSource(); /** * optional string source = 17; * *
     * From the bbox field.
     * 
*/ java.lang.String getSource(); /** * optional string source = 17; * *
     * From the bbox field.
     * 
*/ com.google.protobuf.ByteString getSourceBytes(); /** * optional int64 osmosis_replication_timestamp = 32; * *
     * replication timestamp, expressed in seconds since the epoch, 
     * otherwise the same value as in the "timestamp=..." field
     * in the state.txt file used by Osmosis
     * 
*/ boolean hasOsmosisReplicationTimestamp(); /** * optional int64 osmosis_replication_timestamp = 32; * *
     * replication timestamp, expressed in seconds since the epoch, 
     * otherwise the same value as in the "timestamp=..." field
     * in the state.txt file used by Osmosis
     * 
*/ long getOsmosisReplicationTimestamp(); /** * optional int64 osmosis_replication_sequence_number = 33; * *
     * replication sequence number (sequenceNumber in state.txt)
     * 
*/ boolean hasOsmosisReplicationSequenceNumber(); /** * optional int64 osmosis_replication_sequence_number = 33; * *
     * replication sequence number (sequenceNumber in state.txt)
     * 
*/ long getOsmosisReplicationSequenceNumber(); /** * optional string osmosis_replication_base_url = 34; * *
     * replication base URL (from Osmosis' configuration.txt file)
     * 
*/ boolean hasOsmosisReplicationBaseUrl(); /** * optional string osmosis_replication_base_url = 34; * *
     * replication base URL (from Osmosis' configuration.txt file)
     * 
*/ java.lang.String getOsmosisReplicationBaseUrl(); /** * optional string osmosis_replication_base_url = 34; * *
     * replication base URL (from Osmosis' configuration.txt file)
     * 
*/ com.google.protobuf.ByteString getOsmosisReplicationBaseUrlBytes(); } /** * Protobuf type {@code OSMPBF.HeaderBlock} */ public static final class HeaderBlock extends com.google.protobuf.GeneratedMessageLite implements // @@protoc_insertion_point(message_implements:OSMPBF.HeaderBlock) HeaderBlockOrBuilder { // Use HeaderBlock.newBuilder() to construct. private HeaderBlock(com.google.protobuf.GeneratedMessageLite.Builder builder) { super(builder); this.unknownFields = builder.getUnknownFields(); } private HeaderBlock(boolean noInit) { this.unknownFields = com.google.protobuf.ByteString.EMPTY;} private static final HeaderBlock defaultInstance; public static HeaderBlock getDefaultInstance() { return defaultInstance; } public HeaderBlock getDefaultInstanceForType() { return defaultInstance; } private final com.google.protobuf.ByteString unknownFields; private HeaderBlock( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { initFields(); int mutable_bitField0_ = 0; com.google.protobuf.ByteString.Output unknownFieldsOutput = com.google.protobuf.ByteString.newOutput(); com.google.protobuf.CodedOutputStream unknownFieldsCodedOutput = com.google.protobuf.CodedOutputStream.newInstance( unknownFieldsOutput); try { boolean done = false; while (!done) { int tag = input.readTag(); switch (tag) { case 0: done = true; break; default: { if (!parseUnknownField(input, unknownFieldsCodedOutput, extensionRegistry, tag)) { done = true; } break; } case 10: { org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox.Builder subBuilder = null; if (((bitField0_ & 0x00000001) == 0x00000001)) { subBuilder = bbox_.toBuilder(); } bbox_ = input.readMessage(org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox.PARSER, extensionRegistry); if (subBuilder != null) { subBuilder.mergeFrom(bbox_); bbox_ = subBuilder.buildPartial(); } bitField0_ |= 0x00000001; break; } case 34: { com.google.protobuf.ByteString bs = input.readBytes(); if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) { requiredFeatures_ = new com.google.protobuf.LazyStringArrayList(); mutable_bitField0_ |= 0x00000002; } requiredFeatures_.add(bs); break; } case 42: { com.google.protobuf.ByteString bs = input.readBytes(); if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) { optionalFeatures_ = new com.google.protobuf.LazyStringArrayList(); mutable_bitField0_ |= 0x00000004; } optionalFeatures_.add(bs); break; } case 130: { com.google.protobuf.ByteString bs = input.readBytes(); bitField0_ |= 0x00000002; writingprogram_ = bs; break; } case 138: { com.google.protobuf.ByteString bs = input.readBytes(); bitField0_ |= 0x00000004; source_ = bs; break; } case 256: { bitField0_ |= 0x00000008; osmosisReplicationTimestamp_ = input.readInt64(); break; } case 264: { bitField0_ |= 0x00000010; osmosisReplicationSequenceNumber_ = input.readInt64(); break; } case 274: { com.google.protobuf.ByteString bs = input.readBytes(); bitField0_ |= 0x00000020; osmosisReplicationBaseUrl_ = bs; break; } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { throw e.setUnfinishedMessage(this); } catch (java.io.IOException e) { throw new com.google.protobuf.InvalidProtocolBufferException( e.getMessage()).setUnfinishedMessage(this); } finally { if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) { requiredFeatures_ = requiredFeatures_.getUnmodifiableView(); } if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) { optionalFeatures_ = optionalFeatures_.getUnmodifiableView(); } try { unknownFieldsCodedOutput.flush(); } catch (java.io.IOException e) { // Should not happen } finally { unknownFields = unknownFieldsOutput.toByteString(); } makeExtensionsImmutable(); } } public static com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { public HeaderBlock parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return new HeaderBlock(input, extensionRegistry); } }; @java.lang.Override public com.google.protobuf.Parser getParserForType() { return PARSER; } private int bitField0_; public static final int BBOX_FIELD_NUMBER = 1; private org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox bbox_; /** * optional .OSMPBF.HeaderBBox bbox = 1; */ public boolean hasBbox() { return ((bitField0_ & 0x00000001) == 0x00000001); } /** * optional .OSMPBF.HeaderBBox bbox = 1; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox getBbox() { return bbox_; } public static final int REQUIRED_FEATURES_FIELD_NUMBER = 4; private com.google.protobuf.LazyStringList requiredFeatures_; /** * repeated string required_features = 4; * *
     * Additional tags to aid in parsing this dataset 
     * 
*/ public com.google.protobuf.ProtocolStringList getRequiredFeaturesList() { return requiredFeatures_; } /** * repeated string required_features = 4; * *
     * Additional tags to aid in parsing this dataset 
     * 
*/ public int getRequiredFeaturesCount() { return requiredFeatures_.size(); } /** * repeated string required_features = 4; * *
     * Additional tags to aid in parsing this dataset 
     * 
*/ public java.lang.String getRequiredFeatures(int index) { return requiredFeatures_.get(index); } /** * repeated string required_features = 4; * *
     * Additional tags to aid in parsing this dataset 
     * 
*/ public com.google.protobuf.ByteString getRequiredFeaturesBytes(int index) { return requiredFeatures_.getByteString(index); } public static final int OPTIONAL_FEATURES_FIELD_NUMBER = 5; private com.google.protobuf.LazyStringList optionalFeatures_; /** * repeated string optional_features = 5; */ public com.google.protobuf.ProtocolStringList getOptionalFeaturesList() { return optionalFeatures_; } /** * repeated string optional_features = 5; */ public int getOptionalFeaturesCount() { return optionalFeatures_.size(); } /** * repeated string optional_features = 5; */ public java.lang.String getOptionalFeatures(int index) { return optionalFeatures_.get(index); } /** * repeated string optional_features = 5; */ public com.google.protobuf.ByteString getOptionalFeaturesBytes(int index) { return optionalFeatures_.getByteString(index); } public static final int WRITINGPROGRAM_FIELD_NUMBER = 16; private java.lang.Object writingprogram_; /** * optional string writingprogram = 16; */ public boolean hasWritingprogram() { return ((bitField0_ & 0x00000002) == 0x00000002); } /** * optional string writingprogram = 16; */ public java.lang.String getWritingprogram() { java.lang.Object ref = writingprogram_; if (ref instanceof java.lang.String) { return (java.lang.String) ref; } else { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; java.lang.String s = bs.toStringUtf8(); if (bs.isValidUtf8()) { writingprogram_ = s; } return s; } } /** * optional string writingprogram = 16; */ public com.google.protobuf.ByteString getWritingprogramBytes() { java.lang.Object ref = writingprogram_; if (ref instanceof java.lang.String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( (java.lang.String) ref); writingprogram_ = b; return b; } else { return (com.google.protobuf.ByteString) ref; } } public static final int SOURCE_FIELD_NUMBER = 17; private java.lang.Object source_; /** * optional string source = 17; * *
     * From the bbox field.
     * 
*/ public boolean hasSource() { return ((bitField0_ & 0x00000004) == 0x00000004); } /** * optional string source = 17; * *
     * From the bbox field.
     * 
*/ public java.lang.String getSource() { java.lang.Object ref = source_; if (ref instanceof java.lang.String) { return (java.lang.String) ref; } else { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; java.lang.String s = bs.toStringUtf8(); if (bs.isValidUtf8()) { source_ = s; } return s; } } /** * optional string source = 17; * *
     * From the bbox field.
     * 
*/ public com.google.protobuf.ByteString getSourceBytes() { java.lang.Object ref = source_; if (ref instanceof java.lang.String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( (java.lang.String) ref); source_ = b; return b; } else { return (com.google.protobuf.ByteString) ref; } } public static final int OSMOSIS_REPLICATION_TIMESTAMP_FIELD_NUMBER = 32; private long osmosisReplicationTimestamp_; /** * optional int64 osmosis_replication_timestamp = 32; * *
     * replication timestamp, expressed in seconds since the epoch, 
     * otherwise the same value as in the "timestamp=..." field
     * in the state.txt file used by Osmosis
     * 
*/ public boolean hasOsmosisReplicationTimestamp() { return ((bitField0_ & 0x00000008) == 0x00000008); } /** * optional int64 osmosis_replication_timestamp = 32; * *
     * replication timestamp, expressed in seconds since the epoch, 
     * otherwise the same value as in the "timestamp=..." field
     * in the state.txt file used by Osmosis
     * 
*/ public long getOsmosisReplicationTimestamp() { return osmosisReplicationTimestamp_; } public static final int OSMOSIS_REPLICATION_SEQUENCE_NUMBER_FIELD_NUMBER = 33; private long osmosisReplicationSequenceNumber_; /** * optional int64 osmosis_replication_sequence_number = 33; * *
     * replication sequence number (sequenceNumber in state.txt)
     * 
*/ public boolean hasOsmosisReplicationSequenceNumber() { return ((bitField0_ & 0x00000010) == 0x00000010); } /** * optional int64 osmosis_replication_sequence_number = 33; * *
     * replication sequence number (sequenceNumber in state.txt)
     * 
*/ public long getOsmosisReplicationSequenceNumber() { return osmosisReplicationSequenceNumber_; } public static final int OSMOSIS_REPLICATION_BASE_URL_FIELD_NUMBER = 34; private java.lang.Object osmosisReplicationBaseUrl_; /** * optional string osmosis_replication_base_url = 34; * *
     * replication base URL (from Osmosis' configuration.txt file)
     * 
*/ public boolean hasOsmosisReplicationBaseUrl() { return ((bitField0_ & 0x00000020) == 0x00000020); } /** * optional string osmosis_replication_base_url = 34; * *
     * replication base URL (from Osmosis' configuration.txt file)
     * 
*/ public java.lang.String getOsmosisReplicationBaseUrl() { java.lang.Object ref = osmosisReplicationBaseUrl_; if (ref instanceof java.lang.String) { return (java.lang.String) ref; } else { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; java.lang.String s = bs.toStringUtf8(); if (bs.isValidUtf8()) { osmosisReplicationBaseUrl_ = s; } return s; } } /** * optional string osmosis_replication_base_url = 34; * *
     * replication base URL (from Osmosis' configuration.txt file)
     * 
*/ public com.google.protobuf.ByteString getOsmosisReplicationBaseUrlBytes() { java.lang.Object ref = osmosisReplicationBaseUrl_; if (ref instanceof java.lang.String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( (java.lang.String) ref); osmosisReplicationBaseUrl_ = b; return b; } else { return (com.google.protobuf.ByteString) ref; } } private void initFields() { bbox_ = org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox.getDefaultInstance(); requiredFeatures_ = com.google.protobuf.LazyStringArrayList.EMPTY; optionalFeatures_ = com.google.protobuf.LazyStringArrayList.EMPTY; writingprogram_ = ""; source_ = ""; osmosisReplicationTimestamp_ = 0L; osmosisReplicationSequenceNumber_ = 0L; osmosisReplicationBaseUrl_ = ""; } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized == 1) return true; if (isInitialized == 0) return false; if (hasBbox()) { if (!getBbox().isInitialized()) { memoizedIsInitialized = 0; return false; } } memoizedIsInitialized = 1; return true; } public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { getSerializedSize(); if (((bitField0_ & 0x00000001) == 0x00000001)) { output.writeMessage(1, bbox_); } for (int i = 0; i < requiredFeatures_.size(); i++) { output.writeBytes(4, requiredFeatures_.getByteString(i)); } for (int i = 0; i < optionalFeatures_.size(); i++) { output.writeBytes(5, optionalFeatures_.getByteString(i)); } if (((bitField0_ & 0x00000002) == 0x00000002)) { output.writeBytes(16, getWritingprogramBytes()); } if (((bitField0_ & 0x00000004) == 0x00000004)) { output.writeBytes(17, getSourceBytes()); } if (((bitField0_ & 0x00000008) == 0x00000008)) { output.writeInt64(32, osmosisReplicationTimestamp_); } if (((bitField0_ & 0x00000010) == 0x00000010)) { output.writeInt64(33, osmosisReplicationSequenceNumber_); } if (((bitField0_ & 0x00000020) == 0x00000020)) { output.writeBytes(34, getOsmosisReplicationBaseUrlBytes()); } output.writeRawBytes(unknownFields); } private int memoizedSerializedSize = -1; public int getSerializedSize() { int size = memoizedSerializedSize; if (size != -1) return size; size = 0; if (((bitField0_ & 0x00000001) == 0x00000001)) { size += com.google.protobuf.CodedOutputStream .computeMessageSize(1, bbox_); } { int dataSize = 0; for (int i = 0; i < requiredFeatures_.size(); i++) { dataSize += com.google.protobuf.CodedOutputStream .computeBytesSizeNoTag(requiredFeatures_.getByteString(i)); } size += dataSize; size += 1 * getRequiredFeaturesList().size(); } { int dataSize = 0; for (int i = 0; i < optionalFeatures_.size(); i++) { dataSize += com.google.protobuf.CodedOutputStream .computeBytesSizeNoTag(optionalFeatures_.getByteString(i)); } size += dataSize; size += 1 * getOptionalFeaturesList().size(); } if (((bitField0_ & 0x00000002) == 0x00000002)) { size += com.google.protobuf.CodedOutputStream .computeBytesSize(16, getWritingprogramBytes()); } if (((bitField0_ & 0x00000004) == 0x00000004)) { size += com.google.protobuf.CodedOutputStream .computeBytesSize(17, getSourceBytes()); } if (((bitField0_ & 0x00000008) == 0x00000008)) { size += com.google.protobuf.CodedOutputStream .computeInt64Size(32, osmosisReplicationTimestamp_); } if (((bitField0_ & 0x00000010) == 0x00000010)) { size += com.google.protobuf.CodedOutputStream .computeInt64Size(33, osmosisReplicationSequenceNumber_); } if (((bitField0_ & 0x00000020) == 0x00000020)) { size += com.google.protobuf.CodedOutputStream .computeBytesSize(34, getOsmosisReplicationBaseUrlBytes()); } size += unknownFields.size(); memoizedSerializedSize = size; return size; } private static final long serialVersionUID = 0L; @java.lang.Override protected java.lang.Object writeReplace() throws java.io.ObjectStreamException { return super.writeReplace(); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBlock parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBlock parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBlock parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBlock parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBlock parseFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBlock parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBlock parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseDelimitedFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBlock parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseDelimitedFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBlock parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBlock parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static Builder newBuilder() { return Builder.create(); } public Builder newBuilderForType() { return newBuilder(); } public static Builder newBuilder(org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBlock prototype) { return newBuilder().mergeFrom(prototype); } public Builder toBuilder() { return newBuilder(this); } /** * Protobuf type {@code OSMPBF.HeaderBlock} */ public static final class Builder extends com.google.protobuf.GeneratedMessageLite.Builder< org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBlock, Builder> implements // @@protoc_insertion_point(builder_implements:OSMPBF.HeaderBlock) org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBlockOrBuilder { // Construct using org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBlock.newBuilder() private Builder() { maybeForceBuilderInitialization(); } private void maybeForceBuilderInitialization() { } private static Builder create() { return new Builder(); } public Builder clear() { super.clear(); bbox_ = org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox.getDefaultInstance(); bitField0_ = (bitField0_ & ~0x00000001); requiredFeatures_ = com.google.protobuf.LazyStringArrayList.EMPTY; bitField0_ = (bitField0_ & ~0x00000002); optionalFeatures_ = com.google.protobuf.LazyStringArrayList.EMPTY; bitField0_ = (bitField0_ & ~0x00000004); writingprogram_ = ""; bitField0_ = (bitField0_ & ~0x00000008); source_ = ""; bitField0_ = (bitField0_ & ~0x00000010); osmosisReplicationTimestamp_ = 0L; bitField0_ = (bitField0_ & ~0x00000020); osmosisReplicationSequenceNumber_ = 0L; bitField0_ = (bitField0_ & ~0x00000040); osmosisReplicationBaseUrl_ = ""; bitField0_ = (bitField0_ & ~0x00000080); return this; } public Builder clone() { return create().mergeFrom(buildPartial()); } public org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBlock getDefaultInstanceForType() { return org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBlock.getDefaultInstance(); } public org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBlock build() { org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBlock result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } public org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBlock buildPartial() { org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBlock result = new org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBlock(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) == 0x00000001)) { to_bitField0_ |= 0x00000001; } result.bbox_ = bbox_; if (((bitField0_ & 0x00000002) == 0x00000002)) { requiredFeatures_ = requiredFeatures_.getUnmodifiableView(); bitField0_ = (bitField0_ & ~0x00000002); } result.requiredFeatures_ = requiredFeatures_; if (((bitField0_ & 0x00000004) == 0x00000004)) { optionalFeatures_ = optionalFeatures_.getUnmodifiableView(); bitField0_ = (bitField0_ & ~0x00000004); } result.optionalFeatures_ = optionalFeatures_; if (((from_bitField0_ & 0x00000008) == 0x00000008)) { to_bitField0_ |= 0x00000002; } result.writingprogram_ = writingprogram_; if (((from_bitField0_ & 0x00000010) == 0x00000010)) { to_bitField0_ |= 0x00000004; } result.source_ = source_; if (((from_bitField0_ & 0x00000020) == 0x00000020)) { to_bitField0_ |= 0x00000008; } result.osmosisReplicationTimestamp_ = osmosisReplicationTimestamp_; if (((from_bitField0_ & 0x00000040) == 0x00000040)) { to_bitField0_ |= 0x00000010; } result.osmosisReplicationSequenceNumber_ = osmosisReplicationSequenceNumber_; if (((from_bitField0_ & 0x00000080) == 0x00000080)) { to_bitField0_ |= 0x00000020; } result.osmosisReplicationBaseUrl_ = osmosisReplicationBaseUrl_; result.bitField0_ = to_bitField0_; return result; } public Builder mergeFrom(org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBlock other) { if (other == org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBlock.getDefaultInstance()) return this; if (other.hasBbox()) { mergeBbox(other.getBbox()); } if (!other.requiredFeatures_.isEmpty()) { if (requiredFeatures_.isEmpty()) { requiredFeatures_ = other.requiredFeatures_; bitField0_ = (bitField0_ & ~0x00000002); } else { ensureRequiredFeaturesIsMutable(); requiredFeatures_.addAll(other.requiredFeatures_); } } if (!other.optionalFeatures_.isEmpty()) { if (optionalFeatures_.isEmpty()) { optionalFeatures_ = other.optionalFeatures_; bitField0_ = (bitField0_ & ~0x00000004); } else { ensureOptionalFeaturesIsMutable(); optionalFeatures_.addAll(other.optionalFeatures_); } } if (other.hasWritingprogram()) { bitField0_ |= 0x00000008; writingprogram_ = other.writingprogram_; } if (other.hasSource()) { bitField0_ |= 0x00000010; source_ = other.source_; } if (other.hasOsmosisReplicationTimestamp()) { setOsmosisReplicationTimestamp(other.getOsmosisReplicationTimestamp()); } if (other.hasOsmosisReplicationSequenceNumber()) { setOsmosisReplicationSequenceNumber(other.getOsmosisReplicationSequenceNumber()); } if (other.hasOsmosisReplicationBaseUrl()) { bitField0_ |= 0x00000080; osmosisReplicationBaseUrl_ = other.osmosisReplicationBaseUrl_; } setUnknownFields( getUnknownFields().concat(other.unknownFields)); return this; } public final boolean isInitialized() { if (hasBbox()) { if (!getBbox().isInitialized()) { return false; } } return true; } public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBlock parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { parsedMessage = (org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBlock) e.getUnfinishedMessage(); throw e; } finally { if (parsedMessage != null) { mergeFrom(parsedMessage); } } return this; } private int bitField0_; private org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox bbox_ = org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox.getDefaultInstance(); /** * optional .OSMPBF.HeaderBBox bbox = 1; */ public boolean hasBbox() { return ((bitField0_ & 0x00000001) == 0x00000001); } /** * optional .OSMPBF.HeaderBBox bbox = 1; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox getBbox() { return bbox_; } /** * optional .OSMPBF.HeaderBBox bbox = 1; */ public Builder setBbox(org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox value) { if (value == null) { throw new NullPointerException(); } bbox_ = value; bitField0_ |= 0x00000001; return this; } /** * optional .OSMPBF.HeaderBBox bbox = 1; */ public Builder setBbox( org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox.Builder builderForValue) { bbox_ = builderForValue.build(); bitField0_ |= 0x00000001; return this; } /** * optional .OSMPBF.HeaderBBox bbox = 1; */ public Builder mergeBbox(org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox value) { if (((bitField0_ & 0x00000001) == 0x00000001) && bbox_ != org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox.getDefaultInstance()) { bbox_ = org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox.newBuilder(bbox_).mergeFrom(value).buildPartial(); } else { bbox_ = value; } bitField0_ |= 0x00000001; return this; } /** * optional .OSMPBF.HeaderBBox bbox = 1; */ public Builder clearBbox() { bbox_ = org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox.getDefaultInstance(); bitField0_ = (bitField0_ & ~0x00000001); return this; } private com.google.protobuf.LazyStringList requiredFeatures_ = com.google.protobuf.LazyStringArrayList.EMPTY; private void ensureRequiredFeaturesIsMutable() { if (!((bitField0_ & 0x00000002) == 0x00000002)) { requiredFeatures_ = new com.google.protobuf.LazyStringArrayList(requiredFeatures_); bitField0_ |= 0x00000002; } } /** * repeated string required_features = 4; * *
       * Additional tags to aid in parsing this dataset 
       * 
*/ public com.google.protobuf.ProtocolStringList getRequiredFeaturesList() { return requiredFeatures_.getUnmodifiableView(); } /** * repeated string required_features = 4; * *
       * Additional tags to aid in parsing this dataset 
       * 
*/ public int getRequiredFeaturesCount() { return requiredFeatures_.size(); } /** * repeated string required_features = 4; * *
       * Additional tags to aid in parsing this dataset 
       * 
*/ public java.lang.String getRequiredFeatures(int index) { return requiredFeatures_.get(index); } /** * repeated string required_features = 4; * *
       * Additional tags to aid in parsing this dataset 
       * 
*/ public com.google.protobuf.ByteString getRequiredFeaturesBytes(int index) { return requiredFeatures_.getByteString(index); } /** * repeated string required_features = 4; * *
       * Additional tags to aid in parsing this dataset 
       * 
*/ public Builder setRequiredFeatures( int index, java.lang.String value) { if (value == null) { throw new NullPointerException(); } ensureRequiredFeaturesIsMutable(); requiredFeatures_.set(index, value); return this; } /** * repeated string required_features = 4; * *
       * Additional tags to aid in parsing this dataset 
       * 
*/ public Builder addRequiredFeatures( java.lang.String value) { if (value == null) { throw new NullPointerException(); } ensureRequiredFeaturesIsMutable(); requiredFeatures_.add(value); return this; } /** * repeated string required_features = 4; * *
       * Additional tags to aid in parsing this dataset 
       * 
*/ public Builder addAllRequiredFeatures( java.lang.Iterable values) { ensureRequiredFeaturesIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, requiredFeatures_); return this; } /** * repeated string required_features = 4; * *
       * Additional tags to aid in parsing this dataset 
       * 
*/ public Builder clearRequiredFeatures() { requiredFeatures_ = com.google.protobuf.LazyStringArrayList.EMPTY; bitField0_ = (bitField0_ & ~0x00000002); return this; } /** * repeated string required_features = 4; * *
       * Additional tags to aid in parsing this dataset 
       * 
*/ public Builder addRequiredFeaturesBytes( com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } ensureRequiredFeaturesIsMutable(); requiredFeatures_.add(value); return this; } private com.google.protobuf.LazyStringList optionalFeatures_ = com.google.protobuf.LazyStringArrayList.EMPTY; private void ensureOptionalFeaturesIsMutable() { if (!((bitField0_ & 0x00000004) == 0x00000004)) { optionalFeatures_ = new com.google.protobuf.LazyStringArrayList(optionalFeatures_); bitField0_ |= 0x00000004; } } /** * repeated string optional_features = 5; */ public com.google.protobuf.ProtocolStringList getOptionalFeaturesList() { return optionalFeatures_.getUnmodifiableView(); } /** * repeated string optional_features = 5; */ public int getOptionalFeaturesCount() { return optionalFeatures_.size(); } /** * repeated string optional_features = 5; */ public java.lang.String getOptionalFeatures(int index) { return optionalFeatures_.get(index); } /** * repeated string optional_features = 5; */ public com.google.protobuf.ByteString getOptionalFeaturesBytes(int index) { return optionalFeatures_.getByteString(index); } /** * repeated string optional_features = 5; */ public Builder setOptionalFeatures( int index, java.lang.String value) { if (value == null) { throw new NullPointerException(); } ensureOptionalFeaturesIsMutable(); optionalFeatures_.set(index, value); return this; } /** * repeated string optional_features = 5; */ public Builder addOptionalFeatures( java.lang.String value) { if (value == null) { throw new NullPointerException(); } ensureOptionalFeaturesIsMutable(); optionalFeatures_.add(value); return this; } /** * repeated string optional_features = 5; */ public Builder addAllOptionalFeatures( java.lang.Iterable values) { ensureOptionalFeaturesIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, optionalFeatures_); return this; } /** * repeated string optional_features = 5; */ public Builder clearOptionalFeatures() { optionalFeatures_ = com.google.protobuf.LazyStringArrayList.EMPTY; bitField0_ = (bitField0_ & ~0x00000004); return this; } /** * repeated string optional_features = 5; */ public Builder addOptionalFeaturesBytes( com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } ensureOptionalFeaturesIsMutable(); optionalFeatures_.add(value); return this; } private java.lang.Object writingprogram_ = ""; /** * optional string writingprogram = 16; */ public boolean hasWritingprogram() { return ((bitField0_ & 0x00000008) == 0x00000008); } /** * optional string writingprogram = 16; */ public java.lang.String getWritingprogram() { java.lang.Object ref = writingprogram_; if (!(ref instanceof java.lang.String)) { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; java.lang.String s = bs.toStringUtf8(); if (bs.isValidUtf8()) { writingprogram_ = s; } return s; } else { return (java.lang.String) ref; } } /** * optional string writingprogram = 16; */ public com.google.protobuf.ByteString getWritingprogramBytes() { java.lang.Object ref = writingprogram_; if (ref instanceof String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( (java.lang.String) ref); writingprogram_ = b; return b; } else { return (com.google.protobuf.ByteString) ref; } } /** * optional string writingprogram = 16; */ public Builder setWritingprogram( java.lang.String value) { if (value == null) { throw new NullPointerException(); } bitField0_ |= 0x00000008; writingprogram_ = value; return this; } /** * optional string writingprogram = 16; */ public Builder clearWritingprogram() { bitField0_ = (bitField0_ & ~0x00000008); writingprogram_ = getDefaultInstance().getWritingprogram(); return this; } /** * optional string writingprogram = 16; */ public Builder setWritingprogramBytes( com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } bitField0_ |= 0x00000008; writingprogram_ = value; return this; } private java.lang.Object source_ = ""; /** * optional string source = 17; * *
       * From the bbox field.
       * 
*/ public boolean hasSource() { return ((bitField0_ & 0x00000010) == 0x00000010); } /** * optional string source = 17; * *
       * From the bbox field.
       * 
*/ public java.lang.String getSource() { java.lang.Object ref = source_; if (!(ref instanceof java.lang.String)) { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; java.lang.String s = bs.toStringUtf8(); if (bs.isValidUtf8()) { source_ = s; } return s; } else { return (java.lang.String) ref; } } /** * optional string source = 17; * *
       * From the bbox field.
       * 
*/ public com.google.protobuf.ByteString getSourceBytes() { java.lang.Object ref = source_; if (ref instanceof String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( (java.lang.String) ref); source_ = b; return b; } else { return (com.google.protobuf.ByteString) ref; } } /** * optional string source = 17; * *
       * From the bbox field.
       * 
*/ public Builder setSource( java.lang.String value) { if (value == null) { throw new NullPointerException(); } bitField0_ |= 0x00000010; source_ = value; return this; } /** * optional string source = 17; * *
       * From the bbox field.
       * 
*/ public Builder clearSource() { bitField0_ = (bitField0_ & ~0x00000010); source_ = getDefaultInstance().getSource(); return this; } /** * optional string source = 17; * *
       * From the bbox field.
       * 
*/ public Builder setSourceBytes( com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } bitField0_ |= 0x00000010; source_ = value; return this; } private long osmosisReplicationTimestamp_ ; /** * optional int64 osmosis_replication_timestamp = 32; * *
       * replication timestamp, expressed in seconds since the epoch, 
       * otherwise the same value as in the "timestamp=..." field
       * in the state.txt file used by Osmosis
       * 
*/ public boolean hasOsmosisReplicationTimestamp() { return ((bitField0_ & 0x00000020) == 0x00000020); } /** * optional int64 osmosis_replication_timestamp = 32; * *
       * replication timestamp, expressed in seconds since the epoch, 
       * otherwise the same value as in the "timestamp=..." field
       * in the state.txt file used by Osmosis
       * 
*/ public long getOsmosisReplicationTimestamp() { return osmosisReplicationTimestamp_; } /** * optional int64 osmosis_replication_timestamp = 32; * *
       * replication timestamp, expressed in seconds since the epoch, 
       * otherwise the same value as in the "timestamp=..." field
       * in the state.txt file used by Osmosis
       * 
*/ public Builder setOsmosisReplicationTimestamp(long value) { bitField0_ |= 0x00000020; osmosisReplicationTimestamp_ = value; return this; } /** * optional int64 osmosis_replication_timestamp = 32; * *
       * replication timestamp, expressed in seconds since the epoch, 
       * otherwise the same value as in the "timestamp=..." field
       * in the state.txt file used by Osmosis
       * 
*/ public Builder clearOsmosisReplicationTimestamp() { bitField0_ = (bitField0_ & ~0x00000020); osmosisReplicationTimestamp_ = 0L; return this; } private long osmosisReplicationSequenceNumber_ ; /** * optional int64 osmosis_replication_sequence_number = 33; * *
       * replication sequence number (sequenceNumber in state.txt)
       * 
*/ public boolean hasOsmosisReplicationSequenceNumber() { return ((bitField0_ & 0x00000040) == 0x00000040); } /** * optional int64 osmosis_replication_sequence_number = 33; * *
       * replication sequence number (sequenceNumber in state.txt)
       * 
*/ public long getOsmosisReplicationSequenceNumber() { return osmosisReplicationSequenceNumber_; } /** * optional int64 osmosis_replication_sequence_number = 33; * *
       * replication sequence number (sequenceNumber in state.txt)
       * 
*/ public Builder setOsmosisReplicationSequenceNumber(long value) { bitField0_ |= 0x00000040; osmosisReplicationSequenceNumber_ = value; return this; } /** * optional int64 osmosis_replication_sequence_number = 33; * *
       * replication sequence number (sequenceNumber in state.txt)
       * 
*/ public Builder clearOsmosisReplicationSequenceNumber() { bitField0_ = (bitField0_ & ~0x00000040); osmosisReplicationSequenceNumber_ = 0L; return this; } private java.lang.Object osmosisReplicationBaseUrl_ = ""; /** * optional string osmosis_replication_base_url = 34; * *
       * replication base URL (from Osmosis' configuration.txt file)
       * 
*/ public boolean hasOsmosisReplicationBaseUrl() { return ((bitField0_ & 0x00000080) == 0x00000080); } /** * optional string osmosis_replication_base_url = 34; * *
       * replication base URL (from Osmosis' configuration.txt file)
       * 
*/ public java.lang.String getOsmosisReplicationBaseUrl() { java.lang.Object ref = osmosisReplicationBaseUrl_; if (!(ref instanceof java.lang.String)) { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; java.lang.String s = bs.toStringUtf8(); if (bs.isValidUtf8()) { osmosisReplicationBaseUrl_ = s; } return s; } else { return (java.lang.String) ref; } } /** * optional string osmosis_replication_base_url = 34; * *
       * replication base URL (from Osmosis' configuration.txt file)
       * 
*/ public com.google.protobuf.ByteString getOsmosisReplicationBaseUrlBytes() { java.lang.Object ref = osmosisReplicationBaseUrl_; if (ref instanceof String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( (java.lang.String) ref); osmosisReplicationBaseUrl_ = b; return b; } else { return (com.google.protobuf.ByteString) ref; } } /** * optional string osmosis_replication_base_url = 34; * *
       * replication base URL (from Osmosis' configuration.txt file)
       * 
*/ public Builder setOsmosisReplicationBaseUrl( java.lang.String value) { if (value == null) { throw new NullPointerException(); } bitField0_ |= 0x00000080; osmosisReplicationBaseUrl_ = value; return this; } /** * optional string osmosis_replication_base_url = 34; * *
       * replication base URL (from Osmosis' configuration.txt file)
       * 
*/ public Builder clearOsmosisReplicationBaseUrl() { bitField0_ = (bitField0_ & ~0x00000080); osmosisReplicationBaseUrl_ = getDefaultInstance().getOsmosisReplicationBaseUrl(); return this; } /** * optional string osmosis_replication_base_url = 34; * *
       * replication base URL (from Osmosis' configuration.txt file)
       * 
*/ public Builder setOsmosisReplicationBaseUrlBytes( com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } bitField0_ |= 0x00000080; osmosisReplicationBaseUrl_ = value; return this; } // @@protoc_insertion_point(builder_scope:OSMPBF.HeaderBlock) } static { defaultInstance = new HeaderBlock(true); defaultInstance.initFields(); } // @@protoc_insertion_point(class_scope:OSMPBF.HeaderBlock) } public interface HeaderBBoxOrBuilder extends // @@protoc_insertion_point(interface_extends:OSMPBF.HeaderBBox) com.google.protobuf.MessageLiteOrBuilder { /** * required sint64 left = 1; */ boolean hasLeft(); /** * required sint64 left = 1; */ long getLeft(); /** * required sint64 right = 2; */ boolean hasRight(); /** * required sint64 right = 2; */ long getRight(); /** * required sint64 top = 3; */ boolean hasTop(); /** * required sint64 top = 3; */ long getTop(); /** * required sint64 bottom = 4; */ boolean hasBottom(); /** * required sint64 bottom = 4; */ long getBottom(); } /** * Protobuf type {@code OSMPBF.HeaderBBox} */ public static final class HeaderBBox extends com.google.protobuf.GeneratedMessageLite implements // @@protoc_insertion_point(message_implements:OSMPBF.HeaderBBox) HeaderBBoxOrBuilder { // Use HeaderBBox.newBuilder() to construct. private HeaderBBox(com.google.protobuf.GeneratedMessageLite.Builder builder) { super(builder); this.unknownFields = builder.getUnknownFields(); } private HeaderBBox(boolean noInit) { this.unknownFields = com.google.protobuf.ByteString.EMPTY;} private static final HeaderBBox defaultInstance; public static HeaderBBox getDefaultInstance() { return defaultInstance; } public HeaderBBox getDefaultInstanceForType() { return defaultInstance; } private final com.google.protobuf.ByteString unknownFields; private HeaderBBox( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { initFields(); int mutable_bitField0_ = 0; com.google.protobuf.ByteString.Output unknownFieldsOutput = com.google.protobuf.ByteString.newOutput(); com.google.protobuf.CodedOutputStream unknownFieldsCodedOutput = com.google.protobuf.CodedOutputStream.newInstance( unknownFieldsOutput); try { boolean done = false; while (!done) { int tag = input.readTag(); switch (tag) { case 0: done = true; break; default: { if (!parseUnknownField(input, unknownFieldsCodedOutput, extensionRegistry, tag)) { done = true; } break; } case 8: { bitField0_ |= 0x00000001; left_ = input.readSInt64(); break; } case 16: { bitField0_ |= 0x00000002; right_ = input.readSInt64(); break; } case 24: { bitField0_ |= 0x00000004; top_ = input.readSInt64(); break; } case 32: { bitField0_ |= 0x00000008; bottom_ = input.readSInt64(); break; } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { throw e.setUnfinishedMessage(this); } catch (java.io.IOException e) { throw new com.google.protobuf.InvalidProtocolBufferException( e.getMessage()).setUnfinishedMessage(this); } finally { try { unknownFieldsCodedOutput.flush(); } catch (java.io.IOException e) { // Should not happen } finally { unknownFields = unknownFieldsOutput.toByteString(); } makeExtensionsImmutable(); } } public static com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { public HeaderBBox parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return new HeaderBBox(input, extensionRegistry); } }; @java.lang.Override public com.google.protobuf.Parser getParserForType() { return PARSER; } private int bitField0_; public static final int LEFT_FIELD_NUMBER = 1; private long left_; /** * required sint64 left = 1; */ public boolean hasLeft() { return ((bitField0_ & 0x00000001) == 0x00000001); } /** * required sint64 left = 1; */ public long getLeft() { return left_; } public static final int RIGHT_FIELD_NUMBER = 2; private long right_; /** * required sint64 right = 2; */ public boolean hasRight() { return ((bitField0_ & 0x00000002) == 0x00000002); } /** * required sint64 right = 2; */ public long getRight() { return right_; } public static final int TOP_FIELD_NUMBER = 3; private long top_; /** * required sint64 top = 3; */ public boolean hasTop() { return ((bitField0_ & 0x00000004) == 0x00000004); } /** * required sint64 top = 3; */ public long getTop() { return top_; } public static final int BOTTOM_FIELD_NUMBER = 4; private long bottom_; /** * required sint64 bottom = 4; */ public boolean hasBottom() { return ((bitField0_ & 0x00000008) == 0x00000008); } /** * required sint64 bottom = 4; */ public long getBottom() { return bottom_; } private void initFields() { left_ = 0L; right_ = 0L; top_ = 0L; bottom_ = 0L; } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized == 1) return true; if (isInitialized == 0) return false; if (!hasLeft()) { memoizedIsInitialized = 0; return false; } if (!hasRight()) { memoizedIsInitialized = 0; return false; } if (!hasTop()) { memoizedIsInitialized = 0; return false; } if (!hasBottom()) { memoizedIsInitialized = 0; return false; } memoizedIsInitialized = 1; return true; } public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { getSerializedSize(); if (((bitField0_ & 0x00000001) == 0x00000001)) { output.writeSInt64(1, left_); } if (((bitField0_ & 0x00000002) == 0x00000002)) { output.writeSInt64(2, right_); } if (((bitField0_ & 0x00000004) == 0x00000004)) { output.writeSInt64(3, top_); } if (((bitField0_ & 0x00000008) == 0x00000008)) { output.writeSInt64(4, bottom_); } output.writeRawBytes(unknownFields); } private int memoizedSerializedSize = -1; public int getSerializedSize() { int size = memoizedSerializedSize; if (size != -1) return size; size = 0; if (((bitField0_ & 0x00000001) == 0x00000001)) { size += com.google.protobuf.CodedOutputStream .computeSInt64Size(1, left_); } if (((bitField0_ & 0x00000002) == 0x00000002)) { size += com.google.protobuf.CodedOutputStream .computeSInt64Size(2, right_); } if (((bitField0_ & 0x00000004) == 0x00000004)) { size += com.google.protobuf.CodedOutputStream .computeSInt64Size(3, top_); } if (((bitField0_ & 0x00000008) == 0x00000008)) { size += com.google.protobuf.CodedOutputStream .computeSInt64Size(4, bottom_); } size += unknownFields.size(); memoizedSerializedSize = size; return size; } private static final long serialVersionUID = 0L; @java.lang.Override protected java.lang.Object writeReplace() throws java.io.ObjectStreamException { return super.writeReplace(); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox parseFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseDelimitedFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseDelimitedFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static Builder newBuilder() { return Builder.create(); } public Builder newBuilderForType() { return newBuilder(); } public static Builder newBuilder(org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox prototype) { return newBuilder().mergeFrom(prototype); } public Builder toBuilder() { return newBuilder(this); } /** * Protobuf type {@code OSMPBF.HeaderBBox} */ public static final class Builder extends com.google.protobuf.GeneratedMessageLite.Builder< org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox, Builder> implements // @@protoc_insertion_point(builder_implements:OSMPBF.HeaderBBox) org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBoxOrBuilder { // Construct using org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox.newBuilder() private Builder() { maybeForceBuilderInitialization(); } private void maybeForceBuilderInitialization() { } private static Builder create() { return new Builder(); } public Builder clear() { super.clear(); left_ = 0L; bitField0_ = (bitField0_ & ~0x00000001); right_ = 0L; bitField0_ = (bitField0_ & ~0x00000002); top_ = 0L; bitField0_ = (bitField0_ & ~0x00000004); bottom_ = 0L; bitField0_ = (bitField0_ & ~0x00000008); return this; } public Builder clone() { return create().mergeFrom(buildPartial()); } public org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox getDefaultInstanceForType() { return org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox.getDefaultInstance(); } public org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox build() { org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } public org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox buildPartial() { org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox result = new org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) == 0x00000001)) { to_bitField0_ |= 0x00000001; } result.left_ = left_; if (((from_bitField0_ & 0x00000002) == 0x00000002)) { to_bitField0_ |= 0x00000002; } result.right_ = right_; if (((from_bitField0_ & 0x00000004) == 0x00000004)) { to_bitField0_ |= 0x00000004; } result.top_ = top_; if (((from_bitField0_ & 0x00000008) == 0x00000008)) { to_bitField0_ |= 0x00000008; } result.bottom_ = bottom_; result.bitField0_ = to_bitField0_; return result; } public Builder mergeFrom(org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox other) { if (other == org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox.getDefaultInstance()) return this; if (other.hasLeft()) { setLeft(other.getLeft()); } if (other.hasRight()) { setRight(other.getRight()); } if (other.hasTop()) { setTop(other.getTop()); } if (other.hasBottom()) { setBottom(other.getBottom()); } setUnknownFields( getUnknownFields().concat(other.unknownFields)); return this; } public final boolean isInitialized() { if (!hasLeft()) { return false; } if (!hasRight()) { return false; } if (!hasTop()) { return false; } if (!hasBottom()) { return false; } return true; } public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { parsedMessage = (org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox) e.getUnfinishedMessage(); throw e; } finally { if (parsedMessage != null) { mergeFrom(parsedMessage); } } return this; } private int bitField0_; private long left_ ; /** * required sint64 left = 1; */ public boolean hasLeft() { return ((bitField0_ & 0x00000001) == 0x00000001); } /** * required sint64 left = 1; */ public long getLeft() { return left_; } /** * required sint64 left = 1; */ public Builder setLeft(long value) { bitField0_ |= 0x00000001; left_ = value; return this; } /** * required sint64 left = 1; */ public Builder clearLeft() { bitField0_ = (bitField0_ & ~0x00000001); left_ = 0L; return this; } private long right_ ; /** * required sint64 right = 2; */ public boolean hasRight() { return ((bitField0_ & 0x00000002) == 0x00000002); } /** * required sint64 right = 2; */ public long getRight() { return right_; } /** * required sint64 right = 2; */ public Builder setRight(long value) { bitField0_ |= 0x00000002; right_ = value; return this; } /** * required sint64 right = 2; */ public Builder clearRight() { bitField0_ = (bitField0_ & ~0x00000002); right_ = 0L; return this; } private long top_ ; /** * required sint64 top = 3; */ public boolean hasTop() { return ((bitField0_ & 0x00000004) == 0x00000004); } /** * required sint64 top = 3; */ public long getTop() { return top_; } /** * required sint64 top = 3; */ public Builder setTop(long value) { bitField0_ |= 0x00000004; top_ = value; return this; } /** * required sint64 top = 3; */ public Builder clearTop() { bitField0_ = (bitField0_ & ~0x00000004); top_ = 0L; return this; } private long bottom_ ; /** * required sint64 bottom = 4; */ public boolean hasBottom() { return ((bitField0_ & 0x00000008) == 0x00000008); } /** * required sint64 bottom = 4; */ public long getBottom() { return bottom_; } /** * required sint64 bottom = 4; */ public Builder setBottom(long value) { bitField0_ |= 0x00000008; bottom_ = value; return this; } /** * required sint64 bottom = 4; */ public Builder clearBottom() { bitField0_ = (bitField0_ & ~0x00000008); bottom_ = 0L; return this; } // @@protoc_insertion_point(builder_scope:OSMPBF.HeaderBBox) } static { defaultInstance = new HeaderBBox(true); defaultInstance.initFields(); } // @@protoc_insertion_point(class_scope:OSMPBF.HeaderBBox) } public interface PrimitiveBlockOrBuilder extends // @@protoc_insertion_point(interface_extends:OSMPBF.PrimitiveBlock) com.google.protobuf.MessageLiteOrBuilder { /** * required .OSMPBF.StringTable stringtable = 1; */ boolean hasStringtable(); /** * required .OSMPBF.StringTable stringtable = 1; */ org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable getStringtable(); /** * repeated .OSMPBF.PrimitiveGroup primitivegroup = 2; */ java.util.List getPrimitivegroupList(); /** * repeated .OSMPBF.PrimitiveGroup primitivegroup = 2; */ org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup getPrimitivegroup(int index); /** * repeated .OSMPBF.PrimitiveGroup primitivegroup = 2; */ int getPrimitivegroupCount(); /** * optional int32 granularity = 17 [default = 100]; * *
     * Granularity, units of nanodegrees, used to store coordinates in this block
     * 
*/ boolean hasGranularity(); /** * optional int32 granularity = 17 [default = 100]; * *
     * Granularity, units of nanodegrees, used to store coordinates in this block
     * 
*/ int getGranularity(); /** * optional int64 lat_offset = 19 [default = 0]; * *
     * Offset value between the output coordinates coordinates and the granularity grid in unites of nanodegrees.
     * 
*/ boolean hasLatOffset(); /** * optional int64 lat_offset = 19 [default = 0]; * *
     * Offset value between the output coordinates coordinates and the granularity grid in unites of nanodegrees.
     * 
*/ long getLatOffset(); /** * optional int64 lon_offset = 20 [default = 0]; */ boolean hasLonOffset(); /** * optional int64 lon_offset = 20 [default = 0]; */ long getLonOffset(); /** * optional int32 date_granularity = 18 [default = 1000]; * *
     * Granularity of dates, normally represented in units of milliseconds since the 1970 epoch.
     * 
*/ boolean hasDateGranularity(); /** * optional int32 date_granularity = 18 [default = 1000]; * *
     * Granularity of dates, normally represented in units of milliseconds since the 1970 epoch.
     * 
*/ int getDateGranularity(); } /** * Protobuf type {@code OSMPBF.PrimitiveBlock} */ public static final class PrimitiveBlock extends com.google.protobuf.GeneratedMessageLite implements // @@protoc_insertion_point(message_implements:OSMPBF.PrimitiveBlock) PrimitiveBlockOrBuilder { // Use PrimitiveBlock.newBuilder() to construct. private PrimitiveBlock(com.google.protobuf.GeneratedMessageLite.Builder builder) { super(builder); this.unknownFields = builder.getUnknownFields(); } private PrimitiveBlock(boolean noInit) { this.unknownFields = com.google.protobuf.ByteString.EMPTY;} private static final PrimitiveBlock defaultInstance; public static PrimitiveBlock getDefaultInstance() { return defaultInstance; } public PrimitiveBlock getDefaultInstanceForType() { return defaultInstance; } private final com.google.protobuf.ByteString unknownFields; private PrimitiveBlock( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { initFields(); int mutable_bitField0_ = 0; com.google.protobuf.ByteString.Output unknownFieldsOutput = com.google.protobuf.ByteString.newOutput(); com.google.protobuf.CodedOutputStream unknownFieldsCodedOutput = com.google.protobuf.CodedOutputStream.newInstance( unknownFieldsOutput); try { boolean done = false; while (!done) { int tag = input.readTag(); switch (tag) { case 0: done = true; break; default: { if (!parseUnknownField(input, unknownFieldsCodedOutput, extensionRegistry, tag)) { done = true; } break; } case 10: { org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable.Builder subBuilder = null; if (((bitField0_ & 0x00000001) == 0x00000001)) { subBuilder = stringtable_.toBuilder(); } stringtable_ = input.readMessage(org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable.PARSER, extensionRegistry); if (subBuilder != null) { subBuilder.mergeFrom(stringtable_); stringtable_ = subBuilder.buildPartial(); } bitField0_ |= 0x00000001; break; } case 18: { if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) { primitivegroup_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000002; } primitivegroup_.add(input.readMessage(org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup.PARSER, extensionRegistry)); break; } case 136: { bitField0_ |= 0x00000002; granularity_ = input.readInt32(); break; } case 144: { bitField0_ |= 0x00000010; dateGranularity_ = input.readInt32(); break; } case 152: { bitField0_ |= 0x00000004; latOffset_ = input.readInt64(); break; } case 160: { bitField0_ |= 0x00000008; lonOffset_ = input.readInt64(); break; } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { throw e.setUnfinishedMessage(this); } catch (java.io.IOException e) { throw new com.google.protobuf.InvalidProtocolBufferException( e.getMessage()).setUnfinishedMessage(this); } finally { if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) { primitivegroup_ = java.util.Collections.unmodifiableList(primitivegroup_); } try { unknownFieldsCodedOutput.flush(); } catch (java.io.IOException e) { // Should not happen } finally { unknownFields = unknownFieldsOutput.toByteString(); } makeExtensionsImmutable(); } } public static com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { public PrimitiveBlock parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return new PrimitiveBlock(input, extensionRegistry); } }; @java.lang.Override public com.google.protobuf.Parser getParserForType() { return PARSER; } private int bitField0_; public static final int STRINGTABLE_FIELD_NUMBER = 1; private org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable stringtable_; /** * required .OSMPBF.StringTable stringtable = 1; */ public boolean hasStringtable() { return ((bitField0_ & 0x00000001) == 0x00000001); } /** * required .OSMPBF.StringTable stringtable = 1; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable getStringtable() { return stringtable_; } public static final int PRIMITIVEGROUP_FIELD_NUMBER = 2; private java.util.List primitivegroup_; /** * repeated .OSMPBF.PrimitiveGroup primitivegroup = 2; */ public java.util.List getPrimitivegroupList() { return primitivegroup_; } /** * repeated .OSMPBF.PrimitiveGroup primitivegroup = 2; */ public java.util.List getPrimitivegroupOrBuilderList() { return primitivegroup_; } /** * repeated .OSMPBF.PrimitiveGroup primitivegroup = 2; */ public int getPrimitivegroupCount() { return primitivegroup_.size(); } /** * repeated .OSMPBF.PrimitiveGroup primitivegroup = 2; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup getPrimitivegroup(int index) { return primitivegroup_.get(index); } /** * repeated .OSMPBF.PrimitiveGroup primitivegroup = 2; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroupOrBuilder getPrimitivegroupOrBuilder( int index) { return primitivegroup_.get(index); } public static final int GRANULARITY_FIELD_NUMBER = 17; private int granularity_; /** * optional int32 granularity = 17 [default = 100]; * *
     * Granularity, units of nanodegrees, used to store coordinates in this block
     * 
*/ public boolean hasGranularity() { return ((bitField0_ & 0x00000002) == 0x00000002); } /** * optional int32 granularity = 17 [default = 100]; * *
     * Granularity, units of nanodegrees, used to store coordinates in this block
     * 
*/ public int getGranularity() { return granularity_; } public static final int LAT_OFFSET_FIELD_NUMBER = 19; private long latOffset_; /** * optional int64 lat_offset = 19 [default = 0]; * *
     * Offset value between the output coordinates coordinates and the granularity grid in unites of nanodegrees.
     * 
*/ public boolean hasLatOffset() { return ((bitField0_ & 0x00000004) == 0x00000004); } /** * optional int64 lat_offset = 19 [default = 0]; * *
     * Offset value between the output coordinates coordinates and the granularity grid in unites of nanodegrees.
     * 
*/ public long getLatOffset() { return latOffset_; } public static final int LON_OFFSET_FIELD_NUMBER = 20; private long lonOffset_; /** * optional int64 lon_offset = 20 [default = 0]; */ public boolean hasLonOffset() { return ((bitField0_ & 0x00000008) == 0x00000008); } /** * optional int64 lon_offset = 20 [default = 0]; */ public long getLonOffset() { return lonOffset_; } public static final int DATE_GRANULARITY_FIELD_NUMBER = 18; private int dateGranularity_; /** * optional int32 date_granularity = 18 [default = 1000]; * *
     * Granularity of dates, normally represented in units of milliseconds since the 1970 epoch.
     * 
*/ public boolean hasDateGranularity() { return ((bitField0_ & 0x00000010) == 0x00000010); } /** * optional int32 date_granularity = 18 [default = 1000]; * *
     * Granularity of dates, normally represented in units of milliseconds since the 1970 epoch.
     * 
*/ public int getDateGranularity() { return dateGranularity_; } private void initFields() { stringtable_ = org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable.getDefaultInstance(); primitivegroup_ = java.util.Collections.emptyList(); granularity_ = 100; latOffset_ = 0L; lonOffset_ = 0L; dateGranularity_ = 1000; } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized == 1) return true; if (isInitialized == 0) return false; if (!hasStringtable()) { memoizedIsInitialized = 0; return false; } for (int i = 0; i < getPrimitivegroupCount(); i++) { if (!getPrimitivegroup(i).isInitialized()) { memoizedIsInitialized = 0; return false; } } memoizedIsInitialized = 1; return true; } public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { getSerializedSize(); if (((bitField0_ & 0x00000001) == 0x00000001)) { output.writeMessage(1, stringtable_); } for (int i = 0; i < primitivegroup_.size(); i++) { output.writeMessage(2, primitivegroup_.get(i)); } if (((bitField0_ & 0x00000002) == 0x00000002)) { output.writeInt32(17, granularity_); } if (((bitField0_ & 0x00000010) == 0x00000010)) { output.writeInt32(18, dateGranularity_); } if (((bitField0_ & 0x00000004) == 0x00000004)) { output.writeInt64(19, latOffset_); } if (((bitField0_ & 0x00000008) == 0x00000008)) { output.writeInt64(20, lonOffset_); } output.writeRawBytes(unknownFields); } private int memoizedSerializedSize = -1; public int getSerializedSize() { int size = memoizedSerializedSize; if (size != -1) return size; size = 0; if (((bitField0_ & 0x00000001) == 0x00000001)) { size += com.google.protobuf.CodedOutputStream .computeMessageSize(1, stringtable_); } for (int i = 0; i < primitivegroup_.size(); i++) { size += com.google.protobuf.CodedOutputStream .computeMessageSize(2, primitivegroup_.get(i)); } if (((bitField0_ & 0x00000002) == 0x00000002)) { size += com.google.protobuf.CodedOutputStream .computeInt32Size(17, granularity_); } if (((bitField0_ & 0x00000010) == 0x00000010)) { size += com.google.protobuf.CodedOutputStream .computeInt32Size(18, dateGranularity_); } if (((bitField0_ & 0x00000004) == 0x00000004)) { size += com.google.protobuf.CodedOutputStream .computeInt64Size(19, latOffset_); } if (((bitField0_ & 0x00000008) == 0x00000008)) { size += com.google.protobuf.CodedOutputStream .computeInt64Size(20, lonOffset_); } size += unknownFields.size(); memoizedSerializedSize = size; return size; } private static final long serialVersionUID = 0L; @java.lang.Override protected java.lang.Object writeReplace() throws java.io.ObjectStreamException { return super.writeReplace(); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock parseFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseDelimitedFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseDelimitedFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static Builder newBuilder() { return Builder.create(); } public Builder newBuilderForType() { return newBuilder(); } public static Builder newBuilder(org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock prototype) { return newBuilder().mergeFrom(prototype); } public Builder toBuilder() { return newBuilder(this); } /** * Protobuf type {@code OSMPBF.PrimitiveBlock} */ public static final class Builder extends com.google.protobuf.GeneratedMessageLite.Builder< org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock, Builder> implements // @@protoc_insertion_point(builder_implements:OSMPBF.PrimitiveBlock) org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlockOrBuilder { // Construct using org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock.newBuilder() private Builder() { maybeForceBuilderInitialization(); } private void maybeForceBuilderInitialization() { } private static Builder create() { return new Builder(); } public Builder clear() { super.clear(); stringtable_ = org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable.getDefaultInstance(); bitField0_ = (bitField0_ & ~0x00000001); primitivegroup_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000002); granularity_ = 100; bitField0_ = (bitField0_ & ~0x00000004); latOffset_ = 0L; bitField0_ = (bitField0_ & ~0x00000008); lonOffset_ = 0L; bitField0_ = (bitField0_ & ~0x00000010); dateGranularity_ = 1000; bitField0_ = (bitField0_ & ~0x00000020); return this; } public Builder clone() { return create().mergeFrom(buildPartial()); } public org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock getDefaultInstanceForType() { return org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock.getDefaultInstance(); } public org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock build() { org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } public org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock buildPartial() { org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock result = new org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) == 0x00000001)) { to_bitField0_ |= 0x00000001; } result.stringtable_ = stringtable_; if (((bitField0_ & 0x00000002) == 0x00000002)) { primitivegroup_ = java.util.Collections.unmodifiableList(primitivegroup_); bitField0_ = (bitField0_ & ~0x00000002); } result.primitivegroup_ = primitivegroup_; if (((from_bitField0_ & 0x00000004) == 0x00000004)) { to_bitField0_ |= 0x00000002; } result.granularity_ = granularity_; if (((from_bitField0_ & 0x00000008) == 0x00000008)) { to_bitField0_ |= 0x00000004; } result.latOffset_ = latOffset_; if (((from_bitField0_ & 0x00000010) == 0x00000010)) { to_bitField0_ |= 0x00000008; } result.lonOffset_ = lonOffset_; if (((from_bitField0_ & 0x00000020) == 0x00000020)) { to_bitField0_ |= 0x00000010; } result.dateGranularity_ = dateGranularity_; result.bitField0_ = to_bitField0_; return result; } public Builder mergeFrom(org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock other) { if (other == org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock.getDefaultInstance()) return this; if (other.hasStringtable()) { mergeStringtable(other.getStringtable()); } if (!other.primitivegroup_.isEmpty()) { if (primitivegroup_.isEmpty()) { primitivegroup_ = other.primitivegroup_; bitField0_ = (bitField0_ & ~0x00000002); } else { ensurePrimitivegroupIsMutable(); primitivegroup_.addAll(other.primitivegroup_); } } if (other.hasGranularity()) { setGranularity(other.getGranularity()); } if (other.hasLatOffset()) { setLatOffset(other.getLatOffset()); } if (other.hasLonOffset()) { setLonOffset(other.getLonOffset()); } if (other.hasDateGranularity()) { setDateGranularity(other.getDateGranularity()); } setUnknownFields( getUnknownFields().concat(other.unknownFields)); return this; } public final boolean isInitialized() { if (!hasStringtable()) { return false; } for (int i = 0; i < getPrimitivegroupCount(); i++) { if (!getPrimitivegroup(i).isInitialized()) { return false; } } return true; } public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { parsedMessage = (org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock) e.getUnfinishedMessage(); throw e; } finally { if (parsedMessage != null) { mergeFrom(parsedMessage); } } return this; } private int bitField0_; private org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable stringtable_ = org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable.getDefaultInstance(); /** * required .OSMPBF.StringTable stringtable = 1; */ public boolean hasStringtable() { return ((bitField0_ & 0x00000001) == 0x00000001); } /** * required .OSMPBF.StringTable stringtable = 1; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable getStringtable() { return stringtable_; } /** * required .OSMPBF.StringTable stringtable = 1; */ public Builder setStringtable(org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable value) { if (value == null) { throw new NullPointerException(); } stringtable_ = value; bitField0_ |= 0x00000001; return this; } /** * required .OSMPBF.StringTable stringtable = 1; */ public Builder setStringtable( org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable.Builder builderForValue) { stringtable_ = builderForValue.build(); bitField0_ |= 0x00000001; return this; } /** * required .OSMPBF.StringTable stringtable = 1; */ public Builder mergeStringtable(org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable value) { if (((bitField0_ & 0x00000001) == 0x00000001) && stringtable_ != org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable.getDefaultInstance()) { stringtable_ = org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable.newBuilder(stringtable_).mergeFrom(value).buildPartial(); } else { stringtable_ = value; } bitField0_ |= 0x00000001; return this; } /** * required .OSMPBF.StringTable stringtable = 1; */ public Builder clearStringtable() { stringtable_ = org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable.getDefaultInstance(); bitField0_ = (bitField0_ & ~0x00000001); return this; } private java.util.List primitivegroup_ = java.util.Collections.emptyList(); private void ensurePrimitivegroupIsMutable() { if (!((bitField0_ & 0x00000002) == 0x00000002)) { primitivegroup_ = new java.util.ArrayList(primitivegroup_); bitField0_ |= 0x00000002; } } /** * repeated .OSMPBF.PrimitiveGroup primitivegroup = 2; */ public java.util.List getPrimitivegroupList() { return java.util.Collections.unmodifiableList(primitivegroup_); } /** * repeated .OSMPBF.PrimitiveGroup primitivegroup = 2; */ public int getPrimitivegroupCount() { return primitivegroup_.size(); } /** * repeated .OSMPBF.PrimitiveGroup primitivegroup = 2; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup getPrimitivegroup(int index) { return primitivegroup_.get(index); } /** * repeated .OSMPBF.PrimitiveGroup primitivegroup = 2; */ public Builder setPrimitivegroup( int index, org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup value) { if (value == null) { throw new NullPointerException(); } ensurePrimitivegroupIsMutable(); primitivegroup_.set(index, value); return this; } /** * repeated .OSMPBF.PrimitiveGroup primitivegroup = 2; */ public Builder setPrimitivegroup( int index, org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup.Builder builderForValue) { ensurePrimitivegroupIsMutable(); primitivegroup_.set(index, builderForValue.build()); return this; } /** * repeated .OSMPBF.PrimitiveGroup primitivegroup = 2; */ public Builder addPrimitivegroup(org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup value) { if (value == null) { throw new NullPointerException(); } ensurePrimitivegroupIsMutable(); primitivegroup_.add(value); return this; } /** * repeated .OSMPBF.PrimitiveGroup primitivegroup = 2; */ public Builder addPrimitivegroup( int index, org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup value) { if (value == null) { throw new NullPointerException(); } ensurePrimitivegroupIsMutable(); primitivegroup_.add(index, value); return this; } /** * repeated .OSMPBF.PrimitiveGroup primitivegroup = 2; */ public Builder addPrimitivegroup( org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup.Builder builderForValue) { ensurePrimitivegroupIsMutable(); primitivegroup_.add(builderForValue.build()); return this; } /** * repeated .OSMPBF.PrimitiveGroup primitivegroup = 2; */ public Builder addPrimitivegroup( int index, org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup.Builder builderForValue) { ensurePrimitivegroupIsMutable(); primitivegroup_.add(index, builderForValue.build()); return this; } /** * repeated .OSMPBF.PrimitiveGroup primitivegroup = 2; */ public Builder addAllPrimitivegroup( java.lang.Iterable values) { ensurePrimitivegroupIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, primitivegroup_); return this; } /** * repeated .OSMPBF.PrimitiveGroup primitivegroup = 2; */ public Builder clearPrimitivegroup() { primitivegroup_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000002); return this; } /** * repeated .OSMPBF.PrimitiveGroup primitivegroup = 2; */ public Builder removePrimitivegroup(int index) { ensurePrimitivegroupIsMutable(); primitivegroup_.remove(index); return this; } private int granularity_ = 100; /** * optional int32 granularity = 17 [default = 100]; * *
       * Granularity, units of nanodegrees, used to store coordinates in this block
       * 
*/ public boolean hasGranularity() { return ((bitField0_ & 0x00000004) == 0x00000004); } /** * optional int32 granularity = 17 [default = 100]; * *
       * Granularity, units of nanodegrees, used to store coordinates in this block
       * 
*/ public int getGranularity() { return granularity_; } /** * optional int32 granularity = 17 [default = 100]; * *
       * Granularity, units of nanodegrees, used to store coordinates in this block
       * 
*/ public Builder setGranularity(int value) { bitField0_ |= 0x00000004; granularity_ = value; return this; } /** * optional int32 granularity = 17 [default = 100]; * *
       * Granularity, units of nanodegrees, used to store coordinates in this block
       * 
*/ public Builder clearGranularity() { bitField0_ = (bitField0_ & ~0x00000004); granularity_ = 100; return this; } private long latOffset_ ; /** * optional int64 lat_offset = 19 [default = 0]; * *
       * Offset value between the output coordinates coordinates and the granularity grid in unites of nanodegrees.
       * 
*/ public boolean hasLatOffset() { return ((bitField0_ & 0x00000008) == 0x00000008); } /** * optional int64 lat_offset = 19 [default = 0]; * *
       * Offset value between the output coordinates coordinates and the granularity grid in unites of nanodegrees.
       * 
*/ public long getLatOffset() { return latOffset_; } /** * optional int64 lat_offset = 19 [default = 0]; * *
       * Offset value between the output coordinates coordinates and the granularity grid in unites of nanodegrees.
       * 
*/ public Builder setLatOffset(long value) { bitField0_ |= 0x00000008; latOffset_ = value; return this; } /** * optional int64 lat_offset = 19 [default = 0]; * *
       * Offset value between the output coordinates coordinates and the granularity grid in unites of nanodegrees.
       * 
*/ public Builder clearLatOffset() { bitField0_ = (bitField0_ & ~0x00000008); latOffset_ = 0L; return this; } private long lonOffset_ ; /** * optional int64 lon_offset = 20 [default = 0]; */ public boolean hasLonOffset() { return ((bitField0_ & 0x00000010) == 0x00000010); } /** * optional int64 lon_offset = 20 [default = 0]; */ public long getLonOffset() { return lonOffset_; } /** * optional int64 lon_offset = 20 [default = 0]; */ public Builder setLonOffset(long value) { bitField0_ |= 0x00000010; lonOffset_ = value; return this; } /** * optional int64 lon_offset = 20 [default = 0]; */ public Builder clearLonOffset() { bitField0_ = (bitField0_ & ~0x00000010); lonOffset_ = 0L; return this; } private int dateGranularity_ = 1000; /** * optional int32 date_granularity = 18 [default = 1000]; * *
       * Granularity of dates, normally represented in units of milliseconds since the 1970 epoch.
       * 
*/ public boolean hasDateGranularity() { return ((bitField0_ & 0x00000020) == 0x00000020); } /** * optional int32 date_granularity = 18 [default = 1000]; * *
       * Granularity of dates, normally represented in units of milliseconds since the 1970 epoch.
       * 
*/ public int getDateGranularity() { return dateGranularity_; } /** * optional int32 date_granularity = 18 [default = 1000]; * *
       * Granularity of dates, normally represented in units of milliseconds since the 1970 epoch.
       * 
*/ public Builder setDateGranularity(int value) { bitField0_ |= 0x00000020; dateGranularity_ = value; return this; } /** * optional int32 date_granularity = 18 [default = 1000]; * *
       * Granularity of dates, normally represented in units of milliseconds since the 1970 epoch.
       * 
*/ public Builder clearDateGranularity() { bitField0_ = (bitField0_ & ~0x00000020); dateGranularity_ = 1000; return this; } // @@protoc_insertion_point(builder_scope:OSMPBF.PrimitiveBlock) } static { defaultInstance = new PrimitiveBlock(true); defaultInstance.initFields(); } // @@protoc_insertion_point(class_scope:OSMPBF.PrimitiveBlock) } public interface PrimitiveGroupOrBuilder extends // @@protoc_insertion_point(interface_extends:OSMPBF.PrimitiveGroup) com.google.protobuf.MessageLiteOrBuilder { /** * repeated .OSMPBF.Node nodes = 1; */ java.util.List getNodesList(); /** * repeated .OSMPBF.Node nodes = 1; */ org.openstreetmap.osmosis.osmbinary.Osmformat.Node getNodes(int index); /** * repeated .OSMPBF.Node nodes = 1; */ int getNodesCount(); /** * optional .OSMPBF.DenseNodes dense = 2; */ boolean hasDense(); /** * optional .OSMPBF.DenseNodes dense = 2; */ org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes getDense(); /** * repeated .OSMPBF.Way ways = 3; */ java.util.List getWaysList(); /** * repeated .OSMPBF.Way ways = 3; */ org.openstreetmap.osmosis.osmbinary.Osmformat.Way getWays(int index); /** * repeated .OSMPBF.Way ways = 3; */ int getWaysCount(); /** * repeated .OSMPBF.Relation relations = 4; */ java.util.List getRelationsList(); /** * repeated .OSMPBF.Relation relations = 4; */ org.openstreetmap.osmosis.osmbinary.Osmformat.Relation getRelations(int index); /** * repeated .OSMPBF.Relation relations = 4; */ int getRelationsCount(); /** * repeated .OSMPBF.ChangeSet changesets = 5; */ java.util.List getChangesetsList(); /** * repeated .OSMPBF.ChangeSet changesets = 5; */ org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet getChangesets(int index); /** * repeated .OSMPBF.ChangeSet changesets = 5; */ int getChangesetsCount(); } /** * Protobuf type {@code OSMPBF.PrimitiveGroup} * *
   * Group of OSMPrimitives. All primitives in a group must be the same type.
   * 
*/ public static final class PrimitiveGroup extends com.google.protobuf.GeneratedMessageLite implements // @@protoc_insertion_point(message_implements:OSMPBF.PrimitiveGroup) PrimitiveGroupOrBuilder { // Use PrimitiveGroup.newBuilder() to construct. private PrimitiveGroup(com.google.protobuf.GeneratedMessageLite.Builder builder) { super(builder); this.unknownFields = builder.getUnknownFields(); } private PrimitiveGroup(boolean noInit) { this.unknownFields = com.google.protobuf.ByteString.EMPTY;} private static final PrimitiveGroup defaultInstance; public static PrimitiveGroup getDefaultInstance() { return defaultInstance; } public PrimitiveGroup getDefaultInstanceForType() { return defaultInstance; } private final com.google.protobuf.ByteString unknownFields; private PrimitiveGroup( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { initFields(); int mutable_bitField0_ = 0; com.google.protobuf.ByteString.Output unknownFieldsOutput = com.google.protobuf.ByteString.newOutput(); com.google.protobuf.CodedOutputStream unknownFieldsCodedOutput = com.google.protobuf.CodedOutputStream.newInstance( unknownFieldsOutput); try { boolean done = false; while (!done) { int tag = input.readTag(); switch (tag) { case 0: done = true; break; default: { if (!parseUnknownField(input, unknownFieldsCodedOutput, extensionRegistry, tag)) { done = true; } break; } case 10: { if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) { nodes_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000001; } nodes_.add(input.readMessage(org.openstreetmap.osmosis.osmbinary.Osmformat.Node.PARSER, extensionRegistry)); break; } case 18: { org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes.Builder subBuilder = null; if (((bitField0_ & 0x00000001) == 0x00000001)) { subBuilder = dense_.toBuilder(); } dense_ = input.readMessage(org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes.PARSER, extensionRegistry); if (subBuilder != null) { subBuilder.mergeFrom(dense_); dense_ = subBuilder.buildPartial(); } bitField0_ |= 0x00000001; break; } case 26: { if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) { ways_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000004; } ways_.add(input.readMessage(org.openstreetmap.osmosis.osmbinary.Osmformat.Way.PARSER, extensionRegistry)); break; } case 34: { if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) { relations_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000008; } relations_.add(input.readMessage(org.openstreetmap.osmosis.osmbinary.Osmformat.Relation.PARSER, extensionRegistry)); break; } case 42: { if (!((mutable_bitField0_ & 0x00000010) == 0x00000010)) { changesets_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000010; } changesets_.add(input.readMessage(org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet.PARSER, extensionRegistry)); break; } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { throw e.setUnfinishedMessage(this); } catch (java.io.IOException e) { throw new com.google.protobuf.InvalidProtocolBufferException( e.getMessage()).setUnfinishedMessage(this); } finally { if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) { nodes_ = java.util.Collections.unmodifiableList(nodes_); } if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) { ways_ = java.util.Collections.unmodifiableList(ways_); } if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) { relations_ = java.util.Collections.unmodifiableList(relations_); } if (((mutable_bitField0_ & 0x00000010) == 0x00000010)) { changesets_ = java.util.Collections.unmodifiableList(changesets_); } try { unknownFieldsCodedOutput.flush(); } catch (java.io.IOException e) { // Should not happen } finally { unknownFields = unknownFieldsOutput.toByteString(); } makeExtensionsImmutable(); } } public static com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { public PrimitiveGroup parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return new PrimitiveGroup(input, extensionRegistry); } }; @java.lang.Override public com.google.protobuf.Parser getParserForType() { return PARSER; } private int bitField0_; public static final int NODES_FIELD_NUMBER = 1; private java.util.List nodes_; /** * repeated .OSMPBF.Node nodes = 1; */ public java.util.List getNodesList() { return nodes_; } /** * repeated .OSMPBF.Node nodes = 1; */ public java.util.List getNodesOrBuilderList() { return nodes_; } /** * repeated .OSMPBF.Node nodes = 1; */ public int getNodesCount() { return nodes_.size(); } /** * repeated .OSMPBF.Node nodes = 1; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.Node getNodes(int index) { return nodes_.get(index); } /** * repeated .OSMPBF.Node nodes = 1; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.NodeOrBuilder getNodesOrBuilder( int index) { return nodes_.get(index); } public static final int DENSE_FIELD_NUMBER = 2; private org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes dense_; /** * optional .OSMPBF.DenseNodes dense = 2; */ public boolean hasDense() { return ((bitField0_ & 0x00000001) == 0x00000001); } /** * optional .OSMPBF.DenseNodes dense = 2; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes getDense() { return dense_; } public static final int WAYS_FIELD_NUMBER = 3; private java.util.List ways_; /** * repeated .OSMPBF.Way ways = 3; */ public java.util.List getWaysList() { return ways_; } /** * repeated .OSMPBF.Way ways = 3; */ public java.util.List getWaysOrBuilderList() { return ways_; } /** * repeated .OSMPBF.Way ways = 3; */ public int getWaysCount() { return ways_.size(); } /** * repeated .OSMPBF.Way ways = 3; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.Way getWays(int index) { return ways_.get(index); } /** * repeated .OSMPBF.Way ways = 3; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.WayOrBuilder getWaysOrBuilder( int index) { return ways_.get(index); } public static final int RELATIONS_FIELD_NUMBER = 4; private java.util.List relations_; /** * repeated .OSMPBF.Relation relations = 4; */ public java.util.List getRelationsList() { return relations_; } /** * repeated .OSMPBF.Relation relations = 4; */ public java.util.List getRelationsOrBuilderList() { return relations_; } /** * repeated .OSMPBF.Relation relations = 4; */ public int getRelationsCount() { return relations_.size(); } /** * repeated .OSMPBF.Relation relations = 4; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.Relation getRelations(int index) { return relations_.get(index); } /** * repeated .OSMPBF.Relation relations = 4; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.RelationOrBuilder getRelationsOrBuilder( int index) { return relations_.get(index); } public static final int CHANGESETS_FIELD_NUMBER = 5; private java.util.List changesets_; /** * repeated .OSMPBF.ChangeSet changesets = 5; */ public java.util.List getChangesetsList() { return changesets_; } /** * repeated .OSMPBF.ChangeSet changesets = 5; */ public java.util.List getChangesetsOrBuilderList() { return changesets_; } /** * repeated .OSMPBF.ChangeSet changesets = 5; */ public int getChangesetsCount() { return changesets_.size(); } /** * repeated .OSMPBF.ChangeSet changesets = 5; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet getChangesets(int index) { return changesets_.get(index); } /** * repeated .OSMPBF.ChangeSet changesets = 5; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSetOrBuilder getChangesetsOrBuilder( int index) { return changesets_.get(index); } private void initFields() { nodes_ = java.util.Collections.emptyList(); dense_ = org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes.getDefaultInstance(); ways_ = java.util.Collections.emptyList(); relations_ = java.util.Collections.emptyList(); changesets_ = java.util.Collections.emptyList(); } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized == 1) return true; if (isInitialized == 0) return false; for (int i = 0; i < getNodesCount(); i++) { if (!getNodes(i).isInitialized()) { memoizedIsInitialized = 0; return false; } } for (int i = 0; i < getWaysCount(); i++) { if (!getWays(i).isInitialized()) { memoizedIsInitialized = 0; return false; } } for (int i = 0; i < getRelationsCount(); i++) { if (!getRelations(i).isInitialized()) { memoizedIsInitialized = 0; return false; } } for (int i = 0; i < getChangesetsCount(); i++) { if (!getChangesets(i).isInitialized()) { memoizedIsInitialized = 0; return false; } } memoizedIsInitialized = 1; return true; } public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { getSerializedSize(); for (int i = 0; i < nodes_.size(); i++) { output.writeMessage(1, nodes_.get(i)); } if (((bitField0_ & 0x00000001) == 0x00000001)) { output.writeMessage(2, dense_); } for (int i = 0; i < ways_.size(); i++) { output.writeMessage(3, ways_.get(i)); } for (int i = 0; i < relations_.size(); i++) { output.writeMessage(4, relations_.get(i)); } for (int i = 0; i < changesets_.size(); i++) { output.writeMessage(5, changesets_.get(i)); } output.writeRawBytes(unknownFields); } private int memoizedSerializedSize = -1; public int getSerializedSize() { int size = memoizedSerializedSize; if (size != -1) return size; size = 0; for (int i = 0; i < nodes_.size(); i++) { size += com.google.protobuf.CodedOutputStream .computeMessageSize(1, nodes_.get(i)); } if (((bitField0_ & 0x00000001) == 0x00000001)) { size += com.google.protobuf.CodedOutputStream .computeMessageSize(2, dense_); } for (int i = 0; i < ways_.size(); i++) { size += com.google.protobuf.CodedOutputStream .computeMessageSize(3, ways_.get(i)); } for (int i = 0; i < relations_.size(); i++) { size += com.google.protobuf.CodedOutputStream .computeMessageSize(4, relations_.get(i)); } for (int i = 0; i < changesets_.size(); i++) { size += com.google.protobuf.CodedOutputStream .computeMessageSize(5, changesets_.get(i)); } size += unknownFields.size(); memoizedSerializedSize = size; return size; } private static final long serialVersionUID = 0L; @java.lang.Override protected java.lang.Object writeReplace() throws java.io.ObjectStreamException { return super.writeReplace(); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup parseFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseDelimitedFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseDelimitedFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static Builder newBuilder() { return Builder.create(); } public Builder newBuilderForType() { return newBuilder(); } public static Builder newBuilder(org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup prototype) { return newBuilder().mergeFrom(prototype); } public Builder toBuilder() { return newBuilder(this); } /** * Protobuf type {@code OSMPBF.PrimitiveGroup} * *
     * Group of OSMPrimitives. All primitives in a group must be the same type.
     * 
*/ public static final class Builder extends com.google.protobuf.GeneratedMessageLite.Builder< org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup, Builder> implements // @@protoc_insertion_point(builder_implements:OSMPBF.PrimitiveGroup) org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroupOrBuilder { // Construct using org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup.newBuilder() private Builder() { maybeForceBuilderInitialization(); } private void maybeForceBuilderInitialization() { } private static Builder create() { return new Builder(); } public Builder clear() { super.clear(); nodes_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000001); dense_ = org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes.getDefaultInstance(); bitField0_ = (bitField0_ & ~0x00000002); ways_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000004); relations_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000008); changesets_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000010); return this; } public Builder clone() { return create().mergeFrom(buildPartial()); } public org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup getDefaultInstanceForType() { return org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup.getDefaultInstance(); } public org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup build() { org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } public org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup buildPartial() { org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup result = new org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((bitField0_ & 0x00000001) == 0x00000001)) { nodes_ = java.util.Collections.unmodifiableList(nodes_); bitField0_ = (bitField0_ & ~0x00000001); } result.nodes_ = nodes_; if (((from_bitField0_ & 0x00000002) == 0x00000002)) { to_bitField0_ |= 0x00000001; } result.dense_ = dense_; if (((bitField0_ & 0x00000004) == 0x00000004)) { ways_ = java.util.Collections.unmodifiableList(ways_); bitField0_ = (bitField0_ & ~0x00000004); } result.ways_ = ways_; if (((bitField0_ & 0x00000008) == 0x00000008)) { relations_ = java.util.Collections.unmodifiableList(relations_); bitField0_ = (bitField0_ & ~0x00000008); } result.relations_ = relations_; if (((bitField0_ & 0x00000010) == 0x00000010)) { changesets_ = java.util.Collections.unmodifiableList(changesets_); bitField0_ = (bitField0_ & ~0x00000010); } result.changesets_ = changesets_; result.bitField0_ = to_bitField0_; return result; } public Builder mergeFrom(org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup other) { if (other == org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup.getDefaultInstance()) return this; if (!other.nodes_.isEmpty()) { if (nodes_.isEmpty()) { nodes_ = other.nodes_; bitField0_ = (bitField0_ & ~0x00000001); } else { ensureNodesIsMutable(); nodes_.addAll(other.nodes_); } } if (other.hasDense()) { mergeDense(other.getDense()); } if (!other.ways_.isEmpty()) { if (ways_.isEmpty()) { ways_ = other.ways_; bitField0_ = (bitField0_ & ~0x00000004); } else { ensureWaysIsMutable(); ways_.addAll(other.ways_); } } if (!other.relations_.isEmpty()) { if (relations_.isEmpty()) { relations_ = other.relations_; bitField0_ = (bitField0_ & ~0x00000008); } else { ensureRelationsIsMutable(); relations_.addAll(other.relations_); } } if (!other.changesets_.isEmpty()) { if (changesets_.isEmpty()) { changesets_ = other.changesets_; bitField0_ = (bitField0_ & ~0x00000010); } else { ensureChangesetsIsMutable(); changesets_.addAll(other.changesets_); } } setUnknownFields( getUnknownFields().concat(other.unknownFields)); return this; } public final boolean isInitialized() { for (int i = 0; i < getNodesCount(); i++) { if (!getNodes(i).isInitialized()) { return false; } } for (int i = 0; i < getWaysCount(); i++) { if (!getWays(i).isInitialized()) { return false; } } for (int i = 0; i < getRelationsCount(); i++) { if (!getRelations(i).isInitialized()) { return false; } } for (int i = 0; i < getChangesetsCount(); i++) { if (!getChangesets(i).isInitialized()) { return false; } } return true; } public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { parsedMessage = (org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup) e.getUnfinishedMessage(); throw e; } finally { if (parsedMessage != null) { mergeFrom(parsedMessage); } } return this; } private int bitField0_; private java.util.List nodes_ = java.util.Collections.emptyList(); private void ensureNodesIsMutable() { if (!((bitField0_ & 0x00000001) == 0x00000001)) { nodes_ = new java.util.ArrayList(nodes_); bitField0_ |= 0x00000001; } } /** * repeated .OSMPBF.Node nodes = 1; */ public java.util.List getNodesList() { return java.util.Collections.unmodifiableList(nodes_); } /** * repeated .OSMPBF.Node nodes = 1; */ public int getNodesCount() { return nodes_.size(); } /** * repeated .OSMPBF.Node nodes = 1; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.Node getNodes(int index) { return nodes_.get(index); } /** * repeated .OSMPBF.Node nodes = 1; */ public Builder setNodes( int index, org.openstreetmap.osmosis.osmbinary.Osmformat.Node value) { if (value == null) { throw new NullPointerException(); } ensureNodesIsMutable(); nodes_.set(index, value); return this; } /** * repeated .OSMPBF.Node nodes = 1; */ public Builder setNodes( int index, org.openstreetmap.osmosis.osmbinary.Osmformat.Node.Builder builderForValue) { ensureNodesIsMutable(); nodes_.set(index, builderForValue.build()); return this; } /** * repeated .OSMPBF.Node nodes = 1; */ public Builder addNodes(org.openstreetmap.osmosis.osmbinary.Osmformat.Node value) { if (value == null) { throw new NullPointerException(); } ensureNodesIsMutable(); nodes_.add(value); return this; } /** * repeated .OSMPBF.Node nodes = 1; */ public Builder addNodes( int index, org.openstreetmap.osmosis.osmbinary.Osmformat.Node value) { if (value == null) { throw new NullPointerException(); } ensureNodesIsMutable(); nodes_.add(index, value); return this; } /** * repeated .OSMPBF.Node nodes = 1; */ public Builder addNodes( org.openstreetmap.osmosis.osmbinary.Osmformat.Node.Builder builderForValue) { ensureNodesIsMutable(); nodes_.add(builderForValue.build()); return this; } /** * repeated .OSMPBF.Node nodes = 1; */ public Builder addNodes( int index, org.openstreetmap.osmosis.osmbinary.Osmformat.Node.Builder builderForValue) { ensureNodesIsMutable(); nodes_.add(index, builderForValue.build()); return this; } /** * repeated .OSMPBF.Node nodes = 1; */ public Builder addAllNodes( java.lang.Iterable values) { ensureNodesIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, nodes_); return this; } /** * repeated .OSMPBF.Node nodes = 1; */ public Builder clearNodes() { nodes_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000001); return this; } /** * repeated .OSMPBF.Node nodes = 1; */ public Builder removeNodes(int index) { ensureNodesIsMutable(); nodes_.remove(index); return this; } private org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes dense_ = org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes.getDefaultInstance(); /** * optional .OSMPBF.DenseNodes dense = 2; */ public boolean hasDense() { return ((bitField0_ & 0x00000002) == 0x00000002); } /** * optional .OSMPBF.DenseNodes dense = 2; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes getDense() { return dense_; } /** * optional .OSMPBF.DenseNodes dense = 2; */ public Builder setDense(org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes value) { if (value == null) { throw new NullPointerException(); } dense_ = value; bitField0_ |= 0x00000002; return this; } /** * optional .OSMPBF.DenseNodes dense = 2; */ public Builder setDense( org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes.Builder builderForValue) { dense_ = builderForValue.build(); bitField0_ |= 0x00000002; return this; } /** * optional .OSMPBF.DenseNodes dense = 2; */ public Builder mergeDense(org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes value) { if (((bitField0_ & 0x00000002) == 0x00000002) && dense_ != org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes.getDefaultInstance()) { dense_ = org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes.newBuilder(dense_).mergeFrom(value).buildPartial(); } else { dense_ = value; } bitField0_ |= 0x00000002; return this; } /** * optional .OSMPBF.DenseNodes dense = 2; */ public Builder clearDense() { dense_ = org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes.getDefaultInstance(); bitField0_ = (bitField0_ & ~0x00000002); return this; } private java.util.List ways_ = java.util.Collections.emptyList(); private void ensureWaysIsMutable() { if (!((bitField0_ & 0x00000004) == 0x00000004)) { ways_ = new java.util.ArrayList(ways_); bitField0_ |= 0x00000004; } } /** * repeated .OSMPBF.Way ways = 3; */ public java.util.List getWaysList() { return java.util.Collections.unmodifiableList(ways_); } /** * repeated .OSMPBF.Way ways = 3; */ public int getWaysCount() { return ways_.size(); } /** * repeated .OSMPBF.Way ways = 3; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.Way getWays(int index) { return ways_.get(index); } /** * repeated .OSMPBF.Way ways = 3; */ public Builder setWays( int index, org.openstreetmap.osmosis.osmbinary.Osmformat.Way value) { if (value == null) { throw new NullPointerException(); } ensureWaysIsMutable(); ways_.set(index, value); return this; } /** * repeated .OSMPBF.Way ways = 3; */ public Builder setWays( int index, org.openstreetmap.osmosis.osmbinary.Osmformat.Way.Builder builderForValue) { ensureWaysIsMutable(); ways_.set(index, builderForValue.build()); return this; } /** * repeated .OSMPBF.Way ways = 3; */ public Builder addWays(org.openstreetmap.osmosis.osmbinary.Osmformat.Way value) { if (value == null) { throw new NullPointerException(); } ensureWaysIsMutable(); ways_.add(value); return this; } /** * repeated .OSMPBF.Way ways = 3; */ public Builder addWays( int index, org.openstreetmap.osmosis.osmbinary.Osmformat.Way value) { if (value == null) { throw new NullPointerException(); } ensureWaysIsMutable(); ways_.add(index, value); return this; } /** * repeated .OSMPBF.Way ways = 3; */ public Builder addWays( org.openstreetmap.osmosis.osmbinary.Osmformat.Way.Builder builderForValue) { ensureWaysIsMutable(); ways_.add(builderForValue.build()); return this; } /** * repeated .OSMPBF.Way ways = 3; */ public Builder addWays( int index, org.openstreetmap.osmosis.osmbinary.Osmformat.Way.Builder builderForValue) { ensureWaysIsMutable(); ways_.add(index, builderForValue.build()); return this; } /** * repeated .OSMPBF.Way ways = 3; */ public Builder addAllWays( java.lang.Iterable values) { ensureWaysIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, ways_); return this; } /** * repeated .OSMPBF.Way ways = 3; */ public Builder clearWays() { ways_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000004); return this; } /** * repeated .OSMPBF.Way ways = 3; */ public Builder removeWays(int index) { ensureWaysIsMutable(); ways_.remove(index); return this; } private java.util.List relations_ = java.util.Collections.emptyList(); private void ensureRelationsIsMutable() { if (!((bitField0_ & 0x00000008) == 0x00000008)) { relations_ = new java.util.ArrayList(relations_); bitField0_ |= 0x00000008; } } /** * repeated .OSMPBF.Relation relations = 4; */ public java.util.List getRelationsList() { return java.util.Collections.unmodifiableList(relations_); } /** * repeated .OSMPBF.Relation relations = 4; */ public int getRelationsCount() { return relations_.size(); } /** * repeated .OSMPBF.Relation relations = 4; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.Relation getRelations(int index) { return relations_.get(index); } /** * repeated .OSMPBF.Relation relations = 4; */ public Builder setRelations( int index, org.openstreetmap.osmosis.osmbinary.Osmformat.Relation value) { if (value == null) { throw new NullPointerException(); } ensureRelationsIsMutable(); relations_.set(index, value); return this; } /** * repeated .OSMPBF.Relation relations = 4; */ public Builder setRelations( int index, org.openstreetmap.osmosis.osmbinary.Osmformat.Relation.Builder builderForValue) { ensureRelationsIsMutable(); relations_.set(index, builderForValue.build()); return this; } /** * repeated .OSMPBF.Relation relations = 4; */ public Builder addRelations(org.openstreetmap.osmosis.osmbinary.Osmformat.Relation value) { if (value == null) { throw new NullPointerException(); } ensureRelationsIsMutable(); relations_.add(value); return this; } /** * repeated .OSMPBF.Relation relations = 4; */ public Builder addRelations( int index, org.openstreetmap.osmosis.osmbinary.Osmformat.Relation value) { if (value == null) { throw new NullPointerException(); } ensureRelationsIsMutable(); relations_.add(index, value); return this; } /** * repeated .OSMPBF.Relation relations = 4; */ public Builder addRelations( org.openstreetmap.osmosis.osmbinary.Osmformat.Relation.Builder builderForValue) { ensureRelationsIsMutable(); relations_.add(builderForValue.build()); return this; } /** * repeated .OSMPBF.Relation relations = 4; */ public Builder addRelations( int index, org.openstreetmap.osmosis.osmbinary.Osmformat.Relation.Builder builderForValue) { ensureRelationsIsMutable(); relations_.add(index, builderForValue.build()); return this; } /** * repeated .OSMPBF.Relation relations = 4; */ public Builder addAllRelations( java.lang.Iterable values) { ensureRelationsIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, relations_); return this; } /** * repeated .OSMPBF.Relation relations = 4; */ public Builder clearRelations() { relations_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000008); return this; } /** * repeated .OSMPBF.Relation relations = 4; */ public Builder removeRelations(int index) { ensureRelationsIsMutable(); relations_.remove(index); return this; } private java.util.List changesets_ = java.util.Collections.emptyList(); private void ensureChangesetsIsMutable() { if (!((bitField0_ & 0x00000010) == 0x00000010)) { changesets_ = new java.util.ArrayList(changesets_); bitField0_ |= 0x00000010; } } /** * repeated .OSMPBF.ChangeSet changesets = 5; */ public java.util.List getChangesetsList() { return java.util.Collections.unmodifiableList(changesets_); } /** * repeated .OSMPBF.ChangeSet changesets = 5; */ public int getChangesetsCount() { return changesets_.size(); } /** * repeated .OSMPBF.ChangeSet changesets = 5; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet getChangesets(int index) { return changesets_.get(index); } /** * repeated .OSMPBF.ChangeSet changesets = 5; */ public Builder setChangesets( int index, org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet value) { if (value == null) { throw new NullPointerException(); } ensureChangesetsIsMutable(); changesets_.set(index, value); return this; } /** * repeated .OSMPBF.ChangeSet changesets = 5; */ public Builder setChangesets( int index, org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet.Builder builderForValue) { ensureChangesetsIsMutable(); changesets_.set(index, builderForValue.build()); return this; } /** * repeated .OSMPBF.ChangeSet changesets = 5; */ public Builder addChangesets(org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet value) { if (value == null) { throw new NullPointerException(); } ensureChangesetsIsMutable(); changesets_.add(value); return this; } /** * repeated .OSMPBF.ChangeSet changesets = 5; */ public Builder addChangesets( int index, org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet value) { if (value == null) { throw new NullPointerException(); } ensureChangesetsIsMutable(); changesets_.add(index, value); return this; } /** * repeated .OSMPBF.ChangeSet changesets = 5; */ public Builder addChangesets( org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet.Builder builderForValue) { ensureChangesetsIsMutable(); changesets_.add(builderForValue.build()); return this; } /** * repeated .OSMPBF.ChangeSet changesets = 5; */ public Builder addChangesets( int index, org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet.Builder builderForValue) { ensureChangesetsIsMutable(); changesets_.add(index, builderForValue.build()); return this; } /** * repeated .OSMPBF.ChangeSet changesets = 5; */ public Builder addAllChangesets( java.lang.Iterable values) { ensureChangesetsIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, changesets_); return this; } /** * repeated .OSMPBF.ChangeSet changesets = 5; */ public Builder clearChangesets() { changesets_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000010); return this; } /** * repeated .OSMPBF.ChangeSet changesets = 5; */ public Builder removeChangesets(int index) { ensureChangesetsIsMutable(); changesets_.remove(index); return this; } // @@protoc_insertion_point(builder_scope:OSMPBF.PrimitiveGroup) } static { defaultInstance = new PrimitiveGroup(true); defaultInstance.initFields(); } // @@protoc_insertion_point(class_scope:OSMPBF.PrimitiveGroup) } public interface StringTableOrBuilder extends // @@protoc_insertion_point(interface_extends:OSMPBF.StringTable) com.google.protobuf.MessageLiteOrBuilder { /** * repeated bytes s = 1; */ java.util.List getSList(); /** * repeated bytes s = 1; */ int getSCount(); /** * repeated bytes s = 1; */ com.google.protobuf.ByteString getS(int index); } /** * Protobuf type {@code OSMPBF.StringTable} * *
   ** String table, contains the common strings in each block.
   *Note that we reserve index '0' as a delimiter, so the entry at that
   *index in the table is ALWAYS blank and unused.
   * 
*/ public static final class StringTable extends com.google.protobuf.GeneratedMessageLite implements // @@protoc_insertion_point(message_implements:OSMPBF.StringTable) StringTableOrBuilder { // Use StringTable.newBuilder() to construct. private StringTable(com.google.protobuf.GeneratedMessageLite.Builder builder) { super(builder); this.unknownFields = builder.getUnknownFields(); } private StringTable(boolean noInit) { this.unknownFields = com.google.protobuf.ByteString.EMPTY;} private static final StringTable defaultInstance; public static StringTable getDefaultInstance() { return defaultInstance; } public StringTable getDefaultInstanceForType() { return defaultInstance; } private final com.google.protobuf.ByteString unknownFields; private StringTable( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { initFields(); int mutable_bitField0_ = 0; com.google.protobuf.ByteString.Output unknownFieldsOutput = com.google.protobuf.ByteString.newOutput(); com.google.protobuf.CodedOutputStream unknownFieldsCodedOutput = com.google.protobuf.CodedOutputStream.newInstance( unknownFieldsOutput); try { boolean done = false; while (!done) { int tag = input.readTag(); switch (tag) { case 0: done = true; break; default: { if (!parseUnknownField(input, unknownFieldsCodedOutput, extensionRegistry, tag)) { done = true; } break; } case 10: { if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) { s_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000001; } s_.add(input.readBytes()); break; } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { throw e.setUnfinishedMessage(this); } catch (java.io.IOException e) { throw new com.google.protobuf.InvalidProtocolBufferException( e.getMessage()).setUnfinishedMessage(this); } finally { if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) { s_ = java.util.Collections.unmodifiableList(s_); } try { unknownFieldsCodedOutput.flush(); } catch (java.io.IOException e) { // Should not happen } finally { unknownFields = unknownFieldsOutput.toByteString(); } makeExtensionsImmutable(); } } public static com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { public StringTable parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return new StringTable(input, extensionRegistry); } }; @java.lang.Override public com.google.protobuf.Parser getParserForType() { return PARSER; } public static final int S_FIELD_NUMBER = 1; private java.util.List s_; /** * repeated bytes s = 1; */ public java.util.List getSList() { return s_; } /** * repeated bytes s = 1; */ public int getSCount() { return s_.size(); } /** * repeated bytes s = 1; */ public com.google.protobuf.ByteString getS(int index) { return s_.get(index); } private void initFields() { s_ = java.util.Collections.emptyList(); } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized == 1) return true; if (isInitialized == 0) return false; memoizedIsInitialized = 1; return true; } public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { getSerializedSize(); for (int i = 0; i < s_.size(); i++) { output.writeBytes(1, s_.get(i)); } output.writeRawBytes(unknownFields); } private int memoizedSerializedSize = -1; public int getSerializedSize() { int size = memoizedSerializedSize; if (size != -1) return size; size = 0; { int dataSize = 0; for (int i = 0; i < s_.size(); i++) { dataSize += com.google.protobuf.CodedOutputStream .computeBytesSizeNoTag(s_.get(i)); } size += dataSize; size += 1 * getSList().size(); } size += unknownFields.size(); memoizedSerializedSize = size; return size; } private static final long serialVersionUID = 0L; @java.lang.Override protected java.lang.Object writeReplace() throws java.io.ObjectStreamException { return super.writeReplace(); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable parseFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseDelimitedFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseDelimitedFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static Builder newBuilder() { return Builder.create(); } public Builder newBuilderForType() { return newBuilder(); } public static Builder newBuilder(org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable prototype) { return newBuilder().mergeFrom(prototype); } public Builder toBuilder() { return newBuilder(this); } /** * Protobuf type {@code OSMPBF.StringTable} * *
     ** String table, contains the common strings in each block.
     *Note that we reserve index '0' as a delimiter, so the entry at that
     *index in the table is ALWAYS blank and unused.
     * 
*/ public static final class Builder extends com.google.protobuf.GeneratedMessageLite.Builder< org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable, Builder> implements // @@protoc_insertion_point(builder_implements:OSMPBF.StringTable) org.openstreetmap.osmosis.osmbinary.Osmformat.StringTableOrBuilder { // Construct using org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable.newBuilder() private Builder() { maybeForceBuilderInitialization(); } private void maybeForceBuilderInitialization() { } private static Builder create() { return new Builder(); } public Builder clear() { super.clear(); s_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000001); return this; } public Builder clone() { return create().mergeFrom(buildPartial()); } public org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable getDefaultInstanceForType() { return org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable.getDefaultInstance(); } public org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable build() { org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } public org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable buildPartial() { org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable result = new org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable(this); int from_bitField0_ = bitField0_; if (((bitField0_ & 0x00000001) == 0x00000001)) { s_ = java.util.Collections.unmodifiableList(s_); bitField0_ = (bitField0_ & ~0x00000001); } result.s_ = s_; return result; } public Builder mergeFrom(org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable other) { if (other == org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable.getDefaultInstance()) return this; if (!other.s_.isEmpty()) { if (s_.isEmpty()) { s_ = other.s_; bitField0_ = (bitField0_ & ~0x00000001); } else { ensureSIsMutable(); s_.addAll(other.s_); } } setUnknownFields( getUnknownFields().concat(other.unknownFields)); return this; } public final boolean isInitialized() { return true; } public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { parsedMessage = (org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable) e.getUnfinishedMessage(); throw e; } finally { if (parsedMessage != null) { mergeFrom(parsedMessage); } } return this; } private int bitField0_; private java.util.List s_ = java.util.Collections.emptyList(); private void ensureSIsMutable() { if (!((bitField0_ & 0x00000001) == 0x00000001)) { s_ = new java.util.ArrayList(s_); bitField0_ |= 0x00000001; } } /** * repeated bytes s = 1; */ public java.util.List getSList() { return java.util.Collections.unmodifiableList(s_); } /** * repeated bytes s = 1; */ public int getSCount() { return s_.size(); } /** * repeated bytes s = 1; */ public com.google.protobuf.ByteString getS(int index) { return s_.get(index); } /** * repeated bytes s = 1; */ public Builder setS( int index, com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } ensureSIsMutable(); s_.set(index, value); return this; } /** * repeated bytes s = 1; */ public Builder addS(com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } ensureSIsMutable(); s_.add(value); return this; } /** * repeated bytes s = 1; */ public Builder addAllS( java.lang.Iterable values) { ensureSIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, s_); return this; } /** * repeated bytes s = 1; */ public Builder clearS() { s_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000001); return this; } // @@protoc_insertion_point(builder_scope:OSMPBF.StringTable) } static { defaultInstance = new StringTable(true); defaultInstance.initFields(); } // @@protoc_insertion_point(class_scope:OSMPBF.StringTable) } public interface InfoOrBuilder extends // @@protoc_insertion_point(interface_extends:OSMPBF.Info) com.google.protobuf.MessageLiteOrBuilder { /** * optional int32 version = 1 [default = -1]; */ boolean hasVersion(); /** * optional int32 version = 1 [default = -1]; */ int getVersion(); /** * optional int64 timestamp = 2; */ boolean hasTimestamp(); /** * optional int64 timestamp = 2; */ long getTimestamp(); /** * optional int64 changeset = 3; */ boolean hasChangeset(); /** * optional int64 changeset = 3; */ long getChangeset(); /** * optional int32 uid = 4; */ boolean hasUid(); /** * optional int32 uid = 4; */ int getUid(); /** * optional uint32 user_sid = 5; * *
     * String IDs
     * 
*/ boolean hasUserSid(); /** * optional uint32 user_sid = 5; * *
     * String IDs
     * 
*/ int getUserSid(); /** * optional bool visible = 6; * *
     * The visible flag is used to store history information. It indicates that
     * the current object version has been created by a delete operation on the
     * OSM API.
     * When a writer sets this flag, it MUST add a required_features tag with
     * value "HistoricalInformation" to the HeaderBlock.
     * If this flag is not available for some object it MUST be assumed to be
     * true if the file has the required_features tag "HistoricalInformation"
     * set.
     * 
*/ boolean hasVisible(); /** * optional bool visible = 6; * *
     * The visible flag is used to store history information. It indicates that
     * the current object version has been created by a delete operation on the
     * OSM API.
     * When a writer sets this flag, it MUST add a required_features tag with
     * value "HistoricalInformation" to the HeaderBlock.
     * If this flag is not available for some object it MUST be assumed to be
     * true if the file has the required_features tag "HistoricalInformation"
     * set.
     * 
*/ boolean getVisible(); } /** * Protobuf type {@code OSMPBF.Info} * *
   * Optional metadata that may be included into each primitive. 
   * 
*/ public static final class Info extends com.google.protobuf.GeneratedMessageLite implements // @@protoc_insertion_point(message_implements:OSMPBF.Info) InfoOrBuilder { // Use Info.newBuilder() to construct. private Info(com.google.protobuf.GeneratedMessageLite.Builder builder) { super(builder); this.unknownFields = builder.getUnknownFields(); } private Info(boolean noInit) { this.unknownFields = com.google.protobuf.ByteString.EMPTY;} private static final Info defaultInstance; public static Info getDefaultInstance() { return defaultInstance; } public Info getDefaultInstanceForType() { return defaultInstance; } private final com.google.protobuf.ByteString unknownFields; private Info( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { initFields(); int mutable_bitField0_ = 0; com.google.protobuf.ByteString.Output unknownFieldsOutput = com.google.protobuf.ByteString.newOutput(); com.google.protobuf.CodedOutputStream unknownFieldsCodedOutput = com.google.protobuf.CodedOutputStream.newInstance( unknownFieldsOutput); try { boolean done = false; while (!done) { int tag = input.readTag(); switch (tag) { case 0: done = true; break; default: { if (!parseUnknownField(input, unknownFieldsCodedOutput, extensionRegistry, tag)) { done = true; } break; } case 8: { bitField0_ |= 0x00000001; version_ = input.readInt32(); break; } case 16: { bitField0_ |= 0x00000002; timestamp_ = input.readInt64(); break; } case 24: { bitField0_ |= 0x00000004; changeset_ = input.readInt64(); break; } case 32: { bitField0_ |= 0x00000008; uid_ = input.readInt32(); break; } case 40: { bitField0_ |= 0x00000010; userSid_ = input.readUInt32(); break; } case 48: { bitField0_ |= 0x00000020; visible_ = input.readBool(); break; } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { throw e.setUnfinishedMessage(this); } catch (java.io.IOException e) { throw new com.google.protobuf.InvalidProtocolBufferException( e.getMessage()).setUnfinishedMessage(this); } finally { try { unknownFieldsCodedOutput.flush(); } catch (java.io.IOException e) { // Should not happen } finally { unknownFields = unknownFieldsOutput.toByteString(); } makeExtensionsImmutable(); } } public static com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { public Info parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return new Info(input, extensionRegistry); } }; @java.lang.Override public com.google.protobuf.Parser getParserForType() { return PARSER; } private int bitField0_; public static final int VERSION_FIELD_NUMBER = 1; private int version_; /** * optional int32 version = 1 [default = -1]; */ public boolean hasVersion() { return ((bitField0_ & 0x00000001) == 0x00000001); } /** * optional int32 version = 1 [default = -1]; */ public int getVersion() { return version_; } public static final int TIMESTAMP_FIELD_NUMBER = 2; private long timestamp_; /** * optional int64 timestamp = 2; */ public boolean hasTimestamp() { return ((bitField0_ & 0x00000002) == 0x00000002); } /** * optional int64 timestamp = 2; */ public long getTimestamp() { return timestamp_; } public static final int CHANGESET_FIELD_NUMBER = 3; private long changeset_; /** * optional int64 changeset = 3; */ public boolean hasChangeset() { return ((bitField0_ & 0x00000004) == 0x00000004); } /** * optional int64 changeset = 3; */ public long getChangeset() { return changeset_; } public static final int UID_FIELD_NUMBER = 4; private int uid_; /** * optional int32 uid = 4; */ public boolean hasUid() { return ((bitField0_ & 0x00000008) == 0x00000008); } /** * optional int32 uid = 4; */ public int getUid() { return uid_; } public static final int USER_SID_FIELD_NUMBER = 5; private int userSid_; /** * optional uint32 user_sid = 5; * *
     * String IDs
     * 
*/ public boolean hasUserSid() { return ((bitField0_ & 0x00000010) == 0x00000010); } /** * optional uint32 user_sid = 5; * *
     * String IDs
     * 
*/ public int getUserSid() { return userSid_; } public static final int VISIBLE_FIELD_NUMBER = 6; private boolean visible_; /** * optional bool visible = 6; * *
     * The visible flag is used to store history information. It indicates that
     * the current object version has been created by a delete operation on the
     * OSM API.
     * When a writer sets this flag, it MUST add a required_features tag with
     * value "HistoricalInformation" to the HeaderBlock.
     * If this flag is not available for some object it MUST be assumed to be
     * true if the file has the required_features tag "HistoricalInformation"
     * set.
     * 
*/ public boolean hasVisible() { return ((bitField0_ & 0x00000020) == 0x00000020); } /** * optional bool visible = 6; * *
     * The visible flag is used to store history information. It indicates that
     * the current object version has been created by a delete operation on the
     * OSM API.
     * When a writer sets this flag, it MUST add a required_features tag with
     * value "HistoricalInformation" to the HeaderBlock.
     * If this flag is not available for some object it MUST be assumed to be
     * true if the file has the required_features tag "HistoricalInformation"
     * set.
     * 
*/ public boolean getVisible() { return visible_; } private void initFields() { version_ = -1; timestamp_ = 0L; changeset_ = 0L; uid_ = 0; userSid_ = 0; visible_ = false; } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized == 1) return true; if (isInitialized == 0) return false; memoizedIsInitialized = 1; return true; } public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { getSerializedSize(); if (((bitField0_ & 0x00000001) == 0x00000001)) { output.writeInt32(1, version_); } if (((bitField0_ & 0x00000002) == 0x00000002)) { output.writeInt64(2, timestamp_); } if (((bitField0_ & 0x00000004) == 0x00000004)) { output.writeInt64(3, changeset_); } if (((bitField0_ & 0x00000008) == 0x00000008)) { output.writeInt32(4, uid_); } if (((bitField0_ & 0x00000010) == 0x00000010)) { output.writeUInt32(5, userSid_); } if (((bitField0_ & 0x00000020) == 0x00000020)) { output.writeBool(6, visible_); } output.writeRawBytes(unknownFields); } private int memoizedSerializedSize = -1; public int getSerializedSize() { int size = memoizedSerializedSize; if (size != -1) return size; size = 0; if (((bitField0_ & 0x00000001) == 0x00000001)) { size += com.google.protobuf.CodedOutputStream .computeInt32Size(1, version_); } if (((bitField0_ & 0x00000002) == 0x00000002)) { size += com.google.protobuf.CodedOutputStream .computeInt64Size(2, timestamp_); } if (((bitField0_ & 0x00000004) == 0x00000004)) { size += com.google.protobuf.CodedOutputStream .computeInt64Size(3, changeset_); } if (((bitField0_ & 0x00000008) == 0x00000008)) { size += com.google.protobuf.CodedOutputStream .computeInt32Size(4, uid_); } if (((bitField0_ & 0x00000010) == 0x00000010)) { size += com.google.protobuf.CodedOutputStream .computeUInt32Size(5, userSid_); } if (((bitField0_ & 0x00000020) == 0x00000020)) { size += com.google.protobuf.CodedOutputStream .computeBoolSize(6, visible_); } size += unknownFields.size(); memoizedSerializedSize = size; return size; } private static final long serialVersionUID = 0L; @java.lang.Override protected java.lang.Object writeReplace() throws java.io.ObjectStreamException { return super.writeReplace(); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Info parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Info parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Info parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Info parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Info parseFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Info parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Info parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseDelimitedFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Info parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseDelimitedFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Info parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Info parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static Builder newBuilder() { return Builder.create(); } public Builder newBuilderForType() { return newBuilder(); } public static Builder newBuilder(org.openstreetmap.osmosis.osmbinary.Osmformat.Info prototype) { return newBuilder().mergeFrom(prototype); } public Builder toBuilder() { return newBuilder(this); } /** * Protobuf type {@code OSMPBF.Info} * *
     * Optional metadata that may be included into each primitive. 
     * 
*/ public static final class Builder extends com.google.protobuf.GeneratedMessageLite.Builder< org.openstreetmap.osmosis.osmbinary.Osmformat.Info, Builder> implements // @@protoc_insertion_point(builder_implements:OSMPBF.Info) org.openstreetmap.osmosis.osmbinary.Osmformat.InfoOrBuilder { // Construct using org.openstreetmap.osmosis.osmbinary.Osmformat.Info.newBuilder() private Builder() { maybeForceBuilderInitialization(); } private void maybeForceBuilderInitialization() { } private static Builder create() { return new Builder(); } public Builder clear() { super.clear(); version_ = -1; bitField0_ = (bitField0_ & ~0x00000001); timestamp_ = 0L; bitField0_ = (bitField0_ & ~0x00000002); changeset_ = 0L; bitField0_ = (bitField0_ & ~0x00000004); uid_ = 0; bitField0_ = (bitField0_ & ~0x00000008); userSid_ = 0; bitField0_ = (bitField0_ & ~0x00000010); visible_ = false; bitField0_ = (bitField0_ & ~0x00000020); return this; } public Builder clone() { return create().mergeFrom(buildPartial()); } public org.openstreetmap.osmosis.osmbinary.Osmformat.Info getDefaultInstanceForType() { return org.openstreetmap.osmosis.osmbinary.Osmformat.Info.getDefaultInstance(); } public org.openstreetmap.osmosis.osmbinary.Osmformat.Info build() { org.openstreetmap.osmosis.osmbinary.Osmformat.Info result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } public org.openstreetmap.osmosis.osmbinary.Osmformat.Info buildPartial() { org.openstreetmap.osmosis.osmbinary.Osmformat.Info result = new org.openstreetmap.osmosis.osmbinary.Osmformat.Info(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) == 0x00000001)) { to_bitField0_ |= 0x00000001; } result.version_ = version_; if (((from_bitField0_ & 0x00000002) == 0x00000002)) { to_bitField0_ |= 0x00000002; } result.timestamp_ = timestamp_; if (((from_bitField0_ & 0x00000004) == 0x00000004)) { to_bitField0_ |= 0x00000004; } result.changeset_ = changeset_; if (((from_bitField0_ & 0x00000008) == 0x00000008)) { to_bitField0_ |= 0x00000008; } result.uid_ = uid_; if (((from_bitField0_ & 0x00000010) == 0x00000010)) { to_bitField0_ |= 0x00000010; } result.userSid_ = userSid_; if (((from_bitField0_ & 0x00000020) == 0x00000020)) { to_bitField0_ |= 0x00000020; } result.visible_ = visible_; result.bitField0_ = to_bitField0_; return result; } public Builder mergeFrom(org.openstreetmap.osmosis.osmbinary.Osmformat.Info other) { if (other == org.openstreetmap.osmosis.osmbinary.Osmformat.Info.getDefaultInstance()) return this; if (other.hasVersion()) { setVersion(other.getVersion()); } if (other.hasTimestamp()) { setTimestamp(other.getTimestamp()); } if (other.hasChangeset()) { setChangeset(other.getChangeset()); } if (other.hasUid()) { setUid(other.getUid()); } if (other.hasUserSid()) { setUserSid(other.getUserSid()); } if (other.hasVisible()) { setVisible(other.getVisible()); } setUnknownFields( getUnknownFields().concat(other.unknownFields)); return this; } public final boolean isInitialized() { return true; } public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { org.openstreetmap.osmosis.osmbinary.Osmformat.Info parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { parsedMessage = (org.openstreetmap.osmosis.osmbinary.Osmformat.Info) e.getUnfinishedMessage(); throw e; } finally { if (parsedMessage != null) { mergeFrom(parsedMessage); } } return this; } private int bitField0_; private int version_ = -1; /** * optional int32 version = 1 [default = -1]; */ public boolean hasVersion() { return ((bitField0_ & 0x00000001) == 0x00000001); } /** * optional int32 version = 1 [default = -1]; */ public int getVersion() { return version_; } /** * optional int32 version = 1 [default = -1]; */ public Builder setVersion(int value) { bitField0_ |= 0x00000001; version_ = value; return this; } /** * optional int32 version = 1 [default = -1]; */ public Builder clearVersion() { bitField0_ = (bitField0_ & ~0x00000001); version_ = -1; return this; } private long timestamp_ ; /** * optional int64 timestamp = 2; */ public boolean hasTimestamp() { return ((bitField0_ & 0x00000002) == 0x00000002); } /** * optional int64 timestamp = 2; */ public long getTimestamp() { return timestamp_; } /** * optional int64 timestamp = 2; */ public Builder setTimestamp(long value) { bitField0_ |= 0x00000002; timestamp_ = value; return this; } /** * optional int64 timestamp = 2; */ public Builder clearTimestamp() { bitField0_ = (bitField0_ & ~0x00000002); timestamp_ = 0L; return this; } private long changeset_ ; /** * optional int64 changeset = 3; */ public boolean hasChangeset() { return ((bitField0_ & 0x00000004) == 0x00000004); } /** * optional int64 changeset = 3; */ public long getChangeset() { return changeset_; } /** * optional int64 changeset = 3; */ public Builder setChangeset(long value) { bitField0_ |= 0x00000004; changeset_ = value; return this; } /** * optional int64 changeset = 3; */ public Builder clearChangeset() { bitField0_ = (bitField0_ & ~0x00000004); changeset_ = 0L; return this; } private int uid_ ; /** * optional int32 uid = 4; */ public boolean hasUid() { return ((bitField0_ & 0x00000008) == 0x00000008); } /** * optional int32 uid = 4; */ public int getUid() { return uid_; } /** * optional int32 uid = 4; */ public Builder setUid(int value) { bitField0_ |= 0x00000008; uid_ = value; return this; } /** * optional int32 uid = 4; */ public Builder clearUid() { bitField0_ = (bitField0_ & ~0x00000008); uid_ = 0; return this; } private int userSid_ ; /** * optional uint32 user_sid = 5; * *
       * String IDs
       * 
*/ public boolean hasUserSid() { return ((bitField0_ & 0x00000010) == 0x00000010); } /** * optional uint32 user_sid = 5; * *
       * String IDs
       * 
*/ public int getUserSid() { return userSid_; } /** * optional uint32 user_sid = 5; * *
       * String IDs
       * 
*/ public Builder setUserSid(int value) { bitField0_ |= 0x00000010; userSid_ = value; return this; } /** * optional uint32 user_sid = 5; * *
       * String IDs
       * 
*/ public Builder clearUserSid() { bitField0_ = (bitField0_ & ~0x00000010); userSid_ = 0; return this; } private boolean visible_ ; /** * optional bool visible = 6; * *
       * The visible flag is used to store history information. It indicates that
       * the current object version has been created by a delete operation on the
       * OSM API.
       * When a writer sets this flag, it MUST add a required_features tag with
       * value "HistoricalInformation" to the HeaderBlock.
       * If this flag is not available for some object it MUST be assumed to be
       * true if the file has the required_features tag "HistoricalInformation"
       * set.
       * 
*/ public boolean hasVisible() { return ((bitField0_ & 0x00000020) == 0x00000020); } /** * optional bool visible = 6; * *
       * The visible flag is used to store history information. It indicates that
       * the current object version has been created by a delete operation on the
       * OSM API.
       * When a writer sets this flag, it MUST add a required_features tag with
       * value "HistoricalInformation" to the HeaderBlock.
       * If this flag is not available for some object it MUST be assumed to be
       * true if the file has the required_features tag "HistoricalInformation"
       * set.
       * 
*/ public boolean getVisible() { return visible_; } /** * optional bool visible = 6; * *
       * The visible flag is used to store history information. It indicates that
       * the current object version has been created by a delete operation on the
       * OSM API.
       * When a writer sets this flag, it MUST add a required_features tag with
       * value "HistoricalInformation" to the HeaderBlock.
       * If this flag is not available for some object it MUST be assumed to be
       * true if the file has the required_features tag "HistoricalInformation"
       * set.
       * 
*/ public Builder setVisible(boolean value) { bitField0_ |= 0x00000020; visible_ = value; return this; } /** * optional bool visible = 6; * *
       * The visible flag is used to store history information. It indicates that
       * the current object version has been created by a delete operation on the
       * OSM API.
       * When a writer sets this flag, it MUST add a required_features tag with
       * value "HistoricalInformation" to the HeaderBlock.
       * If this flag is not available for some object it MUST be assumed to be
       * true if the file has the required_features tag "HistoricalInformation"
       * set.
       * 
*/ public Builder clearVisible() { bitField0_ = (bitField0_ & ~0x00000020); visible_ = false; return this; } // @@protoc_insertion_point(builder_scope:OSMPBF.Info) } static { defaultInstance = new Info(true); defaultInstance.initFields(); } // @@protoc_insertion_point(class_scope:OSMPBF.Info) } public interface DenseInfoOrBuilder extends // @@protoc_insertion_point(interface_extends:OSMPBF.DenseInfo) com.google.protobuf.MessageLiteOrBuilder { /** * repeated int32 version = 1 [packed = true]; */ java.util.List getVersionList(); /** * repeated int32 version = 1 [packed = true]; */ int getVersionCount(); /** * repeated int32 version = 1 [packed = true]; */ int getVersion(int index); /** * repeated sint64 timestamp = 2 [packed = true]; * *
     * DELTA coded
     * 
*/ java.util.List getTimestampList(); /** * repeated sint64 timestamp = 2 [packed = true]; * *
     * DELTA coded
     * 
*/ int getTimestampCount(); /** * repeated sint64 timestamp = 2 [packed = true]; * *
     * DELTA coded
     * 
*/ long getTimestamp(int index); /** * repeated sint64 changeset = 3 [packed = true]; * *
     * DELTA coded
     * 
*/ java.util.List getChangesetList(); /** * repeated sint64 changeset = 3 [packed = true]; * *
     * DELTA coded
     * 
*/ int getChangesetCount(); /** * repeated sint64 changeset = 3 [packed = true]; * *
     * DELTA coded
     * 
*/ long getChangeset(int index); /** * repeated sint32 uid = 4 [packed = true]; * *
     * DELTA coded
     * 
*/ java.util.List getUidList(); /** * repeated sint32 uid = 4 [packed = true]; * *
     * DELTA coded
     * 
*/ int getUidCount(); /** * repeated sint32 uid = 4 [packed = true]; * *
     * DELTA coded
     * 
*/ int getUid(int index); /** * repeated sint32 user_sid = 5 [packed = true]; * *
     * String IDs for usernames. DELTA coded
     * 
*/ java.util.List getUserSidList(); /** * repeated sint32 user_sid = 5 [packed = true]; * *
     * String IDs for usernames. DELTA coded
     * 
*/ int getUserSidCount(); /** * repeated sint32 user_sid = 5 [packed = true]; * *
     * String IDs for usernames. DELTA coded
     * 
*/ int getUserSid(int index); /** * repeated bool visible = 6 [packed = true]; * *
     * The visible flag is used to store history information. It indicates that
     * the current object version has been created by a delete operation on the
     * OSM API.
     * When a writer sets this flag, it MUST add a required_features tag with
     * value "HistoricalInformation" to the HeaderBlock.
     * If this flag is not available for some object it MUST be assumed to be
     * true if the file has the required_features tag "HistoricalInformation"
     * set.
     * 
*/ java.util.List getVisibleList(); /** * repeated bool visible = 6 [packed = true]; * *
     * The visible flag is used to store history information. It indicates that
     * the current object version has been created by a delete operation on the
     * OSM API.
     * When a writer sets this flag, it MUST add a required_features tag with
     * value "HistoricalInformation" to the HeaderBlock.
     * If this flag is not available for some object it MUST be assumed to be
     * true if the file has the required_features tag "HistoricalInformation"
     * set.
     * 
*/ int getVisibleCount(); /** * repeated bool visible = 6 [packed = true]; * *
     * The visible flag is used to store history information. It indicates that
     * the current object version has been created by a delete operation on the
     * OSM API.
     * When a writer sets this flag, it MUST add a required_features tag with
     * value "HistoricalInformation" to the HeaderBlock.
     * If this flag is not available for some object it MUST be assumed to be
     * true if the file has the required_features tag "HistoricalInformation"
     * set.
     * 
*/ boolean getVisible(int index); } /** * Protobuf type {@code OSMPBF.DenseInfo} * *
   ** Optional metadata that may be included into each primitive. Special dense format used in DenseNodes. 
   * 
*/ public static final class DenseInfo extends com.google.protobuf.GeneratedMessageLite implements // @@protoc_insertion_point(message_implements:OSMPBF.DenseInfo) DenseInfoOrBuilder { // Use DenseInfo.newBuilder() to construct. private DenseInfo(com.google.protobuf.GeneratedMessageLite.Builder builder) { super(builder); this.unknownFields = builder.getUnknownFields(); } private DenseInfo(boolean noInit) { this.unknownFields = com.google.protobuf.ByteString.EMPTY;} private static final DenseInfo defaultInstance; public static DenseInfo getDefaultInstance() { return defaultInstance; } public DenseInfo getDefaultInstanceForType() { return defaultInstance; } private final com.google.protobuf.ByteString unknownFields; private DenseInfo( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { initFields(); int mutable_bitField0_ = 0; com.google.protobuf.ByteString.Output unknownFieldsOutput = com.google.protobuf.ByteString.newOutput(); com.google.protobuf.CodedOutputStream unknownFieldsCodedOutput = com.google.protobuf.CodedOutputStream.newInstance( unknownFieldsOutput); try { boolean done = false; while (!done) { int tag = input.readTag(); switch (tag) { case 0: done = true; break; default: { if (!parseUnknownField(input, unknownFieldsCodedOutput, extensionRegistry, tag)) { done = true; } break; } case 8: { if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) { version_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000001; } version_.add(input.readInt32()); break; } case 10: { int length = input.readRawVarint32(); int limit = input.pushLimit(length); if (!((mutable_bitField0_ & 0x00000001) == 0x00000001) && input.getBytesUntilLimit() > 0) { version_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000001; } while (input.getBytesUntilLimit() > 0) { version_.add(input.readInt32()); } input.popLimit(limit); break; } case 16: { if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) { timestamp_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000002; } timestamp_.add(input.readSInt64()); break; } case 18: { int length = input.readRawVarint32(); int limit = input.pushLimit(length); if (!((mutable_bitField0_ & 0x00000002) == 0x00000002) && input.getBytesUntilLimit() > 0) { timestamp_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000002; } while (input.getBytesUntilLimit() > 0) { timestamp_.add(input.readSInt64()); } input.popLimit(limit); break; } case 24: { if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) { changeset_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000004; } changeset_.add(input.readSInt64()); break; } case 26: { int length = input.readRawVarint32(); int limit = input.pushLimit(length); if (!((mutable_bitField0_ & 0x00000004) == 0x00000004) && input.getBytesUntilLimit() > 0) { changeset_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000004; } while (input.getBytesUntilLimit() > 0) { changeset_.add(input.readSInt64()); } input.popLimit(limit); break; } case 32: { if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) { uid_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000008; } uid_.add(input.readSInt32()); break; } case 34: { int length = input.readRawVarint32(); int limit = input.pushLimit(length); if (!((mutable_bitField0_ & 0x00000008) == 0x00000008) && input.getBytesUntilLimit() > 0) { uid_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000008; } while (input.getBytesUntilLimit() > 0) { uid_.add(input.readSInt32()); } input.popLimit(limit); break; } case 40: { if (!((mutable_bitField0_ & 0x00000010) == 0x00000010)) { userSid_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000010; } userSid_.add(input.readSInt32()); break; } case 42: { int length = input.readRawVarint32(); int limit = input.pushLimit(length); if (!((mutable_bitField0_ & 0x00000010) == 0x00000010) && input.getBytesUntilLimit() > 0) { userSid_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000010; } while (input.getBytesUntilLimit() > 0) { userSid_.add(input.readSInt32()); } input.popLimit(limit); break; } case 48: { if (!((mutable_bitField0_ & 0x00000020) == 0x00000020)) { visible_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000020; } visible_.add(input.readBool()); break; } case 50: { int length = input.readRawVarint32(); int limit = input.pushLimit(length); if (!((mutable_bitField0_ & 0x00000020) == 0x00000020) && input.getBytesUntilLimit() > 0) { visible_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000020; } while (input.getBytesUntilLimit() > 0) { visible_.add(input.readBool()); } input.popLimit(limit); break; } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { throw e.setUnfinishedMessage(this); } catch (java.io.IOException e) { throw new com.google.protobuf.InvalidProtocolBufferException( e.getMessage()).setUnfinishedMessage(this); } finally { if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) { version_ = java.util.Collections.unmodifiableList(version_); } if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) { timestamp_ = java.util.Collections.unmodifiableList(timestamp_); } if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) { changeset_ = java.util.Collections.unmodifiableList(changeset_); } if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) { uid_ = java.util.Collections.unmodifiableList(uid_); } if (((mutable_bitField0_ & 0x00000010) == 0x00000010)) { userSid_ = java.util.Collections.unmodifiableList(userSid_); } if (((mutable_bitField0_ & 0x00000020) == 0x00000020)) { visible_ = java.util.Collections.unmodifiableList(visible_); } try { unknownFieldsCodedOutput.flush(); } catch (java.io.IOException e) { // Should not happen } finally { unknownFields = unknownFieldsOutput.toByteString(); } makeExtensionsImmutable(); } } public static com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { public DenseInfo parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return new DenseInfo(input, extensionRegistry); } }; @java.lang.Override public com.google.protobuf.Parser getParserForType() { return PARSER; } public static final int VERSION_FIELD_NUMBER = 1; private java.util.List version_; /** * repeated int32 version = 1 [packed = true]; */ public java.util.List getVersionList() { return version_; } /** * repeated int32 version = 1 [packed = true]; */ public int getVersionCount() { return version_.size(); } /** * repeated int32 version = 1 [packed = true]; */ public int getVersion(int index) { return version_.get(index); } private int versionMemoizedSerializedSize = -1; public static final int TIMESTAMP_FIELD_NUMBER = 2; private java.util.List timestamp_; /** * repeated sint64 timestamp = 2 [packed = true]; * *
     * DELTA coded
     * 
*/ public java.util.List getTimestampList() { return timestamp_; } /** * repeated sint64 timestamp = 2 [packed = true]; * *
     * DELTA coded
     * 
*/ public int getTimestampCount() { return timestamp_.size(); } /** * repeated sint64 timestamp = 2 [packed = true]; * *
     * DELTA coded
     * 
*/ public long getTimestamp(int index) { return timestamp_.get(index); } private int timestampMemoizedSerializedSize = -1; public static final int CHANGESET_FIELD_NUMBER = 3; private java.util.List changeset_; /** * repeated sint64 changeset = 3 [packed = true]; * *
     * DELTA coded
     * 
*/ public java.util.List getChangesetList() { return changeset_; } /** * repeated sint64 changeset = 3 [packed = true]; * *
     * DELTA coded
     * 
*/ public int getChangesetCount() { return changeset_.size(); } /** * repeated sint64 changeset = 3 [packed = true]; * *
     * DELTA coded
     * 
*/ public long getChangeset(int index) { return changeset_.get(index); } private int changesetMemoizedSerializedSize = -1; public static final int UID_FIELD_NUMBER = 4; private java.util.List uid_; /** * repeated sint32 uid = 4 [packed = true]; * *
     * DELTA coded
     * 
*/ public java.util.List getUidList() { return uid_; } /** * repeated sint32 uid = 4 [packed = true]; * *
     * DELTA coded
     * 
*/ public int getUidCount() { return uid_.size(); } /** * repeated sint32 uid = 4 [packed = true]; * *
     * DELTA coded
     * 
*/ public int getUid(int index) { return uid_.get(index); } private int uidMemoizedSerializedSize = -1; public static final int USER_SID_FIELD_NUMBER = 5; private java.util.List userSid_; /** * repeated sint32 user_sid = 5 [packed = true]; * *
     * String IDs for usernames. DELTA coded
     * 
*/ public java.util.List getUserSidList() { return userSid_; } /** * repeated sint32 user_sid = 5 [packed = true]; * *
     * String IDs for usernames. DELTA coded
     * 
*/ public int getUserSidCount() { return userSid_.size(); } /** * repeated sint32 user_sid = 5 [packed = true]; * *
     * String IDs for usernames. DELTA coded
     * 
*/ public int getUserSid(int index) { return userSid_.get(index); } private int userSidMemoizedSerializedSize = -1; public static final int VISIBLE_FIELD_NUMBER = 6; private java.util.List visible_; /** * repeated bool visible = 6 [packed = true]; * *
     * The visible flag is used to store history information. It indicates that
     * the current object version has been created by a delete operation on the
     * OSM API.
     * When a writer sets this flag, it MUST add a required_features tag with
     * value "HistoricalInformation" to the HeaderBlock.
     * If this flag is not available for some object it MUST be assumed to be
     * true if the file has the required_features tag "HistoricalInformation"
     * set.
     * 
*/ public java.util.List getVisibleList() { return visible_; } /** * repeated bool visible = 6 [packed = true]; * *
     * The visible flag is used to store history information. It indicates that
     * the current object version has been created by a delete operation on the
     * OSM API.
     * When a writer sets this flag, it MUST add a required_features tag with
     * value "HistoricalInformation" to the HeaderBlock.
     * If this flag is not available for some object it MUST be assumed to be
     * true if the file has the required_features tag "HistoricalInformation"
     * set.
     * 
*/ public int getVisibleCount() { return visible_.size(); } /** * repeated bool visible = 6 [packed = true]; * *
     * The visible flag is used to store history information. It indicates that
     * the current object version has been created by a delete operation on the
     * OSM API.
     * When a writer sets this flag, it MUST add a required_features tag with
     * value "HistoricalInformation" to the HeaderBlock.
     * If this flag is not available for some object it MUST be assumed to be
     * true if the file has the required_features tag "HistoricalInformation"
     * set.
     * 
*/ public boolean getVisible(int index) { return visible_.get(index); } private int visibleMemoizedSerializedSize = -1; private void initFields() { version_ = java.util.Collections.emptyList(); timestamp_ = java.util.Collections.emptyList(); changeset_ = java.util.Collections.emptyList(); uid_ = java.util.Collections.emptyList(); userSid_ = java.util.Collections.emptyList(); visible_ = java.util.Collections.emptyList(); } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized == 1) return true; if (isInitialized == 0) return false; memoizedIsInitialized = 1; return true; } public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { getSerializedSize(); if (getVersionList().size() > 0) { output.writeRawVarint32(10); output.writeRawVarint32(versionMemoizedSerializedSize); } for (int i = 0; i < version_.size(); i++) { output.writeInt32NoTag(version_.get(i)); } if (getTimestampList().size() > 0) { output.writeRawVarint32(18); output.writeRawVarint32(timestampMemoizedSerializedSize); } for (int i = 0; i < timestamp_.size(); i++) { output.writeSInt64NoTag(timestamp_.get(i)); } if (getChangesetList().size() > 0) { output.writeRawVarint32(26); output.writeRawVarint32(changesetMemoizedSerializedSize); } for (int i = 0; i < changeset_.size(); i++) { output.writeSInt64NoTag(changeset_.get(i)); } if (getUidList().size() > 0) { output.writeRawVarint32(34); output.writeRawVarint32(uidMemoizedSerializedSize); } for (int i = 0; i < uid_.size(); i++) { output.writeSInt32NoTag(uid_.get(i)); } if (getUserSidList().size() > 0) { output.writeRawVarint32(42); output.writeRawVarint32(userSidMemoizedSerializedSize); } for (int i = 0; i < userSid_.size(); i++) { output.writeSInt32NoTag(userSid_.get(i)); } if (getVisibleList().size() > 0) { output.writeRawVarint32(50); output.writeRawVarint32(visibleMemoizedSerializedSize); } for (int i = 0; i < visible_.size(); i++) { output.writeBoolNoTag(visible_.get(i)); } output.writeRawBytes(unknownFields); } private int memoizedSerializedSize = -1; public int getSerializedSize() { int size = memoizedSerializedSize; if (size != -1) return size; size = 0; { int dataSize = 0; for (int i = 0; i < version_.size(); i++) { dataSize += com.google.protobuf.CodedOutputStream .computeInt32SizeNoTag(version_.get(i)); } size += dataSize; if (!getVersionList().isEmpty()) { size += 1; size += com.google.protobuf.CodedOutputStream .computeInt32SizeNoTag(dataSize); } versionMemoizedSerializedSize = dataSize; } { int dataSize = 0; for (int i = 0; i < timestamp_.size(); i++) { dataSize += com.google.protobuf.CodedOutputStream .computeSInt64SizeNoTag(timestamp_.get(i)); } size += dataSize; if (!getTimestampList().isEmpty()) { size += 1; size += com.google.protobuf.CodedOutputStream .computeInt32SizeNoTag(dataSize); } timestampMemoizedSerializedSize = dataSize; } { int dataSize = 0; for (int i = 0; i < changeset_.size(); i++) { dataSize += com.google.protobuf.CodedOutputStream .computeSInt64SizeNoTag(changeset_.get(i)); } size += dataSize; if (!getChangesetList().isEmpty()) { size += 1; size += com.google.protobuf.CodedOutputStream .computeInt32SizeNoTag(dataSize); } changesetMemoizedSerializedSize = dataSize; } { int dataSize = 0; for (int i = 0; i < uid_.size(); i++) { dataSize += com.google.protobuf.CodedOutputStream .computeSInt32SizeNoTag(uid_.get(i)); } size += dataSize; if (!getUidList().isEmpty()) { size += 1; size += com.google.protobuf.CodedOutputStream .computeInt32SizeNoTag(dataSize); } uidMemoizedSerializedSize = dataSize; } { int dataSize = 0; for (int i = 0; i < userSid_.size(); i++) { dataSize += com.google.protobuf.CodedOutputStream .computeSInt32SizeNoTag(userSid_.get(i)); } size += dataSize; if (!getUserSidList().isEmpty()) { size += 1; size += com.google.protobuf.CodedOutputStream .computeInt32SizeNoTag(dataSize); } userSidMemoizedSerializedSize = dataSize; } { int dataSize = 0; dataSize = 1 * getVisibleList().size(); size += dataSize; if (!getVisibleList().isEmpty()) { size += 1; size += com.google.protobuf.CodedOutputStream .computeInt32SizeNoTag(dataSize); } visibleMemoizedSerializedSize = dataSize; } size += unknownFields.size(); memoizedSerializedSize = size; return size; } private static final long serialVersionUID = 0L; @java.lang.Override protected java.lang.Object writeReplace() throws java.io.ObjectStreamException { return super.writeReplace(); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo parseFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseDelimitedFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseDelimitedFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static Builder newBuilder() { return Builder.create(); } public Builder newBuilderForType() { return newBuilder(); } public static Builder newBuilder(org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo prototype) { return newBuilder().mergeFrom(prototype); } public Builder toBuilder() { return newBuilder(this); } /** * Protobuf type {@code OSMPBF.DenseInfo} * *
     ** Optional metadata that may be included into each primitive. Special dense format used in DenseNodes. 
     * 
*/ public static final class Builder extends com.google.protobuf.GeneratedMessageLite.Builder< org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo, Builder> implements // @@protoc_insertion_point(builder_implements:OSMPBF.DenseInfo) org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfoOrBuilder { // Construct using org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo.newBuilder() private Builder() { maybeForceBuilderInitialization(); } private void maybeForceBuilderInitialization() { } private static Builder create() { return new Builder(); } public Builder clear() { super.clear(); version_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000001); timestamp_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000002); changeset_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000004); uid_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000008); userSid_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000010); visible_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000020); return this; } public Builder clone() { return create().mergeFrom(buildPartial()); } public org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo getDefaultInstanceForType() { return org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo.getDefaultInstance(); } public org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo build() { org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } public org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo buildPartial() { org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo result = new org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo(this); int from_bitField0_ = bitField0_; if (((bitField0_ & 0x00000001) == 0x00000001)) { version_ = java.util.Collections.unmodifiableList(version_); bitField0_ = (bitField0_ & ~0x00000001); } result.version_ = version_; if (((bitField0_ & 0x00000002) == 0x00000002)) { timestamp_ = java.util.Collections.unmodifiableList(timestamp_); bitField0_ = (bitField0_ & ~0x00000002); } result.timestamp_ = timestamp_; if (((bitField0_ & 0x00000004) == 0x00000004)) { changeset_ = java.util.Collections.unmodifiableList(changeset_); bitField0_ = (bitField0_ & ~0x00000004); } result.changeset_ = changeset_; if (((bitField0_ & 0x00000008) == 0x00000008)) { uid_ = java.util.Collections.unmodifiableList(uid_); bitField0_ = (bitField0_ & ~0x00000008); } result.uid_ = uid_; if (((bitField0_ & 0x00000010) == 0x00000010)) { userSid_ = java.util.Collections.unmodifiableList(userSid_); bitField0_ = (bitField0_ & ~0x00000010); } result.userSid_ = userSid_; if (((bitField0_ & 0x00000020) == 0x00000020)) { visible_ = java.util.Collections.unmodifiableList(visible_); bitField0_ = (bitField0_ & ~0x00000020); } result.visible_ = visible_; return result; } public Builder mergeFrom(org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo other) { if (other == org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo.getDefaultInstance()) return this; if (!other.version_.isEmpty()) { if (version_.isEmpty()) { version_ = other.version_; bitField0_ = (bitField0_ & ~0x00000001); } else { ensureVersionIsMutable(); version_.addAll(other.version_); } } if (!other.timestamp_.isEmpty()) { if (timestamp_.isEmpty()) { timestamp_ = other.timestamp_; bitField0_ = (bitField0_ & ~0x00000002); } else { ensureTimestampIsMutable(); timestamp_.addAll(other.timestamp_); } } if (!other.changeset_.isEmpty()) { if (changeset_.isEmpty()) { changeset_ = other.changeset_; bitField0_ = (bitField0_ & ~0x00000004); } else { ensureChangesetIsMutable(); changeset_.addAll(other.changeset_); } } if (!other.uid_.isEmpty()) { if (uid_.isEmpty()) { uid_ = other.uid_; bitField0_ = (bitField0_ & ~0x00000008); } else { ensureUidIsMutable(); uid_.addAll(other.uid_); } } if (!other.userSid_.isEmpty()) { if (userSid_.isEmpty()) { userSid_ = other.userSid_; bitField0_ = (bitField0_ & ~0x00000010); } else { ensureUserSidIsMutable(); userSid_.addAll(other.userSid_); } } if (!other.visible_.isEmpty()) { if (visible_.isEmpty()) { visible_ = other.visible_; bitField0_ = (bitField0_ & ~0x00000020); } else { ensureVisibleIsMutable(); visible_.addAll(other.visible_); } } setUnknownFields( getUnknownFields().concat(other.unknownFields)); return this; } public final boolean isInitialized() { return true; } public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { parsedMessage = (org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo) e.getUnfinishedMessage(); throw e; } finally { if (parsedMessage != null) { mergeFrom(parsedMessage); } } return this; } private int bitField0_; private java.util.List version_ = java.util.Collections.emptyList(); private void ensureVersionIsMutable() { if (!((bitField0_ & 0x00000001) == 0x00000001)) { version_ = new java.util.ArrayList(version_); bitField0_ |= 0x00000001; } } /** * repeated int32 version = 1 [packed = true]; */ public java.util.List getVersionList() { return java.util.Collections.unmodifiableList(version_); } /** * repeated int32 version = 1 [packed = true]; */ public int getVersionCount() { return version_.size(); } /** * repeated int32 version = 1 [packed = true]; */ public int getVersion(int index) { return version_.get(index); } /** * repeated int32 version = 1 [packed = true]; */ public Builder setVersion( int index, int value) { ensureVersionIsMutable(); version_.set(index, value); return this; } /** * repeated int32 version = 1 [packed = true]; */ public Builder addVersion(int value) { ensureVersionIsMutable(); version_.add(value); return this; } /** * repeated int32 version = 1 [packed = true]; */ public Builder addAllVersion( java.lang.Iterable values) { ensureVersionIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, version_); return this; } /** * repeated int32 version = 1 [packed = true]; */ public Builder clearVersion() { version_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000001); return this; } private java.util.List timestamp_ = java.util.Collections.emptyList(); private void ensureTimestampIsMutable() { if (!((bitField0_ & 0x00000002) == 0x00000002)) { timestamp_ = new java.util.ArrayList(timestamp_); bitField0_ |= 0x00000002; } } /** * repeated sint64 timestamp = 2 [packed = true]; * *
       * DELTA coded
       * 
*/ public java.util.List getTimestampList() { return java.util.Collections.unmodifiableList(timestamp_); } /** * repeated sint64 timestamp = 2 [packed = true]; * *
       * DELTA coded
       * 
*/ public int getTimestampCount() { return timestamp_.size(); } /** * repeated sint64 timestamp = 2 [packed = true]; * *
       * DELTA coded
       * 
*/ public long getTimestamp(int index) { return timestamp_.get(index); } /** * repeated sint64 timestamp = 2 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder setTimestamp( int index, long value) { ensureTimestampIsMutable(); timestamp_.set(index, value); return this; } /** * repeated sint64 timestamp = 2 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder addTimestamp(long value) { ensureTimestampIsMutable(); timestamp_.add(value); return this; } /** * repeated sint64 timestamp = 2 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder addAllTimestamp( java.lang.Iterable values) { ensureTimestampIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, timestamp_); return this; } /** * repeated sint64 timestamp = 2 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder clearTimestamp() { timestamp_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000002); return this; } private java.util.List changeset_ = java.util.Collections.emptyList(); private void ensureChangesetIsMutable() { if (!((bitField0_ & 0x00000004) == 0x00000004)) { changeset_ = new java.util.ArrayList(changeset_); bitField0_ |= 0x00000004; } } /** * repeated sint64 changeset = 3 [packed = true]; * *
       * DELTA coded
       * 
*/ public java.util.List getChangesetList() { return java.util.Collections.unmodifiableList(changeset_); } /** * repeated sint64 changeset = 3 [packed = true]; * *
       * DELTA coded
       * 
*/ public int getChangesetCount() { return changeset_.size(); } /** * repeated sint64 changeset = 3 [packed = true]; * *
       * DELTA coded
       * 
*/ public long getChangeset(int index) { return changeset_.get(index); } /** * repeated sint64 changeset = 3 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder setChangeset( int index, long value) { ensureChangesetIsMutable(); changeset_.set(index, value); return this; } /** * repeated sint64 changeset = 3 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder addChangeset(long value) { ensureChangesetIsMutable(); changeset_.add(value); return this; } /** * repeated sint64 changeset = 3 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder addAllChangeset( java.lang.Iterable values) { ensureChangesetIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, changeset_); return this; } /** * repeated sint64 changeset = 3 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder clearChangeset() { changeset_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000004); return this; } private java.util.List uid_ = java.util.Collections.emptyList(); private void ensureUidIsMutable() { if (!((bitField0_ & 0x00000008) == 0x00000008)) { uid_ = new java.util.ArrayList(uid_); bitField0_ |= 0x00000008; } } /** * repeated sint32 uid = 4 [packed = true]; * *
       * DELTA coded
       * 
*/ public java.util.List getUidList() { return java.util.Collections.unmodifiableList(uid_); } /** * repeated sint32 uid = 4 [packed = true]; * *
       * DELTA coded
       * 
*/ public int getUidCount() { return uid_.size(); } /** * repeated sint32 uid = 4 [packed = true]; * *
       * DELTA coded
       * 
*/ public int getUid(int index) { return uid_.get(index); } /** * repeated sint32 uid = 4 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder setUid( int index, int value) { ensureUidIsMutable(); uid_.set(index, value); return this; } /** * repeated sint32 uid = 4 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder addUid(int value) { ensureUidIsMutable(); uid_.add(value); return this; } /** * repeated sint32 uid = 4 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder addAllUid( java.lang.Iterable values) { ensureUidIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, uid_); return this; } /** * repeated sint32 uid = 4 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder clearUid() { uid_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000008); return this; } private java.util.List userSid_ = java.util.Collections.emptyList(); private void ensureUserSidIsMutable() { if (!((bitField0_ & 0x00000010) == 0x00000010)) { userSid_ = new java.util.ArrayList(userSid_); bitField0_ |= 0x00000010; } } /** * repeated sint32 user_sid = 5 [packed = true]; * *
       * String IDs for usernames. DELTA coded
       * 
*/ public java.util.List getUserSidList() { return java.util.Collections.unmodifiableList(userSid_); } /** * repeated sint32 user_sid = 5 [packed = true]; * *
       * String IDs for usernames. DELTA coded
       * 
*/ public int getUserSidCount() { return userSid_.size(); } /** * repeated sint32 user_sid = 5 [packed = true]; * *
       * String IDs for usernames. DELTA coded
       * 
*/ public int getUserSid(int index) { return userSid_.get(index); } /** * repeated sint32 user_sid = 5 [packed = true]; * *
       * String IDs for usernames. DELTA coded
       * 
*/ public Builder setUserSid( int index, int value) { ensureUserSidIsMutable(); userSid_.set(index, value); return this; } /** * repeated sint32 user_sid = 5 [packed = true]; * *
       * String IDs for usernames. DELTA coded
       * 
*/ public Builder addUserSid(int value) { ensureUserSidIsMutable(); userSid_.add(value); return this; } /** * repeated sint32 user_sid = 5 [packed = true]; * *
       * String IDs for usernames. DELTA coded
       * 
*/ public Builder addAllUserSid( java.lang.Iterable values) { ensureUserSidIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, userSid_); return this; } /** * repeated sint32 user_sid = 5 [packed = true]; * *
       * String IDs for usernames. DELTA coded
       * 
*/ public Builder clearUserSid() { userSid_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000010); return this; } private java.util.List visible_ = java.util.Collections.emptyList(); private void ensureVisibleIsMutable() { if (!((bitField0_ & 0x00000020) == 0x00000020)) { visible_ = new java.util.ArrayList(visible_); bitField0_ |= 0x00000020; } } /** * repeated bool visible = 6 [packed = true]; * *
       * The visible flag is used to store history information. It indicates that
       * the current object version has been created by a delete operation on the
       * OSM API.
       * When a writer sets this flag, it MUST add a required_features tag with
       * value "HistoricalInformation" to the HeaderBlock.
       * If this flag is not available for some object it MUST be assumed to be
       * true if the file has the required_features tag "HistoricalInformation"
       * set.
       * 
*/ public java.util.List getVisibleList() { return java.util.Collections.unmodifiableList(visible_); } /** * repeated bool visible = 6 [packed = true]; * *
       * The visible flag is used to store history information. It indicates that
       * the current object version has been created by a delete operation on the
       * OSM API.
       * When a writer sets this flag, it MUST add a required_features tag with
       * value "HistoricalInformation" to the HeaderBlock.
       * If this flag is not available for some object it MUST be assumed to be
       * true if the file has the required_features tag "HistoricalInformation"
       * set.
       * 
*/ public int getVisibleCount() { return visible_.size(); } /** * repeated bool visible = 6 [packed = true]; * *
       * The visible flag is used to store history information. It indicates that
       * the current object version has been created by a delete operation on the
       * OSM API.
       * When a writer sets this flag, it MUST add a required_features tag with
       * value "HistoricalInformation" to the HeaderBlock.
       * If this flag is not available for some object it MUST be assumed to be
       * true if the file has the required_features tag "HistoricalInformation"
       * set.
       * 
*/ public boolean getVisible(int index) { return visible_.get(index); } /** * repeated bool visible = 6 [packed = true]; * *
       * The visible flag is used to store history information. It indicates that
       * the current object version has been created by a delete operation on the
       * OSM API.
       * When a writer sets this flag, it MUST add a required_features tag with
       * value "HistoricalInformation" to the HeaderBlock.
       * If this flag is not available for some object it MUST be assumed to be
       * true if the file has the required_features tag "HistoricalInformation"
       * set.
       * 
*/ public Builder setVisible( int index, boolean value) { ensureVisibleIsMutable(); visible_.set(index, value); return this; } /** * repeated bool visible = 6 [packed = true]; * *
       * The visible flag is used to store history information. It indicates that
       * the current object version has been created by a delete operation on the
       * OSM API.
       * When a writer sets this flag, it MUST add a required_features tag with
       * value "HistoricalInformation" to the HeaderBlock.
       * If this flag is not available for some object it MUST be assumed to be
       * true if the file has the required_features tag "HistoricalInformation"
       * set.
       * 
*/ public Builder addVisible(boolean value) { ensureVisibleIsMutable(); visible_.add(value); return this; } /** * repeated bool visible = 6 [packed = true]; * *
       * The visible flag is used to store history information. It indicates that
       * the current object version has been created by a delete operation on the
       * OSM API.
       * When a writer sets this flag, it MUST add a required_features tag with
       * value "HistoricalInformation" to the HeaderBlock.
       * If this flag is not available for some object it MUST be assumed to be
       * true if the file has the required_features tag "HistoricalInformation"
       * set.
       * 
*/ public Builder addAllVisible( java.lang.Iterable values) { ensureVisibleIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, visible_); return this; } /** * repeated bool visible = 6 [packed = true]; * *
       * The visible flag is used to store history information. It indicates that
       * the current object version has been created by a delete operation on the
       * OSM API.
       * When a writer sets this flag, it MUST add a required_features tag with
       * value "HistoricalInformation" to the HeaderBlock.
       * If this flag is not available for some object it MUST be assumed to be
       * true if the file has the required_features tag "HistoricalInformation"
       * set.
       * 
*/ public Builder clearVisible() { visible_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000020); return this; } // @@protoc_insertion_point(builder_scope:OSMPBF.DenseInfo) } static { defaultInstance = new DenseInfo(true); defaultInstance.initFields(); } // @@protoc_insertion_point(class_scope:OSMPBF.DenseInfo) } public interface ChangeSetOrBuilder extends // @@protoc_insertion_point(interface_extends:OSMPBF.ChangeSet) com.google.protobuf.MessageLiteOrBuilder { /** * required int64 id = 1; * *
     *   
     *   // Parallel arrays.
     *   repeated uint32 keys = 2 [packed = true]; // String IDs.
     *   repeated uint32 vals = 3 [packed = true]; // String IDs.
     *   optional Info info = 4;
     * 
*/ boolean hasId(); /** * required int64 id = 1; * *
     *   
     *   // Parallel arrays.
     *   repeated uint32 keys = 2 [packed = true]; // String IDs.
     *   repeated uint32 vals = 3 [packed = true]; // String IDs.
     *   optional Info info = 4;
     * 
*/ long getId(); } /** * Protobuf type {@code OSMPBF.ChangeSet} * *
   * THIS IS STUB DESIGN FOR CHANGESETS. NOT USED RIGHT NOW.
   * TODO:    REMOVE THIS?
   * 
*/ public static final class ChangeSet extends com.google.protobuf.GeneratedMessageLite implements // @@protoc_insertion_point(message_implements:OSMPBF.ChangeSet) ChangeSetOrBuilder { // Use ChangeSet.newBuilder() to construct. private ChangeSet(com.google.protobuf.GeneratedMessageLite.Builder builder) { super(builder); this.unknownFields = builder.getUnknownFields(); } private ChangeSet(boolean noInit) { this.unknownFields = com.google.protobuf.ByteString.EMPTY;} private static final ChangeSet defaultInstance; public static ChangeSet getDefaultInstance() { return defaultInstance; } public ChangeSet getDefaultInstanceForType() { return defaultInstance; } private final com.google.protobuf.ByteString unknownFields; private ChangeSet( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { initFields(); int mutable_bitField0_ = 0; com.google.protobuf.ByteString.Output unknownFieldsOutput = com.google.protobuf.ByteString.newOutput(); com.google.protobuf.CodedOutputStream unknownFieldsCodedOutput = com.google.protobuf.CodedOutputStream.newInstance( unknownFieldsOutput); try { boolean done = false; while (!done) { int tag = input.readTag(); switch (tag) { case 0: done = true; break; default: { if (!parseUnknownField(input, unknownFieldsCodedOutput, extensionRegistry, tag)) { done = true; } break; } case 8: { bitField0_ |= 0x00000001; id_ = input.readInt64(); break; } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { throw e.setUnfinishedMessage(this); } catch (java.io.IOException e) { throw new com.google.protobuf.InvalidProtocolBufferException( e.getMessage()).setUnfinishedMessage(this); } finally { try { unknownFieldsCodedOutput.flush(); } catch (java.io.IOException e) { // Should not happen } finally { unknownFields = unknownFieldsOutput.toByteString(); } makeExtensionsImmutable(); } } public static com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { public ChangeSet parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return new ChangeSet(input, extensionRegistry); } }; @java.lang.Override public com.google.protobuf.Parser getParserForType() { return PARSER; } private int bitField0_; public static final int ID_FIELD_NUMBER = 1; private long id_; /** * required int64 id = 1; * *
     *   
     *   // Parallel arrays.
     *   repeated uint32 keys = 2 [packed = true]; // String IDs.
     *   repeated uint32 vals = 3 [packed = true]; // String IDs.
     *   optional Info info = 4;
     * 
*/ public boolean hasId() { return ((bitField0_ & 0x00000001) == 0x00000001); } /** * required int64 id = 1; * *
     *   
     *   // Parallel arrays.
     *   repeated uint32 keys = 2 [packed = true]; // String IDs.
     *   repeated uint32 vals = 3 [packed = true]; // String IDs.
     *   optional Info info = 4;
     * 
*/ public long getId() { return id_; } private void initFields() { id_ = 0L; } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized == 1) return true; if (isInitialized == 0) return false; if (!hasId()) { memoizedIsInitialized = 0; return false; } memoizedIsInitialized = 1; return true; } public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { getSerializedSize(); if (((bitField0_ & 0x00000001) == 0x00000001)) { output.writeInt64(1, id_); } output.writeRawBytes(unknownFields); } private int memoizedSerializedSize = -1; public int getSerializedSize() { int size = memoizedSerializedSize; if (size != -1) return size; size = 0; if (((bitField0_ & 0x00000001) == 0x00000001)) { size += com.google.protobuf.CodedOutputStream .computeInt64Size(1, id_); } size += unknownFields.size(); memoizedSerializedSize = size; return size; } private static final long serialVersionUID = 0L; @java.lang.Override protected java.lang.Object writeReplace() throws java.io.ObjectStreamException { return super.writeReplace(); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet parseFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseDelimitedFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseDelimitedFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static Builder newBuilder() { return Builder.create(); } public Builder newBuilderForType() { return newBuilder(); } public static Builder newBuilder(org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet prototype) { return newBuilder().mergeFrom(prototype); } public Builder toBuilder() { return newBuilder(this); } /** * Protobuf type {@code OSMPBF.ChangeSet} * *
     * THIS IS STUB DESIGN FOR CHANGESETS. NOT USED RIGHT NOW.
     * TODO:    REMOVE THIS?
     * 
*/ public static final class Builder extends com.google.protobuf.GeneratedMessageLite.Builder< org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet, Builder> implements // @@protoc_insertion_point(builder_implements:OSMPBF.ChangeSet) org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSetOrBuilder { // Construct using org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet.newBuilder() private Builder() { maybeForceBuilderInitialization(); } private void maybeForceBuilderInitialization() { } private static Builder create() { return new Builder(); } public Builder clear() { super.clear(); id_ = 0L; bitField0_ = (bitField0_ & ~0x00000001); return this; } public Builder clone() { return create().mergeFrom(buildPartial()); } public org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet getDefaultInstanceForType() { return org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet.getDefaultInstance(); } public org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet build() { org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } public org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet buildPartial() { org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet result = new org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) == 0x00000001)) { to_bitField0_ |= 0x00000001; } result.id_ = id_; result.bitField0_ = to_bitField0_; return result; } public Builder mergeFrom(org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet other) { if (other == org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet.getDefaultInstance()) return this; if (other.hasId()) { setId(other.getId()); } setUnknownFields( getUnknownFields().concat(other.unknownFields)); return this; } public final boolean isInitialized() { if (!hasId()) { return false; } return true; } public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { parsedMessage = (org.openstreetmap.osmosis.osmbinary.Osmformat.ChangeSet) e.getUnfinishedMessage(); throw e; } finally { if (parsedMessage != null) { mergeFrom(parsedMessage); } } return this; } private int bitField0_; private long id_ ; /** * required int64 id = 1; * *
       *   
       *   // Parallel arrays.
       *   repeated uint32 keys = 2 [packed = true]; // String IDs.
       *   repeated uint32 vals = 3 [packed = true]; // String IDs.
       *   optional Info info = 4;
       * 
*/ public boolean hasId() { return ((bitField0_ & 0x00000001) == 0x00000001); } /** * required int64 id = 1; * *
       *   
       *   // Parallel arrays.
       *   repeated uint32 keys = 2 [packed = true]; // String IDs.
       *   repeated uint32 vals = 3 [packed = true]; // String IDs.
       *   optional Info info = 4;
       * 
*/ public long getId() { return id_; } /** * required int64 id = 1; * *
       *   
       *   // Parallel arrays.
       *   repeated uint32 keys = 2 [packed = true]; // String IDs.
       *   repeated uint32 vals = 3 [packed = true]; // String IDs.
       *   optional Info info = 4;
       * 
*/ public Builder setId(long value) { bitField0_ |= 0x00000001; id_ = value; return this; } /** * required int64 id = 1; * *
       *   
       *   // Parallel arrays.
       *   repeated uint32 keys = 2 [packed = true]; // String IDs.
       *   repeated uint32 vals = 3 [packed = true]; // String IDs.
       *   optional Info info = 4;
       * 
*/ public Builder clearId() { bitField0_ = (bitField0_ & ~0x00000001); id_ = 0L; return this; } // @@protoc_insertion_point(builder_scope:OSMPBF.ChangeSet) } static { defaultInstance = new ChangeSet(true); defaultInstance.initFields(); } // @@protoc_insertion_point(class_scope:OSMPBF.ChangeSet) } public interface NodeOrBuilder extends // @@protoc_insertion_point(interface_extends:OSMPBF.Node) com.google.protobuf.MessageLiteOrBuilder { /** * required sint64 id = 1; */ boolean hasId(); /** * required sint64 id = 1; */ long getId(); /** * repeated uint32 keys = 2 [packed = true]; * *
     * Parallel arrays.
     * 
*/ java.util.List getKeysList(); /** * repeated uint32 keys = 2 [packed = true]; * *
     * Parallel arrays.
     * 
*/ int getKeysCount(); /** * repeated uint32 keys = 2 [packed = true]; * *
     * Parallel arrays.
     * 
*/ int getKeys(int index); /** * repeated uint32 vals = 3 [packed = true]; * *
     * String IDs.
     * 
*/ java.util.List getValsList(); /** * repeated uint32 vals = 3 [packed = true]; * *
     * String IDs.
     * 
*/ int getValsCount(); /** * repeated uint32 vals = 3 [packed = true]; * *
     * String IDs.
     * 
*/ int getVals(int index); /** * optional .OSMPBF.Info info = 4; * *
     * May be omitted in omitmeta
     * 
*/ boolean hasInfo(); /** * optional .OSMPBF.Info info = 4; * *
     * May be omitted in omitmeta
     * 
*/ org.openstreetmap.osmosis.osmbinary.Osmformat.Info getInfo(); /** * required sint64 lat = 8; */ boolean hasLat(); /** * required sint64 lat = 8; */ long getLat(); /** * required sint64 lon = 9; */ boolean hasLon(); /** * required sint64 lon = 9; */ long getLon(); } /** * Protobuf type {@code OSMPBF.Node} */ public static final class Node extends com.google.protobuf.GeneratedMessageLite implements // @@protoc_insertion_point(message_implements:OSMPBF.Node) NodeOrBuilder { // Use Node.newBuilder() to construct. private Node(com.google.protobuf.GeneratedMessageLite.Builder builder) { super(builder); this.unknownFields = builder.getUnknownFields(); } private Node(boolean noInit) { this.unknownFields = com.google.protobuf.ByteString.EMPTY;} private static final Node defaultInstance; public static Node getDefaultInstance() { return defaultInstance; } public Node getDefaultInstanceForType() { return defaultInstance; } private final com.google.protobuf.ByteString unknownFields; private Node( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { initFields(); int mutable_bitField0_ = 0; com.google.protobuf.ByteString.Output unknownFieldsOutput = com.google.protobuf.ByteString.newOutput(); com.google.protobuf.CodedOutputStream unknownFieldsCodedOutput = com.google.protobuf.CodedOutputStream.newInstance( unknownFieldsOutput); try { boolean done = false; while (!done) { int tag = input.readTag(); switch (tag) { case 0: done = true; break; default: { if (!parseUnknownField(input, unknownFieldsCodedOutput, extensionRegistry, tag)) { done = true; } break; } case 8: { bitField0_ |= 0x00000001; id_ = input.readSInt64(); break; } case 16: { if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) { keys_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000002; } keys_.add(input.readUInt32()); break; } case 18: { int length = input.readRawVarint32(); int limit = input.pushLimit(length); if (!((mutable_bitField0_ & 0x00000002) == 0x00000002) && input.getBytesUntilLimit() > 0) { keys_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000002; } while (input.getBytesUntilLimit() > 0) { keys_.add(input.readUInt32()); } input.popLimit(limit); break; } case 24: { if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) { vals_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000004; } vals_.add(input.readUInt32()); break; } case 26: { int length = input.readRawVarint32(); int limit = input.pushLimit(length); if (!((mutable_bitField0_ & 0x00000004) == 0x00000004) && input.getBytesUntilLimit() > 0) { vals_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000004; } while (input.getBytesUntilLimit() > 0) { vals_.add(input.readUInt32()); } input.popLimit(limit); break; } case 34: { org.openstreetmap.osmosis.osmbinary.Osmformat.Info.Builder subBuilder = null; if (((bitField0_ & 0x00000002) == 0x00000002)) { subBuilder = info_.toBuilder(); } info_ = input.readMessage(org.openstreetmap.osmosis.osmbinary.Osmformat.Info.PARSER, extensionRegistry); if (subBuilder != null) { subBuilder.mergeFrom(info_); info_ = subBuilder.buildPartial(); } bitField0_ |= 0x00000002; break; } case 64: { bitField0_ |= 0x00000004; lat_ = input.readSInt64(); break; } case 72: { bitField0_ |= 0x00000008; lon_ = input.readSInt64(); break; } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { throw e.setUnfinishedMessage(this); } catch (java.io.IOException e) { throw new com.google.protobuf.InvalidProtocolBufferException( e.getMessage()).setUnfinishedMessage(this); } finally { if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) { keys_ = java.util.Collections.unmodifiableList(keys_); } if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) { vals_ = java.util.Collections.unmodifiableList(vals_); } try { unknownFieldsCodedOutput.flush(); } catch (java.io.IOException e) { // Should not happen } finally { unknownFields = unknownFieldsOutput.toByteString(); } makeExtensionsImmutable(); } } public static com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { public Node parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return new Node(input, extensionRegistry); } }; @java.lang.Override public com.google.protobuf.Parser getParserForType() { return PARSER; } private int bitField0_; public static final int ID_FIELD_NUMBER = 1; private long id_; /** * required sint64 id = 1; */ public boolean hasId() { return ((bitField0_ & 0x00000001) == 0x00000001); } /** * required sint64 id = 1; */ public long getId() { return id_; } public static final int KEYS_FIELD_NUMBER = 2; private java.util.List keys_; /** * repeated uint32 keys = 2 [packed = true]; * *
     * Parallel arrays.
     * 
*/ public java.util.List getKeysList() { return keys_; } /** * repeated uint32 keys = 2 [packed = true]; * *
     * Parallel arrays.
     * 
*/ public int getKeysCount() { return keys_.size(); } /** * repeated uint32 keys = 2 [packed = true]; * *
     * Parallel arrays.
     * 
*/ public int getKeys(int index) { return keys_.get(index); } private int keysMemoizedSerializedSize = -1; public static final int VALS_FIELD_NUMBER = 3; private java.util.List vals_; /** * repeated uint32 vals = 3 [packed = true]; * *
     * String IDs.
     * 
*/ public java.util.List getValsList() { return vals_; } /** * repeated uint32 vals = 3 [packed = true]; * *
     * String IDs.
     * 
*/ public int getValsCount() { return vals_.size(); } /** * repeated uint32 vals = 3 [packed = true]; * *
     * String IDs.
     * 
*/ public int getVals(int index) { return vals_.get(index); } private int valsMemoizedSerializedSize = -1; public static final int INFO_FIELD_NUMBER = 4; private org.openstreetmap.osmosis.osmbinary.Osmformat.Info info_; /** * optional .OSMPBF.Info info = 4; * *
     * May be omitted in omitmeta
     * 
*/ public boolean hasInfo() { return ((bitField0_ & 0x00000002) == 0x00000002); } /** * optional .OSMPBF.Info info = 4; * *
     * May be omitted in omitmeta
     * 
*/ public org.openstreetmap.osmosis.osmbinary.Osmformat.Info getInfo() { return info_; } public static final int LAT_FIELD_NUMBER = 8; private long lat_; /** * required sint64 lat = 8; */ public boolean hasLat() { return ((bitField0_ & 0x00000004) == 0x00000004); } /** * required sint64 lat = 8; */ public long getLat() { return lat_; } public static final int LON_FIELD_NUMBER = 9; private long lon_; /** * required sint64 lon = 9; */ public boolean hasLon() { return ((bitField0_ & 0x00000008) == 0x00000008); } /** * required sint64 lon = 9; */ public long getLon() { return lon_; } private void initFields() { id_ = 0L; keys_ = java.util.Collections.emptyList(); vals_ = java.util.Collections.emptyList(); info_ = org.openstreetmap.osmosis.osmbinary.Osmformat.Info.getDefaultInstance(); lat_ = 0L; lon_ = 0L; } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized == 1) return true; if (isInitialized == 0) return false; if (!hasId()) { memoizedIsInitialized = 0; return false; } if (!hasLat()) { memoizedIsInitialized = 0; return false; } if (!hasLon()) { memoizedIsInitialized = 0; return false; } memoizedIsInitialized = 1; return true; } public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { getSerializedSize(); if (((bitField0_ & 0x00000001) == 0x00000001)) { output.writeSInt64(1, id_); } if (getKeysList().size() > 0) { output.writeRawVarint32(18); output.writeRawVarint32(keysMemoizedSerializedSize); } for (int i = 0; i < keys_.size(); i++) { output.writeUInt32NoTag(keys_.get(i)); } if (getValsList().size() > 0) { output.writeRawVarint32(26); output.writeRawVarint32(valsMemoizedSerializedSize); } for (int i = 0; i < vals_.size(); i++) { output.writeUInt32NoTag(vals_.get(i)); } if (((bitField0_ & 0x00000002) == 0x00000002)) { output.writeMessage(4, info_); } if (((bitField0_ & 0x00000004) == 0x00000004)) { output.writeSInt64(8, lat_); } if (((bitField0_ & 0x00000008) == 0x00000008)) { output.writeSInt64(9, lon_); } output.writeRawBytes(unknownFields); } private int memoizedSerializedSize = -1; public int getSerializedSize() { int size = memoizedSerializedSize; if (size != -1) return size; size = 0; if (((bitField0_ & 0x00000001) == 0x00000001)) { size += com.google.protobuf.CodedOutputStream .computeSInt64Size(1, id_); } { int dataSize = 0; for (int i = 0; i < keys_.size(); i++) { dataSize += com.google.protobuf.CodedOutputStream .computeUInt32SizeNoTag(keys_.get(i)); } size += dataSize; if (!getKeysList().isEmpty()) { size += 1; size += com.google.protobuf.CodedOutputStream .computeInt32SizeNoTag(dataSize); } keysMemoizedSerializedSize = dataSize; } { int dataSize = 0; for (int i = 0; i < vals_.size(); i++) { dataSize += com.google.protobuf.CodedOutputStream .computeUInt32SizeNoTag(vals_.get(i)); } size += dataSize; if (!getValsList().isEmpty()) { size += 1; size += com.google.protobuf.CodedOutputStream .computeInt32SizeNoTag(dataSize); } valsMemoizedSerializedSize = dataSize; } if (((bitField0_ & 0x00000002) == 0x00000002)) { size += com.google.protobuf.CodedOutputStream .computeMessageSize(4, info_); } if (((bitField0_ & 0x00000004) == 0x00000004)) { size += com.google.protobuf.CodedOutputStream .computeSInt64Size(8, lat_); } if (((bitField0_ & 0x00000008) == 0x00000008)) { size += com.google.protobuf.CodedOutputStream .computeSInt64Size(9, lon_); } size += unknownFields.size(); memoizedSerializedSize = size; return size; } private static final long serialVersionUID = 0L; @java.lang.Override protected java.lang.Object writeReplace() throws java.io.ObjectStreamException { return super.writeReplace(); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Node parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Node parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Node parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Node parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Node parseFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Node parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Node parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseDelimitedFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Node parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseDelimitedFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Node parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Node parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static Builder newBuilder() { return Builder.create(); } public Builder newBuilderForType() { return newBuilder(); } public static Builder newBuilder(org.openstreetmap.osmosis.osmbinary.Osmformat.Node prototype) { return newBuilder().mergeFrom(prototype); } public Builder toBuilder() { return newBuilder(this); } /** * Protobuf type {@code OSMPBF.Node} */ public static final class Builder extends com.google.protobuf.GeneratedMessageLite.Builder< org.openstreetmap.osmosis.osmbinary.Osmformat.Node, Builder> implements // @@protoc_insertion_point(builder_implements:OSMPBF.Node) org.openstreetmap.osmosis.osmbinary.Osmformat.NodeOrBuilder { // Construct using org.openstreetmap.osmosis.osmbinary.Osmformat.Node.newBuilder() private Builder() { maybeForceBuilderInitialization(); } private void maybeForceBuilderInitialization() { } private static Builder create() { return new Builder(); } public Builder clear() { super.clear(); id_ = 0L; bitField0_ = (bitField0_ & ~0x00000001); keys_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000002); vals_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000004); info_ = org.openstreetmap.osmosis.osmbinary.Osmformat.Info.getDefaultInstance(); bitField0_ = (bitField0_ & ~0x00000008); lat_ = 0L; bitField0_ = (bitField0_ & ~0x00000010); lon_ = 0L; bitField0_ = (bitField0_ & ~0x00000020); return this; } public Builder clone() { return create().mergeFrom(buildPartial()); } public org.openstreetmap.osmosis.osmbinary.Osmformat.Node getDefaultInstanceForType() { return org.openstreetmap.osmosis.osmbinary.Osmformat.Node.getDefaultInstance(); } public org.openstreetmap.osmosis.osmbinary.Osmformat.Node build() { org.openstreetmap.osmosis.osmbinary.Osmformat.Node result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } public org.openstreetmap.osmosis.osmbinary.Osmformat.Node buildPartial() { org.openstreetmap.osmosis.osmbinary.Osmformat.Node result = new org.openstreetmap.osmosis.osmbinary.Osmformat.Node(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) == 0x00000001)) { to_bitField0_ |= 0x00000001; } result.id_ = id_; if (((bitField0_ & 0x00000002) == 0x00000002)) { keys_ = java.util.Collections.unmodifiableList(keys_); bitField0_ = (bitField0_ & ~0x00000002); } result.keys_ = keys_; if (((bitField0_ & 0x00000004) == 0x00000004)) { vals_ = java.util.Collections.unmodifiableList(vals_); bitField0_ = (bitField0_ & ~0x00000004); } result.vals_ = vals_; if (((from_bitField0_ & 0x00000008) == 0x00000008)) { to_bitField0_ |= 0x00000002; } result.info_ = info_; if (((from_bitField0_ & 0x00000010) == 0x00000010)) { to_bitField0_ |= 0x00000004; } result.lat_ = lat_; if (((from_bitField0_ & 0x00000020) == 0x00000020)) { to_bitField0_ |= 0x00000008; } result.lon_ = lon_; result.bitField0_ = to_bitField0_; return result; } public Builder mergeFrom(org.openstreetmap.osmosis.osmbinary.Osmformat.Node other) { if (other == org.openstreetmap.osmosis.osmbinary.Osmformat.Node.getDefaultInstance()) return this; if (other.hasId()) { setId(other.getId()); } if (!other.keys_.isEmpty()) { if (keys_.isEmpty()) { keys_ = other.keys_; bitField0_ = (bitField0_ & ~0x00000002); } else { ensureKeysIsMutable(); keys_.addAll(other.keys_); } } if (!other.vals_.isEmpty()) { if (vals_.isEmpty()) { vals_ = other.vals_; bitField0_ = (bitField0_ & ~0x00000004); } else { ensureValsIsMutable(); vals_.addAll(other.vals_); } } if (other.hasInfo()) { mergeInfo(other.getInfo()); } if (other.hasLat()) { setLat(other.getLat()); } if (other.hasLon()) { setLon(other.getLon()); } setUnknownFields( getUnknownFields().concat(other.unknownFields)); return this; } public final boolean isInitialized() { if (!hasId()) { return false; } if (!hasLat()) { return false; } if (!hasLon()) { return false; } return true; } public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { org.openstreetmap.osmosis.osmbinary.Osmformat.Node parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { parsedMessage = (org.openstreetmap.osmosis.osmbinary.Osmformat.Node) e.getUnfinishedMessage(); throw e; } finally { if (parsedMessage != null) { mergeFrom(parsedMessage); } } return this; } private int bitField0_; private long id_ ; /** * required sint64 id = 1; */ public boolean hasId() { return ((bitField0_ & 0x00000001) == 0x00000001); } /** * required sint64 id = 1; */ public long getId() { return id_; } /** * required sint64 id = 1; */ public Builder setId(long value) { bitField0_ |= 0x00000001; id_ = value; return this; } /** * required sint64 id = 1; */ public Builder clearId() { bitField0_ = (bitField0_ & ~0x00000001); id_ = 0L; return this; } private java.util.List keys_ = java.util.Collections.emptyList(); private void ensureKeysIsMutable() { if (!((bitField0_ & 0x00000002) == 0x00000002)) { keys_ = new java.util.ArrayList(keys_); bitField0_ |= 0x00000002; } } /** * repeated uint32 keys = 2 [packed = true]; * *
       * Parallel arrays.
       * 
*/ public java.util.List getKeysList() { return java.util.Collections.unmodifiableList(keys_); } /** * repeated uint32 keys = 2 [packed = true]; * *
       * Parallel arrays.
       * 
*/ public int getKeysCount() { return keys_.size(); } /** * repeated uint32 keys = 2 [packed = true]; * *
       * Parallel arrays.
       * 
*/ public int getKeys(int index) { return keys_.get(index); } /** * repeated uint32 keys = 2 [packed = true]; * *
       * Parallel arrays.
       * 
*/ public Builder setKeys( int index, int value) { ensureKeysIsMutable(); keys_.set(index, value); return this; } /** * repeated uint32 keys = 2 [packed = true]; * *
       * Parallel arrays.
       * 
*/ public Builder addKeys(int value) { ensureKeysIsMutable(); keys_.add(value); return this; } /** * repeated uint32 keys = 2 [packed = true]; * *
       * Parallel arrays.
       * 
*/ public Builder addAllKeys( java.lang.Iterable values) { ensureKeysIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, keys_); return this; } /** * repeated uint32 keys = 2 [packed = true]; * *
       * Parallel arrays.
       * 
*/ public Builder clearKeys() { keys_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000002); return this; } private java.util.List vals_ = java.util.Collections.emptyList(); private void ensureValsIsMutable() { if (!((bitField0_ & 0x00000004) == 0x00000004)) { vals_ = new java.util.ArrayList(vals_); bitField0_ |= 0x00000004; } } /** * repeated uint32 vals = 3 [packed = true]; * *
       * String IDs.
       * 
*/ public java.util.List getValsList() { return java.util.Collections.unmodifiableList(vals_); } /** * repeated uint32 vals = 3 [packed = true]; * *
       * String IDs.
       * 
*/ public int getValsCount() { return vals_.size(); } /** * repeated uint32 vals = 3 [packed = true]; * *
       * String IDs.
       * 
*/ public int getVals(int index) { return vals_.get(index); } /** * repeated uint32 vals = 3 [packed = true]; * *
       * String IDs.
       * 
*/ public Builder setVals( int index, int value) { ensureValsIsMutable(); vals_.set(index, value); return this; } /** * repeated uint32 vals = 3 [packed = true]; * *
       * String IDs.
       * 
*/ public Builder addVals(int value) { ensureValsIsMutable(); vals_.add(value); return this; } /** * repeated uint32 vals = 3 [packed = true]; * *
       * String IDs.
       * 
*/ public Builder addAllVals( java.lang.Iterable values) { ensureValsIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, vals_); return this; } /** * repeated uint32 vals = 3 [packed = true]; * *
       * String IDs.
       * 
*/ public Builder clearVals() { vals_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000004); return this; } private org.openstreetmap.osmosis.osmbinary.Osmformat.Info info_ = org.openstreetmap.osmosis.osmbinary.Osmformat.Info.getDefaultInstance(); /** * optional .OSMPBF.Info info = 4; * *
       * May be omitted in omitmeta
       * 
*/ public boolean hasInfo() { return ((bitField0_ & 0x00000008) == 0x00000008); } /** * optional .OSMPBF.Info info = 4; * *
       * May be omitted in omitmeta
       * 
*/ public org.openstreetmap.osmosis.osmbinary.Osmformat.Info getInfo() { return info_; } /** * optional .OSMPBF.Info info = 4; * *
       * May be omitted in omitmeta
       * 
*/ public Builder setInfo(org.openstreetmap.osmosis.osmbinary.Osmformat.Info value) { if (value == null) { throw new NullPointerException(); } info_ = value; bitField0_ |= 0x00000008; return this; } /** * optional .OSMPBF.Info info = 4; * *
       * May be omitted in omitmeta
       * 
*/ public Builder setInfo( org.openstreetmap.osmosis.osmbinary.Osmformat.Info.Builder builderForValue) { info_ = builderForValue.build(); bitField0_ |= 0x00000008; return this; } /** * optional .OSMPBF.Info info = 4; * *
       * May be omitted in omitmeta
       * 
*/ public Builder mergeInfo(org.openstreetmap.osmosis.osmbinary.Osmformat.Info value) { if (((bitField0_ & 0x00000008) == 0x00000008) && info_ != org.openstreetmap.osmosis.osmbinary.Osmformat.Info.getDefaultInstance()) { info_ = org.openstreetmap.osmosis.osmbinary.Osmformat.Info.newBuilder(info_).mergeFrom(value).buildPartial(); } else { info_ = value; } bitField0_ |= 0x00000008; return this; } /** * optional .OSMPBF.Info info = 4; * *
       * May be omitted in omitmeta
       * 
*/ public Builder clearInfo() { info_ = org.openstreetmap.osmosis.osmbinary.Osmformat.Info.getDefaultInstance(); bitField0_ = (bitField0_ & ~0x00000008); return this; } private long lat_ ; /** * required sint64 lat = 8; */ public boolean hasLat() { return ((bitField0_ & 0x00000010) == 0x00000010); } /** * required sint64 lat = 8; */ public long getLat() { return lat_; } /** * required sint64 lat = 8; */ public Builder setLat(long value) { bitField0_ |= 0x00000010; lat_ = value; return this; } /** * required sint64 lat = 8; */ public Builder clearLat() { bitField0_ = (bitField0_ & ~0x00000010); lat_ = 0L; return this; } private long lon_ ; /** * required sint64 lon = 9; */ public boolean hasLon() { return ((bitField0_ & 0x00000020) == 0x00000020); } /** * required sint64 lon = 9; */ public long getLon() { return lon_; } /** * required sint64 lon = 9; */ public Builder setLon(long value) { bitField0_ |= 0x00000020; lon_ = value; return this; } /** * required sint64 lon = 9; */ public Builder clearLon() { bitField0_ = (bitField0_ & ~0x00000020); lon_ = 0L; return this; } // @@protoc_insertion_point(builder_scope:OSMPBF.Node) } static { defaultInstance = new Node(true); defaultInstance.initFields(); } // @@protoc_insertion_point(class_scope:OSMPBF.Node) } public interface DenseNodesOrBuilder extends // @@protoc_insertion_point(interface_extends:OSMPBF.DenseNodes) com.google.protobuf.MessageLiteOrBuilder { /** * repeated sint64 id = 1 [packed = true]; * *
     * DELTA coded
     * 
*/ java.util.List getIdList(); /** * repeated sint64 id = 1 [packed = true]; * *
     * DELTA coded
     * 
*/ int getIdCount(); /** * repeated sint64 id = 1 [packed = true]; * *
     * DELTA coded
     * 
*/ long getId(int index); /** * optional .OSMPBF.DenseInfo denseinfo = 5; * *
     *repeated Info info = 4;
     * 
*/ boolean hasDenseinfo(); /** * optional .OSMPBF.DenseInfo denseinfo = 5; * *
     *repeated Info info = 4;
     * 
*/ org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo getDenseinfo(); /** * repeated sint64 lat = 8 [packed = true]; * *
     * DELTA coded
     * 
*/ java.util.List getLatList(); /** * repeated sint64 lat = 8 [packed = true]; * *
     * DELTA coded
     * 
*/ int getLatCount(); /** * repeated sint64 lat = 8 [packed = true]; * *
     * DELTA coded
     * 
*/ long getLat(int index); /** * repeated sint64 lon = 9 [packed = true]; * *
     * DELTA coded
     * 
*/ java.util.List getLonList(); /** * repeated sint64 lon = 9 [packed = true]; * *
     * DELTA coded
     * 
*/ int getLonCount(); /** * repeated sint64 lon = 9 [packed = true]; * *
     * DELTA coded
     * 
*/ long getLon(int index); /** * repeated int32 keys_vals = 10 [packed = true]; * *
     * Special packing of keys and vals into one array. May be empty if all nodes in this block are tagless.
     * 
*/ java.util.List getKeysValsList(); /** * repeated int32 keys_vals = 10 [packed = true]; * *
     * Special packing of keys and vals into one array. May be empty if all nodes in this block are tagless.
     * 
*/ int getKeysValsCount(); /** * repeated int32 keys_vals = 10 [packed = true]; * *
     * Special packing of keys and vals into one array. May be empty if all nodes in this block are tagless.
     * 
*/ int getKeysVals(int index); } /** * Protobuf type {@code OSMPBF.DenseNodes} */ public static final class DenseNodes extends com.google.protobuf.GeneratedMessageLite implements // @@protoc_insertion_point(message_implements:OSMPBF.DenseNodes) DenseNodesOrBuilder { // Use DenseNodes.newBuilder() to construct. private DenseNodes(com.google.protobuf.GeneratedMessageLite.Builder builder) { super(builder); this.unknownFields = builder.getUnknownFields(); } private DenseNodes(boolean noInit) { this.unknownFields = com.google.protobuf.ByteString.EMPTY;} private static final DenseNodes defaultInstance; public static DenseNodes getDefaultInstance() { return defaultInstance; } public DenseNodes getDefaultInstanceForType() { return defaultInstance; } private final com.google.protobuf.ByteString unknownFields; private DenseNodes( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { initFields(); int mutable_bitField0_ = 0; com.google.protobuf.ByteString.Output unknownFieldsOutput = com.google.protobuf.ByteString.newOutput(); com.google.protobuf.CodedOutputStream unknownFieldsCodedOutput = com.google.protobuf.CodedOutputStream.newInstance( unknownFieldsOutput); try { boolean done = false; while (!done) { int tag = input.readTag(); switch (tag) { case 0: done = true; break; default: { if (!parseUnknownField(input, unknownFieldsCodedOutput, extensionRegistry, tag)) { done = true; } break; } case 8: { if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) { id_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000001; } id_.add(input.readSInt64()); break; } case 10: { int length = input.readRawVarint32(); int limit = input.pushLimit(length); if (!((mutable_bitField0_ & 0x00000001) == 0x00000001) && input.getBytesUntilLimit() > 0) { id_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000001; } while (input.getBytesUntilLimit() > 0) { id_.add(input.readSInt64()); } input.popLimit(limit); break; } case 42: { org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo.Builder subBuilder = null; if (((bitField0_ & 0x00000001) == 0x00000001)) { subBuilder = denseinfo_.toBuilder(); } denseinfo_ = input.readMessage(org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo.PARSER, extensionRegistry); if (subBuilder != null) { subBuilder.mergeFrom(denseinfo_); denseinfo_ = subBuilder.buildPartial(); } bitField0_ |= 0x00000001; break; } case 64: { if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) { lat_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000004; } lat_.add(input.readSInt64()); break; } case 66: { int length = input.readRawVarint32(); int limit = input.pushLimit(length); if (!((mutable_bitField0_ & 0x00000004) == 0x00000004) && input.getBytesUntilLimit() > 0) { lat_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000004; } while (input.getBytesUntilLimit() > 0) { lat_.add(input.readSInt64()); } input.popLimit(limit); break; } case 72: { if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) { lon_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000008; } lon_.add(input.readSInt64()); break; } case 74: { int length = input.readRawVarint32(); int limit = input.pushLimit(length); if (!((mutable_bitField0_ & 0x00000008) == 0x00000008) && input.getBytesUntilLimit() > 0) { lon_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000008; } while (input.getBytesUntilLimit() > 0) { lon_.add(input.readSInt64()); } input.popLimit(limit); break; } case 80: { if (!((mutable_bitField0_ & 0x00000010) == 0x00000010)) { keysVals_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000010; } keysVals_.add(input.readInt32()); break; } case 82: { int length = input.readRawVarint32(); int limit = input.pushLimit(length); if (!((mutable_bitField0_ & 0x00000010) == 0x00000010) && input.getBytesUntilLimit() > 0) { keysVals_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000010; } while (input.getBytesUntilLimit() > 0) { keysVals_.add(input.readInt32()); } input.popLimit(limit); break; } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { throw e.setUnfinishedMessage(this); } catch (java.io.IOException e) { throw new com.google.protobuf.InvalidProtocolBufferException( e.getMessage()).setUnfinishedMessage(this); } finally { if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) { id_ = java.util.Collections.unmodifiableList(id_); } if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) { lat_ = java.util.Collections.unmodifiableList(lat_); } if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) { lon_ = java.util.Collections.unmodifiableList(lon_); } if (((mutable_bitField0_ & 0x00000010) == 0x00000010)) { keysVals_ = java.util.Collections.unmodifiableList(keysVals_); } try { unknownFieldsCodedOutput.flush(); } catch (java.io.IOException e) { // Should not happen } finally { unknownFields = unknownFieldsOutput.toByteString(); } makeExtensionsImmutable(); } } public static com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { public DenseNodes parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return new DenseNodes(input, extensionRegistry); } }; @java.lang.Override public com.google.protobuf.Parser getParserForType() { return PARSER; } private int bitField0_; public static final int ID_FIELD_NUMBER = 1; private java.util.List id_; /** * repeated sint64 id = 1 [packed = true]; * *
     * DELTA coded
     * 
*/ public java.util.List getIdList() { return id_; } /** * repeated sint64 id = 1 [packed = true]; * *
     * DELTA coded
     * 
*/ public int getIdCount() { return id_.size(); } /** * repeated sint64 id = 1 [packed = true]; * *
     * DELTA coded
     * 
*/ public long getId(int index) { return id_.get(index); } private int idMemoizedSerializedSize = -1; public static final int DENSEINFO_FIELD_NUMBER = 5; private org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo denseinfo_; /** * optional .OSMPBF.DenseInfo denseinfo = 5; * *
     *repeated Info info = 4;
     * 
*/ public boolean hasDenseinfo() { return ((bitField0_ & 0x00000001) == 0x00000001); } /** * optional .OSMPBF.DenseInfo denseinfo = 5; * *
     *repeated Info info = 4;
     * 
*/ public org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo getDenseinfo() { return denseinfo_; } public static final int LAT_FIELD_NUMBER = 8; private java.util.List lat_; /** * repeated sint64 lat = 8 [packed = true]; * *
     * DELTA coded
     * 
*/ public java.util.List getLatList() { return lat_; } /** * repeated sint64 lat = 8 [packed = true]; * *
     * DELTA coded
     * 
*/ public int getLatCount() { return lat_.size(); } /** * repeated sint64 lat = 8 [packed = true]; * *
     * DELTA coded
     * 
*/ public long getLat(int index) { return lat_.get(index); } private int latMemoizedSerializedSize = -1; public static final int LON_FIELD_NUMBER = 9; private java.util.List lon_; /** * repeated sint64 lon = 9 [packed = true]; * *
     * DELTA coded
     * 
*/ public java.util.List getLonList() { return lon_; } /** * repeated sint64 lon = 9 [packed = true]; * *
     * DELTA coded
     * 
*/ public int getLonCount() { return lon_.size(); } /** * repeated sint64 lon = 9 [packed = true]; * *
     * DELTA coded
     * 
*/ public long getLon(int index) { return lon_.get(index); } private int lonMemoizedSerializedSize = -1; public static final int KEYS_VALS_FIELD_NUMBER = 10; private java.util.List keysVals_; /** * repeated int32 keys_vals = 10 [packed = true]; * *
     * Special packing of keys and vals into one array. May be empty if all nodes in this block are tagless.
     * 
*/ public java.util.List getKeysValsList() { return keysVals_; } /** * repeated int32 keys_vals = 10 [packed = true]; * *
     * Special packing of keys and vals into one array. May be empty if all nodes in this block are tagless.
     * 
*/ public int getKeysValsCount() { return keysVals_.size(); } /** * repeated int32 keys_vals = 10 [packed = true]; * *
     * Special packing of keys and vals into one array. May be empty if all nodes in this block are tagless.
     * 
*/ public int getKeysVals(int index) { return keysVals_.get(index); } private int keysValsMemoizedSerializedSize = -1; private void initFields() { id_ = java.util.Collections.emptyList(); denseinfo_ = org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo.getDefaultInstance(); lat_ = java.util.Collections.emptyList(); lon_ = java.util.Collections.emptyList(); keysVals_ = java.util.Collections.emptyList(); } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized == 1) return true; if (isInitialized == 0) return false; memoizedIsInitialized = 1; return true; } public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { getSerializedSize(); if (getIdList().size() > 0) { output.writeRawVarint32(10); output.writeRawVarint32(idMemoizedSerializedSize); } for (int i = 0; i < id_.size(); i++) { output.writeSInt64NoTag(id_.get(i)); } if (((bitField0_ & 0x00000001) == 0x00000001)) { output.writeMessage(5, denseinfo_); } if (getLatList().size() > 0) { output.writeRawVarint32(66); output.writeRawVarint32(latMemoizedSerializedSize); } for (int i = 0; i < lat_.size(); i++) { output.writeSInt64NoTag(lat_.get(i)); } if (getLonList().size() > 0) { output.writeRawVarint32(74); output.writeRawVarint32(lonMemoizedSerializedSize); } for (int i = 0; i < lon_.size(); i++) { output.writeSInt64NoTag(lon_.get(i)); } if (getKeysValsList().size() > 0) { output.writeRawVarint32(82); output.writeRawVarint32(keysValsMemoizedSerializedSize); } for (int i = 0; i < keysVals_.size(); i++) { output.writeInt32NoTag(keysVals_.get(i)); } output.writeRawBytes(unknownFields); } private int memoizedSerializedSize = -1; public int getSerializedSize() { int size = memoizedSerializedSize; if (size != -1) return size; size = 0; { int dataSize = 0; for (int i = 0; i < id_.size(); i++) { dataSize += com.google.protobuf.CodedOutputStream .computeSInt64SizeNoTag(id_.get(i)); } size += dataSize; if (!getIdList().isEmpty()) { size += 1; size += com.google.protobuf.CodedOutputStream .computeInt32SizeNoTag(dataSize); } idMemoizedSerializedSize = dataSize; } if (((bitField0_ & 0x00000001) == 0x00000001)) { size += com.google.protobuf.CodedOutputStream .computeMessageSize(5, denseinfo_); } { int dataSize = 0; for (int i = 0; i < lat_.size(); i++) { dataSize += com.google.protobuf.CodedOutputStream .computeSInt64SizeNoTag(lat_.get(i)); } size += dataSize; if (!getLatList().isEmpty()) { size += 1; size += com.google.protobuf.CodedOutputStream .computeInt32SizeNoTag(dataSize); } latMemoizedSerializedSize = dataSize; } { int dataSize = 0; for (int i = 0; i < lon_.size(); i++) { dataSize += com.google.protobuf.CodedOutputStream .computeSInt64SizeNoTag(lon_.get(i)); } size += dataSize; if (!getLonList().isEmpty()) { size += 1; size += com.google.protobuf.CodedOutputStream .computeInt32SizeNoTag(dataSize); } lonMemoizedSerializedSize = dataSize; } { int dataSize = 0; for (int i = 0; i < keysVals_.size(); i++) { dataSize += com.google.protobuf.CodedOutputStream .computeInt32SizeNoTag(keysVals_.get(i)); } size += dataSize; if (!getKeysValsList().isEmpty()) { size += 1; size += com.google.protobuf.CodedOutputStream .computeInt32SizeNoTag(dataSize); } keysValsMemoizedSerializedSize = dataSize; } size += unknownFields.size(); memoizedSerializedSize = size; return size; } private static final long serialVersionUID = 0L; @java.lang.Override protected java.lang.Object writeReplace() throws java.io.ObjectStreamException { return super.writeReplace(); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes parseFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseDelimitedFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseDelimitedFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static Builder newBuilder() { return Builder.create(); } public Builder newBuilderForType() { return newBuilder(); } public static Builder newBuilder(org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes prototype) { return newBuilder().mergeFrom(prototype); } public Builder toBuilder() { return newBuilder(this); } /** * Protobuf type {@code OSMPBF.DenseNodes} */ public static final class Builder extends com.google.protobuf.GeneratedMessageLite.Builder< org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes, Builder> implements // @@protoc_insertion_point(builder_implements:OSMPBF.DenseNodes) org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodesOrBuilder { // Construct using org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes.newBuilder() private Builder() { maybeForceBuilderInitialization(); } private void maybeForceBuilderInitialization() { } private static Builder create() { return new Builder(); } public Builder clear() { super.clear(); id_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000001); denseinfo_ = org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo.getDefaultInstance(); bitField0_ = (bitField0_ & ~0x00000002); lat_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000004); lon_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000008); keysVals_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000010); return this; } public Builder clone() { return create().mergeFrom(buildPartial()); } public org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes getDefaultInstanceForType() { return org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes.getDefaultInstance(); } public org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes build() { org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } public org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes buildPartial() { org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes result = new org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((bitField0_ & 0x00000001) == 0x00000001)) { id_ = java.util.Collections.unmodifiableList(id_); bitField0_ = (bitField0_ & ~0x00000001); } result.id_ = id_; if (((from_bitField0_ & 0x00000002) == 0x00000002)) { to_bitField0_ |= 0x00000001; } result.denseinfo_ = denseinfo_; if (((bitField0_ & 0x00000004) == 0x00000004)) { lat_ = java.util.Collections.unmodifiableList(lat_); bitField0_ = (bitField0_ & ~0x00000004); } result.lat_ = lat_; if (((bitField0_ & 0x00000008) == 0x00000008)) { lon_ = java.util.Collections.unmodifiableList(lon_); bitField0_ = (bitField0_ & ~0x00000008); } result.lon_ = lon_; if (((bitField0_ & 0x00000010) == 0x00000010)) { keysVals_ = java.util.Collections.unmodifiableList(keysVals_); bitField0_ = (bitField0_ & ~0x00000010); } result.keysVals_ = keysVals_; result.bitField0_ = to_bitField0_; return result; } public Builder mergeFrom(org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes other) { if (other == org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes.getDefaultInstance()) return this; if (!other.id_.isEmpty()) { if (id_.isEmpty()) { id_ = other.id_; bitField0_ = (bitField0_ & ~0x00000001); } else { ensureIdIsMutable(); id_.addAll(other.id_); } } if (other.hasDenseinfo()) { mergeDenseinfo(other.getDenseinfo()); } if (!other.lat_.isEmpty()) { if (lat_.isEmpty()) { lat_ = other.lat_; bitField0_ = (bitField0_ & ~0x00000004); } else { ensureLatIsMutable(); lat_.addAll(other.lat_); } } if (!other.lon_.isEmpty()) { if (lon_.isEmpty()) { lon_ = other.lon_; bitField0_ = (bitField0_ & ~0x00000008); } else { ensureLonIsMutable(); lon_.addAll(other.lon_); } } if (!other.keysVals_.isEmpty()) { if (keysVals_.isEmpty()) { keysVals_ = other.keysVals_; bitField0_ = (bitField0_ & ~0x00000010); } else { ensureKeysValsIsMutable(); keysVals_.addAll(other.keysVals_); } } setUnknownFields( getUnknownFields().concat(other.unknownFields)); return this; } public final boolean isInitialized() { return true; } public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { parsedMessage = (org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes) e.getUnfinishedMessage(); throw e; } finally { if (parsedMessage != null) { mergeFrom(parsedMessage); } } return this; } private int bitField0_; private java.util.List id_ = java.util.Collections.emptyList(); private void ensureIdIsMutable() { if (!((bitField0_ & 0x00000001) == 0x00000001)) { id_ = new java.util.ArrayList(id_); bitField0_ |= 0x00000001; } } /** * repeated sint64 id = 1 [packed = true]; * *
       * DELTA coded
       * 
*/ public java.util.List getIdList() { return java.util.Collections.unmodifiableList(id_); } /** * repeated sint64 id = 1 [packed = true]; * *
       * DELTA coded
       * 
*/ public int getIdCount() { return id_.size(); } /** * repeated sint64 id = 1 [packed = true]; * *
       * DELTA coded
       * 
*/ public long getId(int index) { return id_.get(index); } /** * repeated sint64 id = 1 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder setId( int index, long value) { ensureIdIsMutable(); id_.set(index, value); return this; } /** * repeated sint64 id = 1 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder addId(long value) { ensureIdIsMutable(); id_.add(value); return this; } /** * repeated sint64 id = 1 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder addAllId( java.lang.Iterable values) { ensureIdIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, id_); return this; } /** * repeated sint64 id = 1 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder clearId() { id_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000001); return this; } private org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo denseinfo_ = org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo.getDefaultInstance(); /** * optional .OSMPBF.DenseInfo denseinfo = 5; * *
       *repeated Info info = 4;
       * 
*/ public boolean hasDenseinfo() { return ((bitField0_ & 0x00000002) == 0x00000002); } /** * optional .OSMPBF.DenseInfo denseinfo = 5; * *
       *repeated Info info = 4;
       * 
*/ public org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo getDenseinfo() { return denseinfo_; } /** * optional .OSMPBF.DenseInfo denseinfo = 5; * *
       *repeated Info info = 4;
       * 
*/ public Builder setDenseinfo(org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo value) { if (value == null) { throw new NullPointerException(); } denseinfo_ = value; bitField0_ |= 0x00000002; return this; } /** * optional .OSMPBF.DenseInfo denseinfo = 5; * *
       *repeated Info info = 4;
       * 
*/ public Builder setDenseinfo( org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo.Builder builderForValue) { denseinfo_ = builderForValue.build(); bitField0_ |= 0x00000002; return this; } /** * optional .OSMPBF.DenseInfo denseinfo = 5; * *
       *repeated Info info = 4;
       * 
*/ public Builder mergeDenseinfo(org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo value) { if (((bitField0_ & 0x00000002) == 0x00000002) && denseinfo_ != org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo.getDefaultInstance()) { denseinfo_ = org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo.newBuilder(denseinfo_).mergeFrom(value).buildPartial(); } else { denseinfo_ = value; } bitField0_ |= 0x00000002; return this; } /** * optional .OSMPBF.DenseInfo denseinfo = 5; * *
       *repeated Info info = 4;
       * 
*/ public Builder clearDenseinfo() { denseinfo_ = org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo.getDefaultInstance(); bitField0_ = (bitField0_ & ~0x00000002); return this; } private java.util.List lat_ = java.util.Collections.emptyList(); private void ensureLatIsMutable() { if (!((bitField0_ & 0x00000004) == 0x00000004)) { lat_ = new java.util.ArrayList(lat_); bitField0_ |= 0x00000004; } } /** * repeated sint64 lat = 8 [packed = true]; * *
       * DELTA coded
       * 
*/ public java.util.List getLatList() { return java.util.Collections.unmodifiableList(lat_); } /** * repeated sint64 lat = 8 [packed = true]; * *
       * DELTA coded
       * 
*/ public int getLatCount() { return lat_.size(); } /** * repeated sint64 lat = 8 [packed = true]; * *
       * DELTA coded
       * 
*/ public long getLat(int index) { return lat_.get(index); } /** * repeated sint64 lat = 8 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder setLat( int index, long value) { ensureLatIsMutable(); lat_.set(index, value); return this; } /** * repeated sint64 lat = 8 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder addLat(long value) { ensureLatIsMutable(); lat_.add(value); return this; } /** * repeated sint64 lat = 8 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder addAllLat( java.lang.Iterable values) { ensureLatIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, lat_); return this; } /** * repeated sint64 lat = 8 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder clearLat() { lat_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000004); return this; } private java.util.List lon_ = java.util.Collections.emptyList(); private void ensureLonIsMutable() { if (!((bitField0_ & 0x00000008) == 0x00000008)) { lon_ = new java.util.ArrayList(lon_); bitField0_ |= 0x00000008; } } /** * repeated sint64 lon = 9 [packed = true]; * *
       * DELTA coded
       * 
*/ public java.util.List getLonList() { return java.util.Collections.unmodifiableList(lon_); } /** * repeated sint64 lon = 9 [packed = true]; * *
       * DELTA coded
       * 
*/ public int getLonCount() { return lon_.size(); } /** * repeated sint64 lon = 9 [packed = true]; * *
       * DELTA coded
       * 
*/ public long getLon(int index) { return lon_.get(index); } /** * repeated sint64 lon = 9 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder setLon( int index, long value) { ensureLonIsMutable(); lon_.set(index, value); return this; } /** * repeated sint64 lon = 9 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder addLon(long value) { ensureLonIsMutable(); lon_.add(value); return this; } /** * repeated sint64 lon = 9 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder addAllLon( java.lang.Iterable values) { ensureLonIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, lon_); return this; } /** * repeated sint64 lon = 9 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder clearLon() { lon_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000008); return this; } private java.util.List keysVals_ = java.util.Collections.emptyList(); private void ensureKeysValsIsMutable() { if (!((bitField0_ & 0x00000010) == 0x00000010)) { keysVals_ = new java.util.ArrayList(keysVals_); bitField0_ |= 0x00000010; } } /** * repeated int32 keys_vals = 10 [packed = true]; * *
       * Special packing of keys and vals into one array. May be empty if all nodes in this block are tagless.
       * 
*/ public java.util.List getKeysValsList() { return java.util.Collections.unmodifiableList(keysVals_); } /** * repeated int32 keys_vals = 10 [packed = true]; * *
       * Special packing of keys and vals into one array. May be empty if all nodes in this block are tagless.
       * 
*/ public int getKeysValsCount() { return keysVals_.size(); } /** * repeated int32 keys_vals = 10 [packed = true]; * *
       * Special packing of keys and vals into one array. May be empty if all nodes in this block are tagless.
       * 
*/ public int getKeysVals(int index) { return keysVals_.get(index); } /** * repeated int32 keys_vals = 10 [packed = true]; * *
       * Special packing of keys and vals into one array. May be empty if all nodes in this block are tagless.
       * 
*/ public Builder setKeysVals( int index, int value) { ensureKeysValsIsMutable(); keysVals_.set(index, value); return this; } /** * repeated int32 keys_vals = 10 [packed = true]; * *
       * Special packing of keys and vals into one array. May be empty if all nodes in this block are tagless.
       * 
*/ public Builder addKeysVals(int value) { ensureKeysValsIsMutable(); keysVals_.add(value); return this; } /** * repeated int32 keys_vals = 10 [packed = true]; * *
       * Special packing of keys and vals into one array. May be empty if all nodes in this block are tagless.
       * 
*/ public Builder addAllKeysVals( java.lang.Iterable values) { ensureKeysValsIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, keysVals_); return this; } /** * repeated int32 keys_vals = 10 [packed = true]; * *
       * Special packing of keys and vals into one array. May be empty if all nodes in this block are tagless.
       * 
*/ public Builder clearKeysVals() { keysVals_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000010); return this; } // @@protoc_insertion_point(builder_scope:OSMPBF.DenseNodes) } static { defaultInstance = new DenseNodes(true); defaultInstance.initFields(); } // @@protoc_insertion_point(class_scope:OSMPBF.DenseNodes) } public interface WayOrBuilder extends // @@protoc_insertion_point(interface_extends:OSMPBF.Way) com.google.protobuf.MessageLiteOrBuilder { /** * required int64 id = 1; */ boolean hasId(); /** * required int64 id = 1; */ long getId(); /** * repeated uint32 keys = 2 [packed = true]; * *
     * Parallel arrays.
     * 
*/ java.util.List getKeysList(); /** * repeated uint32 keys = 2 [packed = true]; * *
     * Parallel arrays.
     * 
*/ int getKeysCount(); /** * repeated uint32 keys = 2 [packed = true]; * *
     * Parallel arrays.
     * 
*/ int getKeys(int index); /** * repeated uint32 vals = 3 [packed = true]; */ java.util.List getValsList(); /** * repeated uint32 vals = 3 [packed = true]; */ int getValsCount(); /** * repeated uint32 vals = 3 [packed = true]; */ int getVals(int index); /** * optional .OSMPBF.Info info = 4; */ boolean hasInfo(); /** * optional .OSMPBF.Info info = 4; */ org.openstreetmap.osmosis.osmbinary.Osmformat.Info getInfo(); /** * repeated sint64 refs = 8 [packed = true]; * *
     * DELTA coded
     * 
*/ java.util.List getRefsList(); /** * repeated sint64 refs = 8 [packed = true]; * *
     * DELTA coded
     * 
*/ int getRefsCount(); /** * repeated sint64 refs = 8 [packed = true]; * *
     * DELTA coded
     * 
*/ long getRefs(int index); } /** * Protobuf type {@code OSMPBF.Way} */ public static final class Way extends com.google.protobuf.GeneratedMessageLite implements // @@protoc_insertion_point(message_implements:OSMPBF.Way) WayOrBuilder { // Use Way.newBuilder() to construct. private Way(com.google.protobuf.GeneratedMessageLite.Builder builder) { super(builder); this.unknownFields = builder.getUnknownFields(); } private Way(boolean noInit) { this.unknownFields = com.google.protobuf.ByteString.EMPTY;} private static final Way defaultInstance; public static Way getDefaultInstance() { return defaultInstance; } public Way getDefaultInstanceForType() { return defaultInstance; } private final com.google.protobuf.ByteString unknownFields; private Way( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { initFields(); int mutable_bitField0_ = 0; com.google.protobuf.ByteString.Output unknownFieldsOutput = com.google.protobuf.ByteString.newOutput(); com.google.protobuf.CodedOutputStream unknownFieldsCodedOutput = com.google.protobuf.CodedOutputStream.newInstance( unknownFieldsOutput); try { boolean done = false; while (!done) { int tag = input.readTag(); switch (tag) { case 0: done = true; break; default: { if (!parseUnknownField(input, unknownFieldsCodedOutput, extensionRegistry, tag)) { done = true; } break; } case 8: { bitField0_ |= 0x00000001; id_ = input.readInt64(); break; } case 16: { if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) { keys_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000002; } keys_.add(input.readUInt32()); break; } case 18: { int length = input.readRawVarint32(); int limit = input.pushLimit(length); if (!((mutable_bitField0_ & 0x00000002) == 0x00000002) && input.getBytesUntilLimit() > 0) { keys_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000002; } while (input.getBytesUntilLimit() > 0) { keys_.add(input.readUInt32()); } input.popLimit(limit); break; } case 24: { if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) { vals_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000004; } vals_.add(input.readUInt32()); break; } case 26: { int length = input.readRawVarint32(); int limit = input.pushLimit(length); if (!((mutable_bitField0_ & 0x00000004) == 0x00000004) && input.getBytesUntilLimit() > 0) { vals_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000004; } while (input.getBytesUntilLimit() > 0) { vals_.add(input.readUInt32()); } input.popLimit(limit); break; } case 34: { org.openstreetmap.osmosis.osmbinary.Osmformat.Info.Builder subBuilder = null; if (((bitField0_ & 0x00000002) == 0x00000002)) { subBuilder = info_.toBuilder(); } info_ = input.readMessage(org.openstreetmap.osmosis.osmbinary.Osmformat.Info.PARSER, extensionRegistry); if (subBuilder != null) { subBuilder.mergeFrom(info_); info_ = subBuilder.buildPartial(); } bitField0_ |= 0x00000002; break; } case 64: { if (!((mutable_bitField0_ & 0x00000010) == 0x00000010)) { refs_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000010; } refs_.add(input.readSInt64()); break; } case 66: { int length = input.readRawVarint32(); int limit = input.pushLimit(length); if (!((mutable_bitField0_ & 0x00000010) == 0x00000010) && input.getBytesUntilLimit() > 0) { refs_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000010; } while (input.getBytesUntilLimit() > 0) { refs_.add(input.readSInt64()); } input.popLimit(limit); break; } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { throw e.setUnfinishedMessage(this); } catch (java.io.IOException e) { throw new com.google.protobuf.InvalidProtocolBufferException( e.getMessage()).setUnfinishedMessage(this); } finally { if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) { keys_ = java.util.Collections.unmodifiableList(keys_); } if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) { vals_ = java.util.Collections.unmodifiableList(vals_); } if (((mutable_bitField0_ & 0x00000010) == 0x00000010)) { refs_ = java.util.Collections.unmodifiableList(refs_); } try { unknownFieldsCodedOutput.flush(); } catch (java.io.IOException e) { // Should not happen } finally { unknownFields = unknownFieldsOutput.toByteString(); } makeExtensionsImmutable(); } } public static com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { public Way parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return new Way(input, extensionRegistry); } }; @java.lang.Override public com.google.protobuf.Parser getParserForType() { return PARSER; } private int bitField0_; public static final int ID_FIELD_NUMBER = 1; private long id_; /** * required int64 id = 1; */ public boolean hasId() { return ((bitField0_ & 0x00000001) == 0x00000001); } /** * required int64 id = 1; */ public long getId() { return id_; } public static final int KEYS_FIELD_NUMBER = 2; private java.util.List keys_; /** * repeated uint32 keys = 2 [packed = true]; * *
     * Parallel arrays.
     * 
*/ public java.util.List getKeysList() { return keys_; } /** * repeated uint32 keys = 2 [packed = true]; * *
     * Parallel arrays.
     * 
*/ public int getKeysCount() { return keys_.size(); } /** * repeated uint32 keys = 2 [packed = true]; * *
     * Parallel arrays.
     * 
*/ public int getKeys(int index) { return keys_.get(index); } private int keysMemoizedSerializedSize = -1; public static final int VALS_FIELD_NUMBER = 3; private java.util.List vals_; /** * repeated uint32 vals = 3 [packed = true]; */ public java.util.List getValsList() { return vals_; } /** * repeated uint32 vals = 3 [packed = true]; */ public int getValsCount() { return vals_.size(); } /** * repeated uint32 vals = 3 [packed = true]; */ public int getVals(int index) { return vals_.get(index); } private int valsMemoizedSerializedSize = -1; public static final int INFO_FIELD_NUMBER = 4; private org.openstreetmap.osmosis.osmbinary.Osmformat.Info info_; /** * optional .OSMPBF.Info info = 4; */ public boolean hasInfo() { return ((bitField0_ & 0x00000002) == 0x00000002); } /** * optional .OSMPBF.Info info = 4; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.Info getInfo() { return info_; } public static final int REFS_FIELD_NUMBER = 8; private java.util.List refs_; /** * repeated sint64 refs = 8 [packed = true]; * *
     * DELTA coded
     * 
*/ public java.util.List getRefsList() { return refs_; } /** * repeated sint64 refs = 8 [packed = true]; * *
     * DELTA coded
     * 
*/ public int getRefsCount() { return refs_.size(); } /** * repeated sint64 refs = 8 [packed = true]; * *
     * DELTA coded
     * 
*/ public long getRefs(int index) { return refs_.get(index); } private int refsMemoizedSerializedSize = -1; private void initFields() { id_ = 0L; keys_ = java.util.Collections.emptyList(); vals_ = java.util.Collections.emptyList(); info_ = org.openstreetmap.osmosis.osmbinary.Osmformat.Info.getDefaultInstance(); refs_ = java.util.Collections.emptyList(); } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized == 1) return true; if (isInitialized == 0) return false; if (!hasId()) { memoizedIsInitialized = 0; return false; } memoizedIsInitialized = 1; return true; } public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { getSerializedSize(); if (((bitField0_ & 0x00000001) == 0x00000001)) { output.writeInt64(1, id_); } if (getKeysList().size() > 0) { output.writeRawVarint32(18); output.writeRawVarint32(keysMemoizedSerializedSize); } for (int i = 0; i < keys_.size(); i++) { output.writeUInt32NoTag(keys_.get(i)); } if (getValsList().size() > 0) { output.writeRawVarint32(26); output.writeRawVarint32(valsMemoizedSerializedSize); } for (int i = 0; i < vals_.size(); i++) { output.writeUInt32NoTag(vals_.get(i)); } if (((bitField0_ & 0x00000002) == 0x00000002)) { output.writeMessage(4, info_); } if (getRefsList().size() > 0) { output.writeRawVarint32(66); output.writeRawVarint32(refsMemoizedSerializedSize); } for (int i = 0; i < refs_.size(); i++) { output.writeSInt64NoTag(refs_.get(i)); } output.writeRawBytes(unknownFields); } private int memoizedSerializedSize = -1; public int getSerializedSize() { int size = memoizedSerializedSize; if (size != -1) return size; size = 0; if (((bitField0_ & 0x00000001) == 0x00000001)) { size += com.google.protobuf.CodedOutputStream .computeInt64Size(1, id_); } { int dataSize = 0; for (int i = 0; i < keys_.size(); i++) { dataSize += com.google.protobuf.CodedOutputStream .computeUInt32SizeNoTag(keys_.get(i)); } size += dataSize; if (!getKeysList().isEmpty()) { size += 1; size += com.google.protobuf.CodedOutputStream .computeInt32SizeNoTag(dataSize); } keysMemoizedSerializedSize = dataSize; } { int dataSize = 0; for (int i = 0; i < vals_.size(); i++) { dataSize += com.google.protobuf.CodedOutputStream .computeUInt32SizeNoTag(vals_.get(i)); } size += dataSize; if (!getValsList().isEmpty()) { size += 1; size += com.google.protobuf.CodedOutputStream .computeInt32SizeNoTag(dataSize); } valsMemoizedSerializedSize = dataSize; } if (((bitField0_ & 0x00000002) == 0x00000002)) { size += com.google.protobuf.CodedOutputStream .computeMessageSize(4, info_); } { int dataSize = 0; for (int i = 0; i < refs_.size(); i++) { dataSize += com.google.protobuf.CodedOutputStream .computeSInt64SizeNoTag(refs_.get(i)); } size += dataSize; if (!getRefsList().isEmpty()) { size += 1; size += com.google.protobuf.CodedOutputStream .computeInt32SizeNoTag(dataSize); } refsMemoizedSerializedSize = dataSize; } size += unknownFields.size(); memoizedSerializedSize = size; return size; } private static final long serialVersionUID = 0L; @java.lang.Override protected java.lang.Object writeReplace() throws java.io.ObjectStreamException { return super.writeReplace(); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Way parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Way parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Way parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Way parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Way parseFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Way parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Way parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseDelimitedFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Way parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseDelimitedFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Way parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Way parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static Builder newBuilder() { return Builder.create(); } public Builder newBuilderForType() { return newBuilder(); } public static Builder newBuilder(org.openstreetmap.osmosis.osmbinary.Osmformat.Way prototype) { return newBuilder().mergeFrom(prototype); } public Builder toBuilder() { return newBuilder(this); } /** * Protobuf type {@code OSMPBF.Way} */ public static final class Builder extends com.google.protobuf.GeneratedMessageLite.Builder< org.openstreetmap.osmosis.osmbinary.Osmformat.Way, Builder> implements // @@protoc_insertion_point(builder_implements:OSMPBF.Way) org.openstreetmap.osmosis.osmbinary.Osmformat.WayOrBuilder { // Construct using org.openstreetmap.osmosis.osmbinary.Osmformat.Way.newBuilder() private Builder() { maybeForceBuilderInitialization(); } private void maybeForceBuilderInitialization() { } private static Builder create() { return new Builder(); } public Builder clear() { super.clear(); id_ = 0L; bitField0_ = (bitField0_ & ~0x00000001); keys_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000002); vals_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000004); info_ = org.openstreetmap.osmosis.osmbinary.Osmformat.Info.getDefaultInstance(); bitField0_ = (bitField0_ & ~0x00000008); refs_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000010); return this; } public Builder clone() { return create().mergeFrom(buildPartial()); } public org.openstreetmap.osmosis.osmbinary.Osmformat.Way getDefaultInstanceForType() { return org.openstreetmap.osmosis.osmbinary.Osmformat.Way.getDefaultInstance(); } public org.openstreetmap.osmosis.osmbinary.Osmformat.Way build() { org.openstreetmap.osmosis.osmbinary.Osmformat.Way result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } public org.openstreetmap.osmosis.osmbinary.Osmformat.Way buildPartial() { org.openstreetmap.osmosis.osmbinary.Osmformat.Way result = new org.openstreetmap.osmosis.osmbinary.Osmformat.Way(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) == 0x00000001)) { to_bitField0_ |= 0x00000001; } result.id_ = id_; if (((bitField0_ & 0x00000002) == 0x00000002)) { keys_ = java.util.Collections.unmodifiableList(keys_); bitField0_ = (bitField0_ & ~0x00000002); } result.keys_ = keys_; if (((bitField0_ & 0x00000004) == 0x00000004)) { vals_ = java.util.Collections.unmodifiableList(vals_); bitField0_ = (bitField0_ & ~0x00000004); } result.vals_ = vals_; if (((from_bitField0_ & 0x00000008) == 0x00000008)) { to_bitField0_ |= 0x00000002; } result.info_ = info_; if (((bitField0_ & 0x00000010) == 0x00000010)) { refs_ = java.util.Collections.unmodifiableList(refs_); bitField0_ = (bitField0_ & ~0x00000010); } result.refs_ = refs_; result.bitField0_ = to_bitField0_; return result; } public Builder mergeFrom(org.openstreetmap.osmosis.osmbinary.Osmformat.Way other) { if (other == org.openstreetmap.osmosis.osmbinary.Osmformat.Way.getDefaultInstance()) return this; if (other.hasId()) { setId(other.getId()); } if (!other.keys_.isEmpty()) { if (keys_.isEmpty()) { keys_ = other.keys_; bitField0_ = (bitField0_ & ~0x00000002); } else { ensureKeysIsMutable(); keys_.addAll(other.keys_); } } if (!other.vals_.isEmpty()) { if (vals_.isEmpty()) { vals_ = other.vals_; bitField0_ = (bitField0_ & ~0x00000004); } else { ensureValsIsMutable(); vals_.addAll(other.vals_); } } if (other.hasInfo()) { mergeInfo(other.getInfo()); } if (!other.refs_.isEmpty()) { if (refs_.isEmpty()) { refs_ = other.refs_; bitField0_ = (bitField0_ & ~0x00000010); } else { ensureRefsIsMutable(); refs_.addAll(other.refs_); } } setUnknownFields( getUnknownFields().concat(other.unknownFields)); return this; } public final boolean isInitialized() { if (!hasId()) { return false; } return true; } public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { org.openstreetmap.osmosis.osmbinary.Osmformat.Way parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { parsedMessage = (org.openstreetmap.osmosis.osmbinary.Osmformat.Way) e.getUnfinishedMessage(); throw e; } finally { if (parsedMessage != null) { mergeFrom(parsedMessage); } } return this; } private int bitField0_; private long id_ ; /** * required int64 id = 1; */ public boolean hasId() { return ((bitField0_ & 0x00000001) == 0x00000001); } /** * required int64 id = 1; */ public long getId() { return id_; } /** * required int64 id = 1; */ public Builder setId(long value) { bitField0_ |= 0x00000001; id_ = value; return this; } /** * required int64 id = 1; */ public Builder clearId() { bitField0_ = (bitField0_ & ~0x00000001); id_ = 0L; return this; } private java.util.List keys_ = java.util.Collections.emptyList(); private void ensureKeysIsMutable() { if (!((bitField0_ & 0x00000002) == 0x00000002)) { keys_ = new java.util.ArrayList(keys_); bitField0_ |= 0x00000002; } } /** * repeated uint32 keys = 2 [packed = true]; * *
       * Parallel arrays.
       * 
*/ public java.util.List getKeysList() { return java.util.Collections.unmodifiableList(keys_); } /** * repeated uint32 keys = 2 [packed = true]; * *
       * Parallel arrays.
       * 
*/ public int getKeysCount() { return keys_.size(); } /** * repeated uint32 keys = 2 [packed = true]; * *
       * Parallel arrays.
       * 
*/ public int getKeys(int index) { return keys_.get(index); } /** * repeated uint32 keys = 2 [packed = true]; * *
       * Parallel arrays.
       * 
*/ public Builder setKeys( int index, int value) { ensureKeysIsMutable(); keys_.set(index, value); return this; } /** * repeated uint32 keys = 2 [packed = true]; * *
       * Parallel arrays.
       * 
*/ public Builder addKeys(int value) { ensureKeysIsMutable(); keys_.add(value); return this; } /** * repeated uint32 keys = 2 [packed = true]; * *
       * Parallel arrays.
       * 
*/ public Builder addAllKeys( java.lang.Iterable values) { ensureKeysIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, keys_); return this; } /** * repeated uint32 keys = 2 [packed = true]; * *
       * Parallel arrays.
       * 
*/ public Builder clearKeys() { keys_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000002); return this; } private java.util.List vals_ = java.util.Collections.emptyList(); private void ensureValsIsMutable() { if (!((bitField0_ & 0x00000004) == 0x00000004)) { vals_ = new java.util.ArrayList(vals_); bitField0_ |= 0x00000004; } } /** * repeated uint32 vals = 3 [packed = true]; */ public java.util.List getValsList() { return java.util.Collections.unmodifiableList(vals_); } /** * repeated uint32 vals = 3 [packed = true]; */ public int getValsCount() { return vals_.size(); } /** * repeated uint32 vals = 3 [packed = true]; */ public int getVals(int index) { return vals_.get(index); } /** * repeated uint32 vals = 3 [packed = true]; */ public Builder setVals( int index, int value) { ensureValsIsMutable(); vals_.set(index, value); return this; } /** * repeated uint32 vals = 3 [packed = true]; */ public Builder addVals(int value) { ensureValsIsMutable(); vals_.add(value); return this; } /** * repeated uint32 vals = 3 [packed = true]; */ public Builder addAllVals( java.lang.Iterable values) { ensureValsIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, vals_); return this; } /** * repeated uint32 vals = 3 [packed = true]; */ public Builder clearVals() { vals_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000004); return this; } private org.openstreetmap.osmosis.osmbinary.Osmformat.Info info_ = org.openstreetmap.osmosis.osmbinary.Osmformat.Info.getDefaultInstance(); /** * optional .OSMPBF.Info info = 4; */ public boolean hasInfo() { return ((bitField0_ & 0x00000008) == 0x00000008); } /** * optional .OSMPBF.Info info = 4; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.Info getInfo() { return info_; } /** * optional .OSMPBF.Info info = 4; */ public Builder setInfo(org.openstreetmap.osmosis.osmbinary.Osmformat.Info value) { if (value == null) { throw new NullPointerException(); } info_ = value; bitField0_ |= 0x00000008; return this; } /** * optional .OSMPBF.Info info = 4; */ public Builder setInfo( org.openstreetmap.osmosis.osmbinary.Osmformat.Info.Builder builderForValue) { info_ = builderForValue.build(); bitField0_ |= 0x00000008; return this; } /** * optional .OSMPBF.Info info = 4; */ public Builder mergeInfo(org.openstreetmap.osmosis.osmbinary.Osmformat.Info value) { if (((bitField0_ & 0x00000008) == 0x00000008) && info_ != org.openstreetmap.osmosis.osmbinary.Osmformat.Info.getDefaultInstance()) { info_ = org.openstreetmap.osmosis.osmbinary.Osmformat.Info.newBuilder(info_).mergeFrom(value).buildPartial(); } else { info_ = value; } bitField0_ |= 0x00000008; return this; } /** * optional .OSMPBF.Info info = 4; */ public Builder clearInfo() { info_ = org.openstreetmap.osmosis.osmbinary.Osmformat.Info.getDefaultInstance(); bitField0_ = (bitField0_ & ~0x00000008); return this; } private java.util.List refs_ = java.util.Collections.emptyList(); private void ensureRefsIsMutable() { if (!((bitField0_ & 0x00000010) == 0x00000010)) { refs_ = new java.util.ArrayList(refs_); bitField0_ |= 0x00000010; } } /** * repeated sint64 refs = 8 [packed = true]; * *
       * DELTA coded
       * 
*/ public java.util.List getRefsList() { return java.util.Collections.unmodifiableList(refs_); } /** * repeated sint64 refs = 8 [packed = true]; * *
       * DELTA coded
       * 
*/ public int getRefsCount() { return refs_.size(); } /** * repeated sint64 refs = 8 [packed = true]; * *
       * DELTA coded
       * 
*/ public long getRefs(int index) { return refs_.get(index); } /** * repeated sint64 refs = 8 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder setRefs( int index, long value) { ensureRefsIsMutable(); refs_.set(index, value); return this; } /** * repeated sint64 refs = 8 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder addRefs(long value) { ensureRefsIsMutable(); refs_.add(value); return this; } /** * repeated sint64 refs = 8 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder addAllRefs( java.lang.Iterable values) { ensureRefsIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, refs_); return this; } /** * repeated sint64 refs = 8 [packed = true]; * *
       * DELTA coded
       * 
*/ public Builder clearRefs() { refs_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000010); return this; } // @@protoc_insertion_point(builder_scope:OSMPBF.Way) } static { defaultInstance = new Way(true); defaultInstance.initFields(); } // @@protoc_insertion_point(class_scope:OSMPBF.Way) } public interface RelationOrBuilder extends // @@protoc_insertion_point(interface_extends:OSMPBF.Relation) com.google.protobuf.MessageLiteOrBuilder { /** * required int64 id = 1; */ boolean hasId(); /** * required int64 id = 1; */ long getId(); /** * repeated uint32 keys = 2 [packed = true]; * *
     * Parallel arrays.
     * 
*/ java.util.List getKeysList(); /** * repeated uint32 keys = 2 [packed = true]; * *
     * Parallel arrays.
     * 
*/ int getKeysCount(); /** * repeated uint32 keys = 2 [packed = true]; * *
     * Parallel arrays.
     * 
*/ int getKeys(int index); /** * repeated uint32 vals = 3 [packed = true]; */ java.util.List getValsList(); /** * repeated uint32 vals = 3 [packed = true]; */ int getValsCount(); /** * repeated uint32 vals = 3 [packed = true]; */ int getVals(int index); /** * optional .OSMPBF.Info info = 4; */ boolean hasInfo(); /** * optional .OSMPBF.Info info = 4; */ org.openstreetmap.osmosis.osmbinary.Osmformat.Info getInfo(); /** * repeated int32 roles_sid = 8 [packed = true]; * *
     * Parallel arrays
     * 
*/ java.util.List getRolesSidList(); /** * repeated int32 roles_sid = 8 [packed = true]; * *
     * Parallel arrays
     * 
*/ int getRolesSidCount(); /** * repeated int32 roles_sid = 8 [packed = true]; * *
     * Parallel arrays
     * 
*/ int getRolesSid(int index); /** * repeated sint64 memids = 9 [packed = true]; * *
     * DELTA encoded
     * 
*/ java.util.List getMemidsList(); /** * repeated sint64 memids = 9 [packed = true]; * *
     * DELTA encoded
     * 
*/ int getMemidsCount(); /** * repeated sint64 memids = 9 [packed = true]; * *
     * DELTA encoded
     * 
*/ long getMemids(int index); /** * repeated .OSMPBF.Relation.MemberType types = 10 [packed = true]; */ java.util.List getTypesList(); /** * repeated .OSMPBF.Relation.MemberType types = 10 [packed = true]; */ int getTypesCount(); /** * repeated .OSMPBF.Relation.MemberType types = 10 [packed = true]; */ org.openstreetmap.osmosis.osmbinary.Osmformat.Relation.MemberType getTypes(int index); } /** * Protobuf type {@code OSMPBF.Relation} */ public static final class Relation extends com.google.protobuf.GeneratedMessageLite implements // @@protoc_insertion_point(message_implements:OSMPBF.Relation) RelationOrBuilder { // Use Relation.newBuilder() to construct. private Relation(com.google.protobuf.GeneratedMessageLite.Builder builder) { super(builder); this.unknownFields = builder.getUnknownFields(); } private Relation(boolean noInit) { this.unknownFields = com.google.protobuf.ByteString.EMPTY;} private static final Relation defaultInstance; public static Relation getDefaultInstance() { return defaultInstance; } public Relation getDefaultInstanceForType() { return defaultInstance; } private final com.google.protobuf.ByteString unknownFields; private Relation( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { initFields(); int mutable_bitField0_ = 0; com.google.protobuf.ByteString.Output unknownFieldsOutput = com.google.protobuf.ByteString.newOutput(); com.google.protobuf.CodedOutputStream unknownFieldsCodedOutput = com.google.protobuf.CodedOutputStream.newInstance( unknownFieldsOutput); try { boolean done = false; while (!done) { int tag = input.readTag(); switch (tag) { case 0: done = true; break; default: { if (!parseUnknownField(input, unknownFieldsCodedOutput, extensionRegistry, tag)) { done = true; } break; } case 8: { bitField0_ |= 0x00000001; id_ = input.readInt64(); break; } case 16: { if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) { keys_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000002; } keys_.add(input.readUInt32()); break; } case 18: { int length = input.readRawVarint32(); int limit = input.pushLimit(length); if (!((mutable_bitField0_ & 0x00000002) == 0x00000002) && input.getBytesUntilLimit() > 0) { keys_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000002; } while (input.getBytesUntilLimit() > 0) { keys_.add(input.readUInt32()); } input.popLimit(limit); break; } case 24: { if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) { vals_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000004; } vals_.add(input.readUInt32()); break; } case 26: { int length = input.readRawVarint32(); int limit = input.pushLimit(length); if (!((mutable_bitField0_ & 0x00000004) == 0x00000004) && input.getBytesUntilLimit() > 0) { vals_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000004; } while (input.getBytesUntilLimit() > 0) { vals_.add(input.readUInt32()); } input.popLimit(limit); break; } case 34: { org.openstreetmap.osmosis.osmbinary.Osmformat.Info.Builder subBuilder = null; if (((bitField0_ & 0x00000002) == 0x00000002)) { subBuilder = info_.toBuilder(); } info_ = input.readMessage(org.openstreetmap.osmosis.osmbinary.Osmformat.Info.PARSER, extensionRegistry); if (subBuilder != null) { subBuilder.mergeFrom(info_); info_ = subBuilder.buildPartial(); } bitField0_ |= 0x00000002; break; } case 64: { if (!((mutable_bitField0_ & 0x00000010) == 0x00000010)) { rolesSid_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000010; } rolesSid_.add(input.readInt32()); break; } case 66: { int length = input.readRawVarint32(); int limit = input.pushLimit(length); if (!((mutable_bitField0_ & 0x00000010) == 0x00000010) && input.getBytesUntilLimit() > 0) { rolesSid_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000010; } while (input.getBytesUntilLimit() > 0) { rolesSid_.add(input.readInt32()); } input.popLimit(limit); break; } case 72: { if (!((mutable_bitField0_ & 0x00000020) == 0x00000020)) { memids_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000020; } memids_.add(input.readSInt64()); break; } case 74: { int length = input.readRawVarint32(); int limit = input.pushLimit(length); if (!((mutable_bitField0_ & 0x00000020) == 0x00000020) && input.getBytesUntilLimit() > 0) { memids_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000020; } while (input.getBytesUntilLimit() > 0) { memids_.add(input.readSInt64()); } input.popLimit(limit); break; } case 80: { int rawValue = input.readEnum(); org.openstreetmap.osmosis.osmbinary.Osmformat.Relation.MemberType value = org.openstreetmap.osmosis.osmbinary.Osmformat.Relation.MemberType.valueOf(rawValue); if (value == null) { unknownFieldsCodedOutput.writeRawVarint32(tag); unknownFieldsCodedOutput.writeRawVarint32(rawValue); } else { if (!((mutable_bitField0_ & 0x00000040) == 0x00000040)) { types_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000040; } types_.add(value); } break; } case 82: { int length = input.readRawVarint32(); int oldLimit = input.pushLimit(length); while(input.getBytesUntilLimit() > 0) { int rawValue = input.readEnum(); org.openstreetmap.osmosis.osmbinary.Osmformat.Relation.MemberType value = org.openstreetmap.osmosis.osmbinary.Osmformat.Relation.MemberType.valueOf(rawValue); if (value == null) { unknownFieldsCodedOutput.writeRawVarint32(tag); unknownFieldsCodedOutput.writeRawVarint32(rawValue); } else { if (!((mutable_bitField0_ & 0x00000040) == 0x00000040)) { types_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000040; } types_.add(value); } } input.popLimit(oldLimit); break; } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { throw e.setUnfinishedMessage(this); } catch (java.io.IOException e) { throw new com.google.protobuf.InvalidProtocolBufferException( e.getMessage()).setUnfinishedMessage(this); } finally { if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) { keys_ = java.util.Collections.unmodifiableList(keys_); } if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) { vals_ = java.util.Collections.unmodifiableList(vals_); } if (((mutable_bitField0_ & 0x00000010) == 0x00000010)) { rolesSid_ = java.util.Collections.unmodifiableList(rolesSid_); } if (((mutable_bitField0_ & 0x00000020) == 0x00000020)) { memids_ = java.util.Collections.unmodifiableList(memids_); } if (((mutable_bitField0_ & 0x00000040) == 0x00000040)) { types_ = java.util.Collections.unmodifiableList(types_); } try { unknownFieldsCodedOutput.flush(); } catch (java.io.IOException e) { // Should not happen } finally { unknownFields = unknownFieldsOutput.toByteString(); } makeExtensionsImmutable(); } } public static com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { public Relation parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return new Relation(input, extensionRegistry); } }; @java.lang.Override public com.google.protobuf.Parser getParserForType() { return PARSER; } /** * Protobuf enum {@code OSMPBF.Relation.MemberType} */ public enum MemberType implements com.google.protobuf.Internal.EnumLite { /** * NODE = 0; */ NODE(0, 0), /** * WAY = 1; */ WAY(1, 1), /** * RELATION = 2; */ RELATION(2, 2), ; /** * NODE = 0; */ public static final int NODE_VALUE = 0; /** * WAY = 1; */ public static final int WAY_VALUE = 1; /** * RELATION = 2; */ public static final int RELATION_VALUE = 2; public final int getNumber() { return value; } public static MemberType valueOf(int value) { switch (value) { case 0: return NODE; case 1: return WAY; case 2: return RELATION; default: return null; } } public static com.google.protobuf.Internal.EnumLiteMap internalGetValueMap() { return internalValueMap; } private static com.google.protobuf.Internal.EnumLiteMap internalValueMap = new com.google.protobuf.Internal.EnumLiteMap() { public MemberType findValueByNumber(int number) { return MemberType.valueOf(number); } }; private final int value; private MemberType(int index, int value) { this.value = value; } // @@protoc_insertion_point(enum_scope:OSMPBF.Relation.MemberType) } private int bitField0_; public static final int ID_FIELD_NUMBER = 1; private long id_; /** * required int64 id = 1; */ public boolean hasId() { return ((bitField0_ & 0x00000001) == 0x00000001); } /** * required int64 id = 1; */ public long getId() { return id_; } public static final int KEYS_FIELD_NUMBER = 2; private java.util.List keys_; /** * repeated uint32 keys = 2 [packed = true]; * *
     * Parallel arrays.
     * 
*/ public java.util.List getKeysList() { return keys_; } /** * repeated uint32 keys = 2 [packed = true]; * *
     * Parallel arrays.
     * 
*/ public int getKeysCount() { return keys_.size(); } /** * repeated uint32 keys = 2 [packed = true]; * *
     * Parallel arrays.
     * 
*/ public int getKeys(int index) { return keys_.get(index); } private int keysMemoizedSerializedSize = -1; public static final int VALS_FIELD_NUMBER = 3; private java.util.List vals_; /** * repeated uint32 vals = 3 [packed = true]; */ public java.util.List getValsList() { return vals_; } /** * repeated uint32 vals = 3 [packed = true]; */ public int getValsCount() { return vals_.size(); } /** * repeated uint32 vals = 3 [packed = true]; */ public int getVals(int index) { return vals_.get(index); } private int valsMemoizedSerializedSize = -1; public static final int INFO_FIELD_NUMBER = 4; private org.openstreetmap.osmosis.osmbinary.Osmformat.Info info_; /** * optional .OSMPBF.Info info = 4; */ public boolean hasInfo() { return ((bitField0_ & 0x00000002) == 0x00000002); } /** * optional .OSMPBF.Info info = 4; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.Info getInfo() { return info_; } public static final int ROLES_SID_FIELD_NUMBER = 8; private java.util.List rolesSid_; /** * repeated int32 roles_sid = 8 [packed = true]; * *
     * Parallel arrays
     * 
*/ public java.util.List getRolesSidList() { return rolesSid_; } /** * repeated int32 roles_sid = 8 [packed = true]; * *
     * Parallel arrays
     * 
*/ public int getRolesSidCount() { return rolesSid_.size(); } /** * repeated int32 roles_sid = 8 [packed = true]; * *
     * Parallel arrays
     * 
*/ public int getRolesSid(int index) { return rolesSid_.get(index); } private int rolesSidMemoizedSerializedSize = -1; public static final int MEMIDS_FIELD_NUMBER = 9; private java.util.List memids_; /** * repeated sint64 memids = 9 [packed = true]; * *
     * DELTA encoded
     * 
*/ public java.util.List getMemidsList() { return memids_; } /** * repeated sint64 memids = 9 [packed = true]; * *
     * DELTA encoded
     * 
*/ public int getMemidsCount() { return memids_.size(); } /** * repeated sint64 memids = 9 [packed = true]; * *
     * DELTA encoded
     * 
*/ public long getMemids(int index) { return memids_.get(index); } private int memidsMemoizedSerializedSize = -1; public static final int TYPES_FIELD_NUMBER = 10; private java.util.List types_; /** * repeated .OSMPBF.Relation.MemberType types = 10 [packed = true]; */ public java.util.List getTypesList() { return types_; } /** * repeated .OSMPBF.Relation.MemberType types = 10 [packed = true]; */ public int getTypesCount() { return types_.size(); } /** * repeated .OSMPBF.Relation.MemberType types = 10 [packed = true]; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.Relation.MemberType getTypes(int index) { return types_.get(index); } private int typesMemoizedSerializedSize; private void initFields() { id_ = 0L; keys_ = java.util.Collections.emptyList(); vals_ = java.util.Collections.emptyList(); info_ = org.openstreetmap.osmosis.osmbinary.Osmformat.Info.getDefaultInstance(); rolesSid_ = java.util.Collections.emptyList(); memids_ = java.util.Collections.emptyList(); types_ = java.util.Collections.emptyList(); } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized == 1) return true; if (isInitialized == 0) return false; if (!hasId()) { memoizedIsInitialized = 0; return false; } memoizedIsInitialized = 1; return true; } public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { getSerializedSize(); if (((bitField0_ & 0x00000001) == 0x00000001)) { output.writeInt64(1, id_); } if (getKeysList().size() > 0) { output.writeRawVarint32(18); output.writeRawVarint32(keysMemoizedSerializedSize); } for (int i = 0; i < keys_.size(); i++) { output.writeUInt32NoTag(keys_.get(i)); } if (getValsList().size() > 0) { output.writeRawVarint32(26); output.writeRawVarint32(valsMemoizedSerializedSize); } for (int i = 0; i < vals_.size(); i++) { output.writeUInt32NoTag(vals_.get(i)); } if (((bitField0_ & 0x00000002) == 0x00000002)) { output.writeMessage(4, info_); } if (getRolesSidList().size() > 0) { output.writeRawVarint32(66); output.writeRawVarint32(rolesSidMemoizedSerializedSize); } for (int i = 0; i < rolesSid_.size(); i++) { output.writeInt32NoTag(rolesSid_.get(i)); } if (getMemidsList().size() > 0) { output.writeRawVarint32(74); output.writeRawVarint32(memidsMemoizedSerializedSize); } for (int i = 0; i < memids_.size(); i++) { output.writeSInt64NoTag(memids_.get(i)); } if (getTypesList().size() > 0) { output.writeRawVarint32(82); output.writeRawVarint32(typesMemoizedSerializedSize); } for (int i = 0; i < types_.size(); i++) { output.writeEnumNoTag(types_.get(i).getNumber()); } output.writeRawBytes(unknownFields); } private int memoizedSerializedSize = -1; public int getSerializedSize() { int size = memoizedSerializedSize; if (size != -1) return size; size = 0; if (((bitField0_ & 0x00000001) == 0x00000001)) { size += com.google.protobuf.CodedOutputStream .computeInt64Size(1, id_); } { int dataSize = 0; for (int i = 0; i < keys_.size(); i++) { dataSize += com.google.protobuf.CodedOutputStream .computeUInt32SizeNoTag(keys_.get(i)); } size += dataSize; if (!getKeysList().isEmpty()) { size += 1; size += com.google.protobuf.CodedOutputStream .computeInt32SizeNoTag(dataSize); } keysMemoizedSerializedSize = dataSize; } { int dataSize = 0; for (int i = 0; i < vals_.size(); i++) { dataSize += com.google.protobuf.CodedOutputStream .computeUInt32SizeNoTag(vals_.get(i)); } size += dataSize; if (!getValsList().isEmpty()) { size += 1; size += com.google.protobuf.CodedOutputStream .computeInt32SizeNoTag(dataSize); } valsMemoizedSerializedSize = dataSize; } if (((bitField0_ & 0x00000002) == 0x00000002)) { size += com.google.protobuf.CodedOutputStream .computeMessageSize(4, info_); } { int dataSize = 0; for (int i = 0; i < rolesSid_.size(); i++) { dataSize += com.google.protobuf.CodedOutputStream .computeInt32SizeNoTag(rolesSid_.get(i)); } size += dataSize; if (!getRolesSidList().isEmpty()) { size += 1; size += com.google.protobuf.CodedOutputStream .computeInt32SizeNoTag(dataSize); } rolesSidMemoizedSerializedSize = dataSize; } { int dataSize = 0; for (int i = 0; i < memids_.size(); i++) { dataSize += com.google.protobuf.CodedOutputStream .computeSInt64SizeNoTag(memids_.get(i)); } size += dataSize; if (!getMemidsList().isEmpty()) { size += 1; size += com.google.protobuf.CodedOutputStream .computeInt32SizeNoTag(dataSize); } memidsMemoizedSerializedSize = dataSize; } { int dataSize = 0; for (int i = 0; i < types_.size(); i++) { dataSize += com.google.protobuf.CodedOutputStream .computeEnumSizeNoTag(types_.get(i).getNumber()); } size += dataSize; if (!getTypesList().isEmpty()) { size += 1; size += com.google.protobuf.CodedOutputStream .computeRawVarint32Size(dataSize); }typesMemoizedSerializedSize = dataSize; } size += unknownFields.size(); memoizedSerializedSize = size; return size; } private static final long serialVersionUID = 0L; @java.lang.Override protected java.lang.Object writeReplace() throws java.io.ObjectStreamException { return super.writeReplace(); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Relation parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Relation parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Relation parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Relation parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Relation parseFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Relation parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Relation parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseDelimitedFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Relation parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseDelimitedFrom(input, extensionRegistry); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Relation parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } public static org.openstreetmap.osmosis.osmbinary.Osmformat.Relation parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } public static Builder newBuilder() { return Builder.create(); } public Builder newBuilderForType() { return newBuilder(); } public static Builder newBuilder(org.openstreetmap.osmosis.osmbinary.Osmformat.Relation prototype) { return newBuilder().mergeFrom(prototype); } public Builder toBuilder() { return newBuilder(this); } /** * Protobuf type {@code OSMPBF.Relation} */ public static final class Builder extends com.google.protobuf.GeneratedMessageLite.Builder< org.openstreetmap.osmosis.osmbinary.Osmformat.Relation, Builder> implements // @@protoc_insertion_point(builder_implements:OSMPBF.Relation) org.openstreetmap.osmosis.osmbinary.Osmformat.RelationOrBuilder { // Construct using org.openstreetmap.osmosis.osmbinary.Osmformat.Relation.newBuilder() private Builder() { maybeForceBuilderInitialization(); } private void maybeForceBuilderInitialization() { } private static Builder create() { return new Builder(); } public Builder clear() { super.clear(); id_ = 0L; bitField0_ = (bitField0_ & ~0x00000001); keys_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000002); vals_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000004); info_ = org.openstreetmap.osmosis.osmbinary.Osmformat.Info.getDefaultInstance(); bitField0_ = (bitField0_ & ~0x00000008); rolesSid_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000010); memids_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000020); types_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000040); return this; } public Builder clone() { return create().mergeFrom(buildPartial()); } public org.openstreetmap.osmosis.osmbinary.Osmformat.Relation getDefaultInstanceForType() { return org.openstreetmap.osmosis.osmbinary.Osmformat.Relation.getDefaultInstance(); } public org.openstreetmap.osmosis.osmbinary.Osmformat.Relation build() { org.openstreetmap.osmosis.osmbinary.Osmformat.Relation result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } public org.openstreetmap.osmosis.osmbinary.Osmformat.Relation buildPartial() { org.openstreetmap.osmosis.osmbinary.Osmformat.Relation result = new org.openstreetmap.osmosis.osmbinary.Osmformat.Relation(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) == 0x00000001)) { to_bitField0_ |= 0x00000001; } result.id_ = id_; if (((bitField0_ & 0x00000002) == 0x00000002)) { keys_ = java.util.Collections.unmodifiableList(keys_); bitField0_ = (bitField0_ & ~0x00000002); } result.keys_ = keys_; if (((bitField0_ & 0x00000004) == 0x00000004)) { vals_ = java.util.Collections.unmodifiableList(vals_); bitField0_ = (bitField0_ & ~0x00000004); } result.vals_ = vals_; if (((from_bitField0_ & 0x00000008) == 0x00000008)) { to_bitField0_ |= 0x00000002; } result.info_ = info_; if (((bitField0_ & 0x00000010) == 0x00000010)) { rolesSid_ = java.util.Collections.unmodifiableList(rolesSid_); bitField0_ = (bitField0_ & ~0x00000010); } result.rolesSid_ = rolesSid_; if (((bitField0_ & 0x00000020) == 0x00000020)) { memids_ = java.util.Collections.unmodifiableList(memids_); bitField0_ = (bitField0_ & ~0x00000020); } result.memids_ = memids_; if (((bitField0_ & 0x00000040) == 0x00000040)) { types_ = java.util.Collections.unmodifiableList(types_); bitField0_ = (bitField0_ & ~0x00000040); } result.types_ = types_; result.bitField0_ = to_bitField0_; return result; } public Builder mergeFrom(org.openstreetmap.osmosis.osmbinary.Osmformat.Relation other) { if (other == org.openstreetmap.osmosis.osmbinary.Osmformat.Relation.getDefaultInstance()) return this; if (other.hasId()) { setId(other.getId()); } if (!other.keys_.isEmpty()) { if (keys_.isEmpty()) { keys_ = other.keys_; bitField0_ = (bitField0_ & ~0x00000002); } else { ensureKeysIsMutable(); keys_.addAll(other.keys_); } } if (!other.vals_.isEmpty()) { if (vals_.isEmpty()) { vals_ = other.vals_; bitField0_ = (bitField0_ & ~0x00000004); } else { ensureValsIsMutable(); vals_.addAll(other.vals_); } } if (other.hasInfo()) { mergeInfo(other.getInfo()); } if (!other.rolesSid_.isEmpty()) { if (rolesSid_.isEmpty()) { rolesSid_ = other.rolesSid_; bitField0_ = (bitField0_ & ~0x00000010); } else { ensureRolesSidIsMutable(); rolesSid_.addAll(other.rolesSid_); } } if (!other.memids_.isEmpty()) { if (memids_.isEmpty()) { memids_ = other.memids_; bitField0_ = (bitField0_ & ~0x00000020); } else { ensureMemidsIsMutable(); memids_.addAll(other.memids_); } } if (!other.types_.isEmpty()) { if (types_.isEmpty()) { types_ = other.types_; bitField0_ = (bitField0_ & ~0x00000040); } else { ensureTypesIsMutable(); types_.addAll(other.types_); } } setUnknownFields( getUnknownFields().concat(other.unknownFields)); return this; } public final boolean isInitialized() { if (!hasId()) { return false; } return true; } public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { org.openstreetmap.osmosis.osmbinary.Osmformat.Relation parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { parsedMessage = (org.openstreetmap.osmosis.osmbinary.Osmformat.Relation) e.getUnfinishedMessage(); throw e; } finally { if (parsedMessage != null) { mergeFrom(parsedMessage); } } return this; } private int bitField0_; private long id_ ; /** * required int64 id = 1; */ public boolean hasId() { return ((bitField0_ & 0x00000001) == 0x00000001); } /** * required int64 id = 1; */ public long getId() { return id_; } /** * required int64 id = 1; */ public Builder setId(long value) { bitField0_ |= 0x00000001; id_ = value; return this; } /** * required int64 id = 1; */ public Builder clearId() { bitField0_ = (bitField0_ & ~0x00000001); id_ = 0L; return this; } private java.util.List keys_ = java.util.Collections.emptyList(); private void ensureKeysIsMutable() { if (!((bitField0_ & 0x00000002) == 0x00000002)) { keys_ = new java.util.ArrayList(keys_); bitField0_ |= 0x00000002; } } /** * repeated uint32 keys = 2 [packed = true]; * *
       * Parallel arrays.
       * 
*/ public java.util.List getKeysList() { return java.util.Collections.unmodifiableList(keys_); } /** * repeated uint32 keys = 2 [packed = true]; * *
       * Parallel arrays.
       * 
*/ public int getKeysCount() { return keys_.size(); } /** * repeated uint32 keys = 2 [packed = true]; * *
       * Parallel arrays.
       * 
*/ public int getKeys(int index) { return keys_.get(index); } /** * repeated uint32 keys = 2 [packed = true]; * *
       * Parallel arrays.
       * 
*/ public Builder setKeys( int index, int value) { ensureKeysIsMutable(); keys_.set(index, value); return this; } /** * repeated uint32 keys = 2 [packed = true]; * *
       * Parallel arrays.
       * 
*/ public Builder addKeys(int value) { ensureKeysIsMutable(); keys_.add(value); return this; } /** * repeated uint32 keys = 2 [packed = true]; * *
       * Parallel arrays.
       * 
*/ public Builder addAllKeys( java.lang.Iterable values) { ensureKeysIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, keys_); return this; } /** * repeated uint32 keys = 2 [packed = true]; * *
       * Parallel arrays.
       * 
*/ public Builder clearKeys() { keys_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000002); return this; } private java.util.List vals_ = java.util.Collections.emptyList(); private void ensureValsIsMutable() { if (!((bitField0_ & 0x00000004) == 0x00000004)) { vals_ = new java.util.ArrayList(vals_); bitField0_ |= 0x00000004; } } /** * repeated uint32 vals = 3 [packed = true]; */ public java.util.List getValsList() { return java.util.Collections.unmodifiableList(vals_); } /** * repeated uint32 vals = 3 [packed = true]; */ public int getValsCount() { return vals_.size(); } /** * repeated uint32 vals = 3 [packed = true]; */ public int getVals(int index) { return vals_.get(index); } /** * repeated uint32 vals = 3 [packed = true]; */ public Builder setVals( int index, int value) { ensureValsIsMutable(); vals_.set(index, value); return this; } /** * repeated uint32 vals = 3 [packed = true]; */ public Builder addVals(int value) { ensureValsIsMutable(); vals_.add(value); return this; } /** * repeated uint32 vals = 3 [packed = true]; */ public Builder addAllVals( java.lang.Iterable values) { ensureValsIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, vals_); return this; } /** * repeated uint32 vals = 3 [packed = true]; */ public Builder clearVals() { vals_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000004); return this; } private org.openstreetmap.osmosis.osmbinary.Osmformat.Info info_ = org.openstreetmap.osmosis.osmbinary.Osmformat.Info.getDefaultInstance(); /** * optional .OSMPBF.Info info = 4; */ public boolean hasInfo() { return ((bitField0_ & 0x00000008) == 0x00000008); } /** * optional .OSMPBF.Info info = 4; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.Info getInfo() { return info_; } /** * optional .OSMPBF.Info info = 4; */ public Builder setInfo(org.openstreetmap.osmosis.osmbinary.Osmformat.Info value) { if (value == null) { throw new NullPointerException(); } info_ = value; bitField0_ |= 0x00000008; return this; } /** * optional .OSMPBF.Info info = 4; */ public Builder setInfo( org.openstreetmap.osmosis.osmbinary.Osmformat.Info.Builder builderForValue) { info_ = builderForValue.build(); bitField0_ |= 0x00000008; return this; } /** * optional .OSMPBF.Info info = 4; */ public Builder mergeInfo(org.openstreetmap.osmosis.osmbinary.Osmformat.Info value) { if (((bitField0_ & 0x00000008) == 0x00000008) && info_ != org.openstreetmap.osmosis.osmbinary.Osmformat.Info.getDefaultInstance()) { info_ = org.openstreetmap.osmosis.osmbinary.Osmformat.Info.newBuilder(info_).mergeFrom(value).buildPartial(); } else { info_ = value; } bitField0_ |= 0x00000008; return this; } /** * optional .OSMPBF.Info info = 4; */ public Builder clearInfo() { info_ = org.openstreetmap.osmosis.osmbinary.Osmformat.Info.getDefaultInstance(); bitField0_ = (bitField0_ & ~0x00000008); return this; } private java.util.List rolesSid_ = java.util.Collections.emptyList(); private void ensureRolesSidIsMutable() { if (!((bitField0_ & 0x00000010) == 0x00000010)) { rolesSid_ = new java.util.ArrayList(rolesSid_); bitField0_ |= 0x00000010; } } /** * repeated int32 roles_sid = 8 [packed = true]; * *
       * Parallel arrays
       * 
*/ public java.util.List getRolesSidList() { return java.util.Collections.unmodifiableList(rolesSid_); } /** * repeated int32 roles_sid = 8 [packed = true]; * *
       * Parallel arrays
       * 
*/ public int getRolesSidCount() { return rolesSid_.size(); } /** * repeated int32 roles_sid = 8 [packed = true]; * *
       * Parallel arrays
       * 
*/ public int getRolesSid(int index) { return rolesSid_.get(index); } /** * repeated int32 roles_sid = 8 [packed = true]; * *
       * Parallel arrays
       * 
*/ public Builder setRolesSid( int index, int value) { ensureRolesSidIsMutable(); rolesSid_.set(index, value); return this; } /** * repeated int32 roles_sid = 8 [packed = true]; * *
       * Parallel arrays
       * 
*/ public Builder addRolesSid(int value) { ensureRolesSidIsMutable(); rolesSid_.add(value); return this; } /** * repeated int32 roles_sid = 8 [packed = true]; * *
       * Parallel arrays
       * 
*/ public Builder addAllRolesSid( java.lang.Iterable values) { ensureRolesSidIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, rolesSid_); return this; } /** * repeated int32 roles_sid = 8 [packed = true]; * *
       * Parallel arrays
       * 
*/ public Builder clearRolesSid() { rolesSid_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000010); return this; } private java.util.List memids_ = java.util.Collections.emptyList(); private void ensureMemidsIsMutable() { if (!((bitField0_ & 0x00000020) == 0x00000020)) { memids_ = new java.util.ArrayList(memids_); bitField0_ |= 0x00000020; } } /** * repeated sint64 memids = 9 [packed = true]; * *
       * DELTA encoded
       * 
*/ public java.util.List getMemidsList() { return java.util.Collections.unmodifiableList(memids_); } /** * repeated sint64 memids = 9 [packed = true]; * *
       * DELTA encoded
       * 
*/ public int getMemidsCount() { return memids_.size(); } /** * repeated sint64 memids = 9 [packed = true]; * *
       * DELTA encoded
       * 
*/ public long getMemids(int index) { return memids_.get(index); } /** * repeated sint64 memids = 9 [packed = true]; * *
       * DELTA encoded
       * 
*/ public Builder setMemids( int index, long value) { ensureMemidsIsMutable(); memids_.set(index, value); return this; } /** * repeated sint64 memids = 9 [packed = true]; * *
       * DELTA encoded
       * 
*/ public Builder addMemids(long value) { ensureMemidsIsMutable(); memids_.add(value); return this; } /** * repeated sint64 memids = 9 [packed = true]; * *
       * DELTA encoded
       * 
*/ public Builder addAllMemids( java.lang.Iterable values) { ensureMemidsIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, memids_); return this; } /** * repeated sint64 memids = 9 [packed = true]; * *
       * DELTA encoded
       * 
*/ public Builder clearMemids() { memids_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000020); return this; } private java.util.List types_ = java.util.Collections.emptyList(); private void ensureTypesIsMutable() { if (!((bitField0_ & 0x00000040) == 0x00000040)) { types_ = new java.util.ArrayList(types_); bitField0_ |= 0x00000040; } } /** * repeated .OSMPBF.Relation.MemberType types = 10 [packed = true]; */ public java.util.List getTypesList() { return java.util.Collections.unmodifiableList(types_); } /** * repeated .OSMPBF.Relation.MemberType types = 10 [packed = true]; */ public int getTypesCount() { return types_.size(); } /** * repeated .OSMPBF.Relation.MemberType types = 10 [packed = true]; */ public org.openstreetmap.osmosis.osmbinary.Osmformat.Relation.MemberType getTypes(int index) { return types_.get(index); } /** * repeated .OSMPBF.Relation.MemberType types = 10 [packed = true]; */ public Builder setTypes( int index, org.openstreetmap.osmosis.osmbinary.Osmformat.Relation.MemberType value) { if (value == null) { throw new NullPointerException(); } ensureTypesIsMutable(); types_.set(index, value); return this; } /** * repeated .OSMPBF.Relation.MemberType types = 10 [packed = true]; */ public Builder addTypes(org.openstreetmap.osmosis.osmbinary.Osmformat.Relation.MemberType value) { if (value == null) { throw new NullPointerException(); } ensureTypesIsMutable(); types_.add(value); return this; } /** * repeated .OSMPBF.Relation.MemberType types = 10 [packed = true]; */ public Builder addAllTypes( java.lang.Iterable values) { ensureTypesIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, types_); return this; } /** * repeated .OSMPBF.Relation.MemberType types = 10 [packed = true]; */ public Builder clearTypes() { types_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000040); return this; } // @@protoc_insertion_point(builder_scope:OSMPBF.Relation) } static { defaultInstance = new Relation(true); defaultInstance.initFields(); } // @@protoc_insertion_point(class_scope:OSMPBF.Relation) } static { } // @@protoc_insertion_point(outer_class_scope) } osmosis-0.44.1/osmosis-osm-binary/osmosis-protoc.sh000077500000000000000000000001641253404521400224060ustar00rootroot00000000000000#!/bin/sh protoc --java_out=gen-src/main/java src/main/protobuf/fileformat.proto src/main/protobuf/osmformat.proto osmosis-0.44.1/osmosis-osm-binary/readme.txt000066400000000000000000000022101253404521400210370ustar00rootroot00000000000000This is a customised version of Scott Crosby's PBF library. The original version is here: https://github.com/scrosby/OSM-binary The original library is not available on Maven Central, but Osmosis has a dependency on it. Therefore the original library has been modified to be built as part of Osmosis and the code is renamed to live under an Osmosis package name. This re-packaging avoids any conflicts if other versions of the library exist on a target classpath. This codebase is maintained at the following location on the osmosis branch: https://github.com/brettch/OSM-binary The osmosis branch contains a number of customisations including: * Change to use an Osmosis package name. * Remove all C code, and any other unnecessary files. * Add Osmosis compatible Gradle build script. The Osmosis repository contains a copy of this codebase, but it is not the master location. It is manually updated to remain in sync with the above location whenever necessary. It would have been possible to do a true merge into the Osmosis repository, but this would have resulted in full history of both repositories being included which may have been confusing. osmosis-0.44.1/osmosis-osm-binary/src/000077500000000000000000000000001253404521400176355ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/src/main/000077500000000000000000000000001253404521400205615ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/src/main/java/000077500000000000000000000000001253404521400215025ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/src/main/java/org/000077500000000000000000000000001253404521400222715ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/src/main/java/org/openstreetmap/000077500000000000000000000000001253404521400251575ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/src/main/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400266535ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/src/main/java/org/openstreetmap/osmosis/osmbinary/000077500000000000000000000000001253404521400306565ustar00rootroot00000000000000BinaryParser.java000066400000000000000000000127051253404521400340500ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/src/main/java/org/openstreetmap/osmosis/osmbinary/** Copyright (c) 2010 Scott A. Crosby. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package org.openstreetmap.osmosis.osmbinary; import java.util.Date; import java.util.List; import com.google.protobuf.InvalidProtocolBufferException; import org.openstreetmap.osmosis.osmbinary.Osmformat; import org.openstreetmap.osmosis.osmbinary.file.BlockReaderAdapter; import org.openstreetmap.osmosis.osmbinary.file.FileBlock; import org.openstreetmap.osmosis.osmbinary.file.FileBlockPosition; public abstract class BinaryParser implements BlockReaderAdapter { protected int granularity; private long lat_offset; private long lon_offset; protected int date_granularity; private String strings[]; /** Take a Info protocol buffer containing a date and convert it into a java Date object */ protected Date getDate(Osmformat.Info info) { if (info.hasTimestamp()) { return new Date(date_granularity * (long) info.getTimestamp()); } else return NODATE; } public static final Date NODATE = new Date(-1); /** Get a string based on the index used. * * Index 0 is reserved to use as a delimiter, therefore, index 1 corresponds to the first string in the table * @param id * @return */ protected String getStringById(int id) { return strings[id]; } @Override public void handleBlock(FileBlock message) { // TODO Auto-generated method stub try { if (message.getType().equals("OSMHeader")) { Osmformat.HeaderBlock headerblock = Osmformat.HeaderBlock .parseFrom(message.getData()); parse(headerblock); } else if (message.getType().equals("OSMData")) { Osmformat.PrimitiveBlock primblock = Osmformat.PrimitiveBlock .parseFrom(message.getData()); parse(primblock); } } catch (InvalidProtocolBufferException e) { // TODO Auto-generated catch block e.printStackTrace(); throw new Error("ParseError"); // TODO } } @Override public boolean skipBlock(FileBlockPosition block) { // System.out.println("Seeing block of type: "+block.getType()); if (block.getType().equals("OSMData")) return false; if (block.getType().equals("OSMHeader")) return false; System.out.println("Skipped block of type: " + block.getType()); return true; } /** Convert a latitude value stored in a protobuf into a double, compensating for granularity and latitude offset */ public double parseLat(long degree) { // Support non-zero offsets. (We don't currently generate them) return (granularity * degree + lat_offset) * .000000001; } /** Convert a longitude value stored in a protobuf into a double, compensating for granularity and longitude offset */ public double parseLon(long degree) { // Support non-zero offsets. (We don't currently generate them) return (granularity * degree + lon_offset) * .000000001; } /** Parse a Primitive block (containing a string table, other paramaters, and PrimitiveGroups */ public void parse(Osmformat.PrimitiveBlock block) { Osmformat.StringTable stablemessage = block.getStringtable(); strings = new String[stablemessage.getSCount()]; for (int i = 0; i < strings.length; i++) { strings[i] = stablemessage.getS(i).toStringUtf8(); } granularity = block.getGranularity(); lat_offset = block.getLatOffset(); lon_offset = block.getLonOffset(); date_granularity = block.getDateGranularity(); for (Osmformat.PrimitiveGroup groupmessage : block .getPrimitivegroupList()) { // Exactly one of these should trigger on each loop. parseNodes(groupmessage.getNodesList()); parseWays(groupmessage.getWaysList()); parseRelations(groupmessage.getRelationsList()); if (groupmessage.hasDense()) parseDense(groupmessage.getDense()); } } /** Parse a list of Relation protocol buffers and send the resulting relations to a sink. */ protected abstract void parseRelations(List rels); /** Parse a DenseNode protocol buffer and send the resulting nodes to a sink. */ protected abstract void parseDense(Osmformat.DenseNodes nodes); /** Parse a list of Node protocol buffers and send the resulting nodes to a sink. */ protected abstract void parseNodes(List nodes); /** Parse a list of Way protocol buffers and send the resulting ways to a sink. */ protected abstract void parseWays(List ways); /** Parse a header message. */ protected abstract void parse(Osmformat.HeaderBlock header); }BinarySerializer.java000066400000000000000000000126131253404521400347230ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/src/main/java/org/openstreetmap/osmosis/osmbinary/** Copyright (c) 2010 Scott A. Crosby. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package org.openstreetmap.osmosis.osmbinary; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup; import org.openstreetmap.osmosis.osmbinary.file.BlockOutputStream; import org.openstreetmap.osmosis.osmbinary.file.FileBlock; /** * Generic serializer common code * * Serialize a set of blobs and process them. Subclasses implement handlers for * different API's (osmosis, mkgmap, splitter, etc.) * * All data is converted into PrimGroupWriterInterface objects, which are then * ordered to process their data at the appropriate time. * */ public class BinarySerializer { /** * Interface used to write a group of primitives. One of these for each * group type (Node, Way, Relation, DenseNode, Changeset) */ protected interface PrimGroupWriterInterface { /** This callback is invoked on each group that is going into the fileblock in order to give it a chance to * add to the stringtable pool of strings. */ public void addStringsToStringtable(); /** * This callback is invoked to request that the primgroup serialize itself into the given protocol buffer object. */ public Osmformat.PrimitiveGroup serialize(); } /** Set the granularity (precision of lat/lon, measured in unites of nanodegrees. */ public void configGranularity(int granularity) { this.granularity = granularity; } /** Set whether metadata is to be omitted */ public void configOmit(boolean omit_metadata) { this.omit_metadata = omit_metadata; } /** Configure the maximum number of entities in a batch */ public void configBatchLimit(int batch_limit) { this.batch_limit = batch_limit; } // Paramaters affecting the output size. protected final int MIN_DENSE = 10; protected int batch_limit = 4000; // Parmaters affecting the output. protected int granularity = 100; protected int date_granularity = 1000; protected boolean omit_metadata = false; /** How many primitives have been seen in this batch */ protected int batch_size = 0; protected int total_entities = 0; private StringTable stringtable = new StringTable(); protected List groups = new ArrayList(); protected BlockOutputStream output; public BinarySerializer(BlockOutputStream output) { this.output = output; } public StringTable getStringTable() { return stringtable; } public void flush() throws IOException { processBatch(); output.flush(); } public void close() throws IOException { flush(); output.close(); } long debug_bytes = 0; public void processBatch() { // System.out.format("Batch of %d groups: ",groups.size()); if (groups.size() == 0) return; Osmformat.PrimitiveBlock.Builder primblock = Osmformat.PrimitiveBlock .newBuilder(); stringtable.clear(); // Preprocessing: Figure out the stringtable. for (PrimGroupWriterInterface i : groups) i.addStringsToStringtable(); stringtable.finish(); // Now, start serializing. for (PrimGroupWriterInterface i : groups) { PrimitiveGroup group = i.serialize(); if (group != null) primblock.addPrimitivegroup(group); } primblock.setStringtable(stringtable.serialize()); primblock.setGranularity(this.granularity); primblock.setDateGranularity(this.date_granularity); // Only generate data with offset (0,0) // Osmformat.PrimitiveBlock message = primblock.build(); // System.out.println(message); debug_bytes += message.getSerializedSize(); // if (message.getSerializedSize() > 1000000) // System.out.println(message); try { output.write(FileBlock.newInstance("OSMData", message .toByteString(), null)); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); throw new Error(e); } finally { batch_size = 0; groups.clear(); } // System.out.format("\n"); } /** Convert from a degrees represented as a double into the serialized offset in nanodegrees.. */ public long mapRawDegrees(double degrees) { return (long) ((degrees / .000000001)); } /** Convert from a degrees represented as a double into the serialized offset. */ public int mapDegrees(double degrees) { return (int) ((degrees / .0000001) / (granularity / 100)); } } osmosis-0.44.1/osmosis-osm-binary/src/main/java/org/openstreetmap/osmosis/osmbinary/StringTable.java000066400000000000000000000127051253404521400337440ustar00rootroot00000000000000/** Copyright (c) 2010 Scott A. Crosby. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package org.openstreetmap.osmosis.osmbinary; import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import com.google.protobuf.ByteString; /** * Class for mapping a set of strings to integers, giving frequently occuring * strings small integers. */ public class StringTable { public StringTable() { clear(); } private HashMap counts; private HashMap stringmap; private String set[]; public void incr(String s) { if (counts.containsKey(s)) { counts.put(s, new Integer(counts.get(s).intValue() + 1)); } else { counts.put(s, new Integer(1)); } } /** After the stringtable has been built, return the offset of a string in it. * * Note, value '0' is reserved for use as a delimiter and will not be returned. * @param s * @return */ public int getIndex(String s) { return stringmap.get(s).intValue(); } public void finish() { Comparator comparator = new Comparator() { @Override public int compare(final String s1, String s2) { int diff = counts.get(s2) - counts.get(s1); return diff; } }; /* Sort the stringtable */ /* When a string is referenced, strings in the stringtable with indices: 0 : Is reserved (used as a delimiter in tags A: 1 to 127 : Uses can be represented with 1 byte B: 128 to 128**2-1 : Uses can be represented with 2 bytes, C: 128*128 to X : Uses can be represented with 3 bytes in the unlikely case we have >16k strings in a block. No block will contain enough strings that we'll need 4 bytes. There are goals that will improve compression: 1. I want to use 1 bytes for the most frequently occurring strings, then 2 bytes, then 3 bytes. 2. I want to use low integers as frequently as possible (for better entropy encoding out of deflate) 3. I want the stringtable to compress as small as possible. Condition 1 is obvious. Condition 2 makes deflate compress stringtable references more effectively. When compressing entities, delta coding causes small positive integers to occur more frequently than larger integers. Even though a stringtable references to indices of 1 and 127 both use one byte in a decompressed file, the small integer bias causes deflate to use fewer bits to represent the smaller index when compressed. Condition 3 is most effective when adjacent strings in the stringtable have a lot of common substrings. So, when I decide on the master stringtable to use, I put the 127 most frequently occurring strings into A (accomplishing goal 1), and sort them by frequency (to accomplish goal 2), but for B and C, which contain the less progressively less frequently encountered strings, I sort them lexiconographically, to maximize goal 3 and ignoring goal 2. Goal 1 is the most important. Goal 2 helped enough to be worth it, and goal 3 was pretty minor, but all should be re-benchmarked. */ set = counts.keySet().toArray(new String[0]); if (set.length > 0) { // Sort based on the frequency. Arrays.sort(set, comparator); // Each group of keys that serializes to the same number of bytes is // sorted lexiconographically. // to maximize deflate compression. // Don't sort the first array. There's not likely to be much benefit, and we want frequent values to be small. //Arrays.sort(set, Math.min(0, set.length-1), Math.min(1 << 7, set.length-1)); Arrays.sort(set, Math.min(1 << 7, set.length-1), Math.min(1 << 14, set.length-1)); Arrays.sort(set, Math.min(1 << 14, set.length-1), Math.min(1 << 21, set.length-1), comparator); } stringmap = new HashMap(2 * set.length); for (int i = 0; i < set.length; i++) { stringmap.put(set[i], new Integer(i+1)); // Index 0 is reserved for use as a delimiter. } counts = null; } public void clear() { counts = new HashMap(100); stringmap = null; set = null; } public Osmformat.StringTable.Builder serialize() { Osmformat.StringTable.Builder builder = Osmformat.StringTable .newBuilder(); builder.addS(ByteString.copyFromUtf8("")); // Add a unused string at offset 0 which is used as a delimiter. for (int i = 0; i < set.length; i++) builder.addS(ByteString.copyFromUtf8(set[i])); return builder; } } osmosis-0.44.1/osmosis-osm-binary/src/main/java/org/openstreetmap/osmosis/osmbinary/file/000077500000000000000000000000001253404521400315755ustar00rootroot00000000000000BlockInputStream.java000066400000000000000000000026161253404521400356140ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/src/main/java/org/openstreetmap/osmosis/osmbinary/file/** Copyright (c) 2010 Scott A. Crosby. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package org.openstreetmap.osmosis.osmbinary.file; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; public class BlockInputStream { // TODO: Should be seekable input stream! public BlockInputStream(InputStream input, BlockReaderAdapter adaptor) { this.input = input; this.adaptor = adaptor; } public void process() throws IOException { try { while (true) { FileBlock.process(input, adaptor); } } catch (EOFException e) { adaptor.complete(); } } public void close() throws IOException { input.close(); } InputStream input; BlockReaderAdapter adaptor; } BlockOutputStream.java000066400000000000000000000043661253404521400360210ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/src/main/java/org/openstreetmap/osmosis/osmbinary/file/** Copyright (c) 2010 Scott A. Crosby. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package org.openstreetmap.osmosis.osmbinary.file; import java.io.DataOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; enum CompressFlags { NONE, DEFLATE } public class BlockOutputStream { public BlockOutputStream(OutputStream output) { this.outwrite = new DataOutputStream(output); this.compression = CompressFlags.DEFLATE; } public void setCompress(CompressFlags flag) { compression = flag; } public void setCompress(String s) { if (s.equals("none")) compression = CompressFlags.NONE; else if (s.equals("deflate")) compression = CompressFlags.DEFLATE; else throw new Error("Unknown compression type: " + s); } /** Write a block with the stream's default compression flag */ public void write(FileBlock block) throws IOException { this.write(block, compression); } /** Write a specific block with a specific compression flags */ public void write(FileBlock block, CompressFlags compression) throws IOException { FileBlockPosition ref = block.writeTo(outwrite, compression); writtenblocks.add(ref); } public void flush() throws IOException { outwrite.flush(); } public void close() throws IOException { outwrite.flush(); outwrite.close(); } OutputStream outwrite; List writtenblocks = new ArrayList(); CompressFlags compression; } BlockReaderAdapter.java000066400000000000000000000027161253404521400360450ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/src/main/java/org/openstreetmap/osmosis/osmbinary/file/** Copyright (c) 2010 Scott A. Crosby. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package org.openstreetmap.osmosis.osmbinary.file; /** An adaptor that receives blocks from an input stream */ public interface BlockReaderAdapter { /** * Does the reader understand this block? Does it want the data in it? * * A reference contains the metadata about a block and can saved --- or * stored ---- for future random access. However, during a strea read of the * file, does the user want this block? * * handleBlock will be called on all blocks that are not skipped, in file * order. * * */ boolean skipBlock(FileBlockPosition message); /** Called with the data in the block. */ void handleBlock(FileBlock message); /** Called when the file is fully read. */ void complete(); } FileBlock.java000066400000000000000000000127631253404521400342240ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/src/main/java/org/openstreetmap/osmosis/osmbinary/file/** Copyright (c) 2010 Scott A. Crosby. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package org.openstreetmap.osmosis.osmbinary.file; import java.io.DataOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Arrays; import java.util.zip.Deflater; import com.google.protobuf.ByteString; import org.openstreetmap.osmosis.osmbinary.Fileformat; import org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader; /** A full fileblock object contains both the metadata and data of a fileblock */ public class FileBlock extends FileBlockBase { /** Contains the contents of a block for use or further processing */ ByteString data; // serialized Format.Blob /** Don't be noisy unless the warning occurs somewhat often */ static int warncount = 0; private FileBlock(String type, ByteString blob, ByteString indexdata) { super(type, indexdata); this.data = blob; } public static FileBlock newInstance(String type, ByteString blob, ByteString indexdata) { if (blob != null && blob.size() > MAX_BODY_SIZE/2) { System.err.println("Warning: Fileblock has body size too large and may be considered corrupt"); if (blob != null && blob.size() > MAX_BODY_SIZE-1024*1024) { throw new Error("This file has too many entities in a block. Parsers will reject it."); } } if (indexdata != null && indexdata.size() > MAX_HEADER_SIZE/2) { System.err.println("Warning: Fileblock has indexdata too large and may be considered corrupt"); if (indexdata != null && indexdata.size() > MAX_HEADER_SIZE-512) { throw new Error("This file header is too large. Parsers will reject it."); } } return new FileBlock(type, blob, indexdata); } protected void deflateInto(org.openstreetmap.osmosis.osmbinary.Fileformat.Blob.Builder blobbuilder) { int size = data.size(); Deflater deflater = new Deflater(); deflater.setInput(data.toByteArray()); deflater.finish(); byte out[] = new byte[size]; deflater.deflate(out); if (!deflater.finished()) { // Buffer wasn't long enough. Be noisy. ++warncount; if (warncount > 10 && warncount%100 == 0) System.out.println("Compressed buffers are too short, causing extra copy"); out = Arrays.copyOf(out, size + size / 64 + 16); deflater.deflate(out, deflater.getTotalOut(), out.length - deflater.getTotalOut()); if (!deflater.finished()) { throw new Error("Internal error in compressor"); } } ByteString compressed = ByteString.copyFrom(out, 0, deflater .getTotalOut()); blobbuilder.setZlibData(compressed); deflater.end(); } public FileBlockPosition writeTo(OutputStream outwrite, CompressFlags flags) throws IOException { BlobHeader.Builder builder = Fileformat.BlobHeader .newBuilder(); if (indexdata != null) builder.setIndexdata(indexdata); builder.setType(type); Fileformat.Blob.Builder blobbuilder = Fileformat.Blob.newBuilder(); if (flags == CompressFlags.NONE) { blobbuilder.setRaw(data); blobbuilder.setRawSize(data.size()); } else { blobbuilder.setRawSize(data.size()); if (flags == CompressFlags.DEFLATE) deflateInto(blobbuilder); else throw new Error("Compression flag not understood"); } Fileformat.Blob blob = blobbuilder.build(); builder.setDatasize(blob.getSerializedSize()); Fileformat.BlobHeader message = builder.build(); int size = message.getSerializedSize(); // System.out.format("Outputed header size %d bytes, header of %d bytes, and blob of %d bytes\n", // size,message.getSerializedSize(),blob.getSerializedSize()); (new DataOutputStream(outwrite)).writeInt(size); message.writeTo(outwrite); long offset = -1; if (outwrite instanceof FileOutputStream) offset = ((FileOutputStream) outwrite).getChannel().position(); blob.writeTo(outwrite); return FileBlockPosition.newInstance(this, offset, size); } /** Reads or skips a fileblock. */ static void process(InputStream input, BlockReaderAdapter callback) throws IOException { FileBlockHead fileblock = FileBlockHead.readHead(input); if (callback.skipBlock(fileblock)) { // System.out.format("Attempt to skip %d bytes\n",header.getDatasize()); fileblock.skipContents(input); } else { callback.handleBlock(fileblock.readContents(input)); } } public ByteString getData() { return data; } } FileBlockBase.java000066400000000000000000000036311253404521400350110ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/src/main/java/org/openstreetmap/osmosis/osmbinary/file/** Copyright (c) 2010 Scott A. Crosby. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package org.openstreetmap.osmosis.osmbinary.file; import com.google.protobuf.ByteString; /** * Base class that contains the metadata about a fileblock. * * Subclasses of this include additional fields, such as byte offsets that let a * fileblock be read in a random-access fashion, or the data itself. * * @author crosby * */ public class FileBlockBase { /** If a block header is bigger than this, fail. We use excessively large header size as an indication of corrupt files */ static final int MAX_HEADER_SIZE = 64*1024; /** If a block's size is bigger than this, fail. We use excessively large block sizes as an indication of corrupt files */ static final int MAX_BODY_SIZE = 32*1024*1024; protected FileBlockBase(String type, ByteString indexdata) { this.type = type; this.indexdata = indexdata; } /** Identifies the type of the data within a block */ protected final String type; /** * Block metadata, stored in the index block and as a prefix for every * block. */ protected final ByteString indexdata; public String getType() { return type; } public ByteString getIndexData() { return indexdata; } } FileBlockHead.java000066400000000000000000000067001253404521400350000ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/src/main/java/org/openstreetmap/osmosis/osmbinary/file/** Copyright (c) 2010 Scott A. Crosby. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package org.openstreetmap.osmosis.osmbinary.file; import java.io.DataInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import com.google.protobuf.ByteString; import org.openstreetmap.osmosis.osmbinary.Fileformat; /** * Intermediate representation of the header of a fileblock when a set of * fileblocks is read as in a stream. The data in the fileblock must be either * skipped (where the returned value is a reference to the fileblock) or parsed. * * @author crosby * */ public class FileBlockHead extends FileBlockReference { protected FileBlockHead(String type, ByteString indexdata) { super(type, indexdata); } /** * Read the header. After reading the header, either the contents must be * skipped or read */ static FileBlockHead readHead(InputStream input) throws IOException { DataInputStream datinput = new DataInputStream(input); int headersize = datinput.readInt(); // System.out.format("Header size %d %x\n",headersize,headersize); if (headersize > MAX_HEADER_SIZE) { throw new FileFormatException("Unexpectedly long header "+MAX_HEADER_SIZE+ " bytes. Possibly corrupt file."); } byte buf[] = new byte[headersize]; datinput.readFully(buf); // System.out.format("Read buffer for header of %d bytes\n",buf.length); Fileformat.BlobHeader header = Fileformat.BlobHeader .parseFrom(buf); FileBlockHead fileblock = new FileBlockHead(header.getType(), header .getIndexdata()); fileblock.datasize = header.getDatasize(); if (header.getDatasize() > MAX_BODY_SIZE) { throw new FileFormatException("Unexpectedly long body "+MAX_BODY_SIZE+ " bytes. Possibly corrupt file."); } fileblock.input = input; if (input instanceof FileInputStream) fileblock.data_offset = ((FileInputStream) input).getChannel() .position(); return fileblock; } /** * Assumes the stream is positioned over at the start of the data, skip over * it. * * @throws IOException */ void skipContents(InputStream input) throws IOException { if (input.skip(getDatasize()) != getDatasize()) assert false : "SHORT READ"; } /** * Assumes the stream is positioned over at the start of the data, read it * and return the complete FileBlock * * @throws IOException */ FileBlock readContents(InputStream input) throws IOException { DataInputStream datinput = new DataInputStream(input); byte buf[] = new byte[getDatasize()]; datinput.readFully(buf); return parseData(buf); } } FileBlockPosition.java000066400000000000000000000074761253404521400357560ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/src/main/java/org/openstreetmap/osmosis/osmbinary/file/** Copyright (c) 2010 Scott A. Crosby. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package org.openstreetmap.osmosis.osmbinary.file; import java.io.DataInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.zip.DataFormatException; import java.util.zip.Inflater; import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; import org.openstreetmap.osmosis.osmbinary.Fileformat; /** * Stores the position in the stream of a fileblock so that it can be easily * read in a random-access fashion. * * We can turn this into a 'real' block by appropriately seeking into the file * and doing a 'read'. * * */ public class FileBlockPosition extends FileBlockBase { protected FileBlockPosition(String type, ByteString indexdata) { super(type, indexdata); } /** Parse out and decompress the data part of a fileblock helper function. */ FileBlock parseData(byte buf[]) throws InvalidProtocolBufferException { FileBlock out = FileBlock.newInstance(type, null, indexdata); Fileformat.Blob blob = Fileformat.Blob.parseFrom(buf); if (blob.hasRaw()) { out.data = blob.getRaw(); } else if (blob.hasZlibData()) { byte buf2[] = new byte[blob.getRawSize()]; Inflater decompresser = new Inflater(); decompresser.setInput(blob.getZlibData().toByteArray()); // decompresser.getRemaining(); try { decompresser.inflate(buf2); } catch (DataFormatException e) { e.printStackTrace(); throw new Error(e); } assert (decompresser.finished()); decompresser.end(); out.data = ByteString.copyFrom(buf2); } return out; } public int getDatasize() { return datasize; } /* * Given any form of fileblock and an offset/length value, return a * reference that can be used to dereference and read the contents. */ static FileBlockPosition newInstance(FileBlockBase base, long offset, int length) { FileBlockPosition out = new FileBlockPosition(base.type, base.indexdata); out.datasize = length; out.data_offset = offset; return out; } public FileBlock read(InputStream input) throws IOException { if (input instanceof FileInputStream) { ((FileInputStream) input).getChannel().position(data_offset); byte buf[] = new byte[getDatasize()]; (new DataInputStream(input)).readFully(buf); return parseData(buf); } else { throw new Error("Random access binary reads require seekability"); } } /** * TODO: Convert this reference into a serialized representation that can be * stored. */ public ByteString serialize() { throw new Error("TODO"); } /** TODO: Parse a serialized representation of this block reference */ static FileBlockPosition parseFrom(ByteString b) { throw new Error("TODO"); } protected int datasize; /** Offset into the file of the data part of the block */ long data_offset; } FileBlockReference.java000066400000000000000000000033001253404521400360260ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/src/main/java/org/openstreetmap/osmosis/osmbinary/file/** Copyright (c) 2010 Scott A. Crosby. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package org.openstreetmap.osmosis.osmbinary.file; import java.io.IOException; import java.io.InputStream; import com.google.protobuf.ByteString; /** * A FileBlockPosition that remembers what file this is so that it can simply be * dereferenced */ public class FileBlockReference extends FileBlockPosition { /** * Convenience cache for storing the input this reference is contained * within so that it can be cached */ protected InputStream input; protected FileBlockReference(String type, ByteString indexdata) { super(type, indexdata); } public FileBlock read() throws IOException { return read(input); } static FileBlockPosition newInstance(FileBlockBase base, InputStream input, long offset, int length) { FileBlockReference out = new FileBlockReference(base.type, base.indexdata); out.datasize = length; out.data_offset = offset; out.input = input; return out; } } FileFormatException.java000066400000000000000000000017671253404521400363030ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/src/main/java/org/openstreetmap/osmosis/osmbinary/file/** Copyright (c) 2010 Scott A. Crosby. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package org.openstreetmap.osmosis.osmbinary.file; import java.io.IOException; public class FileFormatException extends IOException { public FileFormatException(String string) { super(string); } /** * */ private static final long serialVersionUID = -8128010128748910923L; } osmosis-0.44.1/osmosis-osm-binary/src/main/java/org/openstreetmap/osmosis/osmbinary/test/000077500000000000000000000000001253404521400316355ustar00rootroot00000000000000BuildTestFile.java000066400000000000000000000224531253404521400351260ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/src/main/java/org/openstreetmap/osmosis/osmbinary/test/** Copyright (c) 2010 Scott A. Crosby. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package org.openstreetmap.osmosis.osmbinary.test; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.Arrays; import java.util.Collections; import com.google.protobuf.ByteString; import org.openstreetmap.osmosis.osmbinary.Fileformat.Blob; import org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader; import org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes; import org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBlock; import org.openstreetmap.osmosis.osmbinary.Osmformat.Info; import org.openstreetmap.osmosis.osmbinary.Osmformat.Node; import org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock; import org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock.Builder; import org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup; import org.openstreetmap.osmosis.osmbinary.Osmformat.Relation; import org.openstreetmap.osmosis.osmbinary.Osmformat.Relation.MemberType; import org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable; import org.openstreetmap.osmosis.osmbinary.Osmformat.Way; import org.openstreetmap.osmosis.osmbinary.file.BlockOutputStream; import org.openstreetmap.osmosis.osmbinary.file.FileBlock; public class BuildTestFile { BlockOutputStream output; public static final long BILLION = 1000000000L; StringTable makeStringTable(String prefix) { return StringTable.newBuilder() .addS(ByteString.copyFromUtf8("")) // Never used. .addS(ByteString.copyFromUtf8(prefix+"Offset1")) .addS(ByteString.copyFromUtf8(prefix+"Offset2")) .addS(ByteString.copyFromUtf8(prefix+"Offset3")) .addS(ByteString.copyFromUtf8(prefix+"Offset4")) .addS(ByteString.copyFromUtf8(prefix+"Offset5")) .addS(ByteString.copyFromUtf8(prefix+"Offset6")) .addS(ByteString.copyFromUtf8(prefix+"Offset7")) .addS(ByteString.copyFromUtf8(prefix+"Offset8")) .build(); } void makeSimpleFileBlock1() throws IOException { PrimitiveBlock.Builder b1 = PrimitiveBlock.newBuilder(); b1.setStringtable(makeStringTable("B1")); b1.addPrimitivegroup( PrimitiveGroup.newBuilder() .addNodes(Node.newBuilder() .setId(101).setLat(13*10*1000*1000).setLon(-14*10*1000*1000) .addKeys(1).addVals(2)) .addNodes(Node.newBuilder() .setId(101).setLat(12345678).setLon(-23456789)) // Should be 1.2345678 degrees lat and -2.3456789 lon. ); b1.addPrimitivegroup( PrimitiveGroup.newBuilder() .addWays(Way.newBuilder() .setId(201) .addRefs(101).addRefs(1).addRefs(-1).addRefs(10).addRefs(-20) // Delta coded. Should be 101, 102, 101, 111, 91. .addKeys(2).addVals(1).addKeys(3).addVals(4)) .addWays(Way.newBuilder() .setId(-301) .addRefs(211).addRefs(1).addRefs(-1).addRefs(10).addRefs(-300) // Delta coded. Should be 211, 212, 211, 221, -79 .addKeys(4).addVals(3).addKeys(5).addVals(6)) .addWays(Way.newBuilder() .setId(401).addRefs(211).addRefs(1)) .addWays(Way.newBuilder() .setId(501)) ); b1.addPrimitivegroup( PrimitiveGroup.newBuilder() .addRelations(Relation.newBuilder() .setId(601) .addTypes(MemberType.NODE).addMemids(50).addRolesSid(2) .addTypes(MemberType.NODE).addMemids(3).addRolesSid(3) .addTypes(MemberType.WAY).addMemids(3).addRolesSid(4) .addTypes(MemberType.RELATION).addMemids(3).addRolesSid(5)) .addRelations(Relation.newBuilder() .setId(701) .addTypes(MemberType.RELATION).addMemids(60).addRolesSid(6) .addTypes(MemberType.RELATION).addMemids(5).addRolesSid(7) .addKeys(1).addVals(2))); b1.addPrimitivegroup( PrimitiveGroup.newBuilder() .setDense(DenseNodes.newBuilder() .addId(1001).addId(110).addId(-2000).addId(8889) .addLat(12*10000000).addLat(1500000).addLat(-12*10000000).addLat(-12*10000000) .addLon(-12*10000000).addLon(2500000).addLon(13*10000000).addLon(2*10000000) .addKeysVals(1).addKeysVals(2).addKeysVals(0) .addKeysVals(0) .addKeysVals(2).addKeysVals(3).addKeysVals(4).addKeysVals(5).addKeysVals(0) .addKeysVals(3).addKeysVals(3).addKeysVals(0) )); output.write(FileBlock.newInstance("OSMData", b1.build().toByteString(),null)); PrimitiveBlock.Builder b2 = PrimitiveBlock.newBuilder(); b2.setLatOffset(10*BILLION + 109208300) .setLonOffset(20*BILLION + 901802700) .setGranularity(1200); b2.setStringtable(makeStringTable("B2")); // Test out granularity stuff. b2.addPrimitivegroup( PrimitiveGroup.newBuilder() .addNodes(Node.newBuilder().setId(100000).setLat(0).setLon(0)) .addNodes(Node.newBuilder().setId(100001).setLat(1000).setLon(2000)) .addNodes(Node.newBuilder().setId(100002).setLat(1001).setLon(2001)) .addNodes(Node.newBuilder().setId(100003).setLat(1002).setLon(2002)) .addNodes(Node.newBuilder().setId(100004).setLat(1003).setLon(2003)) .addNodes(Node.newBuilder().setId(100005).setLat(1004).setLon(2004))); output.write(FileBlock.newInstance("OSMData", b2.build().toByteString(),null)); } BuildTestFile(String name, String compress) throws IOException { output = new BlockOutputStream(new FileOutputStream(name)); output.setCompress(compress); HeaderBlock.Builder b = HeaderBlock.newBuilder(); b.addRequiredFeatures("OsmSchema-V0.6").addRequiredFeatures("DenseNodes").setSource("QuickBrownFox"); output.write(FileBlock.newInstance("OSMHeader",b.build().toByteString(),null)); } public static void main(String [] args) { try { BuildTestFile out1a = new BuildTestFile("TestFile1-deflate.osm.pbf","deflate"); out1a.makeSimpleFileBlock1(); out1a.output.close(); BuildTestFile out1b = new BuildTestFile("TestFile1-none.osm.pbf","none"); out1b.makeSimpleFileBlock1(); out1b.output.close(); BuildTestFile out2 = new BuildTestFile("TestFile2-uncom.osm.pbf","deflate"); out2.makeGranFileBlock1(); out2.output.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } void makeGranFileBlock1() throws IOException { PrimitiveBlock.Builder b1 = PrimitiveBlock.newBuilder(); b1.setLatOffset(10*BILLION + 109208300) .setLonOffset(20*BILLION + 901802700) .setGranularity(1200) .setDateGranularity(2500); b1.setStringtable(makeStringTable("C1")); b1.addPrimitivegroup( PrimitiveGroup.newBuilder() .addNodes(Node.newBuilder() .setId(100001) .setLat(1000).setLon(2000) .setInfo(Info.newBuilder() .setTimestamp(1001) .setChangeset(-12) .setUid(21) .setUserSid(6) .build()) .build()) .addNodes(Node.newBuilder() .setId(100002) .setLat(1001).setLon(2001) .setInfo(Info.newBuilder() .setVersion(102) .setTimestamp(1002) .setChangeset(12) .setUid(-21) .setUserSid(5) .build()) .build()) .addNodes(Node.newBuilder() .setId(100003) .setLat(1003).setLon(2003) .setInfo(Info.newBuilder() .setVersion(103) .setUserSid(4) .build()) .build()) ) ; // The same, but with different granularities. PrimitiveBlock.Builder b2 = PrimitiveBlock.newBuilder(); b2.setLatOffset(12*BILLION + 303) .setLonOffset(22*BILLION + 404) .setGranularity(1401) .setDateGranularity(3003); b2.setStringtable(makeStringTable("C2")); b2.addPrimitivegroup( PrimitiveGroup.newBuilder() .addNodes(Node.newBuilder() .setId(100001) .addKeys(1).addVals(2) .addKeys(1).addVals(3) // Support multiple vals for a key. .addKeys(3).addVals(4) .setLat(1000).setLon(2000) .build()) .addNodes(Node.newBuilder() .setId(100002) .setLat(1001).setLon(2001) .build()) .addNodes(Node.newBuilder() .setId(100003) .setLat(1003).setLon(2003) .addKeys(5).addVals(6) .build()) ); output.write(FileBlock.newInstance("OSMData", b1.build().toByteString(),null)); output.write(FileBlock.newInstance("OSMData", b2.build().toByteString(),null)); } } osmosis-0.44.1/osmosis-osm-binary/src/main/protobuf/000077500000000000000000000000001253404521400224215ustar00rootroot00000000000000osmosis-0.44.1/osmosis-osm-binary/src/main/protobuf/fileformat.proto000066400000000000000000000033101253404521400256330ustar00rootroot00000000000000/** Copyright (c) 2010 Scott A. Crosby. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ option optimize_for = LITE_RUNTIME; option java_package = "org.openstreetmap.osmosis.osmbinary"; package OSMPBF; //protoc --java_out=../.. fileformat.proto // // STORAGE LAYER: Storing primitives. // message Blob { optional bytes raw = 1; // No compression optional int32 raw_size = 2; // When compressed, the uncompressed size // Possible compressed versions of the data. optional bytes zlib_data = 3; // PROPOSED feature for LZMA compressed data. SUPPORT IS NOT REQUIRED. optional bytes lzma_data = 4; // Formerly used for bzip2 compressed data. Depreciated in 2010. optional bytes OBSOLETE_bzip2_data = 5 [deprecated=true]; // Don't reuse this tag number. } /* A file contains an sequence of fileblock headers, each prefixed by their length in network byte order, followed by a data block containing the actual data. types staring with a "_" are reserved. */ message BlobHeader { required string type = 1; optional bytes indexdata = 2; required int32 datasize = 3; } osmosis-0.44.1/osmosis-osm-binary/src/main/protobuf/osmformat.proto000066400000000000000000000210271253404521400255170ustar00rootroot00000000000000/** Copyright (c) 2010 Scott A. Crosby. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ option optimize_for = LITE_RUNTIME; option java_package = "org.openstreetmap.osmosis.osmbinary"; package OSMPBF; /* OSM Binary file format This is the master schema file of the OSM binary file format. This file is designed to support limited random-access and future extendability. A binary OSM file consists of a sequence of FileBlocks (please see fileformat.proto). The first fileblock contains a serialized instance of HeaderBlock, followed by a sequence of PrimitiveBlock blocks that contain the primitives. Each primitiveblock is designed to be independently parsable. It contains a string table storing all strings in that block (keys and values in tags, roles in relations, usernames, etc.) as well as metadata containing the precision of coordinates or timestamps in that block. A primitiveblock contains a sequence of primitive groups, each containing primitives of the same type (nodes, densenodes, ways, relations). Coordinates are stored in signed 64-bit integers. Lat&lon are measured in units nanodegrees. The default of granularity of 100 nanodegrees corresponds to about 1cm on the ground, and a full lat or lon fits into 32 bits. Converting an integer to a lattitude or longitude uses the formula: $OUT = IN * granularity / 10**9$. Many encoding schemes use delta coding when representing nodes and relations. */ ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// /* Contains the file header. */ message HeaderBlock { optional HeaderBBox bbox = 1; /* Additional tags to aid in parsing this dataset */ repeated string required_features = 4; repeated string optional_features = 5; optional string writingprogram = 16; optional string source = 17; // From the bbox field. /* Tags that allow continuing an Osmosis replication */ // replication timestamp, expressed in seconds since the epoch, // otherwise the same value as in the "timestamp=..." field // in the state.txt file used by Osmosis optional int64 osmosis_replication_timestamp = 32; // replication sequence number (sequenceNumber in state.txt) optional int64 osmosis_replication_sequence_number = 33; // replication base URL (from Osmosis' configuration.txt file) optional string osmosis_replication_base_url = 34; } /** The bounding box field in the OSM header. BBOX, as used in the OSM header. Units are always in nanodegrees -- they do not obey granularity rules. */ message HeaderBBox { required sint64 left = 1; required sint64 right = 2; required sint64 top = 3; required sint64 bottom = 4; } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// message PrimitiveBlock { required StringTable stringtable = 1; repeated PrimitiveGroup primitivegroup = 2; // Granularity, units of nanodegrees, used to store coordinates in this block optional int32 granularity = 17 [default=100]; // Offset value between the output coordinates coordinates and the granularity grid in unites of nanodegrees. optional int64 lat_offset = 19 [default=0]; optional int64 lon_offset = 20 [default=0]; // Granularity of dates, normally represented in units of milliseconds since the 1970 epoch. optional int32 date_granularity = 18 [default=1000]; // Proposed extension: //optional BBox bbox = XX; } // Group of OSMPrimitives. All primitives in a group must be the same type. message PrimitiveGroup { repeated Node nodes = 1; optional DenseNodes dense = 2; repeated Way ways = 3; repeated Relation relations = 4; repeated ChangeSet changesets = 5; } /** String table, contains the common strings in each block. Note that we reserve index '0' as a delimiter, so the entry at that index in the table is ALWAYS blank and unused. */ message StringTable { repeated bytes s = 1; } /* Optional metadata that may be included into each primitive. */ message Info { optional int32 version = 1 [default = -1]; optional int64 timestamp = 2; optional int64 changeset = 3; optional int32 uid = 4; optional uint32 user_sid = 5; // String IDs // The visible flag is used to store history information. It indicates that // the current object version has been created by a delete operation on the // OSM API. // When a writer sets this flag, it MUST add a required_features tag with // value "HistoricalInformation" to the HeaderBlock. // If this flag is not available for some object it MUST be assumed to be // true if the file has the required_features tag "HistoricalInformation" // set. optional bool visible = 6; } /** Optional metadata that may be included into each primitive. Special dense format used in DenseNodes. */ message DenseInfo { repeated int32 version = 1 [packed = true]; repeated sint64 timestamp = 2 [packed = true]; // DELTA coded repeated sint64 changeset = 3 [packed = true]; // DELTA coded repeated sint32 uid = 4 [packed = true]; // DELTA coded repeated sint32 user_sid = 5 [packed = true]; // String IDs for usernames. DELTA coded // The visible flag is used to store history information. It indicates that // the current object version has been created by a delete operation on the // OSM API. // When a writer sets this flag, it MUST add a required_features tag with // value "HistoricalInformation" to the HeaderBlock. // If this flag is not available for some object it MUST be assumed to be // true if the file has the required_features tag "HistoricalInformation" // set. repeated bool visible = 6 [packed = true]; } // THIS IS STUB DESIGN FOR CHANGESETS. NOT USED RIGHT NOW. // TODO: REMOVE THIS? message ChangeSet { required int64 id = 1; // // // Parallel arrays. // repeated uint32 keys = 2 [packed = true]; // String IDs. // repeated uint32 vals = 3 [packed = true]; // String IDs. // // optional Info info = 4; // optional int64 created_at = 8; // optional int64 closetime_delta = 9; // optional bool open = 10; // optional HeaderBBox bbox = 11; } message Node { required sint64 id = 1; // Parallel arrays. repeated uint32 keys = 2 [packed = true]; // String IDs. repeated uint32 vals = 3 [packed = true]; // String IDs. optional Info info = 4; // May be omitted in omitmeta required sint64 lat = 8; required sint64 lon = 9; } /* Used to densly represent a sequence of nodes that do not have any tags. We represent these nodes columnwise as five columns: ID's, lats, and lons, all delta coded. When metadata is not omitted, We encode keys & vals for all nodes as a single array of integers containing key-stringid and val-stringid, using a stringid of 0 as a delimiter between nodes. ( ( )* '0' )* */ message DenseNodes { repeated sint64 id = 1 [packed = true]; // DELTA coded //repeated Info info = 4; optional DenseInfo denseinfo = 5; repeated sint64 lat = 8 [packed = true]; // DELTA coded repeated sint64 lon = 9 [packed = true]; // DELTA coded // Special packing of keys and vals into one array. May be empty if all nodes in this block are tagless. repeated int32 keys_vals = 10 [packed = true]; } message Way { required int64 id = 1; // Parallel arrays. repeated uint32 keys = 2 [packed = true]; repeated uint32 vals = 3 [packed = true]; optional Info info = 4; repeated sint64 refs = 8 [packed = true]; // DELTA coded } message Relation { enum MemberType { NODE = 0; WAY = 1; RELATION = 2; } required int64 id = 1; // Parallel arrays. repeated uint32 keys = 2 [packed = true]; repeated uint32 vals = 3 [packed = true]; optional Info info = 4; // Parallel arrays repeated int32 roles_sid = 8 [packed = true]; repeated sint64 memids = 9 [packed = true]; // DELTA encoded repeated MemberType types = 10 [packed = true]; } osmosis-0.44.1/osmosis-pbf/000077500000000000000000000000001253404521400155355ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf/.checkstyle000066400000000000000000000010051253404521400176700ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-pbf/.gitignore000066400000000000000000000000531253404521400175230ustar00rootroot00000000000000.classpath .project .settings /bin /build osmosis-0.44.1/osmosis-pbf/build.gradle000066400000000000000000000004321253404521400200130ustar00rootroot00000000000000dependencies { compile project(':osmosis-core') compile project(':osmosis-osm-binary') compile group: 'com.google.protobuf', name: 'protobuf-java', version: dependencyVersionProtobuf testCompile project(':osmosis-testutil') testCompile project(':osmosis-xml') } osmosis-0.44.1/osmosis-pbf/src/000077500000000000000000000000001253404521400163245ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf/src/main/000077500000000000000000000000001253404521400172505ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf/src/main/java/000077500000000000000000000000001253404521400201715ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf/src/main/java/crosby/000077500000000000000000000000001253404521400214725ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf/src/main/java/crosby/binary/000077500000000000000000000000001253404521400227565ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf/src/main/java/crosby/binary/osmosis/000077500000000000000000000000001253404521400244525ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf/src/main/java/crosby/binary/osmosis/BinaryPluginLoader.java000066400000000000000000000022251253404521400310500ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package crosby.binary.osmosis; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.plugin.PluginLoader; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; /** Register the binary reading and writing functions. */ public class BinaryPluginLoader implements PluginLoader { @Override public Map loadTaskFactories() { Map factoryMap; OsmosisReaderFactory reader = new OsmosisReaderFactory(); OsmosisSerializerFactory writer = new OsmosisSerializerFactory(); factoryMap = new HashMap(); factoryMap.put("read-pbf", reader); factoryMap.put("read-bin", reader); factoryMap.put("rb", reader); factoryMap.put("write-pbf", writer); factoryMap.put("write-bin", writer); factoryMap.put("wb", writer); factoryMap.put("read-pbf-0.6", reader); factoryMap.put("write-pbf-0.6", writer); return factoryMap; } } osmosis-0.44.1/osmosis-pbf/src/main/java/crosby/binary/osmosis/OsmosisBinaryParser.java000066400000000000000000000241241253404521400312760ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package crosby.binary.osmosis; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.openstreetmap.osmosis.core.OsmosisConstants; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.osmbinary.BinaryParser; import org.openstreetmap.osmosis.osmbinary.Osmformat; import org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo; /** Class that reads and parses binary files and sends the contained entities to the sink. */ public class OsmosisBinaryParser extends BinaryParser { @Override public void complete() { sink.complete(); } /** Get the osmosis object representing a the user in a given Info protobuf. * @param info The info protobuf. * @return The OsmUser object */ OsmUser getUser(Osmformat.Info info) { // System.out.println(info); if (info.hasUid() && info.hasUserSid()) { if (info.getUid() < 0) { return OsmUser.NONE; } return new OsmUser(info.getUid(), getStringById(info.getUserSid())); } else { return OsmUser.NONE; } } /** The magic number used to indicate no version number metadata for this entity. */ static final int NOVERSION = -1; /** The magic number used to indicate no changeset metadata for this entity. */ static final int NOCHANGESET = -1; @Override protected void parseNodes(List nodes) { for (Osmformat.Node i : nodes) { List tags = new ArrayList(); for (int j = 0; j < i.getKeysCount(); j++) { tags.add(new Tag(getStringById(i.getKeys(j)), getStringById(i.getVals(j)))); } // long id, int version, Date timestamp, OsmUser user, // long changesetId, Collection tags, // double latitude, double longitude Node tmp; long id = i.getId(); double latf = parseLat(i.getLat()), lonf = parseLon(i.getLon()); if (i.hasInfo()) { Osmformat.Info info = i.getInfo(); tmp = new Node(new CommonEntityData(id, info.getVersion(), getDate(info), getUser(info), info.getChangeset(), tags), latf, lonf); } else { tmp = new Node(new CommonEntityData(id, NOVERSION, NODATE, OsmUser.NONE, NOCHANGESET, tags), latf, lonf); } sink.process(new NodeContainer(tmp)); } } @Override protected void parseDense(Osmformat.DenseNodes nodes) { long lastId = 0, lastLat = 0, lastLon = 0; int j = 0; // Index into the keysvals array. // Stuff for dense info long lasttimestamp = 0, lastchangeset = 0; int lastuserSid = 0, lastuid = 0; DenseInfo di = null; if (nodes.hasDenseinfo()) { di = nodes.getDenseinfo(); } for (int i = 0; i < nodes.getIdCount(); i++) { Node tmp; List tags = new ArrayList(0); long lat = nodes.getLat(i) + lastLat; lastLat = lat; long lon = nodes.getLon(i) + lastLon; lastLon = lon; long id = nodes.getId(i) + lastId; lastId = id; double latf = parseLat(lat), lonf = parseLon(lon); // If empty, assume that nothing here has keys or vals. if (nodes.getKeysValsCount() > 0) { while (nodes.getKeysVals(j) != 0) { int keyid = nodes.getKeysVals(j++); int valid = nodes.getKeysVals(j++); tags.add(new Tag(getStringById(keyid), getStringById(valid))); } j++; // Skip over the '0' delimiter. } // Handle dense info. if (di != null) { int uid = di.getUid(i) + lastuid; lastuid = uid; int userSid = di.getUserSid(i) + lastuserSid; lastuserSid = userSid; long timestamp = di.getTimestamp(i) + lasttimestamp; lasttimestamp = timestamp; int version = di.getVersion(i); long changeset = di.getChangeset(i) + lastchangeset; lastchangeset = changeset; Date date = new Date(date_granularity * timestamp); OsmUser user; if (uid < 0) { user = OsmUser.NONE; } else { user = new OsmUser(uid, getStringById(userSid)); } tmp = new Node(new CommonEntityData(id, version, date, user, changeset, tags), latf, lonf); } else { tmp = new Node(new CommonEntityData(id, NOVERSION, NODATE, OsmUser.NONE, NOCHANGESET, tags), latf, lonf); } sink.process(new NodeContainer(tmp)); } } @Override protected void parseWays(List ways) { for (Osmformat.Way i : ways) { List tags = new ArrayList(); for (int j = 0; j < i.getKeysCount(); j++) { tags.add(new Tag(getStringById(i.getKeys(j)), getStringById(i.getVals(j)))); } long lastId = 0; List nodes = new ArrayList(); for (long j : i.getRefsList()) { nodes.add(new WayNode(j + lastId)); lastId = j + lastId; } long id = i.getId(); // long id, int version, Date timestamp, OsmUser user, // long changesetId, Collection tags, // List wayNodes Way tmp; if (i.hasInfo()) { Osmformat.Info info = i.getInfo(); tmp = new Way(new CommonEntityData(id, info.getVersion(), getDate(info), getUser(info), info.getChangeset(), tags), nodes); } else { tmp = new Way(new CommonEntityData(id, NOVERSION, NODATE, OsmUser.NONE, NOCHANGESET, tags), nodes); } sink.process(new WayContainer(tmp)); } } @Override protected void parseRelations(List rels) { for (Osmformat.Relation i : rels) { List tags = new ArrayList(); for (int j = 0; j < i.getKeysCount(); j++) { tags.add(new Tag(getStringById(i.getKeys(j)), getStringById(i.getVals(j)))); } long id = i.getId(); long lastMid = 0; List nodes = new ArrayList(); for (int j = 0; j < i.getMemidsCount(); j++) { long mid = lastMid + i.getMemids(j); lastMid = mid; String role = getStringById(i.getRolesSid(j)); EntityType etype = null; if (i.getTypes(j) == Osmformat.Relation.MemberType.NODE) { etype = EntityType.Node; } else if (i.getTypes(j) == Osmformat.Relation.MemberType.WAY) { etype = EntityType.Way; } else if (i.getTypes(j) == Osmformat.Relation.MemberType.RELATION) { etype = EntityType.Relation; } else { assert false; // TODO; Illegal file? } nodes.add(new RelationMember(mid, etype, role)); } // long id, int version, TimestampContainer timestampContainer, // OsmUser user, // long changesetId, Collection tags, // List members Relation tmp; if (i.hasInfo()) { Osmformat.Info info = i.getInfo(); tmp = new Relation(new CommonEntityData(id, info.getVersion(), getDate(info), getUser(info), info.getChangeset(), tags), nodes); } else { tmp = new Relation(new CommonEntityData(id, NOVERSION, NODATE, OsmUser.NONE, NOCHANGESET, tags), nodes); } sink.process(new RelationContainer(tmp)); } } @Override public void parse(Osmformat.HeaderBlock block) { for (String s : block.getRequiredFeaturesList()) { if (s.equals("OsmSchema-V0.6")) { continue; // We can parse this. } if (s.equals("DenseNodes")) { continue; // We can parse this. } throw new OsmosisRuntimeException("File requires unknown feature: " + s); } if (block.hasBbox()) { String source = OsmosisConstants.VERSION; if (block.hasSource()) { source = block.getSource(); } double multiplier = .000000001; double rightf = block.getBbox().getRight() * multiplier; double leftf = block.getBbox().getLeft() * multiplier; double topf = block.getBbox().getTop() * multiplier; double bottomf = block.getBbox().getBottom() * multiplier; Bound bounds = new Bound(rightf, leftf, topf, bottomf, source); sink.process(new BoundContainer(bounds)); } } /** * {@inheritDoc} */ public void setSink(Sink sink) { this.sink = sink; } private Sink sink; } osmosis-0.44.1/osmosis-pbf/src/main/java/crosby/binary/osmosis/OsmosisReader.java000066400000000000000000000031311253404521400300720ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package crosby.binary.osmosis; import java.io.IOException; import java.io.InputStream; import java.util.Collections; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.task.v0_6.RunnableSource; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.osmbinary.file.BlockInputStream; /** Glue code that implements a task that connects an InputStream a containing binary-format data to a Sink. * @author crosby * */ public class OsmosisReader implements RunnableSource { private Sink sink; /** * Make a reader based on a target input stream. * @param input The input stream to read from. */ public OsmosisReader(InputStream input) { if (input == null) { throw new Error("Null input"); } this.input = input; parser = new OsmosisBinaryParser(); } @Override public void setSink(Sink sink) { this.sink = sink; parser.setSink(sink); } @Override public void run() { try { sink.initialize(Collections.emptyMap()); (new BlockInputStream(input, parser)).process(); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to process PBF stream", e); } finally { sink.release(); } } /** Store the input stream we're using. */ InputStream input; /** The binary parser object. */ OsmosisBinaryParser parser; } osmosis-0.44.1/osmosis-pbf/src/main/java/crosby/binary/osmosis/OsmosisReaderFactory.java000066400000000000000000000031201253404521400314200ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package crosby.binary.osmosis; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.RunnableSourceManager; /** * The task manager factory for a binary (PBF) reader. */ public class OsmosisReaderFactory extends TaskManagerFactory { private static final String ARG_FILE_NAME = "file"; private static final String DEFAULT_FILE_NAME = "dump.osm.pbf"; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String fileName; File file; OsmosisReader task; // Get the task arguments. fileName = getStringArgument(taskConfig, ARG_FILE_NAME, getDefaultStringArgument(taskConfig, DEFAULT_FILE_NAME)); // Create a file object from the file name provided. file = new File(fileName); // Build the task object. try { task = new OsmosisReader(new FileInputStream(file)); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } return new RunnableSourceManager(taskConfig.getId(), task, taskConfig .getPipeArgs()); } } osmosis-0.44.1/osmosis-pbf/src/main/java/crosby/binary/osmosis/OsmosisSerializer.java000066400000000000000000000426321253404521400310120ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package crosby.binary.osmosis; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisConstants; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityProcessor; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.osmbinary.BinarySerializer; import org.openstreetmap.osmosis.osmbinary.Osmformat; import org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo; import org.openstreetmap.osmosis.osmbinary.StringTable; import org.openstreetmap.osmosis.osmbinary.Osmformat.Relation.MemberType; import org.openstreetmap.osmosis.osmbinary.file.BlockOutputStream; import org.openstreetmap.osmosis.osmbinary.file.FileBlock; /** * Receives data from the Osmosis pipeline and stores it in the PBF format. */ public class OsmosisSerializer extends BinarySerializer implements Sink { private static final Logger LOG = Logger.getLogger(OsmosisSerializer.class.getName()); /** Additional configuration flag for whether to serialize into DenseNodes/DenseInfo? */ protected boolean useDense = true; /** Has the header been written yet? */ protected boolean headerWritten = false; /** * Tracks the number of warnings that have occurred during serialisation. */ static int warncount = 0; /** * Construct a serializer that writes to the target BlockOutputStream. * * @param output * The PBF block stream to send serialized data. */ public OsmosisSerializer(BlockOutputStream output) { super(output); } /** * Change the flag of whether to use the dense format. * * @param useDense * The new use dense value. */ public void setUseDense(boolean useDense) { this.useDense = useDense; } /** Base class containing common code needed for serializing each type of primitives. */ private abstract class Prim { /** Queue that tracks the list of all primitives. */ ArrayList contents = new ArrayList(); /** Add to the queue. * @param item The entity to add */ public void add(T item) { contents.add(item); } /** Add all of the tags of all entities in the queue to the stringtable. */ public void addStringsToStringtable() { StringTable stable = getStringTable(); for (T i : contents) { Collection tags = i.getTags(); for (Tag tag : tags) { stable.incr(tag.getKey()); stable.incr(tag.getValue()); } if (!omit_metadata) { stable.incr(i.getUser().getName()); } } } private static final int MAXWARN = 100; public void serializeMetadataDense(DenseInfo.Builder b, List entities) { if (omit_metadata) { return; } long lasttimestamp = 0, lastchangeset = 0; int lastuserSid = 0, lastuid = 0; StringTable stable = getStringTable(); for (Entity e : entities) { if (e.getUser() == OsmUser.NONE && warncount < MAXWARN) { LOG.warning("Attention: Data being output lacks metadata. Please use omitmetadata=true"); warncount++; } int uid = e.getUser().getId(); int userSid = stable.getIndex(e.getUser().getName()); int timestamp = (int) (e.getTimestamp().getTime() / date_granularity); int version = e.getVersion(); long changeset = e.getChangesetId(); b.addVersion(version); b.addTimestamp(timestamp - lasttimestamp); lasttimestamp = timestamp; b.addChangeset(changeset - lastchangeset); lastchangeset = changeset; b.addUid(uid - lastuid); lastuid = uid; b.addUserSid(userSid - lastuserSid); lastuserSid = userSid; } } public Osmformat.Info.Builder serializeMetadata(Entity e) { StringTable stable = getStringTable(); Osmformat.Info.Builder b = Osmformat.Info.newBuilder(); if (!omit_metadata) { if (e.getUser() == OsmUser.NONE && warncount < MAXWARN) { LOG.warning("Attention: Data being output lacks metadata. Please use omitmetadata=true"); warncount++; } if (e.getUser() != OsmUser.NONE) { b.setUid(e.getUser().getId()); b.setUserSid(stable.getIndex(e.getUser().getName())); } b.setTimestamp((int) (e.getTimestamp().getTime() / date_granularity)); b.setVersion(e.getVersion()); b.setChangeset(e.getChangesetId()); } return b; } } private class NodeGroup extends Prim implements PrimGroupWriterInterface { public Osmformat.PrimitiveGroup serialize() { if (useDense) { return serializeDense(); } else { return serializeNonDense(); } } /** * Serialize all nodes in the 'dense' format. */ public Osmformat.PrimitiveGroup serializeDense() { if (contents.size() == 0) { return null; } // System.out.format("%d Dense ",nodes.size()); Osmformat.PrimitiveGroup.Builder builder = Osmformat.PrimitiveGroup .newBuilder(); StringTable stable = getStringTable(); long lastlat = 0, lastlon = 0, lastid = 0; Osmformat.DenseNodes.Builder bi = Osmformat.DenseNodes.newBuilder(); boolean doesBlockHaveTags = false; // Does anything in this block have tags? for (Node i : contents) { doesBlockHaveTags = doesBlockHaveTags || (!i.getTags().isEmpty()); } if (!omit_metadata) { Osmformat.DenseInfo.Builder bdi = Osmformat.DenseInfo.newBuilder(); serializeMetadataDense(bdi, contents); bi.setDenseinfo(bdi); } for (Node i : contents) { long id = i.getId(); int lat = mapDegrees(i.getLatitude()); int lon = mapDegrees(i.getLongitude()); bi.addId(id - lastid); lastid = id; bi.addLon(lon - lastlon); lastlon = lon; bi.addLat(lat - lastlat); lastlat = lat; // Then we must include tag information. if (doesBlockHaveTags) { for (Tag t : i.getTags()) { bi.addKeysVals(stable.getIndex(t.getKey())); bi.addKeysVals(stable.getIndex(t.getValue())); } bi.addKeysVals(0); // Add delimiter. } } builder.setDense(bi); return builder.build(); } /** * Serialize all nodes in the non-dense format. * * @param parentbuilder Add to this PrimitiveBlock. */ public Osmformat.PrimitiveGroup serializeNonDense() { if (contents.size() == 0) { return null; } // System.out.format("%d Nodes ",nodes.size()); StringTable stable = getStringTable(); Osmformat.PrimitiveGroup.Builder builder = Osmformat.PrimitiveGroup .newBuilder(); for (Node i : contents) { long id = i.getId(); int lat = mapDegrees(i.getLatitude()); int lon = mapDegrees(i.getLongitude()); Osmformat.Node.Builder bi = Osmformat.Node.newBuilder(); bi.setId(id); bi.setLon(lon); bi.setLat(lat); for (Tag t : i.getTags()) { bi.addKeys(stable.getIndex(t.getKey())); bi.addVals(stable.getIndex(t.getValue())); } if (!omit_metadata) { bi.setInfo(serializeMetadata(i)); } builder.addNodes(bi); } return builder.build(); } } private class WayGroup extends Prim implements PrimGroupWriterInterface { public Osmformat.PrimitiveGroup serialize() { if (contents.size() == 0) { return null; } // System.out.format("%d Ways ",contents.size()); StringTable stable = getStringTable(); Osmformat.PrimitiveGroup.Builder builder = Osmformat.PrimitiveGroup .newBuilder(); for (Way i : contents) { Osmformat.Way.Builder bi = Osmformat.Way.newBuilder(); bi.setId(i.getId()); long lastid = 0; for (WayNode j : i.getWayNodes()) { long id = j.getNodeId(); bi.addRefs(id - lastid); lastid = id; } for (Tag t : i.getTags()) { bi.addKeys(stable.getIndex(t.getKey())); bi.addVals(stable.getIndex(t.getValue())); } if (!omit_metadata) { bi.setInfo(serializeMetadata(i)); } builder.addWays(bi); } return builder.build(); } } private class RelationGroup extends Prim implements PrimGroupWriterInterface { public void addStringsToStringtable() { StringTable stable = getStringTable(); super.addStringsToStringtable(); for (Relation i : contents) { for (RelationMember j : i.getMembers()) { stable.incr(j.getMemberRole()); } } } public Osmformat.PrimitiveGroup serialize() { if (contents.size() == 0) { return null; } // System.out.format("%d Relations ",contents.size()); StringTable stable = getStringTable(); Osmformat.PrimitiveGroup.Builder builder = Osmformat.PrimitiveGroup .newBuilder(); for (Relation i : contents) { Osmformat.Relation.Builder bi = Osmformat.Relation.newBuilder(); bi.setId(i.getId()); RelationMember[] arr = new RelationMember[i.getMembers().size()]; i.getMembers().toArray(arr); long lastid = 0; for (RelationMember j : i.getMembers()) { long id = j.getMemberId(); bi.addMemids(id - lastid); lastid = id; if (j.getMemberType() == EntityType.Node) { bi.addTypes(MemberType.NODE); } else if (j.getMemberType() == EntityType.Way) { bi.addTypes(MemberType.WAY); } else if (j.getMemberType() == EntityType.Relation) { bi.addTypes(MemberType.RELATION); } else { assert (false); // Software bug: Unknown entity. } bi.addRolesSid(stable.getIndex(j.getMemberRole())); } for (Tag t : i.getTags()) { bi.addKeys(stable.getIndex(t.getKey())); bi.addVals(stable.getIndex(t.getValue())); } if (!omit_metadata) { bi.setInfo(serializeMetadata(i)); } builder.addRelations(bi); } return builder.build(); } } /* One list for each type */ private WayGroup ways; private NodeGroup nodes; private RelationGroup relations; private Processor processor = new Processor(); /** * Buffer up events into groups that are all of the same type, or all of the * same length, then process each buffer. */ public class Processor implements EntityProcessor { @Override public void process(BoundContainer bound) { // Specialcase this. Assume we only ever get one contigious bound // request. switchTypes(); processBounds(bound.getEntity()); } /** * Check if we've reached the batch size limit and process the batch if * we have. */ public void checkLimit() { total_entities++; if (++batch_size < batch_limit) { return; } switchTypes(); processBatch(); } @Override public void process(NodeContainer node) { if (nodes == null) { writeEmptyHeaderIfNeeded(); // Need to switch types. switchTypes(); nodes = new NodeGroup(); } nodes.add(node.getEntity()); checkLimit(); } @Override public void process(WayContainer way) { if (ways == null) { writeEmptyHeaderIfNeeded(); switchTypes(); ways = new WayGroup(); } ways.add(way.getEntity()); checkLimit(); } @Override public void process(RelationContainer relation) { if (relations == null) { writeEmptyHeaderIfNeeded(); switchTypes(); relations = new RelationGroup(); } relations.add(relation.getEntity()); checkLimit(); } } /** * At the end of this function, all of the lists of unprocessed 'things' * must be null */ private void switchTypes() { if (nodes != null) { groups.add(nodes); nodes = null; } else if (ways != null) { groups.add(ways); ways = null; } else if (relations != null) { groups.add(relations); relations = null; } else { return; // No data. Is this an empty file? } } /** * {@inheritDoc} */ public void processBounds(Bound entity) { Osmformat.HeaderBlock.Builder headerblock = Osmformat.HeaderBlock .newBuilder(); Osmformat.HeaderBBox.Builder bbox = Osmformat.HeaderBBox.newBuilder(); bbox.setLeft(mapRawDegrees(entity.getLeft())); bbox.setBottom(mapRawDegrees(entity.getBottom())); bbox.setRight(mapRawDegrees(entity.getRight())); bbox.setTop(mapRawDegrees(entity.getTop())); headerblock.setBbox(bbox); if (entity.getOrigin() != null) { headerblock.setSource(entity.getOrigin()); } finishHeader(headerblock); } /** Write empty header block when there's no bounds entity. */ public void writeEmptyHeaderIfNeeded() { if (headerWritten) { return; } Osmformat.HeaderBlock.Builder headerblock = Osmformat.HeaderBlock.newBuilder(); finishHeader(headerblock); } /** Write the header fields that are always needed. * * @param headerblock Incomplete builder to complete and write. * */ public void finishHeader(Osmformat.HeaderBlock.Builder headerblock) { headerblock.setWritingprogram(OsmosisConstants.VERSION); headerblock.addRequiredFeatures("OsmSchema-V0.6"); if (useDense) { headerblock.addRequiredFeatures("DenseNodes"); } Osmformat.HeaderBlock message = headerblock.build(); try { output.write(FileBlock.newInstance("OSMHeader", message .toByteString(), null)); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write OSM header.", e); } headerWritten = true; } /** * {@inheritDoc} */ public void initialize(Map metaData) { // Do nothing. } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { entityContainer.process(processor); } @Override public void complete() { try { switchTypes(); processBatch(); flush(); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to complete the PBF file.", e); } } @Override public void release() { try { close(); } catch (IOException e) { LOG.log(Level.WARNING, "Unable to release PBF file resources during release.", e); } } } osmosis-0.44.1/osmosis-pbf/src/main/java/crosby/binary/osmosis/OsmosisSerializerFactory.java000066400000000000000000000045161253404521400323410ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package crosby.binary.osmosis; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkManager; import org.openstreetmap.osmosis.osmbinary.file.BlockOutputStream; /** * The task manager factory for a binary (PBF) writer. */ public class OsmosisSerializerFactory extends TaskManagerFactory { private static final String ARG_FILE_NAME = "file"; private static final String DEFAULT_FILE_NAME = "dump.osm.pbf"; @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { // TODO Auto-generated method stub String fileName; File file; OsmosisSerializer task = null; // Get the task arguments. fileName = getStringArgument(taskConfig, ARG_FILE_NAME, getDefaultStringArgument(taskConfig, DEFAULT_FILE_NAME)); // Create a file object from the file name provided. file = new File(fileName); // Build the task object. try { BlockOutputStream output = new BlockOutputStream( new FileOutputStream(file)); task = new OsmosisSerializer(output); task.configBatchLimit(this.getIntegerArgument(taskConfig, "batchlimit", 8000)); task.configOmit(this.getBooleanArgument(taskConfig, "omitmetadata", false)); task.setUseDense(this.getBooleanArgument(taskConfig, "usedense", true)); task.configGranularity(this.getIntegerArgument(taskConfig, "granularity", 100)); output.setCompress(this.getStringArgument(taskConfig, "compress", "deflate")); } catch (FileNotFoundException e) { throw new OsmosisRuntimeException("Failed to initialize Osmosis pbf serializer.", e); } return new SinkManager(taskConfig.getId(), task, taskConfig .getPipeArgs()); } } osmosis-0.44.1/osmosis-pbf/src/main/resources/000077500000000000000000000000001253404521400212625ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf/src/main/resources/osmosis-plugins.conf000066400000000000000000000000501253404521400252770ustar00rootroot00000000000000crosby.binary.osmosis.BinaryPluginLoaderosmosis-0.44.1/osmosis-pbf/src/test/000077500000000000000000000000001253404521400173035ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf/src/test/java/000077500000000000000000000000001253404521400202245ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf/src/test/java/crosby/000077500000000000000000000000001253404521400215255ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf/src/test/java/crosby/binary/000077500000000000000000000000001253404521400230115ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf/src/test/java/crosby/binary/osmosis/000077500000000000000000000000001253404521400245055ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf/src/test/java/crosby/binary/osmosis/OsmosisReaderAndSerializerTest.java000066400000000000000000000026471253404521400334550ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package crosby.binary.osmosis; import java.io.File; import java.io.IOException; import org.junit.Test; import org.openstreetmap.osmosis.core.Osmosis; import org.openstreetmap.osmosis.testutil.AbstractDataTest; /** * Tests the OsmosisReader and OsmosisSerializer classes. * * @author Brett Henderson */ public class OsmosisReaderAndSerializerTest extends AbstractDataTest { /** * Tests writing to and reading from PBF files. * * @throws IOException * if any file operations fail. */ @Test public void testWriteAndRead() throws IOException { // Generate data files. File inputXmlFile = dataUtils.createDataFile("v0_6/data-snapshot.osm"); File pbfFile = dataUtils.newFile(); File outputXmlFile = dataUtils.newFile(); // Read the XML and write to PBF. Osmosis.run(new String[] { "-q", "--read-xml-0.6", inputXmlFile.getPath(), "--write-pbf-0.6", pbfFile.getPath() }); // Read the PBF and write to XML. Osmosis.run(new String[] { "-q", "--read-pbf-0.6", pbfFile.getPath(), "--write-xml-0.6", outputXmlFile.getPath() }); // Validate that the output file matches the input file. dataUtils.compareFiles(inputXmlFile, outputXmlFile); } } osmosis-0.44.1/osmosis-pbf/src/test/resources/000077500000000000000000000000001253404521400213155ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf/src/test/resources/data/000077500000000000000000000000001253404521400222265ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf/src/test/resources/data/template/000077500000000000000000000000001253404521400240415ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf/src/test/resources/data/template/v0_6/000077500000000000000000000000001253404521400246135ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf/src/test/resources/data/template/v0_6/data-snapshot.osm000066400000000000000000000037261253404521400301110ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-pbf2/000077500000000000000000000000001253404521400156175ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf2/.checkstyle000066400000000000000000000010051253404521400177520ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-pbf2/.gitignore000066400000000000000000000000531253404521400176050ustar00rootroot00000000000000.classpath .project .settings /bin /build osmosis-0.44.1/osmosis-pbf2/build.gradle000066400000000000000000000005021253404521400200730ustar00rootroot00000000000000dependencies { compile project(':osmosis-core') compile project(':osmosis-osm-binary') compile group: 'com.google.protobuf', name: 'protobuf-java', version: dependencyVersionProtobuf testCompile project(':osmosis-pbf') testCompile project(':osmosis-testutil') testCompile project(':osmosis-xml') } osmosis-0.44.1/osmosis-pbf2/src/000077500000000000000000000000001253404521400164065ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf2/src/main/000077500000000000000000000000001253404521400173325ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf2/src/main/java/000077500000000000000000000000001253404521400202535ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf2/src/main/java/org/000077500000000000000000000000001253404521400210425ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf2/src/main/java/org/openstreetmap/000077500000000000000000000000001253404521400237305ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf2/src/main/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400254245ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf2/src/main/java/org/openstreetmap/osmosis/pbf2/000077500000000000000000000000001253404521400262555ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf2/src/main/java/org/openstreetmap/osmosis/pbf2/PbfPluginLoader.java000066400000000000000000000015671253404521400321460ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pbf2; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.plugin.PluginLoader; import org.openstreetmap.osmosis.pbf2.v0_6.PbfReaderFactory; /** * The plugin loader for the PBF2 tasks. * * @author Brett Henderson */ public class PbfPluginLoader implements PluginLoader { @Override public Map loadTaskFactories() { Map factoryMap; PbfReaderFactory reader = new PbfReaderFactory(); factoryMap = new HashMap(); factoryMap.put("read-pbf-fast", reader); factoryMap.put("rbf", reader); factoryMap.put("read-pbf-fast-0.6", reader); return factoryMap; } } osmosis-0.44.1/osmosis-pbf2/src/main/java/org/openstreetmap/osmosis/pbf2/v0_6/000077500000000000000000000000001253404521400270275ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf2/src/main/java/org/openstreetmap/osmosis/pbf2/v0_6/PbfReader.java000066400000000000000000000051221253404521400315240ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pbf2.v0_6; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Collections; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.task.v0_6.RunnableSource; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.pbf2.v0_6.impl.PbfDecoder; import org.openstreetmap.osmosis.pbf2.v0_6.impl.PbfStreamSplitter; /** * An OSM data source reading from a PBF file. The entire contents of the file * are read. * * @author Brett Henderson */ public class PbfReader implements RunnableSource { private File file; private Sink sink; private int workers; /** * Creates a new instance. * * @param file * The file to read. * @param workers * The number of worker threads for decoding PBF blocks. */ public PbfReader(File file, int workers) { this.file = file; this.workers = workers; } @Override public void setSink(Sink sink) { this.sink = sink; } @Override public void run() { PbfStreamSplitter streamSplitter = null; ExecutorService executorService = Executors.newFixedThreadPool(workers); try { InputStream inputStream; sink.initialize(Collections.emptyMap()); // make "-" an alias for /dev/stdin if (file.getName().equals("-")) { inputStream = System.in; } else { inputStream = new FileInputStream(file); } // Create a stream splitter to break the PBF stream into blobs. streamSplitter = new PbfStreamSplitter(new DataInputStream(inputStream)); // Process all blobs of data in the stream using threads from the // executor service. We allow the decoder to issue an extra blob // than there are workers to ensure there is another blob // immediately ready for processing when a worker thread completes. // The main thread is responsible for splitting blobs from the // request stream, and sending decoded entities to the sink. PbfDecoder pbfDecoder = new PbfDecoder(streamSplitter, executorService, workers + 1, sink); pbfDecoder.run(); sink.complete(); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to read PBF file " + file + ".", e); } finally { sink.release(); executorService.shutdownNow(); if (streamSplitter != null) { streamSplitter.release(); } } } } osmosis-0.44.1/osmosis-pbf2/src/main/java/org/openstreetmap/osmosis/pbf2/v0_6/PbfReaderFactory.java000066400000000000000000000026641253404521400330640ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pbf2.v0_6; import java.io.File; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.RunnableSourceManager; /** * The task manager factory for a PBF reader. * * @author Brett Henderson */ public class PbfReaderFactory extends TaskManagerFactory { private static final String ARG_FILE_NAME = "file"; private static final String DEFAULT_FILE_NAME = "dump.osm.pbf"; private static final String ARG_WORKERS = "workers"; private static final int DEFAULT_WORKERS = 1; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String fileName; File file; PbfReader task; int workers; // Get the task arguments. fileName = getStringArgument(taskConfig, ARG_FILE_NAME, getDefaultStringArgument(taskConfig, DEFAULT_FILE_NAME)); workers = getIntegerArgument(taskConfig, ARG_WORKERS, DEFAULT_WORKERS); // Create a file object from the file name provided. file = new File(fileName); // Build the task object. task = new PbfReader(file, workers); return new RunnableSourceManager(taskConfig.getId(), task, taskConfig.getPipeArgs()); } } osmosis-0.44.1/osmosis-pbf2/src/main/java/org/openstreetmap/osmosis/pbf2/v0_6/impl/000077500000000000000000000000001253404521400277705ustar00rootroot00000000000000PbfBlobDecoder.java000066400000000000000000000363141253404521400333570ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf2/src/main/java/org/openstreetmap/osmosis/pbf2/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pbf2.v0_6.impl; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import java.util.zip.DataFormatException; import java.util.zip.Inflater; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.openstreetmap.osmosis.osmbinary.Osmformat; import org.openstreetmap.osmosis.osmbinary.Fileformat.Blob; import org.openstreetmap.osmosis.osmbinary.Osmformat.DenseInfo; import org.openstreetmap.osmosis.osmbinary.Osmformat.DenseNodes; import org.openstreetmap.osmosis.osmbinary.Osmformat.HeaderBBox; import org.openstreetmap.osmosis.osmbinary.Osmformat.Info; import org.openstreetmap.osmosis.osmbinary.Osmformat.Node; import org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveGroup; import org.openstreetmap.osmosis.osmbinary.Osmformat.Relation; import org.openstreetmap.osmosis.osmbinary.Osmformat.Way; import org.openstreetmap.osmosis.osmbinary.Osmformat.Relation.MemberType; import com.google.protobuf.InvalidProtocolBufferException; /** * Converts PBF block data into decoded entities ready to be passed into an * Osmosis pipeline. This class is designed to be passed into a pool of worker * threads to allow multi-threaded decoding. * * @author Brett Henderson */ public class PbfBlobDecoder implements Runnable { private static Logger log = Logger.getLogger(PbfBlobDecoder.class.getName()); private static final double COORDINATE_SCALING_FACTOR = 0.000000001; private static final int EMPTY_VERSION = -1; private static final Date EMPTY_TIMESTAMP = new Date(0); private static final long EMPTY_CHANGESET = -1; private String blobType; private byte[] rawBlob; private PbfBlobDecoderListener listener; private List decodedEntities; /** * Creates a new instance. * * @param blobType * The type of blob. * @param rawBlob * The raw data of the blob. * @param listener * The listener for receiving decoding results. */ public PbfBlobDecoder(String blobType, byte[] rawBlob, PbfBlobDecoderListener listener) { this.blobType = blobType; this.rawBlob = rawBlob; this.listener = listener; } private byte[] readBlobContent() throws IOException { Blob blob = Blob.parseFrom(rawBlob); byte[] blobData; if (blob.hasRaw()) { blobData = blob.getRaw().toByteArray(); } else if (blob.hasZlibData()) { Inflater inflater = new Inflater(); inflater.setInput(blob.getZlibData().toByteArray()); blobData = new byte[blob.getRawSize()]; try { inflater.inflate(blobData); } catch (DataFormatException e) { throw new OsmosisRuntimeException("Unable to decompress PBF blob.", e); } if (!inflater.finished()) { throw new OsmosisRuntimeException("PBF blob contains incomplete compressed data."); } } else { throw new OsmosisRuntimeException("PBF blob uses unsupported compression, only raw or zlib may be used."); } return blobData; } private void processOsmHeader(byte[] data) throws InvalidProtocolBufferException { Osmformat.HeaderBlock header = Osmformat.HeaderBlock.parseFrom(data); // Build the list of active and unsupported features in the file. List supportedFeatures = Arrays.asList("OsmSchema-V0.6", "DenseNodes"); List activeFeatures = new ArrayList(); List unsupportedFeatures = new ArrayList(); for (String feature : header.getRequiredFeaturesList()) { if (supportedFeatures.contains(feature)) { activeFeatures.add(feature); } else { unsupportedFeatures.add(feature); } } // We can't continue if there are any unsupported features. We wait // until now so that we can display all unsupported features instead of // just the first one we encounter. if (unsupportedFeatures.size() > 0) { throw new OsmosisRuntimeException("PBF file contains unsupported features " + unsupportedFeatures); } // Build a new bound object which corresponds to the header. Bound bound; if (header.hasBbox()) { HeaderBBox bbox = header.getBbox(); bound = new Bound(bbox.getRight() * COORDINATE_SCALING_FACTOR, bbox.getLeft() * COORDINATE_SCALING_FACTOR, bbox.getTop() * COORDINATE_SCALING_FACTOR, bbox.getBottom() * COORDINATE_SCALING_FACTOR, header.getSource()); } else { bound = new Bound(header.getSource()); } // Add the bound object to the results. decodedEntities.add(new BoundContainer(bound)); } private void buildTags(CommonEntityData entityData, List keys, List values, PbfFieldDecoder fieldDecoder) { Collection tags = entityData.getTags(); // Ensure parallel lists are of equal size. if (keys.size() != values.size()) { throw new OsmosisRuntimeException("Number of tag keys (" + keys.size() + ") and tag values (" + values.size() + ") don't match"); } Iterator keyIterator = keys.iterator(); Iterator valueIterator = values.iterator(); while (keyIterator.hasNext()) { String key = fieldDecoder.decodeString(keyIterator.next()); String value = fieldDecoder.decodeString(valueIterator.next()); Tag tag = new Tag(key, value); tags.add(tag); } } private CommonEntityData buildCommonEntityData(long entityId, List keys, List values, Info info, PbfFieldDecoder fieldDecoder) { OsmUser user; CommonEntityData entityData; // Build the user, but only if one exists. if (info.hasUid() && info.getUid() >= 0 && info.hasUserSid()) { user = new OsmUser(info.getUid(), fieldDecoder.decodeString(info.getUserSid())); } else { user = OsmUser.NONE; } entityData = new CommonEntityData(entityId, info.getVersion(), fieldDecoder.decodeTimestamp(info.getTimestamp()), user, info.getChangeset()); buildTags(entityData, keys, values, fieldDecoder); return entityData; } private CommonEntityData buildCommonEntityData(long entityId, List keys, List values, PbfFieldDecoder fieldDecoder) { CommonEntityData entityData; entityData = new CommonEntityData(entityId, EMPTY_VERSION, EMPTY_TIMESTAMP, OsmUser.NONE, EMPTY_CHANGESET); buildTags(entityData, keys, values, fieldDecoder); return entityData; } private void processNodes(List nodes, PbfFieldDecoder fieldDecoder) { for (Node node : nodes) { org.openstreetmap.osmosis.core.domain.v0_6.Node osmNode; CommonEntityData entityData; if (node.hasInfo()) { entityData = buildCommonEntityData(node.getId(), node.getKeysList(), node.getValsList(), node.getInfo(), fieldDecoder); } else { entityData = buildCommonEntityData(node.getId(), node.getKeysList(), node.getValsList(), fieldDecoder); } osmNode = new org.openstreetmap.osmosis.core.domain.v0_6.Node(entityData, fieldDecoder.decodeLatitude(node .getLat()), fieldDecoder.decodeLatitude(node.getLon())); // Add the bound object to the results. decodedEntities.add(new NodeContainer(osmNode)); } } private void processNodes(DenseNodes nodes, PbfFieldDecoder fieldDecoder) { List idList = nodes.getIdList(); List latList = nodes.getLatList(); List lonList = nodes.getLonList(); // Ensure parallel lists are of equal size. if ((idList.size() != latList.size()) || (idList.size() != lonList.size())) { throw new OsmosisRuntimeException("Number of ids (" + idList.size() + "), latitudes (" + latList.size() + "), and longitudes (" + lonList.size() + ") don't match"); } Iterator keysValuesIterator = nodes.getKeysValsList().iterator(); DenseInfo denseInfo; if (nodes.hasDenseinfo()) { denseInfo = nodes.getDenseinfo(); } else { denseInfo = null; } long nodeId = 0; long latitude = 0; long longitude = 0; int userId = 0; int userSid = 0; long timestamp = 0; long changesetId = 0; for (int i = 0; i < idList.size(); i++) { CommonEntityData entityData; org.openstreetmap.osmosis.core.domain.v0_6.Node node; // Delta decode node fields. nodeId += idList.get(i); latitude += latList.get(i); longitude += lonList.get(i); if (denseInfo != null) { // Delta decode dense info fields. userId += denseInfo.getUid(i); userSid += denseInfo.getUserSid(i); timestamp += denseInfo.getTimestamp(i); changesetId += denseInfo.getChangeset(i); // Build the user, but only if one exists. OsmUser user; if (userId >= 0) { user = new OsmUser(userId, fieldDecoder.decodeString(userSid)); } else { user = OsmUser.NONE; } entityData = new CommonEntityData(nodeId, denseInfo.getVersion(i), fieldDecoder.decodeTimestamp(timestamp), user, changesetId); } else { entityData = new CommonEntityData(nodeId, EMPTY_VERSION, EMPTY_TIMESTAMP, OsmUser.NONE, EMPTY_CHANGESET); } // Build the tags. The key and value string indexes are sequential // in the same PBF array. Each set of tags is delimited by an index // with a value of 0. Collection tags = entityData.getTags(); while (keysValuesIterator.hasNext()) { int keyIndex = keysValuesIterator.next(); if (keyIndex == 0) { break; } if (!keysValuesIterator.hasNext()) { throw new OsmosisRuntimeException( "The PBF DenseInfo keys/values list contains a key with no corresponding value."); } int valueIndex = keysValuesIterator.next(); Tag tag = new Tag(fieldDecoder.decodeString(keyIndex), fieldDecoder.decodeString(valueIndex)); tags.add(tag); } node = new org.openstreetmap.osmosis.core.domain.v0_6.Node(entityData, fieldDecoder.decodeLatitude(latitude), fieldDecoder.decodeLongitude(longitude)); // Add the bound object to the results. decodedEntities.add(new NodeContainer(node)); } } private void processWays(List ways, PbfFieldDecoder fieldDecoder) { for (Way way : ways) { org.openstreetmap.osmosis.core.domain.v0_6.Way osmWay; CommonEntityData entityData; if (way.hasInfo()) { entityData = buildCommonEntityData(way.getId(), way.getKeysList(), way.getValsList(), way.getInfo(), fieldDecoder); } else { entityData = buildCommonEntityData(way.getId(), way.getKeysList(), way.getValsList(), fieldDecoder); } osmWay = new org.openstreetmap.osmosis.core.domain.v0_6.Way(entityData); // Build up the list of way nodes for the way. The node ids are // delta encoded meaning that each id is stored as a delta against // the previous one. long nodeId = 0; List wayNodes = osmWay.getWayNodes(); for (long nodeIdOffset : way.getRefsList()) { nodeId += nodeIdOffset; wayNodes.add(new WayNode(nodeId)); } decodedEntities.add(new WayContainer(osmWay)); } } private void buildRelationMembers(org.openstreetmap.osmosis.core.domain.v0_6.Relation relation, List memberIds, List memberRoles, List memberTypes, PbfFieldDecoder fieldDecoder) { List members = relation.getMembers(); // Ensure parallel lists are of equal size. if ((memberIds.size() != memberRoles.size()) || (memberIds.size() != memberTypes.size())) { throw new OsmosisRuntimeException("Number of member ids (" + memberIds.size() + "), member roles (" + memberRoles.size() + "), and member types (" + memberTypes.size() + ") don't match"); } Iterator memberIdIterator = memberIds.iterator(); Iterator memberRoleIterator = memberRoles.iterator(); Iterator memberTypeIterator = memberTypes.iterator(); // Build up the list of relation members for the way. The member ids are // delta encoded meaning that each id is stored as a delta against // the previous one. long memberId = 0; while (memberIdIterator.hasNext()) { MemberType memberType = memberTypeIterator.next(); memberId += memberIdIterator.next(); EntityType entityType; RelationMember member; if (memberType == MemberType.NODE) { entityType = EntityType.Node; } else if (memberType == MemberType.WAY) { entityType = EntityType.Way; } else if (memberType == MemberType.RELATION) { entityType = EntityType.Relation; } else { throw new OsmosisRuntimeException("Member type of " + memberType + " is not supported."); } member = new RelationMember(memberId, entityType, fieldDecoder.decodeString(memberRoleIterator.next())); members.add(member); } } private void processRelations(List relations, PbfFieldDecoder fieldDecoder) { for (Relation relation : relations) { org.openstreetmap.osmosis.core.domain.v0_6.Relation osmRelation; CommonEntityData entityData; if (relation.hasInfo()) { entityData = buildCommonEntityData(relation.getId(), relation.getKeysList(), relation.getValsList(), relation.getInfo(), fieldDecoder); } else { entityData = buildCommonEntityData(relation.getId(), relation.getKeysList(), relation.getValsList(), fieldDecoder); } osmRelation = new org.openstreetmap.osmosis.core.domain.v0_6.Relation(entityData); buildRelationMembers(osmRelation, relation.getMemidsList(), relation.getRolesSidList(), relation.getTypesList(), fieldDecoder); // Add the bound object to the results. decodedEntities.add(new RelationContainer(osmRelation)); } } private void processOsmPrimitives(byte[] data) throws InvalidProtocolBufferException { Osmformat.PrimitiveBlock block = Osmformat.PrimitiveBlock.parseFrom(data); PbfFieldDecoder fieldDecoder = new PbfFieldDecoder(block); for (PrimitiveGroup primitiveGroup : block.getPrimitivegroupList()) { log.finer("Processing OSM primitive group."); processNodes(primitiveGroup.getDense(), fieldDecoder); processNodes(primitiveGroup.getNodesList(), fieldDecoder); processWays(primitiveGroup.getWaysList(), fieldDecoder); processRelations(primitiveGroup.getRelationsList(), fieldDecoder); } } private void runAndTrapExceptions() { try { decodedEntities = new ArrayList(); if ("OSMHeader".equals(blobType)) { processOsmHeader(readBlobContent()); } else if ("OSMData".equals(blobType)) { processOsmPrimitives(readBlobContent()); } else { if (log.isLoggable(Level.FINER)) { log.finer("Skipping unrecognised blob type " + blobType); } } } catch (IOException e) { throw new OsmosisRuntimeException("Unable to process PBF blob", e); } } @Override public void run() { try { runAndTrapExceptions(); listener.complete(decodedEntities); } catch (RuntimeException e) { listener.error(); } } } PbfBlobDecoderListener.java000066400000000000000000000012531253404521400350570ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf2/src/main/java/org/openstreetmap/osmosis/pbf2/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pbf2.v0_6.impl; import java.util.List; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; /** * Instances of this interface are used to receive results from PBFBlobDecoder. * * @author Brett Henderson */ public interface PbfBlobDecoderListener { /** * Provides the listener with the list of decoded entities. * * @param decodedEntities * The decoded entities. */ void complete(List decodedEntities); /** * Notifies the listener that an error occurred during processing. */ void error(); } PbfBlobResult.java000066400000000000000000000030011253404521400332530ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf2/src/main/java/org/openstreetmap/osmosis/pbf2/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pbf2.v0_6.impl; import java.util.List; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; /** * Stores the results for a decoded Blob. * * @author Brett Henderson */ public class PbfBlobResult { private List entities; private boolean complete; private boolean success; /** * Creates a new instance. */ public PbfBlobResult() { complete = false; success = false; } /** * Stores the results of a successful blob decoding operation. * * @param decodedEntities * The entities from the blob. */ public void storeSuccessResult(List decodedEntities) { entities = decodedEntities; complete = true; success = true; } /** * Stores a failure result for a blob decoding operation. */ public void storeFailureResult() { complete = true; success = false; } /** * Gets the complete flag. * * @return True if complete. */ public boolean isComplete() { return complete; } /** * Gets the success flag. This is only valid after complete becomes true. * * @return True if successful. */ public boolean isSuccess() { return success; } /** * Gets the entities decoded from the blob. This is only valid after * complete becomes true, and if success is true. * * @return The list of decoded entities. */ public List getEntities() { return entities; } } osmosis-0.44.1/osmosis-pbf2/src/main/java/org/openstreetmap/osmosis/pbf2/v0_6/impl/PbfDecoder.java000066400000000000000000000117051253404521400326340ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pbf2.v0_6.impl; import java.util.LinkedList; import java.util.List; import java.util.Queue; import java.util.concurrent.ExecutorService; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.task.v0_6.Sink; /** * Decodes all blocks from a PBF stream using worker threads, and passes the * results to the downstream sink. * * @author Brett Henderson */ public class PbfDecoder implements Runnable { private PbfStreamSplitter streamSplitter; private ExecutorService executorService; private int maxPendingBlobs; private Sink sink; private Lock lock; private Condition dataWaitCondition; private Queue blobResults; /** * Creates a new instance. * * @param streamSplitter * The PBF stream splitter providing the source of blobs to be * decoded. * @param executorService * The executor service managing the thread pool. * @param maxPendingBlobs * The maximum number of blobs to have in progress at any point * in time. * @param sink * The sink to send all decoded entities to. */ public PbfDecoder(PbfStreamSplitter streamSplitter, ExecutorService executorService, int maxPendingBlobs, Sink sink) { this.streamSplitter = streamSplitter; this.executorService = executorService; this.maxPendingBlobs = maxPendingBlobs; this.sink = sink; // Create the thread synchronisation primitives. lock = new ReentrantLock(); dataWaitCondition = lock.newCondition(); // Create the queue of blobs being decoded. blobResults = new LinkedList(); } /** * Any thread can call this method when they wish to wait until an update * has been performed by another thread. */ private void waitForUpdate() { try { dataWaitCondition.await(); } catch (InterruptedException e) { throw new OsmosisRuntimeException("Thread was interrupted.", e); } } /** * Any thread can call this method when they wish to signal another thread * that an update has occurred. */ private void signalUpdate() { dataWaitCondition.signal(); } private void sendResultsToSink(int targetQueueSize) { while (blobResults.size() > targetQueueSize) { // Get the next result from the queue and wait for it to complete. PbfBlobResult blobResult = blobResults.remove(); while (!blobResult.isComplete()) { // The thread hasn't finished processing yet so wait for an // update from another thread before checking again. waitForUpdate(); } if (!blobResult.isSuccess()) { throw new OsmosisRuntimeException("A PBF decoding worker thread failed, aborting."); } // Send the processed entities to the sink. We can release the lock // for the duration of processing to allow worker threads to post // their results. lock.unlock(); try { for (EntityContainer entity : blobResult.getEntities()) { sink.process(entity); } } finally { lock.lock(); } } } private void processBlobs() { // Process until the PBF stream is exhausted. while (streamSplitter.hasNext()) { // Obtain the next raw blob from the PBF stream. PbfRawBlob rawBlob = streamSplitter.next(); // Create the result object to capture the results of the decoded // blob and add it to the blob results queue. final PbfBlobResult blobResult = new PbfBlobResult(); blobResults.add(blobResult); // Create the listener object that will update the blob results // based on an event fired by the blob decoder. PbfBlobDecoderListener decoderListener = new PbfBlobDecoderListener() { @Override public void error() { lock.lock(); try { blobResult.storeFailureResult(); signalUpdate(); } finally { lock.unlock(); } } @Override public void complete(List decodedEntities) { lock.lock(); try { blobResult.storeSuccessResult(decodedEntities); signalUpdate(); } finally { lock.unlock(); } } }; // Create the blob decoder itself and execute it on a worker thread. PbfBlobDecoder blobDecoder = new PbfBlobDecoder(rawBlob.getType(), rawBlob.getData(), decoderListener); executorService.execute(blobDecoder); // If the number of pending blobs has reached capacity we must begin // sending results to the sink. This method will block until blob // decoding is complete. sendResultsToSink(maxPendingBlobs - 1); } // There are no more entities available in the PBF stream, so send all remaining data to the sink. sendResultsToSink(0); } @Override public void run() { lock.lock(); try { processBlobs(); } finally { lock.unlock(); } } } PbfFieldDecoder.java000066400000000000000000000046201253404521400335170ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf2/src/main/java/org/openstreetmap/osmosis/pbf2/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pbf2.v0_6.impl; import java.util.Date; import org.openstreetmap.osmosis.osmbinary.Osmformat.PrimitiveBlock; import org.openstreetmap.osmosis.osmbinary.Osmformat.StringTable; /** * Manages decoding of the lower level PBF data structures. * * @author Brett Henderson * */ public class PbfFieldDecoder { private static final double COORDINATE_SCALING_FACTOR = 0.000000001; private String[] strings; private int coordGranularity; private long coordLatitudeOffset; private long coordLongitudeOffset; private int dateGranularity; /** * Creates a new instance. * * @param primitiveBlock * The primitive block containing the fields to be decoded. */ public PbfFieldDecoder(PrimitiveBlock primitiveBlock) { this.coordGranularity = primitiveBlock.getGranularity(); this.coordLatitudeOffset = primitiveBlock.getLatOffset(); this.coordLongitudeOffset = primitiveBlock.getLonOffset(); this.dateGranularity = primitiveBlock.getDateGranularity(); StringTable stringTable = primitiveBlock.getStringtable(); strings = new String[stringTable.getSCount()]; for (int i = 0; i < strings.length; i++) { strings[i] = stringTable.getS(i).toStringUtf8(); } } /** * Decodes a raw latitude value into degrees. * * @param rawLatitude * The PBF encoded value. * @return The latitude in degrees. */ public double decodeLatitude(long rawLatitude) { return COORDINATE_SCALING_FACTOR * (coordLatitudeOffset + (coordGranularity * rawLatitude)); } /** * Decodes a raw longitude value into degrees. * * @param rawLongitude * The PBF encoded value. * @return The longitude in degrees. */ public double decodeLongitude(long rawLongitude) { return COORDINATE_SCALING_FACTOR * (coordLongitudeOffset + (coordGranularity * rawLongitude)); } /** * Decodes a raw timestamp value into a Date. * * @param rawTimestamp * The PBF encoded timestamp. * @return The timestamp as a Date. */ public Date decodeTimestamp(long rawTimestamp) { return new Date(dateGranularity * rawTimestamp); } /** * Decodes a raw string into a String. * * @param rawString * The PBF encoding string. * @return The string as a String. */ public String decodeString(int rawString) { return strings[rawString]; } } osmosis-0.44.1/osmosis-pbf2/src/main/java/org/openstreetmap/osmosis/pbf2/v0_6/impl/PbfRawBlob.java000066400000000000000000000021131253404521400326100ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pbf2.v0_6.impl; /** * Represents a single piece of raw blob data extracted from the PBF stream. It * has not yet been decoded into a PBF blob object. * * @author Brett Henderson */ public class PbfRawBlob { private String type; private byte[] data; /** * Creates a new instance. * * @param type * The type of data represented by this blob. This corresponds to * the type field in the blob header. * @param data * The raw contents of the blob in binary undecoded form. */ public PbfRawBlob(String type, byte[] data) { this.type = type; this.data = data; } /** * Gets the type of data represented by this blob. This corresponds to the * type field in the blob header. * * @return The blob type. */ public String getType() { return type; } /** * Gets the raw contents of the blob in binary undecoded form. * * @return The raw blob data. */ public byte[] getData() { return data; } } PbfStreamSplitter.java000066400000000000000000000057441253404521400342000ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf2/src/main/java/org/openstreetmap/osmosis/pbf2/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pbf2.v0_6.impl; import java.io.DataInputStream; import java.io.EOFException; import java.io.IOException; import java.util.Iterator; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.lifecycle.Releasable; import org.openstreetmap.osmosis.osmbinary.Fileformat; import org.openstreetmap.osmosis.osmbinary.Fileformat.BlobHeader; /** * Parses a PBF data stream and extracts the raw data of each blob in sequence * until the end of the stream is reached. * * @author Brett Henderson */ public class PbfStreamSplitter implements Iterator, Releasable { private static Logger log = Logger.getLogger(PbfStreamSplitter.class.getName()); private DataInputStream dis; private int dataBlockCount; private boolean eof; private PbfRawBlob nextBlob; /** * Creates a new instance. * * @param pbfStream * The PBF data stream to be parsed. */ public PbfStreamSplitter(DataInputStream pbfStream) { dis = pbfStream; dataBlockCount = 0; eof = false; } private BlobHeader readHeader(int headerLength) throws IOException { byte[] headerBuffer = new byte[headerLength]; dis.readFully(headerBuffer); BlobHeader blobHeader = Fileformat.BlobHeader.parseFrom(headerBuffer); return blobHeader; } private byte[] readRawBlob(BlobHeader blobHeader) throws IOException { byte[] rawBlob = new byte[blobHeader.getDatasize()]; dis.readFully(rawBlob); return rawBlob; } private void getNextBlob() { try { // Read the length of the next header block. This is the only time // we should expect to encounter an EOF exception. In all other // cases it indicates a corrupt or truncated file. int headerLength; try { headerLength = dis.readInt(); } catch (EOFException e) { eof = true; return; } if (log.isLoggable(Level.FINER)) { log.finer("Reading header for blob " + dataBlockCount++); } BlobHeader blobHeader = readHeader(headerLength); if (log.isLoggable(Level.FINER)) { log.finer("Processing blob of type " + blobHeader.getType() + "."); } byte[] blobData = readRawBlob(blobHeader); nextBlob = new PbfRawBlob(blobHeader.getType(), blobData); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to get next blob from PBF stream.", e); } } @Override public boolean hasNext() { if (nextBlob == null && !eof) { getNextBlob(); } return nextBlob != null; } @Override public PbfRawBlob next() { PbfRawBlob result = nextBlob; nextBlob = null; return result; } @Override public void remove() { throw new UnsupportedOperationException(); } @Override public void release() { if (dis != null) { try { dis.close(); } catch (IOException e) { log.log(Level.SEVERE, "Unable to close PBF stream.", e); } } dis = null; } } osmosis-0.44.1/osmosis-pbf2/src/main/resources/000077500000000000000000000000001253404521400213445ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf2/src/main/resources/osmosis-plugins.conf000066400000000000000000000000561253404521400253670ustar00rootroot00000000000000org.openstreetmap.osmosis.pbf2.PbfPluginLoaderosmosis-0.44.1/osmosis-pbf2/src/test/000077500000000000000000000000001253404521400173655ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf2/src/test/java/000077500000000000000000000000001253404521400203065ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf2/src/test/java/org/000077500000000000000000000000001253404521400210755ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf2/src/test/java/org/openstreetmap/000077500000000000000000000000001253404521400237635ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf2/src/test/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400254575ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf2/src/test/java/org/openstreetmap/osmosis/pbf2/000077500000000000000000000000001253404521400263105ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf2/src/test/java/org/openstreetmap/osmosis/pbf2/v0_6/000077500000000000000000000000001253404521400270625ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf2/src/test/java/org/openstreetmap/osmosis/pbf2/v0_6/OsmosisReaderTest.java000066400000000000000000000027411253404521400333500ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pbf2.v0_6; import java.io.File; import java.io.IOException; import org.junit.Test; import org.openstreetmap.osmosis.core.Osmosis; import org.openstreetmap.osmosis.testutil.AbstractDataTest; /** * Tests the OsmosisReader and OsmosisSerializer classes. * * @author Brett Henderson */ public class OsmosisReaderTest extends AbstractDataTest { /** * Tests writing to and reading from PBF files. * * @throws IOException * if any file operations fail. */ @Test public void testWriteAndRead() throws IOException { // Generate data files. File inputXmlFile = dataUtils.createDataFile("v0_6/data-snapshot.osm"); File pbfFile = dataUtils.newFile(); File outputXmlFile = dataUtils.newFile(); // Read the XML and write to PBF using the standard PBF writer. Osmosis.run(new String[] { "-q", "--read-xml-0.6", inputXmlFile.getPath(), "--write-pbf-0.6", pbfFile.getPath() }); // Read the PBF using the PBF2 reader and write to XML. Osmosis.run(new String[] { "-q", "--read-pbf-fast-0.6", pbfFile.getPath(), "--write-xml-0.6", outputXmlFile.getPath() }); // Validate that the output file matches the input file. dataUtils.compareFiles(inputXmlFile, outputXmlFile); } } osmosis-0.44.1/osmosis-pbf2/src/test/resources/000077500000000000000000000000001253404521400213775ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf2/src/test/resources/data/000077500000000000000000000000001253404521400223105ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf2/src/test/resources/data/template/000077500000000000000000000000001253404521400241235ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf2/src/test/resources/data/template/v0_6/000077500000000000000000000000001253404521400246755ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pbf2/src/test/resources/data/template/v0_6/data-snapshot.osm000066400000000000000000000037261253404521400301730ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-pgsimple/000077500000000000000000000000001253404521400166065ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/.checkstyle000066400000000000000000000010051253404521400207410ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-pgsimple/.gitignore000066400000000000000000000000531253404521400205740ustar00rootroot00000000000000.classpath .project .settings /bin /build osmosis-0.44.1/osmosis-pgsimple/build.gradle000066400000000000000000000011221253404521400210610ustar00rootroot00000000000000configurations { // Exclude unnecessary postgis stub classes. all*.exclude group: 'org.postgis', module: 'postgis-stubs' } dependencies { compile project(':osmosis-core') compile group: 'org.postgis', name: 'postgis-jdbc', version: dependencyVersionPostGis compile group: 'org.postgresql', name: 'postgresql', version: dependencyVersionPostgreSql testCompile project(':osmosis-dataset') testCompile project(':osmosis-testutil') testCompile project(':osmosis-xml') } // Disable tests until continuous integration has a database configured. test.enabled = false osmosis-0.44.1/osmosis-pgsimple/src/000077500000000000000000000000001253404521400173755ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/000077500000000000000000000000001253404521400203215ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/000077500000000000000000000000001253404521400212425ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/000077500000000000000000000000001253404521400220315ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/000077500000000000000000000000001253404521400247175ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400264135ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/000077500000000000000000000000001253404521400302335ustar00rootroot00000000000000PgSimplePluginLoader.java000066400000000000000000000045651253404521400350570ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.plugin.PluginLoader; import org.openstreetmap.osmosis.pgsimple.v0_6.PostgreSqlChangeWriterFactory; import org.openstreetmap.osmosis.pgsimple.v0_6.PostgreSqlCopyWriterFactory; import org.openstreetmap.osmosis.pgsimple.v0_6.PostgreSqlDatasetReaderFactory; import org.openstreetmap.osmosis.pgsimple.v0_6.PostgreSqlDumpWriterFactory; import org.openstreetmap.osmosis.pgsimple.v0_6.PostgreSqlTruncatorFactory; import org.openstreetmap.osmosis.pgsimple.v0_6.PostgreSqlWriterFactory; /** * The plugin loader for the PostgreSQL Snapshot Schema tasks. * * @author Brett Henderson */ public class PgSimplePluginLoader implements PluginLoader { /** * {@inheritDoc} */ @Override public Map loadTaskFactories() { Map factoryMap; factoryMap = new HashMap(); factoryMap.put("write-pgsimp", new PostgreSqlWriterFactory()); factoryMap.put("ws", new PostgreSqlWriterFactory()); factoryMap.put("fast-write-pgsimp", new PostgreSqlCopyWriterFactory()); factoryMap.put("fws", new PostgreSqlCopyWriterFactory()); factoryMap.put("truncate-pgsimp", new PostgreSqlTruncatorFactory()); factoryMap.put("ts", new PostgreSqlTruncatorFactory()); factoryMap.put("write-pgsimp-dump", new PostgreSqlDumpWriterFactory()); factoryMap.put("wsd", new PostgreSqlDumpWriterFactory()); factoryMap.put("read-pgsimp", new PostgreSqlDatasetReaderFactory()); factoryMap.put("rs", new PostgreSqlDatasetReaderFactory()); factoryMap.put("write-pgsimp-change", new PostgreSqlChangeWriterFactory()); factoryMap.put("wsc", new PostgreSqlChangeWriterFactory()); factoryMap.put("write-pgsimp-0.6", new PostgreSqlWriterFactory()); factoryMap.put("fast-write-pgsimp-0.6", new PostgreSqlCopyWriterFactory()); factoryMap.put("truncate-pgsimp-0.6", new PostgreSqlTruncatorFactory()); factoryMap.put("write-pgsimp-dump-0.6", new PostgreSqlDumpWriterFactory()); factoryMap.put("read-pgsimp-0.6", new PostgreSqlDatasetReaderFactory()); factoryMap.put("write-pgsimp-change-0.6", new PostgreSqlChangeWriterFactory()); return factoryMap; } } osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/common/000077500000000000000000000000001253404521400315235ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/common/BaseDao.java000066400000000000000000000027731253404521400336750ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.common; import java.sql.PreparedStatement; import org.openstreetmap.osmosis.core.database.ReleasableStatementContainer; import org.openstreetmap.osmosis.core.lifecycle.Releasable; /** * Provides functionality common to all dao implementations. * * @author Brett Henderson */ public class BaseDao implements Releasable { private DatabaseContext dbCtx; private ReleasableStatementContainer statementContainer; /** * Creates a new instance. * * @param dbCtx * The database context to use for accessing the database. */ protected BaseDao(DatabaseContext dbCtx) { this.dbCtx = dbCtx; statementContainer = new ReleasableStatementContainer(); } /** * Provides access to the database context. In most cases alternative * methods such as prepareStatement should be used. * * @return The database context. */ protected DatabaseContext getDatabaseContext() { return dbCtx; } /** * Creates a new database prepared statement. This statement will be * automatically released when the dao is released. * * @param sql * The statement to be created. * @return The newly created statement. */ protected PreparedStatement prepareStatement(String sql) { return statementContainer.add(dbCtx.prepareStatement(sql)); } /** * {@inheritDoc} */ @Override public void release() { statementContainer.release(); } } BaseTableReader.java000066400000000000000000000105661253404521400352640ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.common; import java.sql.ResultSet; import java.sql.SQLException; import java.util.NoSuchElementException; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; /** * Provides the base implementation of all database table readers. * * @author Brett Henderson * * @param * The type of entity to retrieved. */ public abstract class BaseTableReader implements ReleasableIterator { private static final Logger LOG = Logger.getLogger(BaseTableReader.class.getName()); private DatabaseContext dbCtx; private ResultSet resultSet; private T nextValue; /** * Creates a new instance. * * @param dbCtx * The active connection to use for reading from the database. */ public BaseTableReader(DatabaseContext dbCtx) { this.dbCtx = dbCtx; } /** * Builds the result set that the reader will iterate over. * * @param queryDbCtx * The database context to query against. * @return A result set positioned before the first record. */ protected abstract ResultSet createResultSet(DatabaseContext queryDbCtx); /** * Builds an entity object from the current recordset row. * * @param activeResultSet * The record set to retrieve the data from. * @return The result of the read. */ protected abstract ReadResult createNextValue(ResultSet activeResultSet); /** * If the implementation requires multiple rows to build an entity object, * this method allows the implementation to return an entity based on the * fact that no more rows are available. This default implementation returns * a blank result. * * @return The last result record. */ protected ReadResult createLastValue() { return new ReadResult(true, null); } /** * Reads the next entity from the database and stores it in the internal * nextValue variable. This will be set to null if no more data is * available. */ private void readNextValue() { if (resultSet == null) { resultSet = createResultSet(dbCtx); } try { ReadResult readResult; // Loop until a valid result is determined. Typically a loop is // required when a record on the result set is skipped over by the // reader implementation. do { if (resultSet.next()) { readResult = createNextValue(resultSet); } else { readResult = createLastValue(); } } while (!readResult.isUsableResult()); nextValue = readResult.getEntity(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to move to next record.", e); } } /** * {@inheritDoc} */ public boolean hasNext() { if (resultSet == null) { readNextValue(); } return (nextValue != null); } /** * {@inheritDoc} */ public T next() { T result; if (!hasNext()) { throw new NoSuchElementException(); } result = nextValue; readNextValue(); return result; } /** * {@inheritDoc} */ public void release() { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { // We cannot throw an exception within a release method. LOG.log(Level.WARNING, "Unable to close result set.", e); } resultSet = null; } } /** * {@inheritDoc} */ public void remove() { throw new UnsupportedOperationException(); } /** * Represents the result of an entity read from the result set at the current position. * * @param * The type of entity to retrieved. */ protected static class ReadResult { private boolean usableResult; private T entity; /** * Creates a new instance. * * @param usableResult * Indicates if this result should be used. * @param entity * The entity being read. */ public ReadResult(boolean usableResult, T entity) { this.usableResult = usableResult; this.entity = entity; } /** * Returns the usable result flag. * * @return The usable result flag. */ public boolean isUsableResult() { return usableResult; } /** * Returns the entity. * * @return The entity. */ public T getEntity() { return entity; } } } CompactPersistentNodeLocation.java000066400000000000000000000030021253404521400402500ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.common; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; import org.openstreetmap.osmosis.core.store.Storeable; /** * The compact persistent node location store persists instances of this class. * * @author Brett Henderson */ public class CompactPersistentNodeLocation implements Storeable { private NodeLocation nodeLocation; /** * Creates a new instance. * * @param nodeLocation The node location details. */ public CompactPersistentNodeLocation(NodeLocation nodeLocation) { this.nodeLocation = nodeLocation; } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers within the store. */ public CompactPersistentNodeLocation(StoreReader sr, StoreClassRegister scr) { nodeLocation = new NodeLocation(sr.readDouble(), sr.readDouble()); } /** * {@inheritDoc} */ @Override public void store(StoreWriter writer, StoreClassRegister storeClassRegister) { writer.writeDouble(nodeLocation.getLongitude()); writer.writeDouble(nodeLocation.getLatitude()); } /** * Gets the node location details. * @return The node location. */ public NodeLocation getNodeLocation() { return nodeLocation; } } CompactPersistentNodeLocationStore.java000066400000000000000000000037401253404521400412760ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.common; import org.openstreetmap.osmosis.core.store.IndexedObjectStore; import org.openstreetmap.osmosis.core.store.IndexedObjectStoreReader; import org.openstreetmap.osmosis.core.store.NoSuchIndexElementException; import org.openstreetmap.osmosis.core.store.SingleClassObjectSerializationFactory; /** * A file-based node location store implementation. This differs from the normal * file-based implementation in that it consumes disk space proportionally to * the number of nodes being managed. This is more efficient for smaller data * sets, but less efficient when processing a full planet. * * @author Brett Henderson */ public class CompactPersistentNodeLocationStore implements NodeLocationStore { private IndexedObjectStore nodeLocations; private IndexedObjectStoreReader nodeLocationsReader; /** * Creates a new instance. */ public CompactPersistentNodeLocationStore() { nodeLocations = new IndexedObjectStore( new SingleClassObjectSerializationFactory(CompactPersistentNodeLocation.class), "nodeLocation"); } /** * {@inheritDoc} */ @Override public void addLocation(long nodeId, NodeLocation nodeLocation) { nodeLocations.add(nodeId, new CompactPersistentNodeLocation(nodeLocation)); } /** * {@inheritDoc} */ @Override public NodeLocation getNodeLocation(long nodeId) { if (nodeLocationsReader == null) { nodeLocations.complete(); nodeLocationsReader = nodeLocations.createReader(); } try { return nodeLocationsReader.get(nodeId).getNodeLocation(); } catch (NoSuchIndexElementException e) { return new NodeLocation(); } } /** * {@inheritDoc} */ @Override public void release() { if (nodeLocationsReader != null) { nodeLocationsReader.release(); } nodeLocations.release(); } } CopyFileWriter.java000066400000000000000000000156071253404521400352270ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.common; import java.io.BufferedOutputStream; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.text.SimpleDateFormat; import java.util.Date; import java.util.logging.Level; import java.util.logging.Logger; import org.postgis.Geometry; import org.postgis.binary.BinaryWriter; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.lifecycle.Completable; /** * This class provides the capability to write a file that contains data for a * database COPY statement for loading a single table into the database. * * @author Brett Henderson */ public class CopyFileWriter implements Completable { private static Logger log = Logger.getLogger(CopyFileWriter.class.getName()); private File file; private boolean initialized; private BufferedWriter writer; private boolean midRecord; private SimpleDateFormat dateFormat; private BinaryWriter postgisBinaryWriter; /** * Creates a new instance. * * @param file * The file to write. */ public CopyFileWriter(File file) { this.file = file; midRecord = false; dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ"); postgisBinaryWriter = new BinaryWriter(); } /** * Adds a field separator if required. * * @throws IOException * if the field cannot be written. */ private void separateField() throws IOException { if (midRecord) { writer.write('\t'); } else { midRecord = true; } } /** * Writes data to the output file. * * @param data * The data to be written. */ public void writeField(boolean data) { initialize(); try { separateField(); if (data) { writer.write("t"); } else { writer.write("f"); } } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write value (" + data + ")", e); } } /** * Writes data to the output file. * * @param data * The data to be written. */ public void writeField(int data) { initialize(); try { separateField(); writer.write(Integer.toString(data)); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write value (" + data + ")", e); } } /** * Writes data to the output file. * * @param data * The data to be written. */ public void writeField(long data) { initialize(); try { separateField(); writer.write(Long.toString(data)); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write value (" + data + ")", e); } } /** * Inserts escape sequences needed to make a String suitable for writing to * a COPY file. * * @param data * The raw data string. * @return The escaped string. */ private String escapeString(String data) { StringBuilder result; char[] dataArray; if (data == null) { return "\\N"; } result = new StringBuilder(data.length()); dataArray = data.toCharArray(); for (int i = 0; i < dataArray.length; i++) { char currentChar; currentChar = dataArray[i]; switch (currentChar) { case '\\': // Slash result.append("\\\\"); break; case 8: // Backspace result.append("\\b"); break; case 12: // Form feed result.append("\\f"); break; case 10: // Newline result.append("\\n"); break; case 13: // Carriage return result.append("\\r"); break; case 9: // Tab result.append("\\t"); break; case 11: // Vertical tab result.append("\\v"); break; default: result.append(currentChar); } } return result.toString(); } /** * Writes data to the output file. * * @param data * The data to be written. */ public void writeField(String data) { initialize(); try { separateField(); writer.write(escapeString(data)); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write value (" + data + ")", e); } } /** * Writes data to the output file. * * @param data * The data to be written. */ public void writeField(Date data) { initialize(); try { separateField(); writer.write(dateFormat.format(data)); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write value (" + data + ")", e); } } /** * Writes data to the output file. * * @param data * The data to be written. */ public void writeField(Geometry data) { initialize(); try { separateField(); if (data == null) { writer.write(escapeString(null)); } else { writer.write(postgisBinaryWriter.writeHexed(data)); } } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write value (" + data + ")", e); } } /** * Writes a new line in the output file. */ public void endRecord() { try { writer.newLine(); midRecord = false; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to end record.", e); } } /** * Initialises the output file for writing. This must be called by * sub-classes before any writing is performed. This method may be called * multiple times without adverse affect allowing sub-classes to invoke it * every time they perform processing. */ private void initialize() { if (!initialized) { OutputStream outStream = null; try { outStream = new FileOutputStream(file); writer = new BufferedWriter( new OutputStreamWriter(new BufferedOutputStream(outStream, 65536), "UTF-8")); outStream = null; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to open file for writing.", e); } finally { if (outStream != null) { try { outStream.close(); } catch (Exception e) { log.log(Level.SEVERE, "Unable to close output stream.", e); } outStream = null; } } initialized = true; } } /** * Flushes all changes to file. */ public void complete() { initialize(); try { if (midRecord) { throw new OsmosisRuntimeException("The current record has not been ended."); } if (writer != null) { writer.close(); } } catch (IOException e) { throw new OsmosisRuntimeException("Unable to complete writing to the data stream.", e); } finally { initialized = false; writer = null; } } /** * Cleans up any open file handles. */ public void release() { try { try { if (writer != null) { writer.close(); } } catch (IOException e) { log.log(Level.SEVERE, "Unable to close writer.", e); } } finally { initialized = false; writer = null; } } } DatabaseContext.java000066400000000000000000000237111253404521400353640ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.common; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.logging.Level; import java.util.logging.Logger; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.sql.DataSource; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; /** * This class manages the lifecycle of JDBC objects to minimise the risk of * connection leaks and to support a consistent approach to database access. * * @author Brett Henderson */ public class DatabaseContext { private static final Logger LOG = Logger.getLogger(DatabaseContext.class.getName()); static { // Register the database driver. try { Class.forName("org.postgresql.Driver"); } catch (ClassNotFoundException e) { throw new OsmosisRuntimeException("Unable to find database driver.", e); } } private DatabaseLoginCredentials loginCredentials; private Connection connection; private boolean autoCommit; private Statement statement; /** * Creates a new instance. * * @param loginCredentials * Contains all information required to connect to the database. */ public DatabaseContext(DatabaseLoginCredentials loginCredentials) { this.loginCredentials = loginCredentials; autoCommit = false; } private Connection getConnectionFromDriverManager() { try { return DriverManager.getConnection( "jdbc:postgresql://" + loginCredentials.getHost() + "/" + loginCredentials.getDatabase(), // + "?logLevel=2" loginCredentials.getUser(), loginCredentials.getPassword() ); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to establish a new database connection.", e); } } private Connection getConnectionFromDatasource() { InitialContext cxt; DataSource ds; String jndiLocation; jndiLocation = loginCredentials.getDatasourceJndiLocation(); try { cxt = new InitialContext(); } catch (NamingException e) { throw new OsmosisRuntimeException("Unable to create an initial JNDI context.", e); } try { ds = (DataSource) cxt.lookup(jndiLocation); } catch (NamingException e) { throw new OsmosisRuntimeException("Unable to locate the datasource (" + jndiLocation + ")", e); } try { return ds.getConnection(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to obtain a connection from the datasource.", e); } } /** * If no database connection is open, a new connection is opened. The * database connection is then returned. * * @return The database connection. */ public Connection getConnection() { if (connection == null) { String jndiLocation; jndiLocation = loginCredentials.getDatasourceJndiLocation(); if (jndiLocation != null) { LOG.finer("Creating a new database connection from JNDI."); connection = getConnectionFromDatasource(); } else { LOG.finer("Creating a new database connection using DriverManager."); connection = getConnectionFromDriverManager(); } try { connection.setAutoCommit(autoCommit); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to set auto commit to " + autoCommit + ".", e); } } return connection; } /** * Executes a sql statement against the database. * * @param sql * The sql statement to be invoked. */ public void executeStatement(String sql) { try { LOG.finest("Executing statement {" + sql + "}"); if (statement != null) { statement.close(); } statement = getConnection().createStatement(); statement.execute(sql); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to execute statement.", e); } } /** * Creates a new database prepared statement. * * @param sql * The statement to be created. * @return The newly created statement. */ public PreparedStatement prepareStatement(String sql) { try { PreparedStatement preparedStatement; LOG.finest("Creating prepared statement {" + sql + "}"); preparedStatement = getConnection().prepareStatement(sql); return preparedStatement; } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to create database prepared statement.", e); } } /** * Creates a new database callable statement. * * @param sql * The statement to be created. * @return The newly created statement. */ public CallableStatement prepareCall(String sql) { try { CallableStatement callableStatement; LOG.finest("Creating callable statement {" + sql + "}"); callableStatement = getConnection().prepareCall(sql); return callableStatement; } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to create database callable statement.", e); } } /** * Creates a new database statement. * * @return The newly created statement. */ public Statement createStatement() { try { Statement resultStatement; LOG.finest("Creating a new statement."); resultStatement = getConnection().createStatement(); return resultStatement; } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to create database statement.", e); } } /** * Executes a query and returns a result set. The returned result set must * be closed by the caller. * * @param sql * The query to execute. * @return The newly created result set. */ public ResultSet executeQuery(String sql) { try { ResultSet resultSet; LOG.finest("Executing query {" + sql + "}"); if (statement != null) { statement.close(); } statement = getConnection().createStatement( ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY ); statement.setFetchSize(10000); resultSet = statement.executeQuery(sql); return resultSet; } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to create resultset.", e); } } /** * Indicates if the specified column exists in the database. * * @param tableName The table to check for. * @param columnName The column to check for. * @return True if the column exists, false otherwise. */ public boolean doesColumnExist(String tableName, String columnName) { ResultSet resultSet = null; boolean result; try { LOG.finest("Checking if column {" + columnName + "} in table {" + tableName + "} exists."); resultSet = getConnection().getMetaData().getColumns(null, null, tableName, columnName); result = resultSet.next(); resultSet.close(); resultSet = null; return result; } catch (SQLException e) { throw new OsmosisRuntimeException( "Unable to check for the existence of column " + tableName + "." + columnName + ".", e ); } finally { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to close column existence result set.", e); } } } } /** * Indicates if the specified table exists in the database. * * @param tableName The table to check for. * @return True if the table exists, false otherwise. */ public boolean doesTableExist(String tableName) { ResultSet resultSet = null; boolean result; try { LOG.finest("Checking if table {" + tableName + "} exists."); resultSet = getConnection().getMetaData().getTables(null, null, tableName, new String[]{"TABLE"}); result = resultSet.next(); resultSet.close(); resultSet = null; return result; } catch (SQLException e) { throw new OsmosisRuntimeException( "Unable to check for the existence of table " + tableName + ".", e ); } finally { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to close table existence result set.", e); } } } } /** * Sets the auto-commit property on the underlying connection. * * @param autoCommit * The new auto commit value. */ public void setAutoCommit(boolean autoCommit) { if (connection != null) { try { LOG.finest("Setting auto commit to " + autoCommit + "."); connection.setAutoCommit(autoCommit); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to commit changes.", e); } } this.autoCommit = autoCommit; } /** * Commits any outstanding transaction. */ public void commit() { if (connection != null) { try { LOG.finest("Committing changes."); connection.commit(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to commit changes.", e); } } } /** * Releases all database resources. This method is guaranteed not to throw * transactions and should always be called in a finally block whenever this * class is used. */ public void release() { if (connection != null) { try { LOG.finest("Closing the database connection."); connection.close(); } catch (SQLException e) { // We cannot throw an exception within a release statement. LOG.log(Level.WARNING, "Unable to close result set.", e); } connection = null; } } /** * Enforces cleanup of any remaining resources during garbage collection. * This is a safeguard and should not be required if release is called * appropriately. * * @throws Throwable * if an unexpected problem occurs during finalization. */ @Override protected void finalize() throws Throwable { release(); super.finalize(); } } InMemoryNodeLocationStore.java000066400000000000000000000116561253404521400373730ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.common; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.util.FixedPrecisionCoordinateConvertor; /** * An in-memory node location store implementation. * * @author Brett Henderson */ public class InMemoryNodeLocationStore implements NodeLocationStore { private static final Logger LOG = Logger.getLogger(InMemoryNodeLocationStore.class.getName()); private static final int NODE_DATA_SIZE = 9; private static final int BUFFER_ELEMENT_COUNT = 131072; private static final int BUFFER_SIZE = NODE_DATA_SIZE * BUFFER_ELEMENT_COUNT; private List buffers; private NodeLocation invalidNodeLocation; /** * Creates a new instance. */ public InMemoryNodeLocationStore() { buffers = new ArrayList(); invalidNodeLocation = new NodeLocation(); } /** * Writes a summary of the current memory consumption at the specified * logging level. * * @param level * The logging level to write the summary at. */ private void logMemoryConsumption(Level level) { if (LOG.isLoggable(level)) { Runtime runtime; long totalUsed; double percentageUsed; long maxMemory; DecimalFormat percentageFormat; runtime = Runtime.getRuntime(); percentageFormat = new DecimalFormat("#0.##"); // Calculate the percentage of memory currently used. percentageUsed = ((double) runtime.totalMemory()) / runtime.maxMemory() * 100; totalUsed = ((long) buffers.size()) * BUFFER_SIZE / 1048576; maxMemory = runtime.maxMemory() / 1048576; LOG.log( level, "The store contains " + buffers.size() + " buffers of " + (BUFFER_SIZE / 1024) + "KB, total " + totalUsed + "MB."); LOG.log( level, "The JVM is using " + percentageFormat.format(percentageUsed) + "% of the maximum " + maxMemory + "MB of memory."); } } /** * Writes the specified integer to a buffer. * * @param value * The integer to write. * @param buffer * The destination buffer. * @param initialOffset * The buffer offset to begin writing at. */ private void writeIntToBuffer(int value, byte[] buffer, int initialOffset) { int offset; offset = initialOffset; buffer[offset++] = (byte) (value >>> 24); buffer[offset++] = (byte) (value >>> 16); buffer[offset++] = (byte) (value >>> 8); buffer[offset++] = (byte) value; } /** * Reads an integer from a buffer. * * @param buffer * The buffer to read from. * @param initialOffset * The buffer offset to begin reading from. * @return The integer. */ private int readIntFromBuffer(byte[] buffer, int initialOffset) { int offset; offset = initialOffset; return ( buffer[offset++] << 24) + ((buffer[offset++] & 0xFF) << 16) + ((buffer[offset++] & 0xFF) << 8) + (buffer[offset++] & 0xFF); } /** * {@inheritDoc} */ @Override public void addLocation(long nodeId, NodeLocation nodeLocation) { int bufferIndex; byte[] buffer; int bufferOffset; bufferIndex = (int) (nodeId / BUFFER_ELEMENT_COUNT); while (bufferIndex >= buffers.size()) { buffer = new byte[BUFFER_SIZE]; buffers.add(buffer); logMemoryConsumption(Level.FINER); } buffer = buffers.get(bufferIndex); bufferOffset = (int) ((nodeId - (bufferIndex * BUFFER_ELEMENT_COUNT)) * NODE_DATA_SIZE); buffer[bufferOffset++] = 1; writeIntToBuffer( FixedPrecisionCoordinateConvertor.convertToFixed(nodeLocation.getLongitude()), buffer, bufferOffset); bufferOffset += 4; writeIntToBuffer( FixedPrecisionCoordinateConvertor.convertToFixed(nodeLocation.getLatitude()), buffer, bufferOffset); bufferOffset += 4; } /** * {@inheritDoc} */ @Override public NodeLocation getNodeLocation(long nodeId) { NodeLocation nodeLocation; int bufferIndex; nodeLocation = invalidNodeLocation; bufferIndex = (int) (nodeId / BUFFER_ELEMENT_COUNT); if (bufferIndex < buffers.size()) { byte[] buffer; int bufferOffset; byte validFlag; buffer = buffers.get(bufferIndex); bufferOffset = (int) ((nodeId - (bufferIndex * BUFFER_ELEMENT_COUNT)) * NODE_DATA_SIZE); validFlag = buffer[bufferOffset++]; if (validFlag != 0) { int longitude; int latitude; longitude = readIntFromBuffer(buffer, bufferOffset); bufferOffset += 4; latitude = readIntFromBuffer(buffer, bufferOffset); bufferOffset += 4; nodeLocation = new NodeLocation( FixedPrecisionCoordinateConvertor.convertToDouble(longitude), FixedPrecisionCoordinateConvertor.convertToDouble(latitude) ); } } return nodeLocation; } /** * {@inheritDoc} */ @Override public void release() { logMemoryConsumption(Level.FINE); } } NoSuchRecordException.java000066400000000000000000000030311253404521400365210ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.common; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * A runtime exception indicating that the requested database record doesn't exist. * * @author Brett Henderson */ public class NoSuchRecordException extends OsmosisRuntimeException { private static final long serialVersionUID = 1L; /** * Constructs a new exception with null as its detail message. */ public NoSuchRecordException() { super(); } /** * Constructs a new exception with the specified detail message. The * cause is not initialized, and may subsequently be initialized by * a call to {@link #initCause}. * * @param message the detail message. */ public NoSuchRecordException(String message) { super(message); } /** * Constructs a new exception with the specified cause and a detail * message of (cause==null ? null : cause.toString()) (which * typically contains the class and detail message of cause). * * @param cause the cause. */ public NoSuchRecordException(Throwable cause) { super(cause); } /** * Constructs a new exception with the specified detail message and * cause. * * @param message the detail message. * @param cause the cause. */ public NoSuchRecordException(String message, Throwable cause) { super(message, cause); } } NodeLocation.java000066400000000000000000000024021253404521400346630ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.common; /** * Represents the minimal geo-spatial information associated with a node. * * @author Brett Henderson */ public class NodeLocation { private boolean valid; private double longitude; private double latitude; /** * Creates a new empty instance which is marked as invalid. */ public NodeLocation() { this.valid = false; } /** * Creates a new instance with populated location details. * * @param longitude * The longitude of the node. * @param latitude * The latitude of the node. */ public NodeLocation(double longitude, double latitude) { this.valid = true; this.longitude = longitude; this.latitude = latitude; } /** * Indicates if the node is valid. A node may be invalid if it does not * exist. * * @return The valid flag. */ public boolean isValid() { return valid; } /** * Gets the longitude of the node. * * @return The node longitude. */ public double getLongitude() { return longitude; } /** * Gets the latitude of the node. * * @return The node latitude. */ public double getLatitude() { return latitude; } } NodeLocationStore.java000066400000000000000000000016641253404521400357110ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.common; import org.openstreetmap.osmosis.core.lifecycle.Releasable; /** * A node location store is used for caching node locations that are * subsequently used to build way geometries. * * @author Brett Henderson */ public interface NodeLocationStore extends Releasable { /** * Adds the specified node location details. * * @param nodeId * The node identifier. * @param nodeLocation * The geo-spatial location details. */ void addLocation(long nodeId, NodeLocation nodeLocation); /** * Gets the location details of the specified node. * * @param nodeId * The node identifier. * @return The geo-spatial location details. If the node doesn't exist, the * valid flag will be set to false. */ NodeLocation getNodeLocation(long nodeId); } NodeLocationStoreType.java000066400000000000000000000014011253404521400365400ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.common; /** * Defines the different node location store implementations available. * * @author Brett Henderson */ public enum NodeLocationStoreType { /** * An in-memory node location store holds all information in memory. This * typically requires a very large JVM heap space. */ InMemory, /** * A temporary file based node location store holds all information in a temporary file on disk. */ TempFile, /** * A temporary file based node location store holds all information in a * temporary file on disk. This is optimised for small datasets, and is less * efficient for large datasets. */ CompactTempFile } PersistentNodeLocationStore.java000066400000000000000000000154151253404521400377710ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.common; import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.Arrays; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.store.BufferedRandomAccessFileInputStream; import org.openstreetmap.osmosis.core.store.StorageStage; import org.openstreetmap.osmosis.core.util.FixedPrecisionCoordinateConvertor; /** * A file-based node location store implementation. * * @author Brett Henderson */ public class PersistentNodeLocationStore implements NodeLocationStore { private static final Logger LOG = Logger.getLogger(PersistentNodeLocationStore.class.getName()); private static final int ZERO_BUFFER_SIZE = 1024 * 1024; private static final int NODE_DATA_SIZE = 9; private File nodeStorageFile; private StorageStage stage; private long lastNodeId; private FileOutputStream fileOutStream; private DataOutputStream dataOutStream; private BufferedRandomAccessFileInputStream fileInStream; private DataInputStream dataInStream; private long currentFileOffset; private byte[] zeroBuffer; private NodeLocation invalidNodeLocation; /** * Creates a new instance. */ public PersistentNodeLocationStore() { stage = StorageStage.NotStarted; lastNodeId = Long.MIN_VALUE; zeroBuffer = new byte[ZERO_BUFFER_SIZE]; Arrays.fill(zeroBuffer, (byte) 0); invalidNodeLocation = new NodeLocation(); } private void initializeAddStage() { // We can't add if we've passed the add stage. if (stage.compareTo(StorageStage.Add) > 0) { throw new OsmosisRuntimeException("Cannot add to storage in stage " + stage + "."); } // If we're not up to the add stage, initialise for adding. if (stage.compareTo(StorageStage.Add) < 0) { try { nodeStorageFile = File.createTempFile("nodelatlon", null); fileOutStream = new FileOutputStream(nodeStorageFile); dataOutStream = new DataOutputStream(new BufferedOutputStream(fileOutStream, 65536)); currentFileOffset = 0; stage = StorageStage.Add; } catch (IOException e) { throw new OsmosisRuntimeException( "Unable to create object stream writing to temporary file " + nodeStorageFile + ".", e); } } } private void initializeReadingStage() { // If we're already in the reading stage, do nothing. if (stage.compareTo(StorageStage.Reading) == 0) { return; } // If we've been released, we can't iterate. if (stage.compareTo(StorageStage.Released) >= 0) { throw new OsmosisRuntimeException("Cannot read from node storage in stage " + stage + "."); } // If no data was written, writing should be initialized before reading. if (stage.compareTo(StorageStage.NotStarted) <= 0) { initializeAddStage(); } // If we're in the add stage, close the output streams. if (stage.compareTo(StorageStage.Add) == 0) { try { dataOutStream.close(); fileOutStream.close(); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to close output stream.", e); } finally { dataOutStream = null; fileOutStream = null; } try { fileInStream = new BufferedRandomAccessFileInputStream(nodeStorageFile); dataInStream = new DataInputStream(fileInStream); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to open the node data file " + nodeStorageFile + ".", e); } stage = StorageStage.Reading; } } /** * {@inheritDoc} */ @Override public void addLocation(long nodeId, NodeLocation nodeLocation) { long requiredFileOffset; initializeAddStage(); // We can only add nodes in sorted order. if (nodeId <= lastNodeId) { throw new OsmosisRuntimeException( "The node id of " + nodeId + " must be greater than the previous id of " + lastNodeId + "." ); } lastNodeId = nodeId; try { // Write zeros to the file where no node data is available. requiredFileOffset = nodeId * NODE_DATA_SIZE; if (requiredFileOffset > currentFileOffset) { while (currentFileOffset < requiredFileOffset) { long offsetDifference; offsetDifference = requiredFileOffset - currentFileOffset; if (offsetDifference > ZERO_BUFFER_SIZE) { offsetDifference = ZERO_BUFFER_SIZE; } dataOutStream.write(zeroBuffer, 0, (int) offsetDifference); currentFileOffset += offsetDifference; } } // Write the node data. Prefix with a non-zero byte to identify that // data is available for this node. dataOutStream.writeByte(1); dataOutStream.writeInt(FixedPrecisionCoordinateConvertor.convertToFixed(nodeLocation.getLongitude())); dataOutStream.writeInt(FixedPrecisionCoordinateConvertor.convertToFixed(nodeLocation.getLatitude())); currentFileOffset += NODE_DATA_SIZE; } catch (IOException e) { throw new OsmosisRuntimeException( "Unable to write node location data to node storage file " + nodeStorageFile + ".", e ); } } /** * {@inheritDoc} */ @Override public NodeLocation getNodeLocation(long nodeId) { NodeLocation nodeLocation; long offset; initializeReadingStage(); offset = nodeId * NODE_DATA_SIZE; nodeLocation = invalidNodeLocation; if (offset < currentFileOffset) { try { byte validFlag; fileInStream.seek(offset); validFlag = dataInStream.readByte(); if (validFlag != 0) { nodeLocation = new NodeLocation( FixedPrecisionCoordinateConvertor.convertToDouble(dataInStream.readInt()), FixedPrecisionCoordinateConvertor.convertToDouble(dataInStream.readInt()) ); } } catch (IOException e) { throw new OsmosisRuntimeException("Unable to read node information from the node storage file.", e); } } return nodeLocation; } /** * {@inheritDoc} */ @Override public void release() { if (fileOutStream != null) { try { fileOutStream.close(); } catch (Exception e) { // We cannot throw an exception within a release method. LOG.log(Level.WARNING, "Unable to close file output stream.", e); } fileOutStream = null; } if (fileInStream != null) { try { fileInStream.close(); } catch (Exception e) { // We cannot throw an exception within a release method. LOG.log(Level.WARNING, "Unable to close file input stream.", e); } fileInStream = null; } if (nodeStorageFile != null) { if (!nodeStorageFile.delete()) { // We cannot throw an exception within a release method. LOG.warning("Unable to delete file " + nodeStorageFile); } nodeStorageFile = null; } } } PointBuilder.java000066400000000000000000000013301253404521400347040ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.common; import org.postgis.Point; /** * Builds PostGIS Point objects based on a set of coordinates. * * @author Brett Henderson */ public class PointBuilder { /** * Creates a PostGIS Point object corresponding to the provided coordinates. * * @param latitude * The latitude measured in degrees. * @param longitude * The longitude measured in degrees. * @return The Point object. */ public Point createPoint(double latitude, double longitude) { Point result; result = new Point(longitude, latitude); result.srid = 4326; return result; } } PolygonBuilder.java000066400000000000000000000013401253404521400352430ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.common; import org.postgis.LinearRing; import org.postgis.Point; import org.postgis.Polygon; /** * Builds PostGIS Polygon objects based on a series of points. * * @author Brett Henderson */ public class PolygonBuilder { /** * Creates a PostGIS Polygon object corresponding to the provided Point * list. * * @param points * The points to build a polygon from. * @return The Polygon object. */ public Polygon createPolygon(Point[] points) { Polygon result; result = new Polygon(new LinearRing[] {new LinearRing(points)}); result.srid = 4326; return result; } } SchemaVersionValidator.java000066400000000000000000000047611253404521400367330ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.common; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.database.DatabasePreferences; /** * Reads the version number stored in the schema_info table and verifies that it * matches the expected version. * * @author Brett Henderson */ public class SchemaVersionValidator { private static final String SELECT_SQL = "SELECT version FROM schema_info"; private DatabasePreferences preferences; private DatabaseContext dbCtx; private boolean validated; /** * Creates a new instance. * * @param dbCtx * The database context to use for accessing the database. * @param preferences * The database preferences. */ public SchemaVersionValidator(DatabaseContext dbCtx, DatabasePreferences preferences) { this.dbCtx = dbCtx; this.preferences = preferences; } /** * Validates that the version number of the schema matches the expected * version. This method caches the result allowing it to be called multiple * times without a performance penalty. * * @param expectedVersion * The expected version number. */ public void validateVersion(int expectedVersion) { if (!validated) { validateDBVersion(expectedVersion); validated = true; } } /** * Performs the database lookup and validates the expected version. * * @param expectedVersion * The expected version number. */ private void validateDBVersion(int expectedVersion) { if (preferences.getValidateSchemaVersion()) { try { Statement statement; ResultSet resultSet; int dbVersion; statement = dbCtx.createStatement(); resultSet = statement.executeQuery(SELECT_SQL); if (!resultSet.next()) { throw new OsmosisRuntimeException("No rows were found in the schema info table."); } dbVersion = resultSet.getInt("version"); if (dbVersion != expectedVersion) { throw new OsmosisRuntimeException( "The database schema version of " + dbVersion + " does not match the expected version of " + expectedVersion + "." ); } resultSet.close(); statement.close(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to read the schema version from the schema info table.", e); } } } } osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/000077500000000000000000000000001253404521400310055ustar00rootroot00000000000000PostgreSqlChangeWriter.java000066400000000000000000000060741253404521400362060ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.pgsimple.common.DatabaseContext; import org.openstreetmap.osmosis.pgsimple.common.SchemaVersionValidator; import org.openstreetmap.osmosis.pgsimple.v0_6.impl.ActionChangeWriter; import org.openstreetmap.osmosis.pgsimple.v0_6.impl.ChangeWriter; import org.openstreetmap.osmosis.core.task.common.ChangeAction; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; /** * A change sink writing to database tables. This aims to be suitable for * running at regular intervals with database overhead proportional to changeset * size. * * @author Brett Henderson */ public class PostgreSqlChangeWriter implements ChangeSink { private ChangeWriter changeWriter; private Map actionWriterMap; private DatabaseContext dbCtx; private SchemaVersionValidator schemaVersionValidator; /** * Creates a new instance. * * @param loginCredentials * Contains all information required to connect to the database. * @param preferences * Contains preferences configuring database behaviour. */ public PostgreSqlChangeWriter(DatabaseLoginCredentials loginCredentials, DatabasePreferences preferences) { dbCtx = new DatabaseContext(loginCredentials); changeWriter = new ChangeWriter(dbCtx); actionWriterMap = new HashMap(); actionWriterMap.put(ChangeAction.Create, new ActionChangeWriter(changeWriter, ChangeAction.Create)); actionWriterMap.put(ChangeAction.Modify, new ActionChangeWriter(changeWriter, ChangeAction.Modify)); actionWriterMap.put(ChangeAction.Delete, new ActionChangeWriter(changeWriter, ChangeAction.Delete)); schemaVersionValidator = new SchemaVersionValidator(dbCtx, preferences); } /** * {@inheritDoc} */ public void initialize(Map metaData) { // Do nothing. } /** * {@inheritDoc} */ public void process(ChangeContainer change) { ChangeAction action; // Verify that the schema version is supported. schemaVersionValidator.validateVersion(PostgreSqlVersionConstants.SCHEMA_VERSION); action = change.getAction(); if (!actionWriterMap.containsKey(action)) { throw new OsmosisRuntimeException("The action " + action + " is unrecognized."); } // Process the entity using the action writer appropriate for the change // action. change.getEntityContainer().process(actionWriterMap.get(action)); } /** * {@inheritDoc} */ public void complete() { changeWriter.complete(); dbCtx.commit(); } /** * {@inheritDoc} */ public void release() { changeWriter.release(); dbCtx.release(); } } PostgreSqlChangeWriterFactory.java000066400000000000000000000023461253404521400375340ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.database.DatabaseTaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.v0_6.ChangeSinkManager; /** * The task manager factory for a database change writer. * * @author Brett Henderson */ public class PostgreSqlChangeWriterFactory extends DatabaseTaskManagerFactory { /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { DatabaseLoginCredentials loginCredentials; DatabasePreferences preferences; // Get the task arguments. loginCredentials = getDatabaseLoginCredentials(taskConfig); preferences = getDatabasePreferences(taskConfig); return new ChangeSinkManager( taskConfig.getId(), new PostgreSqlChangeWriter( loginCredentials, preferences ), taskConfig.getPipeArgs() ); } } PostgreSqlCopyWriter.java000066400000000000000000000073731253404521400357360ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6; import java.util.Map; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.pgsimple.common.DatabaseContext; import org.openstreetmap.osmosis.pgsimple.common.NodeLocationStoreType; import org.openstreetmap.osmosis.pgsimple.v0_6.impl.CopyFilesetLoader; import org.openstreetmap.osmosis.pgsimple.v0_6.impl.DatabaseCapabilityChecker; import org.openstreetmap.osmosis.pgsimple.v0_6.impl.CopyFilesetBuilder; import org.openstreetmap.osmosis.pgsimple.v0_6.impl.TempCopyFileset; import org.openstreetmap.osmosis.core.task.v0_6.Sink; /** * An OSM data sink for storing all data to a database using the COPY command. * This task is intended for writing to an empty database. * * @author Brett Henderson */ public class PostgreSqlCopyWriter implements Sink { private static final Logger LOG = Logger.getLogger(PostgreSqlCopyWriter.class.getName()); private CopyFilesetBuilder copyFilesetBuilder; private CopyFilesetLoader copyFilesetLoader; private TempCopyFileset copyFileset; private DatabaseLoginCredentials loginCredentials; private DatabasePreferences preferences; private NodeLocationStoreType storeType; private boolean populateBbox; private boolean populateLinestring; private boolean initialized; /** * Creates a new instance. * * @param loginCredentials * Contains all information required to connect to the database. * @param preferences * Contains preferences configuring database behaviour. * @param storeType * The node location storage type used by the geometry builders. */ public PostgreSqlCopyWriter( DatabaseLoginCredentials loginCredentials, DatabasePreferences preferences, NodeLocationStoreType storeType) { this.loginCredentials = loginCredentials; this.preferences = preferences; this.storeType = storeType; copyFileset = new TempCopyFileset(); } private void initialize() { if (!initialized) { DatabaseContext dbCtx; DatabaseCapabilityChecker capabilityChecker; LOG.fine("Initializing the database and temporary processing files."); dbCtx = new DatabaseContext(loginCredentials); try { capabilityChecker = new DatabaseCapabilityChecker(dbCtx); populateBbox = capabilityChecker.isWayBboxSupported(); populateLinestring = capabilityChecker.isWayLinestringSupported(); copyFilesetBuilder = new CopyFilesetBuilder(copyFileset, populateBbox, populateLinestring, storeType); copyFilesetLoader = new CopyFilesetLoader(loginCredentials, preferences, copyFileset); LOG.fine("Processing input data, building geometries and creating database load files."); } finally { dbCtx.release(); } initialized = true; } } /** * {@inheritDoc} */ public void initialize(Map metaData) { // Do nothing. } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { initialize(); copyFilesetBuilder.process(entityContainer); } /** * Writes any buffered data to the files, then loads the files into the database. */ public void complete() { initialize(); LOG.fine("All data has been received, beginning database load."); copyFilesetBuilder.complete(); copyFilesetLoader.run(); LOG.fine("Processing complete."); } /** * Releases all database resources. */ public void release() { copyFilesetBuilder.release(); copyFileset.release(); initialized = false; } } PostgreSqlCopyWriterFactory.java000066400000000000000000000032421253404521400372550ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.database.DatabaseTaskManagerFactory; import org.openstreetmap.osmosis.pgsimple.common.NodeLocationStoreType; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkManager; /** * The task manager factory for a database writer using the PostgreSQL COPY method. * * @author Brett Henderson */ public class PostgreSqlCopyWriterFactory extends DatabaseTaskManagerFactory { private static final String ARG_NODE_LOCATION_STORE_TYPE = "nodeLocationStoreType"; private static final String DEFAULT_NODE_LOCATION_STORE_TYPE = "CompactTempFile"; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { DatabaseLoginCredentials loginCredentials; DatabasePreferences preferences; NodeLocationStoreType storeType; // Get the task arguments. loginCredentials = getDatabaseLoginCredentials(taskConfig); preferences = getDatabasePreferences(taskConfig); storeType = Enum.valueOf( NodeLocationStoreType.class, getStringArgument(taskConfig, ARG_NODE_LOCATION_STORE_TYPE, DEFAULT_NODE_LOCATION_STORE_TYPE)); return new SinkManager( taskConfig.getId(), new PostgreSqlCopyWriter(loginCredentials, preferences, storeType), taskConfig.getPipeArgs() ); } } PostgreSqlDatasetReader.java000066400000000000000000000034431253404521400363310ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6; import org.openstreetmap.osmosis.core.container.v0_6.Dataset; import org.openstreetmap.osmosis.core.container.v0_6.DatasetContext; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.pgsimple.v0_6.impl.PostgreSqlDatasetContext; import org.openstreetmap.osmosis.core.task.v0_6.DatasetSink; import org.openstreetmap.osmosis.core.task.v0_6.RunnableDatasetSource; /** * An OSM dataset source exposing generic access to a custom PostgreSQL database. * * @author Brett Henderson */ public class PostgreSqlDatasetReader implements RunnableDatasetSource, Dataset { private DatasetSink datasetSink; private DatabaseLoginCredentials loginCredentials; private DatabasePreferences preferences; /** * Creates a new instance. * * @param loginCredentials * Contains all information required to connect to the database. * @param preferences * Contains preferences configuring database behaviour. */ public PostgreSqlDatasetReader(DatabaseLoginCredentials loginCredentials, DatabasePreferences preferences) { this.loginCredentials = loginCredentials; this.preferences = preferences; } /** * {@inheritDoc} */ @Override public void setDatasetSink(DatasetSink datasetSink) { this.datasetSink = datasetSink; } /** * {@inheritDoc} */ @Override public void run() { try { datasetSink.process(this); } finally { datasetSink.release(); } } /** * {@inheritDoc} */ @Override public DatasetContext createReader() { return new PostgreSqlDatasetContext(loginCredentials, preferences); } } PostgreSqlDatasetReaderFactory.java000066400000000000000000000023521253404521400376570ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.database.DatabaseTaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.v0_6.RunnableDatasetSourceManager; /** * The task manager factory for a database reader. * * @author Brett Henderson */ public class PostgreSqlDatasetReaderFactory extends DatabaseTaskManagerFactory { /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { DatabaseLoginCredentials loginCredentials; DatabasePreferences preferences; // Get the task arguments. loginCredentials = getDatabaseLoginCredentials(taskConfig); preferences = getDatabasePreferences(taskConfig); return new RunnableDatasetSourceManager( taskConfig.getId(), new PostgreSqlDatasetReader(loginCredentials, preferences), taskConfig.getPipeArgs() ); } } PostgreSqlDumpWriter.java000066400000000000000000000046441253404521400357270ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6; import java.io.File; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.pgsimple.common.NodeLocationStoreType; import org.openstreetmap.osmosis.pgsimple.v0_6.impl.DirectoryCopyFileset; import org.openstreetmap.osmosis.pgsimple.v0_6.impl.CopyFilesetBuilder; import org.openstreetmap.osmosis.core.task.v0_6.Sink; /** * An OSM data sink for storing all data to database dump files. This task is * intended for populating an empty database. * * @author Brett Henderson */ public class PostgreSqlDumpWriter implements Sink { private CopyFilesetBuilder copyFilesetBuilder; /** * Creates a new instance. * * @param filePrefix * The prefix to prepend to all generated file names. * @param enableBboxBuilder * If true, the way bbox geometry is built during processing * instead of relying on the database to build them after import. * This increases processing but is faster than relying on the * database. * @param enableLinestringBuilder * If true, the way linestring geometry is built during * processing instead of relying on the database to build them * after import. This increases processing but is faster than * relying on the database. * @param storeType * The node location storage type used by the geometry builders. */ public PostgreSqlDumpWriter( File filePrefix, boolean enableBboxBuilder, boolean enableLinestringBuilder, NodeLocationStoreType storeType) { DirectoryCopyFileset copyFileset; copyFileset = new DirectoryCopyFileset(filePrefix); copyFilesetBuilder = new CopyFilesetBuilder(copyFileset, enableBboxBuilder, enableLinestringBuilder, storeType); } /** * {@inheritDoc} */ public void initialize(Map metaData) { // Do nothing. } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { copyFilesetBuilder.process(entityContainer); } /** * Writes any buffered data to the database and commits. */ public void complete() { copyFilesetBuilder.complete(); } /** * Releases all database resources. */ public void release() { copyFilesetBuilder.release(); } } PostgreSqlDumpWriterFactory.java000066400000000000000000000045071253404521400372550ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6; import java.io.File; import org.openstreetmap.osmosis.pgsimple.common.NodeLocationStoreType; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkManager; /** * The task manager factory for a database dump writer. * * @author Brett Henderson */ public class PostgreSqlDumpWriterFactory extends TaskManagerFactory { private static final String ARG_ENABLE_BBOX_BUILDER = "enableBboxBuilder"; private static final String ARG_ENABLE_LINESTRING_BUILDER = "enableLinestringBuilder"; private static final String ARG_FILE_NAME = "directory"; private static final String ARG_NODE_LOCATION_STORE_TYPE = "nodeLocationStoreType"; private static final boolean DEFAULT_ENABLE_BBOX_BUILDER = false; private static final boolean DEFAULT_ENABLE_LINESTRING_BUILDER = false; private static final String DEFAULT_FILE_PREFIX = "pgimport"; private static final String DEFAULT_NODE_LOCATION_STORE_TYPE = "CompactTempFile"; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String filePrefixString; File filePrefix; boolean enableBboxBuilder; boolean enableLinestringBuilder; NodeLocationStoreType storeType; // Get the task arguments. filePrefixString = getStringArgument( taskConfig, ARG_FILE_NAME, DEFAULT_FILE_PREFIX); enableBboxBuilder = getBooleanArgument( taskConfig, ARG_ENABLE_BBOX_BUILDER, DEFAULT_ENABLE_BBOX_BUILDER); enableLinestringBuilder = getBooleanArgument( taskConfig, ARG_ENABLE_LINESTRING_BUILDER, DEFAULT_ENABLE_LINESTRING_BUILDER); storeType = Enum.valueOf( NodeLocationStoreType.class, getStringArgument(taskConfig, ARG_NODE_LOCATION_STORE_TYPE, DEFAULT_NODE_LOCATION_STORE_TYPE)); // Create a file object representing the directory from the file name provided. filePrefix = new File(filePrefixString); return new SinkManager( taskConfig.getId(), new PostgreSqlDumpWriter(filePrefix, enableBboxBuilder, enableLinestringBuilder, storeType), taskConfig.getPipeArgs() ); } } PostgreSqlTruncator.java000066400000000000000000000046601253404521400356040ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.pgsimple.common.DatabaseContext; import org.openstreetmap.osmosis.pgsimple.common.SchemaVersionValidator; import org.openstreetmap.osmosis.core.task.common.RunnableTask; /** * A standalone OSM task with no inputs or outputs that truncates tables in a * PostgreSQL database. This is used for removing all existing data from tables. * * @author Brett Henderson */ public class PostgreSqlTruncator implements RunnableTask { private static final Logger LOG = Logger.getLogger(PostgreSqlTruncator.class.getName()); // These tables will be truncated. private static final String[] SQL_TABLE_NAMES = { "actions", "users", "nodes", "node_tags", "ways", "way_tags", "way_nodes", "relations", "relation_tags", "relation_members" }; private DatabaseContext dbCtx; private SchemaVersionValidator schemaVersionValidator; /** * Creates a new instance. * * @param loginCredentials * Contains all information required to connect to the database. * @param preferences * Contains preferences configuring database behaviour. */ public PostgreSqlTruncator(DatabaseLoginCredentials loginCredentials, DatabasePreferences preferences) { dbCtx = new DatabaseContext(loginCredentials); schemaVersionValidator = new SchemaVersionValidator(dbCtx, preferences); } /** * Truncates all data from the database. */ public void run() { try { schemaVersionValidator.validateVersion(PostgreSqlVersionConstants.SCHEMA_VERSION); LOG.fine("Truncating tables."); for (int i = 0; i < SQL_TABLE_NAMES.length; i++) { if (dbCtx.doesTableExist(SQL_TABLE_NAMES[i])) { LOG.finer("Truncating table " + SQL_TABLE_NAMES[i] + "."); dbCtx.executeStatement("TRUNCATE " + SQL_TABLE_NAMES[i]); } else { LOG.finer("Skipping table " + SQL_TABLE_NAMES[i] + " which doesn't exist in the current schema."); } } LOG.fine("Committing changes."); dbCtx.commit(); LOG.fine("Vacuuming database."); dbCtx.setAutoCommit(true); dbCtx.executeStatement("VACUUM ANALYZE"); LOG.fine("Complete."); } finally { dbCtx.release(); } } } PostgreSqlTruncatorFactory.java000066400000000000000000000016441253404521400371330ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6; import org.openstreetmap.osmosis.core.database.DatabaseTaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.common.RunnableTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; /** * The task manager factory for a database table truncator. * * @author Brett Henderson */ public class PostgreSqlTruncatorFactory extends DatabaseTaskManagerFactory { /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { return new RunnableTaskManager( taskConfig.getId(), new PostgreSqlTruncator( getDatabaseLoginCredentials(taskConfig), getDatabasePreferences(taskConfig) ), taskConfig.getPipeArgs() ); } } PostgreSqlVersionConstants.java000066400000000000000000000007611253404521400371430ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6; /** * Defines constants specific to the specific schema version. * * @author Brett Henderson */ public final class PostgreSqlVersionConstants { /** * This class cannot be instantiated. */ private PostgreSqlVersionConstants() { } /** * Defines the schema version number currently supported. */ public static final int SCHEMA_VERSION = 5; } PostgreSqlWriter.java000066400000000000000000000650001253404521400350720ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityProcessor; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.database.DbFeature; import org.openstreetmap.osmosis.core.database.DbOrderedFeature; import org.openstreetmap.osmosis.core.database.ReleasableStatementContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.pgsimple.common.DatabaseContext; import org.openstreetmap.osmosis.pgsimple.common.NodeLocationStoreType; import org.openstreetmap.osmosis.pgsimple.common.SchemaVersionValidator; import org.openstreetmap.osmosis.pgsimple.v0_6.impl.ActionDao; import org.openstreetmap.osmosis.pgsimple.v0_6.impl.IndexManager; import org.openstreetmap.osmosis.pgsimple.v0_6.impl.NodeMapper; import org.openstreetmap.osmosis.pgsimple.v0_6.impl.RelationMapper; import org.openstreetmap.osmosis.pgsimple.v0_6.impl.RelationMemberMapper; import org.openstreetmap.osmosis.pgsimple.v0_6.impl.TagMapper; import org.openstreetmap.osmosis.pgsimple.v0_6.impl.UserDao; import org.openstreetmap.osmosis.pgsimple.v0_6.impl.WayGeometryBuilder; import org.openstreetmap.osmosis.pgsimple.v0_6.impl.WayMapper; import org.openstreetmap.osmosis.pgsimple.v0_6.impl.WayNodeMapper; import org.postgis.Geometry; /** * An OSM data sink for storing all data to a database. This task is intended * for writing to an empty database. * * @author Brett Henderson */ public class PostgreSqlWriter implements Sink, EntityProcessor { private static final Logger LOG = Logger.getLogger(PostgreSqlWriter.class.getName()); // These constants define how many rows of each data type will be inserted // with single insert statements. private static final int INSERT_BULK_ROW_COUNT_NODE = 1000; private static final int INSERT_BULK_ROW_COUNT_NODE_TAG = 1000; private static final int INSERT_BULK_ROW_COUNT_WAY = 1000; private static final int INSERT_BULK_ROW_COUNT_WAY_TAG = 1000; private static final int INSERT_BULK_ROW_COUNT_WAY_NODE = 1000; private static final int INSERT_BULK_ROW_COUNT_RELATION = 1000; private static final int INSERT_BULK_ROW_COUNT_RELATION_TAG = 1000; private static final int INSERT_BULK_ROW_COUNT_RELATION_MEMBER = 1000; private DatabaseContext dbCtx; private boolean enableBboxBuilder; private boolean enableLinestringBuilder; private SchemaVersionValidator schemaVersionValidator; private IndexManager indexManager; private List nodeBuffer; private List> nodeTagBuffer; private List wayBuffer; private List> wayTagBuffer; private List> wayNodeBuffer; private List relationBuffer; private List> relationTagBuffer; private List> relationMemberBuffer; private boolean initialized; private HashSet userSet; private ActionDao actionDao; private UserDao userDao; private ReleasableStatementContainer statementContainer; private PreparedStatement singleNodeStatement; private PreparedStatement bulkNodeStatement; private PreparedStatement singleNodeTagStatement; private PreparedStatement bulkNodeTagStatement; private PreparedStatement singleWayStatement; private PreparedStatement bulkWayStatement; private PreparedStatement singleWayTagStatement; private PreparedStatement bulkWayTagStatement; private PreparedStatement singleWayNodeStatement; private PreparedStatement bulkWayNodeStatement; private PreparedStatement singleRelationStatement; private PreparedStatement bulkRelationStatement; private PreparedStatement singleRelationTagStatement; private PreparedStatement bulkRelationTagStatement; private PreparedStatement singleRelationMemberStatement; private PreparedStatement bulkRelationMemberStatement; private NodeMapper nodeBuilder; private WayMapper wayBuilder; private RelationMapper relationBuilder; private TagMapper nodeTagBuilder; private TagMapper wayTagBuilder; private TagMapper relationTagBuilder; private WayNodeMapper wayNodeBuilder; private RelationMemberMapper relationMemberBuilder; private WayGeometryBuilder wayGeometryBuilder; /** * Creates a new instance. * * @param loginCredentials * Contains all information required to connect to the database. * @param preferences * Contains preferences configuring database behaviour. * @param enableBboxBuilder * If true, the way bbox geometry is built during processing * instead of relying on the database to build them after import. * This increases processing but is faster than relying on the * database. * @param enableLinestringBuilder * If true, the way linestring geometry is built during * processing instead of relying on the database to build them * after import. This increases processing but is faster than * relying on the database. * @param storeType * The node location storage type used by the geometry builders. */ public PostgreSqlWriter( DatabaseLoginCredentials loginCredentials, DatabasePreferences preferences, boolean enableBboxBuilder, boolean enableLinestringBuilder, NodeLocationStoreType storeType) { dbCtx = new DatabaseContext(loginCredentials); this.enableBboxBuilder = enableBboxBuilder; this.enableLinestringBuilder = enableLinestringBuilder; schemaVersionValidator = new SchemaVersionValidator(dbCtx, preferences); indexManager = new IndexManager(dbCtx, !enableBboxBuilder, !enableLinestringBuilder); nodeBuffer = new ArrayList(); nodeTagBuffer = new ArrayList>(); wayBuffer = new ArrayList(); wayTagBuffer = new ArrayList>(); wayNodeBuffer = new ArrayList>(); relationBuffer = new ArrayList(); relationTagBuffer = new ArrayList>(); relationMemberBuffer = new ArrayList>(); // Create an action dao but disable it so that no records will be written. actionDao = new ActionDao(dbCtx, false); userSet = new HashSet(); userDao = new UserDao(dbCtx, actionDao); nodeBuilder = new NodeMapper(); wayBuilder = new WayMapper(enableBboxBuilder, enableLinestringBuilder); relationBuilder = new RelationMapper(); nodeTagBuilder = new TagMapper(nodeBuilder.getEntityName()); wayTagBuilder = new TagMapper(wayBuilder.getEntityName()); relationTagBuilder = new TagMapper(relationBuilder.getEntityName()); wayNodeBuilder = new WayNodeMapper(); relationMemberBuilder = new RelationMemberMapper(); wayGeometryBuilder = new WayGeometryBuilder(storeType); statementContainer = new ReleasableStatementContainer(); initialized = false; } /** * Initialises prepared statements and obtains database locks. Can be called * multiple times. */ private void initialize() { if (!initialized) { schemaVersionValidator.validateVersion(PostgreSqlVersionConstants.SCHEMA_VERSION); bulkNodeStatement = statementContainer.add( dbCtx.prepareStatement(nodeBuilder.getSqlInsert(INSERT_BULK_ROW_COUNT_NODE))); singleNodeStatement = statementContainer.add( dbCtx.prepareStatement(nodeBuilder.getSqlInsert(1))); bulkNodeTagStatement = statementContainer.add( dbCtx.prepareStatement(nodeTagBuilder.getSqlInsert(INSERT_BULK_ROW_COUNT_NODE_TAG))); singleNodeTagStatement = statementContainer.add( dbCtx.prepareStatement(nodeTagBuilder.getSqlInsert(1))); bulkWayStatement = statementContainer.add( dbCtx.prepareStatement(wayBuilder.getSqlInsert(INSERT_BULK_ROW_COUNT_WAY))); singleWayStatement = statementContainer.add( dbCtx.prepareStatement(wayBuilder.getSqlInsert(1))); bulkWayTagStatement = statementContainer.add( dbCtx.prepareStatement(wayTagBuilder.getSqlInsert(INSERT_BULK_ROW_COUNT_WAY_TAG))); singleWayTagStatement = statementContainer.add( dbCtx.prepareStatement(wayTagBuilder.getSqlInsert(1))); bulkWayNodeStatement = statementContainer.add( dbCtx.prepareStatement(wayNodeBuilder.getSqlInsert(INSERT_BULK_ROW_COUNT_WAY_NODE))); singleWayNodeStatement = statementContainer.add( dbCtx.prepareStatement(wayNodeBuilder.getSqlInsert(1))); bulkRelationStatement = statementContainer.add( dbCtx.prepareStatement(relationBuilder.getSqlInsert(INSERT_BULK_ROW_COUNT_RELATION))); singleRelationStatement = statementContainer.add( dbCtx.prepareStatement(relationBuilder.getSqlInsert(1))); bulkRelationTagStatement = statementContainer.add( dbCtx.prepareStatement(relationTagBuilder.getSqlInsert(INSERT_BULK_ROW_COUNT_RELATION_TAG))); singleRelationTagStatement = statementContainer.add( dbCtx.prepareStatement(relationTagBuilder.getSqlInsert(1))); bulkRelationMemberStatement = statementContainer.add( dbCtx.prepareStatement(relationMemberBuilder.getSqlInsert(INSERT_BULK_ROW_COUNT_RELATION_MEMBER))); singleRelationMemberStatement = statementContainer.add( dbCtx.prepareStatement(relationMemberBuilder.getSqlInsert(1))); // Drop all constraints and indexes. indexManager.prepareForLoad(); LOG.fine("Loading data."); initialized = true; } } /** * Writes the specified user to the database if it hasn't already been. * * @param user * The user to add. */ private void writeUser(OsmUser user) { // Write the user to the database if it hasn't already been. if (!user.equals(OsmUser.NONE)) { if (!userSet.contains(user.getId())) { userDao.addUser(user); userSet.add(user.getId()); } } } /** * Flushes nodes to the database. If complete is false, this will only write * nodes until the remaining node count is less than the multi-row insert * statement row count. If complete is true, all remaining rows will be * written using single row insert statements. * * @param complete * If true, all data will be written to the database. If false, * some data may be left until more data is available. */ private void flushNodes(boolean complete) { while (nodeBuffer.size() >= INSERT_BULK_ROW_COUNT_NODE) { List processedNodes; int prmIndex; processedNodes = new ArrayList(INSERT_BULK_ROW_COUNT_NODE); prmIndex = 1; for (int i = 0; i < INSERT_BULK_ROW_COUNT_NODE; i++) { Node node; node = nodeBuffer.remove(0); processedNodes.add(node); prmIndex = nodeBuilder.populateEntityParameters(bulkNodeStatement, prmIndex, node); } try { bulkNodeStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to bulk insert nodes into the database.", e); } for (Node node : processedNodes) { addNodeTags(node); } } if (complete) { while (nodeBuffer.size() > 0) { Node node; node = nodeBuffer.remove(0); nodeBuilder.populateEntityParameters(singleNodeStatement, 1, node); try { singleNodeStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert a node into the database.", e); } addNodeTags(node); } } } /** * Process the node tags. * * @param node * The node to be processed. */ private void addNodeTags(Node node) { for (Tag tag : node.getTags()) { nodeTagBuffer.add(new DbFeature(node.getId(), tag)); } flushNodeTags(false); } /** * Flushes node tags to the database. If complete is false, this will only * write node tags until the remaining node tag count is less than the * multi-row insert statement row count. If complete is true, all remaining * rows will be written using single row insert statements. * * @param complete * If true, all data will be written to the database. If false, * some data may be left until more data is available. */ private void flushNodeTags(boolean complete) { while (nodeTagBuffer.size() >= INSERT_BULK_ROW_COUNT_NODE_TAG) { int prmIndex; prmIndex = 1; for (int i = 0; i < INSERT_BULK_ROW_COUNT_NODE_TAG; i++) { prmIndex = nodeTagBuilder.populateEntityParameters( bulkNodeTagStatement, prmIndex, nodeTagBuffer.remove(0)); } try { bulkNodeTagStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to bulk insert node tags into the database.", e); } } if (complete) { while (nodeTagBuffer.size() > 0) { nodeTagBuilder.populateEntityParameters(singleNodeTagStatement, 1, nodeTagBuffer.remove(0)); try { singleNodeTagStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert a node tag into the database.", e); } } } } /** * Flushes ways to the database. If complete is false, this will only write * ways until the remaining way count is less than the multi-row insert * statement row count. If complete is true, all remaining rows will be * written using single row insert statements. * * @param complete * If true, all data will be written to the database. If false, * some data may be left until more data is available. */ private void flushWays(boolean complete) { while (wayBuffer.size() >= INSERT_BULK_ROW_COUNT_WAY) { List processedWays; int prmIndex; processedWays = new ArrayList(INSERT_BULK_ROW_COUNT_WAY); prmIndex = 1; for (int i = 0; i < INSERT_BULK_ROW_COUNT_WAY; i++) { Way way; List geometries; way = wayBuffer.remove(0); processedWays.add(way); geometries = new ArrayList(); if (enableBboxBuilder) { geometries.add(wayGeometryBuilder.createWayBbox(way)); } if (enableLinestringBuilder) { geometries.add(wayGeometryBuilder.createWayLinestring(way)); } prmIndex = wayBuilder.populateEntityParameters(bulkWayStatement, prmIndex, way, geometries); } try { bulkWayStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to bulk insert ways into the database.", e); } for (Way way : processedWays) { addWayTags(way); addWayNodes(way); } } if (complete) { while (wayBuffer.size() > 0) { Way way; List geometries; way = wayBuffer.remove(0); geometries = new ArrayList(); if (enableBboxBuilder) { geometries.add(wayGeometryBuilder.createWayBbox(way)); } if (enableLinestringBuilder) { geometries.add(wayGeometryBuilder.createWayLinestring(way)); } wayBuilder.populateEntityParameters(singleWayStatement, 1, way, geometries); try { singleWayStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert a way into the database.", e); } addWayTags(way); addWayNodes(way); } } } /** * Process the way tags. * * @param way * The way to be processed. */ private void addWayTags(Way way) { for (Tag tag : way.getTags()) { wayTagBuffer.add(new DbFeature(way.getId(), tag)); } flushWayTags(false); } /** * Process the way nodes. * * @param way * The way to be processed. */ private void addWayNodes(Way way) { int sequenceId; sequenceId = 0; for (WayNode wayNode : way.getWayNodes()) { wayNodeBuffer.add(new DbOrderedFeature(way.getId(), wayNode, sequenceId++)); } flushWayNodes(false); } /** * Flushes way tags to the database. If complete is false, this will only * write way tags until the remaining way tag count is less than the * multi-row insert statement row count. If complete is true, all remaining * rows will be written using single row insert statements. * * @param complete * If true, all data will be written to the database. If false, * some data may be left until more data is available. */ private void flushWayTags(boolean complete) { while (wayTagBuffer.size() >= INSERT_BULK_ROW_COUNT_WAY_TAG) { int prmIndex; prmIndex = 1; for (int i = 0; i < INSERT_BULK_ROW_COUNT_WAY_TAG; i++) { prmIndex = wayTagBuilder.populateEntityParameters( bulkWayTagStatement, prmIndex, wayTagBuffer.remove(0)); } try { bulkWayTagStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to bulk insert way tags into the database.", e); } } if (complete) { while (wayTagBuffer.size() > 0) { wayTagBuilder.populateEntityParameters(singleWayTagStatement, 1, wayTagBuffer.remove(0)); try { singleWayTagStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert a way tag into the database.", e); } } } } /** * Flushes way nodes to the database. If complete is false, this will only * write way nodes until the remaining way node count is less than the * multi-row insert statement row count. If complete is true, all remaining * rows will be written using single row insert statements. * * @param complete * If true, all data will be written to the database. If false, * some data may be left until more data is available. */ private void flushWayNodes(boolean complete) { while (wayNodeBuffer.size() >= INSERT_BULK_ROW_COUNT_WAY_NODE) { int prmIndex; prmIndex = 1; for (int i = 0; i < INSERT_BULK_ROW_COUNT_WAY_NODE; i++) { prmIndex = wayNodeBuilder.populateEntityParameters( bulkWayNodeStatement, prmIndex, wayNodeBuffer.remove(0)); } try { bulkWayNodeStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to bulk insert way nodes into the database.", e); } } if (complete) { while (wayNodeBuffer.size() > 0) { wayNodeBuilder.populateEntityParameters(singleWayNodeStatement, 1, wayNodeBuffer.remove(0)); try { singleWayNodeStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert a way node into the database.", e); } } } } /** * Flushes relations to the database. If complete is false, this will only write * relations until the remaining relation count is less than the multi-row insert * statement row count. If complete is true, all remaining rows will be * written using single row insert statements. * * @param complete * If true, all data will be written to the database. If false, * some data may be left until more data is available. */ private void flushRelations(boolean complete) { while (relationBuffer.size() >= INSERT_BULK_ROW_COUNT_RELATION) { List processedRelations; int prmIndex; processedRelations = new ArrayList(INSERT_BULK_ROW_COUNT_RELATION); prmIndex = 1; for (int i = 0; i < INSERT_BULK_ROW_COUNT_RELATION; i++) { Relation relation; relation = relationBuffer.remove(0); processedRelations.add(relation); prmIndex = relationBuilder.populateEntityParameters(bulkRelationStatement, prmIndex, relation); } try { bulkRelationStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to bulk insert relations into the database.", e); } for (Relation relation : processedRelations) { addRelationTags(relation); addRelationMembers(relation); } } if (complete) { while (relationBuffer.size() > 0) { Relation relation; relation = relationBuffer.remove(0); relationBuilder.populateEntityParameters(singleRelationStatement, 1, relation); try { singleRelationStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert a relation into the database.", e); } addRelationTags(relation); addRelationMembers(relation); } } } /** * Process the relation tags. * * @param relation * The relation to be processed. */ private void addRelationTags(Relation relation) { for (Tag tag : relation.getTags()) { relationTagBuffer.add(new DbFeature(relation.getId(), tag)); } flushRelationTags(false); } /** * Process the relation members. * * @param relation * The relation to be processed. */ private void addRelationMembers(Relation relation) { int sequenceId; sequenceId = 0; for (RelationMember relationMember : relation.getMembers()) { relationMemberBuffer.add( new DbOrderedFeature(relation.getId(), relationMember, sequenceId++)); } flushRelationMembers(false); } /** * Flushes relation tags to the database. If complete is false, this will only * write relation tags until the remaining relation tag count is less than the * multi-row insert statement row count. If complete is true, all remaining * rows will be written using single row insert statements. * * @param complete * If true, all data will be written to the database. If false, * some data may be left until more data is available. */ private void flushRelationTags(boolean complete) { while (relationTagBuffer.size() >= INSERT_BULK_ROW_COUNT_RELATION_TAG) { int prmIndex; prmIndex = 1; for (int i = 0; i < INSERT_BULK_ROW_COUNT_RELATION_TAG; i++) { prmIndex = relationTagBuilder.populateEntityParameters( bulkRelationTagStatement, prmIndex, relationTagBuffer.remove(0)); } try { bulkRelationTagStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to bulk insert relation tags into the database.", e); } } if (complete) { while (relationTagBuffer.size() > 0) { relationTagBuilder.populateEntityParameters(singleRelationTagStatement, 1, relationTagBuffer.remove(0)); try { singleRelationTagStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert a relation tag into the database.", e); } } } } /** * Flushes relation members to the database. If complete is false, this will only * write relation members until the remaining relation member count is less than the * multi-row insert statement row count. If complete is true, all remaining * rows will be written using single row insert statements. * * @param complete * If true, all data will be written to the database. If false, * some data may be left until more data is available. */ private void flushRelationMembers(boolean complete) { while (relationMemberBuffer.size() >= INSERT_BULK_ROW_COUNT_RELATION_MEMBER) { int prmIndex; prmIndex = 1; for (int i = 0; i < INSERT_BULK_ROW_COUNT_RELATION_MEMBER; i++) { prmIndex = relationMemberBuilder.populateEntityParameters( bulkRelationMemberStatement, prmIndex, relationMemberBuffer.remove(0)); } try { bulkRelationMemberStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to bulk insert relation members into the database.", e); } } if (complete) { while (relationMemberBuffer.size() > 0) { relationMemberBuilder.populateEntityParameters( singleRelationMemberStatement, 1, relationMemberBuffer.remove(0)); try { singleRelationMemberStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to insert a relation member into the database.", e); } } } } /** * {@inheritDoc} */ public void initialize(Map metaData) { // Do nothing. } /** * Writes any buffered data to the database and commits. */ public void complete() { initialize(); LOG.fine("Flushing buffers."); flushNodes(true); flushNodeTags(true); flushWays(true); flushWayTags(true); flushWayNodes(true); flushRelations(true); flushRelationTags(true); flushRelationMembers(true); LOG.fine("Data load complete."); // Add all constraints and indexes. indexManager.completeAfterLoad(); LOG.fine("Committing changes."); dbCtx.commit(); LOG.fine("Vacuuming database."); dbCtx.setAutoCommit(true); dbCtx.executeStatement("VACUUM ANALYZE"); LOG.fine("Complete."); } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { initialize(); // Write the user to the database if required. writeUser(entityContainer.getEntity().getUser()); entityContainer.process(this); } /** * {@inheritDoc} */ @Override public void process(BoundContainer bound) { // Do nothing. } /** * {@inheritDoc} */ public void process(NodeContainer nodeContainer) { if (enableBboxBuilder || enableLinestringBuilder) { wayGeometryBuilder.addNodeLocation(nodeContainer.getEntity()); } nodeBuffer.add(nodeContainer.getEntity()); flushNodes(false); } /** * {@inheritDoc} */ public void process(WayContainer wayContainer) { // Ignore ways with a single node because they can't be loaded into postgis. if (wayContainer.getEntity().getWayNodes().size() > 1) { wayBuffer.add(wayContainer.getEntity()); } flushWays(false); } /** * {@inheritDoc} */ public void process(RelationContainer relationContainer) { relationBuffer.add(relationContainer.getEntity()); flushRelations(false); } /** * {@inheritDoc} */ @Override public void release() { statementContainer.release(); wayGeometryBuilder.release(); dbCtx.release(); } } PostgreSqlWriterFactory.java000066400000000000000000000044041253404521400364230ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.database.DatabaseTaskManagerFactory; import org.openstreetmap.osmosis.pgsimple.common.NodeLocationStoreType; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkManager; /** * The task manager factory for a database writer. * * @author Brett Henderson */ public class PostgreSqlWriterFactory extends DatabaseTaskManagerFactory { private static final String ARG_ENABLE_BBOX_BUILDER = "enableBboxBuilder"; private static final String ARG_ENABLE_LINESTRING_BUILDER = "enableLinestringBuilder"; private static final String ARG_NODE_LOCATION_STORE_TYPE = "nodeLocationStoreType"; private static final boolean DEFAULT_ENABLE_BBOX_BUILDER = false; private static final boolean DEFAULT_ENABLE_LINESTRING_BUILDER = false; private static final String DEFAULT_NODE_LOCATION_STORE_TYPE = "CompactTempFile"; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { DatabaseLoginCredentials loginCredentials; DatabasePreferences preferences; boolean enableBboxBuilder; boolean enableLinestringBuilder; NodeLocationStoreType storeType; // Get the task arguments. loginCredentials = getDatabaseLoginCredentials(taskConfig); preferences = getDatabasePreferences(taskConfig); enableBboxBuilder = getBooleanArgument(taskConfig, ARG_ENABLE_BBOX_BUILDER, DEFAULT_ENABLE_BBOX_BUILDER); enableLinestringBuilder = getBooleanArgument( taskConfig, ARG_ENABLE_LINESTRING_BUILDER, DEFAULT_ENABLE_LINESTRING_BUILDER); storeType = Enum.valueOf( NodeLocationStoreType.class, getStringArgument(taskConfig, ARG_NODE_LOCATION_STORE_TYPE, DEFAULT_NODE_LOCATION_STORE_TYPE)); return new SinkManager( taskConfig.getId(), new PostgreSqlWriter(loginCredentials, preferences, enableBboxBuilder, enableLinestringBuilder, storeType), taskConfig.getPipeArgs() ); } } osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl/000077500000000000000000000000001253404521400317465ustar00rootroot00000000000000ActionChangeWriter.java000066400000000000000000000032051253404521400362520ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityProcessor; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.task.common.ChangeAction; /** * Writes entities to a database according to a specific action. * * @author Brett Henderson */ public class ActionChangeWriter implements EntityProcessor { private ChangeWriter changeWriter; private ChangeAction action; /** * Creates a new instance. * * @param changeWriter * The underlying change writer. * @param action * The action to apply to all writes. */ public ActionChangeWriter(ChangeWriter changeWriter, ChangeAction action) { this.changeWriter = changeWriter; this.action = action; } /** * {@inheritDoc} */ public void process(BoundContainer bound) { // Do nothing. } /** * {@inheritDoc} */ public void process(NodeContainer nodeContainer) { changeWriter.write(nodeContainer.getEntity(), action); } /** * {@inheritDoc} */ public void process(WayContainer wayContainer) { changeWriter.write(wayContainer.getEntity(), action); } /** * {@inheritDoc} */ public void process(RelationContainer relationContainer) { changeWriter.write(relationContainer.getEntity(), action); } } ActionDao.java000066400000000000000000000054011253404521400343730ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.sql.PreparedStatement; import java.sql.SQLException; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.pgsimple.common.BaseDao; import org.openstreetmap.osmosis.pgsimple.common.DatabaseContext; /** * Performs all action db operations. * * @author Brett Henderson */ public class ActionDao extends BaseDao { private static final String SQL_INSERT = "INSERT INTO actions(data_type, action, id) VALUES(?, ?, ?)"; private static final String SQL_TRUNCATE = "TRUNCATE actions"; private boolean enabled; private DatabaseCapabilityChecker capabilityChecker; private PreparedStatement insertStatement; private PreparedStatement truncateStatement; /** * Creates a new instance. * * @param dbCtx * The database context to use for accessing the database. */ public ActionDao(DatabaseContext dbCtx) { this(dbCtx, true); capabilityChecker = new DatabaseCapabilityChecker(dbCtx); } /** * Creates a new instance. * * @param dbCtx * The database context to use for accessing the database. * @param enabled * Action records will only be written if this is set to true. */ public ActionDao(DatabaseContext dbCtx, boolean enabled) { super(dbCtx); this.enabled = enabled; } /** * Adds the specified action to the database. * * @param dataType The type of data being represented by this action. * @param action The action being performed on the data. * @param id The identifier of the data. */ public void addAction(ActionDataType dataType, ChangesetAction action, long id) { if (enabled && capabilityChecker.isActionSupported()) { int prmIndex; if (insertStatement == null) { insertStatement = prepareStatement(SQL_INSERT); } prmIndex = 1; try { insertStatement.setString(prmIndex++, dataType.getDatabaseValue()); insertStatement.setString(prmIndex++, action.getDatabaseValue()); insertStatement.setLong(prmIndex++, id); insertStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException( "Unable to insert action with type=" + dataType + ", action=" + action + " and id=" + id + ".", e); } } } /** * Removes all action records. */ public void truncate() { if (enabled && capabilityChecker.isActionSupported()) { if (truncateStatement == null) { truncateStatement = prepareStatement(SQL_TRUNCATE); } try { truncateStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException( "Truncate failed for actions.", e ); } } } } ActionDataType.java000066400000000000000000000013131253404521400354010ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; /** * Defines all the data types supported by the action table. * * @author Brett Henderson */ public enum ActionDataType { /** * A user record. */ USER("U"), /** * A node entity. */ NODE("N"), /** * A way entity. */ WAY("W"), /** * A relation entity. */ RELATION("R"); private final String dbValue; private ActionDataType(String dbValue) { this.dbValue = dbValue; } /** * Returns the database value representing this action. * * @return The database value. */ public String getDatabaseValue() { return dbValue; } } ChangeWriter.java000066400000000000000000000135311253404521400351170ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.sql.CallableStatement; import java.sql.SQLException; import java.util.HashSet; import java.util.Set; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.database.ReleasableStatementContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.pgsimple.common.DatabaseContext; import org.openstreetmap.osmosis.pgsimple.common.NoSuchRecordException; import org.openstreetmap.osmosis.core.task.common.ChangeAction; /** * Writes changes to a database. * * @author Brett Henderson */ public class ChangeWriter { private DatabaseContext dbCtx; private ActionDao actionDao; private UserDao userDao; private NodeDao nodeDao; private WayDao wayDao; private RelationDao relationDao; private Set userSet; /** * Creates a new instance. * * @param dbCtx * The database context to use for accessing the database. */ public ChangeWriter(DatabaseContext dbCtx) { this.dbCtx = dbCtx; actionDao = new ActionDao(dbCtx); userDao = new UserDao(dbCtx, actionDao); nodeDao = new NodeDao(dbCtx, actionDao); wayDao = new WayDao(dbCtx, actionDao); relationDao = new RelationDao(dbCtx, actionDao); userSet = new HashSet(); } /** * Writes the specified user to the database. * * @param user * The user to write. */ private void writeUser(OsmUser user) { // Entities without a user assigned should not be written. if (!OsmUser.NONE.equals(user)) { // Users will only be updated in the database once per changeset // run. if (!userSet.contains(user.getId())) { int userId; OsmUser existingUser; userId = user.getId(); try { existingUser = userDao.getUser(userId); if (!user.equals(existingUser)) { userDao.updateUser(user); } } catch (NoSuchRecordException e) { userDao.addUser(user); } userSet.add(user.getId()); } } } /** * Performs any validation and pre-processing required for all entity types. */ private void processEntityPrerequisites(Entity entity) { // We can't write an entity with a null timestamp. if (entity.getTimestamp() == null) { throw new OsmosisRuntimeException("Entity(" + entity.getType() + ") " + entity.getId() + " does not have a timestamp set."); } // Process the user data. writeUser(entity.getUser()); } /** * Writes the specified node change to the database. * * @param node * The node to be written. * @param action * The change to be applied. */ public void write(Node node, ChangeAction action) { processEntityPrerequisites(node); // If this is a create or modify, we must create or modify the records // in the database. Note that we don't use the input source to // distinguish between create and modify, we make this determination // based on our current data set. if (ChangeAction.Create.equals(action) || ChangeAction.Modify.equals(action)) { if (nodeDao.exists(node.getId())) { nodeDao.modifyEntity(node); } else { nodeDao.addEntity(node); } } else { // Remove the node from the database. nodeDao.removeEntity(node.getId()); } } /** * Writes the specified way change to the database. * * @param way * The way to be written. * @param action * The change to be applied. */ public void write(Way way, ChangeAction action) { processEntityPrerequisites(way); // If this is a create or modify, we must create or modify the records // in the database. Note that we don't use the input source to // distinguish between create and modify, we make this determination // based on our current data set. if (ChangeAction.Create.equals(action) || ChangeAction.Modify.equals(action)) { if (wayDao.exists(way.getId())) { wayDao.modifyEntity(way); } else { wayDao.addEntity(way); } } else { // Remove the way from the database. wayDao.removeEntity(way.getId()); } } /** * Writes the specified relation change to the database. * * @param relation * The relation to be written. * @param action * The change to be applied. */ public void write(Relation relation, ChangeAction action) { processEntityPrerequisites(relation); // If this is a create or modify, we must create or modify the records // in the database. Note that we don't use the input source to // distinguish between create and modify, we make this determination // based on our current data set. if (ChangeAction.Create.equals(action) || ChangeAction.Modify.equals(action)) { if (relationDao.exists(relation.getId())) { relationDao.modifyEntity(relation); } else { relationDao.addEntity(relation); } } else { // Remove the relation from the database. relationDao.removeEntity(relation.getId()); } } /** * Performs post-change database updates. */ public void complete() { ReleasableStatementContainer statementContainer; CallableStatement updateStatement; statementContainer = new ReleasableStatementContainer(); try { updateStatement = statementContainer.add(dbCtx.prepareCall("{call osmosisUpdate()}")); updateStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to invoke the osmosis update stored function.", e); } finally { statementContainer.release(); } // Clear all action records. actionDao.truncate(); } /** * Releases all resources. */ public void release() { } } ChangesetAction.java000066400000000000000000000015621253404521400355750ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; /** * Defines the values for the "action" columns in the pgsql schema. These * actions define what activity has been performed on an entity during * application of a changeset. * * @author Brett Henderson */ public enum ChangesetAction { /** * No entity is unchanged. */ NONE("N"), /** * The entity has been added. */ CREATE("C"), /** * The entity has been modified. */ MODIFY("M"), /** * The entity has been deleted. */ DELETE("D"); private final String dbValue; private ChangesetAction(String dbValue) { this.dbValue = dbValue; } /** * Returns the database value representing this action. * * @return The database value. */ public String getDatabaseValue() { return dbValue; } } CopyFileset.java000066400000000000000000000025131253404521400347610ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.io.File; /** * A copy fileset is a collection of files in the PostgreSQL "COPY" format that * can be used to populate the database. * * @author Brett Henderson */ public interface CopyFileset { /** * Gets the user table file. * * @return The user table file. */ File getUserFile(); /** * Gets the node table file. * * @return The node table file. */ File getNodeFile(); /** * Gets the node tag table file. * * @return The node tag table file. */ File getNodeTagFile(); /** * Gets the way table file. * * @return The way table file. */ File getWayFile(); /** * Gets the way tag table file. * * @return The way tag table file. */ File getWayTagFile(); /** * Gets the way node table file. * * @return The way node table file. */ File getWayNodeFile(); /** * Gets the relation table file. * * @return The relation table file. */ File getRelationFile(); /** * Gets the relation tag table file. * * @return The relation tag table file. */ File getRelationTagFile(); /** * Gets the relation member table file. * * @return The relation member table file. */ File getRelationMemberFile(); } CopyFilesetBuilder.java000066400000000000000000000205611253404521400362730ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityProcessor; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.openstreetmap.osmosis.core.lifecycle.CompletableContainer; import org.openstreetmap.osmosis.pgsimple.common.CopyFileWriter; import org.openstreetmap.osmosis.pgsimple.common.NodeLocationStoreType; import org.openstreetmap.osmosis.pgsimple.common.PointBuilder; import org.openstreetmap.osmosis.core.task.v0_6.Sink; /** * An OSM data sink for storing all data to a set of database dump files. These * files can be used for populating an empty database. * * @author Brett Henderson */ public class CopyFilesetBuilder implements Sink, EntityProcessor { private boolean enableBboxBuilder; private boolean enableLinestringBuilder; private WayGeometryBuilder wayGeometryBuilder; private CompletableContainer writerContainer; private MemberTypeValueMapper memberTypeValueMapper; private CopyFileWriter userWriter; private CopyFileWriter nodeWriter; private CopyFileWriter nodeTagWriter; private CopyFileWriter wayWriter; private CopyFileWriter wayTagWriter; private CopyFileWriter wayNodeWriter; private CopyFileWriter relationWriter; private CopyFileWriter relationTagWriter; private CopyFileWriter relationMemberWriter; private PointBuilder pointBuilder; private Set userSet; /** * Creates a new instance. * * @param copyFileset * The set of COPY files to be populated. * @param enableBboxBuilder * If true, the way bbox geometry is built during processing * instead of relying on the database to build them after import. * This increases processing but is faster than relying on the * database. * @param enableLinestringBuilder * If true, the way linestring geometry is built during * processing instead of relying on the database to build them * after import. This increases processing but is faster than * relying on the database. * @param storeType * The node location storage type used by the geometry builders. */ public CopyFilesetBuilder( CopyFileset copyFileset, boolean enableBboxBuilder, boolean enableLinestringBuilder, NodeLocationStoreType storeType) { this.enableBboxBuilder = enableBboxBuilder; this.enableLinestringBuilder = enableLinestringBuilder; writerContainer = new CompletableContainer(); userWriter = writerContainer.add(new CopyFileWriter(copyFileset.getUserFile())); nodeWriter = writerContainer.add(new CopyFileWriter(copyFileset.getNodeFile())); nodeTagWriter = writerContainer.add(new CopyFileWriter(copyFileset.getNodeTagFile())); wayWriter = writerContainer.add(new CopyFileWriter(copyFileset.getWayFile())); wayTagWriter = writerContainer.add(new CopyFileWriter(copyFileset.getWayTagFile())); wayNodeWriter = writerContainer.add(new CopyFileWriter(copyFileset.getWayNodeFile())); relationWriter = writerContainer.add(new CopyFileWriter(copyFileset.getRelationFile())); relationTagWriter = writerContainer.add(new CopyFileWriter(copyFileset.getRelationTagFile())); relationMemberWriter = writerContainer.add(new CopyFileWriter(copyFileset.getRelationMemberFile())); pointBuilder = new PointBuilder(); wayGeometryBuilder = new WayGeometryBuilder(storeType); memberTypeValueMapper = new MemberTypeValueMapper(); memberTypeValueMapper = new MemberTypeValueMapper(); userSet = new HashSet(); } /** * {@inheritDoc} */ public void initialize(Map metaData) { // Do nothing. } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { OsmUser user; // Write a user entry if the user doesn't already exist. user = entityContainer.getEntity().getUser(); if (!user.equals(OsmUser.NONE)) { if (!userSet.contains(user.getId())) { userWriter.writeField(user.getId()); userWriter.writeField(user.getName()); userWriter.endRecord(); userSet.add(user.getId()); } } // Process the entity itself. entityContainer.process(this); } /** * {@inheritDoc} */ public void process(BoundContainer boundContainer) { // Do nothing. } /** * {@inheritDoc} */ public void process(NodeContainer nodeContainer) { Node node; node = nodeContainer.getEntity(); nodeWriter.writeField(node.getId()); nodeWriter.writeField(node.getVersion()); nodeWriter.writeField(node.getUser().getId()); nodeWriter.writeField(node.getTimestamp()); nodeWriter.writeField(node.getChangesetId()); nodeWriter.writeField(pointBuilder.createPoint(node.getLatitude(), node.getLongitude())); nodeWriter.endRecord(); for (Tag tag : node.getTags()) { nodeTagWriter.writeField(node.getId()); nodeTagWriter.writeField(tag.getKey()); nodeTagWriter.writeField(tag.getValue()); nodeTagWriter.endRecord(); } if (enableBboxBuilder || enableLinestringBuilder) { wayGeometryBuilder.addNodeLocation(node); } } /** * {@inheritDoc} */ public void process(WayContainer wayContainer) { Way way; int sequenceId; way = wayContainer.getEntity(); // Ignore ways with a single node because they can't be loaded into postgis. if (way.getWayNodes().size() > 1) { wayWriter.writeField(way.getId()); wayWriter.writeField(way.getVersion()); wayWriter.writeField(way.getUser().getId()); wayWriter.writeField(way.getTimestamp()); wayWriter.writeField(way.getChangesetId()); if (enableBboxBuilder) { wayWriter.writeField(wayGeometryBuilder.createWayBbox(way)); } if (enableLinestringBuilder) { wayWriter.writeField(wayGeometryBuilder.createWayLinestring(way)); } wayWriter.endRecord(); for (Tag tag : way.getTags()) { wayTagWriter.writeField(way.getId()); wayTagWriter.writeField(tag.getKey()); wayTagWriter.writeField(tag.getValue()); wayTagWriter.endRecord(); } sequenceId = 0; for (WayNode wayNode : way.getWayNodes()) { wayNodeWriter.writeField(way.getId()); wayNodeWriter.writeField(wayNode.getNodeId()); wayNodeWriter.writeField(sequenceId++); wayNodeWriter.endRecord(); } } } /** * {@inheritDoc} */ public void process(RelationContainer relationContainer) { Relation relation; int memberSequenceId; relation = relationContainer.getEntity(); relationWriter.writeField(relation.getId()); relationWriter.writeField(relation.getVersion()); relationWriter.writeField(relation.getUser().getId()); relationWriter.writeField(relation.getTimestamp()); relationWriter.writeField(relation.getChangesetId()); relationWriter.endRecord(); for (Tag tag : relation.getTags()) { relationTagWriter.writeField(relation.getId()); relationTagWriter.writeField(tag.getKey()); relationTagWriter.writeField(tag.getValue()); relationTagWriter.endRecord(); } memberSequenceId = 0; for (RelationMember member : relation.getMembers()) { relationMemberWriter.writeField(relation.getId()); relationMemberWriter.writeField(member.getMemberId()); relationMemberWriter.writeField(memberTypeValueMapper.getMemberType(member.getMemberType())); relationMemberWriter.writeField(member.getMemberRole()); relationMemberWriter.writeField(memberSequenceId++); relationMemberWriter.endRecord(); } } /** * Writes any buffered data to the database and commits. */ public void complete() { writerContainer.complete(); } /** * Releases all resources. */ public void release() { writerContainer.release(); wayGeometryBuilder.release(); } } CopyFilesetLoader.java000066400000000000000000000116251253404521400361140ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.sql.SQLException; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.pgsimple.common.DatabaseContext; import org.openstreetmap.osmosis.pgsimple.common.SchemaVersionValidator; import org.openstreetmap.osmosis.pgsimple.v0_6.PostgreSqlVersionConstants; import org.postgresql.copy.CopyManager; import org.postgresql.core.BaseConnection; /** * Loads a COPY fileset into a database. * * @author Brett Henderson */ public class CopyFilesetLoader implements Runnable { private static final Logger LOG = Logger.getLogger(CopyFilesetLoader.class.getName()); private DatabaseLoginCredentials loginCredentials; private DatabasePreferences preferences; private CopyFileset copyFileset; /** * Creates a new instance. * * @param loginCredentials * Contains all information required to connect to the database. * @param preferences * Contains preferences configuring database behaviour. * @param copyFileset * The set of COPY files to be loaded into the database. */ public CopyFilesetLoader(DatabaseLoginCredentials loginCredentials, DatabasePreferences preferences, CopyFileset copyFileset) { this.loginCredentials = loginCredentials; this.preferences = preferences; this.copyFileset = copyFileset; } /** * Loads a table from a COPY file. * * @param dbCtx * The database connection. * @param copyFile * The file to be loaded. * @param tableName * The table to load the data into. */ public void loadCopyFile(DatabaseContext dbCtx, File copyFile, String tableName) { CopyManager copyManager; InputStream inStream = null; try { InputStream bufferedInStream; inStream = new FileInputStream(copyFile); bufferedInStream = new BufferedInputStream(inStream, 65536); copyManager = new CopyManager((BaseConnection) dbCtx.getConnection()); copyManager.copyIn("COPY " + tableName + " FROM STDIN", bufferedInStream); inStream.close(); inStream = null; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to process COPY file " + copyFile + ".", e); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to process COPY file " + copyFile + ".", e); } finally { if (inStream != null) { try { inStream.close(); } catch (Exception e) { LOG.log(Level.SEVERE, "Unable to close COPY file.", e); } inStream = null; } } } /** * Reads all data from the database and send it to the sink. */ public void run() { DatabaseContext dbCtx = new DatabaseContext(loginCredentials); try { IndexManager indexManager; new SchemaVersionValidator(dbCtx, preferences) .validateVersion(PostgreSqlVersionConstants.SCHEMA_VERSION); indexManager = new IndexManager(dbCtx, false, false); // Drop all constraints and indexes. indexManager.prepareForLoad(); LOG.finer("Loading users."); loadCopyFile(dbCtx, copyFileset.getUserFile(), "users"); LOG.finer("Loading nodes."); loadCopyFile(dbCtx, copyFileset.getNodeFile(), "nodes"); LOG.finer("Loading node tags."); loadCopyFile(dbCtx, copyFileset.getNodeTagFile(), "node_tags"); LOG.finer("Loading ways."); loadCopyFile(dbCtx, copyFileset.getWayFile(), "ways"); LOG.finer("Loading way tags."); loadCopyFile(dbCtx, copyFileset.getWayTagFile(), "way_tags"); LOG.finer("Loading way nodes."); loadCopyFile(dbCtx, copyFileset.getWayNodeFile(), "way_nodes"); LOG.finer("Loading relations."); loadCopyFile(dbCtx, copyFileset.getRelationFile(), "relations"); LOG.finer("Loading relation tags."); loadCopyFile(dbCtx, copyFileset.getRelationTagFile(), "relation_tags"); LOG.finer("Loading relation members."); loadCopyFile(dbCtx, copyFileset.getRelationMemberFile(), "relation_members"); LOG.finer("Committing changes."); LOG.fine("Data load complete."); // Add all constraints and indexes. indexManager.completeAfterLoad(); LOG.fine("Committing changes."); dbCtx.commit(); LOG.fine("Vacuuming database."); dbCtx.setAutoCommit(true); dbCtx.executeStatement("VACUUM ANALYZE"); LOG.fine("Complete."); } finally { dbCtx.release(); } } } DatabaseCapabilityChecker.java000066400000000000000000000032221253404521400375240ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import org.openstreetmap.osmosis.pgsimple.common.DatabaseContext; /** * Provides information about which features a database supports. * * @author Brett Henderson */ public class DatabaseCapabilityChecker { private DatabaseContext dbCtx; private boolean initialized; private boolean isActionSupported; private boolean isWayBboxSupported; private boolean isWayLinestringSupported; /** * Creates a new instance. * * @param dbCtx The database context to use for accessing the database. */ public DatabaseCapabilityChecker(DatabaseContext dbCtx) { this.dbCtx = dbCtx; initialized = false; } private void initialize() { if (!initialized) { isActionSupported = dbCtx.doesTableExist("actions"); isWayBboxSupported = dbCtx.doesColumnExist("ways", "bbox"); isWayLinestringSupported = dbCtx.doesColumnExist("ways", "linestring"); initialized = true; } } /** * Indicates if action support is available. * * @return True if supported, otherwise false. */ public boolean isActionSupported() { initialize(); return isActionSupported; } /** * Indicates if way bounding box support is available. * * @return True if supported, otherwise false. */ public boolean isWayBboxSupported() { initialize(); return isWayBboxSupported; } /** * Indicates if way linestring support is available. * * @return True if supported, otherwise false. */ public boolean isWayLinestringSupported() { initialize(); return isWayLinestringSupported; } } DbOrderedFeatureComparator.java000066400000000000000000000016411253404521400377320ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.util.Comparator; import org.openstreetmap.osmosis.core.database.DbOrderedFeature; import org.openstreetmap.osmosis.core.store.Storeable; /** * Compares way nodes to allow them to be sorted by way id then sequence * number. * * @author Brett Henderson * @param * The encapsulated feature type. */ public class DbOrderedFeatureComparator implements Comparator> { /** * {@inheritDoc} */ public int compare(DbOrderedFeature o1, DbOrderedFeature o2) { long way1Id; long way2Id; way1Id = o1.getEntityId(); way2Id = o2.getEntityId(); if (way1Id != way2Id) { if (way1Id < way2Id) { return -1; } else { return 1; } } return o1.getSequenceId() - o2.getSequenceId(); } } DirectoryCopyFileset.java000066400000000000000000000043321253404521400366470ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.io.File; /** * A COPY fileset implementation that defines fixed filenames within a specified * directory. * * @author Brett Henderson * */ public class DirectoryCopyFileset implements CopyFileset { private static final String USER_SUFFIX = "users.txt"; private static final String NODE_SUFFIX = "nodes.txt"; private static final String NODE_TAG_SUFFIX = "node_tags.txt"; private static final String WAY_SUFFIX = "ways.txt"; private static final String WAY_TAG_SUFFIX = "way_tags.txt"; private static final String WAY_NODE_SUFFIX = "way_nodes.txt"; private static final String RELATION_SUFFIX = "relations.txt"; private static final String RELATION_TAG_SUFFIX = "relation_tags.txt"; private static final String RELATION_MEMBER_SUFFIX = "relation_members.txt"; private File directory; /** * Creates a new instance. * * @param directory * The directory to store all files in. */ public DirectoryCopyFileset(File directory) { this.directory = directory; } /** * {@inheritDoc} */ @Override public File getNodeFile() { return new File(directory, NODE_SUFFIX); } /** * {@inheritDoc} */ @Override public File getNodeTagFile() { return new File(directory, NODE_TAG_SUFFIX); } /** * {@inheritDoc} */ @Override public File getRelationFile() { return new File(directory, RELATION_SUFFIX); } /** * {@inheritDoc} */ @Override public File getRelationMemberFile() { return new File(directory, RELATION_MEMBER_SUFFIX); } /** * {@inheritDoc} */ @Override public File getRelationTagFile() { return new File(directory, RELATION_TAG_SUFFIX); } /** * {@inheritDoc} */ @Override public File getUserFile() { return new File(directory, USER_SUFFIX); } /** * {@inheritDoc} */ @Override public File getWayFile() { return new File(directory, WAY_SUFFIX); } /** * {@inheritDoc} */ @Override public File getWayNodeFile() { return new File(directory, WAY_NODE_SUFFIX); } /** * {@inheritDoc} */ @Override public File getWayTagFile() { return new File(directory, WAY_TAG_SUFFIX); } } EntityDao.java000066400000000000000000000172521253404521400344410ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.database.DbFeature; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.pgsimple.common.BaseDao; import org.openstreetmap.osmosis.pgsimple.common.DatabaseContext; import org.openstreetmap.osmosis.pgsimple.common.NoSuchRecordException; /** * Provides functionality common to all top level entity daos. * * @author Brett Henderson * @param * The entity type to be supported. */ public abstract class EntityDao extends BaseDao { private static final Logger LOG = Logger.getLogger(EntityDao.class.getName()); private EntityFeatureDao> tagDao; private ActionDao actionDao; private EntityMapper entityMapper; private PreparedStatement countStatement; private PreparedStatement getStatement; private PreparedStatement insertStatement; private PreparedStatement updateStatement; private PreparedStatement deleteStatement; /** * Creates a new instance. * * @param dbCtx * The database context to use for accessing the database. * @param entityMapper * Provides entity type specific JDBC support. * @param actionDao * The dao to use for adding action records to the database. */ protected EntityDao(DatabaseContext dbCtx, EntityMapper entityMapper, ActionDao actionDao) { super(dbCtx); this.entityMapper = entityMapper; this.actionDao = actionDao; tagDao = new EntityFeatureDao>(dbCtx, new TagMapper(entityMapper.getEntityName())); } /** * Checks if the specified entity exists in the database. * * @param entityId * The unique identifier of the entity. * @return True if the entity exists in the database. */ public boolean exists(long entityId) { ResultSet resultSet = null; if (countStatement == null) { countStatement = prepareStatement(entityMapper.getSqlSelectCount(true)); } try { boolean result; countStatement.setLong(1, entityId); resultSet = countStatement.executeQuery(); if (!resultSet.next()) { throw new OsmosisRuntimeException( "Entity count query didn't return any rows."); } result = resultSet.getLong("count") > 0; resultSet.close(); resultSet = null; return result; } catch (SQLException e) { throw new OsmosisRuntimeException( "Count query failed for " + entityMapper.getEntityName() + " " + entityId + ".", e ); } finally { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to close result set.", e); } } } } /** * Loads the specified entity from the database. * * @param entityId * The unique identifier of the entity. * @return The loaded entity. */ public T getEntity(long entityId) { ResultSet resultSet = null; T entity; if (getStatement == null) { getStatement = prepareStatement(entityMapper.getSqlSelect(true, true)); } try { getStatement.setLong(1, entityId); resultSet = getStatement.executeQuery(); if (!resultSet.next()) { throw new NoSuchRecordException(entityMapper.getEntityName() + " " + entityId + " doesn't exist."); } entity = entityMapper.parseRecord(resultSet); resultSet.close(); resultSet = null; for (DbFeature dbTag : tagDao.getAll(entityId)) { entity.getTags().add(dbTag.getFeature()); } // Add the type specific features. loadFeatures(entityId, entity); return entity; } catch (SQLException e) { throw new OsmosisRuntimeException( "Query failed for " + entityMapper.getEntityName() + " " + entityId + ".", e ); } finally { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to close result set.", e); } } } } /** * Adds the specified tags to the database. * * @param entityId * The identifier of the entity to add these features to. * @param tags * The features to add. */ private void addTags(long entityId, Collection tags) { Collection> dbList; dbList = new ArrayList>(tags.size()); for (Tag tag : tags) { dbList.add(new DbFeature(entityId, tag)); } tagDao.addAll(dbList); } /** * Adds the type specific features to the entity. * * @param entityId * The entity id. * @param entity * The entity requiring features to be added. */ protected abstract void loadFeatures(long entityId, T entity); /** * Adds the specified entity to the database. * * @param entity * The entity to add. */ public void addEntity(T entity) { if (insertStatement == null) { insertStatement = prepareStatement(entityMapper.getSqlInsert(1)); } try { entityMapper.populateEntityParameters(insertStatement, 1, entity); insertStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException( "Insert failed for " + entityMapper.getEntityName() + " " + entity.getId() + ".", e ); } addTags(entity.getId(), entity.getTags()); actionDao.addAction(entityMapper.getEntityType(), ChangesetAction.CREATE, entity.getId()); } /** * Updates the specified entity details in the database. * * @param entity * The entity to update. */ public void modifyEntity(T entity) { if (updateStatement == null) { updateStatement = prepareStatement(entityMapper.getSqlUpdate(true)); } try { int prmIndex; prmIndex = 1; prmIndex = entityMapper.populateEntityParameters(updateStatement, prmIndex, entity); updateStatement.setLong(prmIndex++, entity.getId()); updateStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException( "Update failed for " + entityMapper.getEntityName() + " " + entity.getId() + ".", e ); } tagDao.removeList(entity.getId()); addTags(entity.getId(), entity.getTags()); actionDao.addAction(entityMapper.getEntityType(), ChangesetAction.MODIFY, entity.getId()); } /** * Removes the specified entity from the database. * * @param entityId * The id of the entity to remove. */ public void removeEntity(long entityId) { int prmIndex; tagDao.removeList(entityId); if (deleteStatement == null) { deleteStatement = prepareStatement(entityMapper.getSqlDelete(true)); } try { prmIndex = 1; deleteStatement.setLong(prmIndex++, entityId); deleteStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException( "Delete failed for " + entityMapper.getEntityName() + " " + entityId + ".", e ); } actionDao.addAction(entityMapper.getEntityType(), ChangesetAction.DELETE, entityId); } /** * Returns an iterator providing access to all entities in the database. * * @return The entity iterator. */ public abstract ReleasableIterator iterate(); } EntityFeatureDao.java000066400000000000000000000120521253404521400357460ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.database.DbFeature; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.store.Storeable; import org.openstreetmap.osmosis.pgsimple.common.BaseDao; import org.openstreetmap.osmosis.pgsimple.common.DatabaseContext; /** * Provides functionality common to all entity feature daos. * * @author Brett Henderson * @param * The entity feature type to be supported. * @param * The entity feature database wrapper type to be used. */ public class EntityFeatureDao> extends BaseDao { private static final Logger LOG = Logger.getLogger(EntityFeatureDao.class.getName()); /** * Provides jdbc mapping functionality for this entity feature type. */ protected EntityFeatureMapper entityFeatureBuilder; private PreparedStatement getStatement; private PreparedStatement insertStatement; private PreparedStatement deleteStatement; /** * Creates a new instance. * * @param dbCtx * The database context to use for accessing the database. * @param entityFeatureBuilder * Provides entity type specific JDBC support. */ protected EntityFeatureDao(DatabaseContext dbCtx, EntityFeatureMapper entityFeatureBuilder) { super(dbCtx); this.entityFeatureBuilder = entityFeatureBuilder; } /** * Loads all instances of this feature for the specified entity from the database. * * @param entityId * The unique identifier of the entity. * @return All instances of this feature type for the entity. */ public Collection getAll(long entityId) { ResultSet resultSet = null; if (getStatement == null) { getStatement = prepareStatement(entityFeatureBuilder.getSqlSelect(true, true)); } try { List resultList; getStatement.setLong(1, entityId); resultSet = getStatement.executeQuery(); resultList = new ArrayList(); while (resultSet.next()) { resultList.add(entityFeatureBuilder.buildEntity(resultSet)); } resultSet.close(); resultSet = null; return resultList; } catch (SQLException e) { throw new OsmosisRuntimeException("Query failed for " + entityFeatureBuilder.getEntityName() + " " + entityId + ".", e); } finally { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to close result set.", e); } } } } /** * Loads all instances of this feature for the specified entity from the database. * * @param entityId * The unique identifier of the entity. * @return All instances of this feature type for the entity. */ public Collection getAllRaw(long entityId) { Collection dbFeatures; Collection rawFeatures; dbFeatures = getAll(entityId); rawFeatures = new ArrayList(dbFeatures.size()); for (Tdb dbFeature : dbFeatures) { rawFeatures.add(dbFeature.getFeature()); } return rawFeatures; } /** * Adds the specified features to the database. * * @param features * The features to add. */ public void addAll(Collection features) { if (insertStatement == null) { insertStatement = prepareStatement(entityFeatureBuilder.getSqlInsert(1)); } for (Tdb feature : features) { try { entityFeatureBuilder.populateEntityParameters(insertStatement, 1, feature); insertStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException( "Insert failed for " + entityFeatureBuilder.getEntityName() + " " + feature.getEntityId() + "." ); } } } /** * Removes the specified feature list from the database. * * @param entityId * The id of the entity to remove. */ public void removeList(long entityId) { int prmIndex; if (deleteStatement == null) { deleteStatement = prepareStatement(entityFeatureBuilder.getSqlDelete(true)); } try { prmIndex = 1; deleteStatement.setLong(prmIndex++, entityId); deleteStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException( "Delete failed for " + entityFeatureBuilder.getEntityName() + " " + entityId + "." ); } } /** * Returns an iterator providing access to all entity features of this type * in the database. * * @return The entity feature iterator. */ public ReleasableIterator iterate() { return new EntityFeatureTableReader(getDatabaseContext(), entityFeatureBuilder); } } EntityFeatureMapper.java000066400000000000000000000053451253404521400364760ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.sql.PreparedStatement; import java.sql.ResultSet; /** * Provides functionality common to all entity feature mapper implementations. * * @author Brett Henderson * @param * The type of feature to be built. */ public abstract class EntityFeatureMapper { /** * Returns the name of the entity features entity type. * * @return The parent entity name. */ public abstract String getParentEntityName(); /** * Returns the name of the entity feature. This is used for error messages. * * @return The entity name. */ public abstract String getEntityName(); /** * Provides a default SQL ORDER BY clause suitable for this entity feature. * * @return The ORDER BY clause. */ public String getSqlDefaultOrderBy() { return " ORDER BY entity_id"; } /** * The SQL SELECT statement for retrieving entity feature details. * * @param filterByEntityId * If true, a WHERE clause will be added filtering by the entity * id column. * @param orderBy * If true, a default ORDER BY clause will be added ordering by * the entity id column at a minimum and possibly other fields * depending on implementation. * @return The SQL string. */ public abstract String getSqlSelect(boolean filterByEntityId, boolean orderBy); /** * The SQL INSERT statement for adding features. * * @param rowCount * The number of rows to insert in a single statement. * @return The SQL string. */ public abstract String getSqlInsert(int rowCount); /** * The SQL DELETE statement for deleting entity features. * * @param filterByEntityId * If true, a WHERE clause will be added filtering by the entity * id column. * @return The SQL String. */ public abstract String getSqlDelete(boolean filterByEntityId); /** * Creates a new entity based upon the current row in the result set. * * @param resultSet * The result set to read from. * @return The newly built entity object. */ public abstract T buildEntity(ResultSet resultSet); /** * Sets entity values as bind variable parameters to an entity insert query. * * @param statement * The prepared statement to add the values to. * @param initialIndex * The offset index of the first variable to set. * @param entityFeature * The entity containing the data to be inserted. * @return The current parameter offset. */ public abstract int populateEntityParameters(PreparedStatement statement, int initialIndex, T entityFeature); } EntityFeatureTableReader.java000066400000000000000000000047471253404521400374310ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.sql.ResultSet; import org.openstreetmap.osmosis.core.database.DbFeature; import org.openstreetmap.osmosis.core.store.Storeable; import org.openstreetmap.osmosis.pgsimple.common.BaseTableReader; import org.openstreetmap.osmosis.pgsimple.common.DatabaseContext; /** * Reads all features of a particular type for an entity from a feature table * ordered by the entity identifier. * * @author Brett Henderson * @param * The entity feature type to be read. * @param * The entity feature database wrapper type to be used. */ public class EntityFeatureTableReader> extends BaseTableReader { private EntityFeatureMapper entityFeatureBuilder; private String sql; /** * Creates a new instance. * * @param dbCtx * The active connection to use for reading from the database. * @param entityFeatureBuilder * Provides entity feature jdbc bindings. */ public EntityFeatureTableReader(DatabaseContext dbCtx, EntityFeatureMapper entityFeatureBuilder) { super(dbCtx); this.entityFeatureBuilder = entityFeatureBuilder; sql = entityFeatureBuilder.getSqlSelect(false, true); } /** * Creates a new instance. * * @param dbCtx * The active connection to use for reading from the database. * @param entityFeatureBuilder * Provides entity feature jdbc bindings. * @param constraintTable * The table containing a column named id defining the list of * entities to be returned. */ public EntityFeatureTableReader( DatabaseContext dbCtx, EntityFeatureMapper entityFeatureBuilder, String constraintTable) { super(dbCtx); this.entityFeatureBuilder = entityFeatureBuilder; sql = entityFeatureBuilder.getSqlSelect(false, false) + " INNER JOIN " + constraintTable + " c ON f." + entityFeatureBuilder.getParentEntityName() + "_id = c.id" + entityFeatureBuilder.getSqlDefaultOrderBy(); } /** * {@inheritDoc} */ @Override protected ResultSet createResultSet(DatabaseContext queryDbCtx) { return queryDbCtx.executeQuery(sql); } /** * {@inheritDoc} */ @Override protected ReadResult createNextValue(ResultSet resultSet) { return new ReadResult( true, entityFeatureBuilder.buildEntity(resultSet) ); } } EntityMapper.java000066400000000000000000000176571253404521400351730ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.util.Arrays; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; /** * Provides functionality common to all database entity builder implementations. * * @author Brett Henderson * @param * The entity type to be supported. */ public abstract class EntityMapper { /** * Returns the name of the entity to substitute into SQL statements. This is * a low-tech way of making the queries type independent. * * @return The entity name as defined in the database schema. */ public abstract String getEntityName(); /** * Returns the action data type of the entity. * * @return The action type. */ public abstract ActionDataType getEntityType(); /** * Returns the class type for the entity. * * @return The entity type class. */ public abstract Class getEntityClass(); /** * The SQL SELECT statement for counting entities. It will return a count of * matching records. * * @param filterByEntityId * If true, a WHERE clause will be added filtering by the entity * id column. * @return The SQL string. */ public String getSqlSelectCount(boolean filterByEntityId) { StringBuilder resultSql; resultSql = new StringBuilder(); resultSql.append("SELECT Count(e.*) AS count FROM " + getEntityName() + "s e"); if (filterByEntityId) { resultSql.append(" WHERE e.id = ?"); } return resultSql.toString(); } /** * Produces an array of additional column names specific to this entity type * to be returned by entity queries. * * @return The column names. */ protected abstract String[] getTypeSpecificFieldNames(); /** * The SQL SELECT statement for retrieving entity details. * * @param filterByEntityId * If true, a WHERE clause will be added filtering by the entity * id column. * @param orderByEntityId * If true, an ORDER BY clause will be added ordering by the * entity id column. * @return The SQL string. */ public String getSqlSelect(boolean filterByEntityId, boolean orderByEntityId) { StringBuilder resultSql; resultSql = new StringBuilder(); resultSql.append("SELECT e.id, e.version, e.user_id, u.name AS user_name, e.tstamp, e.changeset_id"); for (String fieldName : Arrays.asList(getTypeSpecificFieldNames())) { resultSql.append(", ").append(fieldName); } resultSql.append(" FROM "); resultSql.append(getEntityName()); resultSql.append("s e"); resultSql.append(" LEFT OUTER JOIN users u ON e.user_id = u.id"); if (filterByEntityId) { resultSql.append(" WHERE e.id = ?"); } if (orderByEntityId) { resultSql.append(" ORDER BY e.id"); } return resultSql.toString(); } /** * The SQL INSERT statement for adding entities. * * @param rowCount * The number of rows to insert in a single statement. * @return The SQL string. */ public String getSqlInsert(int rowCount) { String[] typeSpecificFieldNames; StringBuilder resultSql; typeSpecificFieldNames = getTypeSpecificFieldNames(); resultSql = new StringBuilder(); resultSql.append("INSERT INTO ").append(getEntityName()).append("s"); resultSql.append("(id, version, user_id, tstamp, changeset_id"); for (String fieldName : Arrays.asList(typeSpecificFieldNames)) { resultSql.append(", ").append(fieldName); } resultSql.append(") VALUES "); for (int row = 0; row < rowCount; row++) { if (row > 0) { resultSql.append(", "); } resultSql.append("(?, ?, ?, ?, ?"); for (int i = 0; i < typeSpecificFieldNames.length; i++) { resultSql.append(", ?"); } resultSql.append(")"); } return resultSql.toString(); } /** * The SQL UPDATE statement for updating entity details. * * @param filterByEntityId * If true, a WHERE clause will be added filtering by the entity * id column. * @return The SQL String. */ public String getSqlUpdate(boolean filterByEntityId) { StringBuilder resultSql; resultSql = new StringBuilder(); resultSql.append("UPDATE ").append(getEntityName()) .append("s SET id = ?, version = ?, user_id = ?, tstamp = ?, changeset_id = ?"); for (String fieldName : Arrays.asList(getTypeSpecificFieldNames())) { resultSql.append(", ").append(fieldName).append(" = ?"); } if (filterByEntityId) { resultSql.append(" WHERE id = ?"); } return resultSql.toString(); } /** * The SQL UPDATE statement for logically deleting entities. * * @param filterByEntityId * If true, a WHERE clause will be added filtering by the entity * id column. * @return The SQL String. */ public String getSqlDelete(boolean filterByEntityId) { StringBuilder resultSql; resultSql = new StringBuilder(); resultSql.append("DELETE FROM ").append(getEntityName()).append("s"); if (filterByEntityId) { resultSql.append(" WHERE id = ?"); } return resultSql.toString(); } /** * Creates a new entity based upon the current row in the result set. * * @param resultSet * The result set to read from. * @return The newly built entity object. */ public abstract T parseRecord(ResultSet resultSet); /** * Creates a new user record based upon the current result set row. * * @param resultSet * The result set to read from. * @return The newly build user object. */ protected OsmUser buildUser(ResultSet resultSet) { try { int userId; OsmUser user; userId = resultSet.getInt("user_id"); if (userId == OsmUser.NONE.getId()) { user = OsmUser.NONE; } else { user = new OsmUser( userId, resultSet.getString("user_name") ); } return user; } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to build a user from the current recordset row.", e); } } /** * Sets common entity values as bind variable parameters to an entity insert * query. * * @param statement * The prepared statement to add the values to. * @param initialIndex * The offset index of the first variable to set. * @param entity * The entity containing the data to be inserted. * @return The current parameter offset. */ protected int populateCommonEntityParameters(PreparedStatement statement, int initialIndex, Entity entity) { int prmIndex; prmIndex = initialIndex; // We can't write an entity with a null timestamp. if (entity.getTimestamp() == null) { throw new OsmosisRuntimeException( "Entity(" + entity.getType() + ") " + entity.getId() + " does not have a timestamp set."); } try { statement.setLong(prmIndex++, entity.getId()); statement.setInt(prmIndex++, entity.getVersion()); statement.setInt(prmIndex++, entity.getUser().getId()); statement.setTimestamp(prmIndex++, new Timestamp(entity.getTimestamp().getTime())); statement.setLong(prmIndex++, entity.getChangesetId()); } catch (SQLException e) { throw new OsmosisRuntimeException( "Unable to set a prepared statement parameter for entity(" + entity.getType() + ") " + entity.getId() + ".", e); } return prmIndex; } /** * Sets entity values as bind variable parameters to an entity insert query. * * @param statement * The prepared statement to add the values to. * @param initialIndex * The offset index of the first variable to set. * @param entity * The entity containing the data to be inserted. * @return The current parameter offset. */ public abstract int populateEntityParameters(PreparedStatement statement, int initialIndex, T entity); } EntityReader.java000066400000000000000000000115011253404521400351270ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.util.NoSuchElementException; import org.openstreetmap.osmosis.core.database.DbFeature; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.store.PeekableIterator; import org.openstreetmap.osmosis.core.store.PersistentIterator; import org.openstreetmap.osmosis.core.store.SingleClassObjectSerializationFactory; import org.openstreetmap.osmosis.pgsimple.common.DatabaseContext; /** * Reads instances of an entity type from a database ordered by the identifier. * It combines the output of the entity feature table readers to produce fully * configured entity objects. * * @author Brett Henderson * @param * The entity type to be supported. */ public class EntityReader implements ReleasableIterator { private ReleasableIterator entityReader; private PeekableIterator> entityTagReader; private T nextValue; private boolean nextValueLoaded; /** * Creates a new instance. * * @param dbCtx * The database context to use for accessing the database. * @param entityMapper * The database mapper for the entity type. */ public EntityReader(DatabaseContext dbCtx, EntityMapper entityMapper) { // The postgres jdbc driver doesn't appear to allow concurrent result // sets on the same connection so only the last opened result set may be // streamed. The rest of the result sets must be persisted first. entityReader = new PersistentIterator( new SingleClassObjectSerializationFactory(entityMapper.getEntityClass()), new EntityTableReader(dbCtx, entityMapper), "ent", true ); entityTagReader = new PeekableIterator>( new PersistentIterator>( new SingleClassObjectSerializationFactory(DbFeature.class), new EntityFeatureTableReader>(dbCtx, new TagMapper(entityMapper.getEntityName())), "enttag", true ) ); } /** * Creates a new instance. * * @param dbCtx * The database context to use for accessing the database. * @param entityMapper * The database mapper for the entity type. * @param constraintTable * The table containing a column named id defining the list of * entities to be returned. */ public EntityReader(DatabaseContext dbCtx, EntityMapper entityMapper, String constraintTable) { // The postgres jdbc driver doesn't appear to allow concurrent result // sets on the same connection so only the last opened result set may be // streamed. The rest of the result sets must be persisted first. entityReader = new PersistentIterator( new SingleClassObjectSerializationFactory(entityMapper.getEntityClass()), new EntityTableReader(dbCtx, entityMapper, constraintTable), "nod", true ); entityTagReader = new PeekableIterator>( new PersistentIterator>( new SingleClassObjectSerializationFactory(DbFeature.class), new EntityFeatureTableReader>( dbCtx, new TagMapper(entityMapper.getEntityName()), constraintTable), "enttag", true ) ); } /** * Populates the entity with the its features. These features will be read * from related tables. * * @param entity * The entity to be populated. */ protected void populateEntityFeatures(T entity) { long entityId; entityId = entity.getId(); // Skip all tags that are from a lower entity. while (entityTagReader.hasNext()) { DbFeature dbTag; dbTag = entityTagReader.peekNext(); if (dbTag.getEntityId() < entityId) { entityTagReader.next(); } else { break; } } // Load all tags matching this version of the node. while (entityTagReader.hasNext() && entityTagReader.peekNext().getEntityId() == entityId) { entity.getTags().add(entityTagReader.next().getFeature()); } } /** * {@inheritDoc} */ public boolean hasNext() { if (!nextValueLoaded && entityReader.hasNext()) { T entity; entity = entityReader.next(); populateEntityFeatures(entity); nextValue = entity; nextValueLoaded = true; } return nextValueLoaded; } /** * {@inheritDoc} */ public T next() { T result; if (!hasNext()) { throw new NoSuchElementException(); } result = nextValue; nextValueLoaded = false; return result; } /** * {@inheritDoc} */ public void remove() { throw new UnsupportedOperationException(); } /** * {@inheritDoc} */ public void release() { entityReader.release(); entityTagReader.release(); } } EntityTableReader.java000066400000000000000000000042531253404521400361050ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.sql.ResultSet; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.pgsimple.common.BaseTableReader; import org.openstreetmap.osmosis.pgsimple.common.DatabaseContext; /** * Reads entities from a database ordered by their identifier. These entities * won't be populated with tags. * * @author Brett Henderson * @param * The entity type to be supported. */ public class EntityTableReader extends BaseTableReader { private EntityMapper entityMapper; private String sql; /** * Creates a new instance. * * @param dbCtx * The active connection to use for reading from the database. * @param entityBuilder * The entity builder implementation to utilise. */ public EntityTableReader(DatabaseContext dbCtx, EntityMapper entityBuilder) { super(dbCtx); this.entityMapper = entityBuilder; sql = entityBuilder.getSqlSelect(false, false) + " ORDER BY e.id"; } /** * Creates a new instance with a constrained search. * * @param dbCtx * The active connection to use for reading from the database. * @param entityBuilder * The entity builder implementation to utilise. * @param constraintTable * The table containing a column named id defining the list of * entities to be returned. */ public EntityTableReader(DatabaseContext dbCtx, EntityMapper entityBuilder, String constraintTable) { super(dbCtx); this.entityMapper = entityBuilder; sql = entityBuilder.getSqlSelect(false, false) + " INNER JOIN " + constraintTable + " c ON e.id = c.id" + " ORDER BY e.id"; } /** * {@inheritDoc} */ @Override protected ResultSet createResultSet(DatabaseContext queryDbCtx) { return queryDbCtx.executeQuery(sql); } /** * {@inheritDoc} */ @Override protected ReadResult createNextValue(ResultSet resultSet) { T entity; entity = entityMapper.parseRecord(resultSet); return new ReadResult(true, entity); } } IndexManager.java000066400000000000000000000133571253404521400351050ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.util.logging.Logger; import org.openstreetmap.osmosis.pgsimple.common.DatabaseContext; /** * Drops and creates indexes in support of bulk load activities. * * @author Brett Henderson */ public class IndexManager { private static final Logger LOG = Logger.getLogger(IndexManager.class.getName()); private static final String[] PRE_LOAD_SQL = { "ALTER TABLE users DROP CONSTRAINT pk_users", "ALTER TABLE nodes DROP CONSTRAINT pk_nodes", "ALTER TABLE ways DROP CONSTRAINT pk_ways", "ALTER TABLE way_nodes DROP CONSTRAINT pk_way_nodes", "ALTER TABLE relations DROP CONSTRAINT pk_relations", "ALTER TABLE relation_members DROP CONSTRAINT pk_relation_members", "DROP INDEX idx_node_tags_node_id", "DROP INDEX idx_nodes_geom", "DROP INDEX idx_way_tags_way_id", "DROP INDEX idx_relation_tags_relation_id", "DROP INDEX idx_way_nodes_node_id" }; private static final String[] PRE_LOAD_SQL_WAY_BBOX = { "DROP INDEX idx_ways_bbox" }; private static final String[] PRE_LOAD_SQL_WAY_LINESTRING = { "DROP INDEX idx_ways_linestring" }; private static final String[] POST_LOAD_SQL = { "ALTER TABLE ONLY users ADD CONSTRAINT pk_users PRIMARY KEY (id)", "ALTER TABLE ONLY nodes ADD CONSTRAINT pk_nodes PRIMARY KEY (id)", "ALTER TABLE ONLY ways ADD CONSTRAINT pk_ways PRIMARY KEY (id)", "ALTER TABLE ONLY way_nodes ADD CONSTRAINT pk_way_nodes PRIMARY KEY (way_id, sequence_id)", "ALTER TABLE ONLY relations ADD CONSTRAINT pk_relations PRIMARY KEY (id)", "ALTER TABLE ONLY relation_members ADD CONSTRAINT pk_relation_members PRIMARY KEY (relation_id, sequence_id)", "CREATE INDEX idx_node_tags_node_id ON node_tags USING btree (node_id)", "CREATE INDEX idx_nodes_geom ON nodes USING gist (geom)", "CREATE INDEX idx_way_tags_way_id ON way_tags USING btree (way_id)", "CREATE INDEX idx_relation_tags_relation_id ON relation_tags USING btree (relation_id)", "CREATE INDEX idx_way_nodes_node_id ON way_nodes USING btree (node_id)" }; private static final String[] POST_LOAD_SQL_WAY_BBOX = { "CREATE INDEX idx_ways_bbox ON ways USING gist (bbox)" }; private static final String[] POST_LOAD_SQL_WAY_LINESTRING = { "CREATE INDEX idx_ways_linestring ON ways USING gist (linestring)" }; private static final String POST_LOAD_SQL_POPULATE_WAY_BBOX = "UPDATE ways SET bbox = (" + "SELECT ST_Envelope(ST_Collect(geom)) FROM nodes JOIN way_nodes ON way_nodes.node_id = nodes.id" + " WHERE way_nodes.way_id = ways.id" + ")"; private static final String POST_LOAD_SQL_POPULATE_WAY_LINESTRING = "UPDATE ways w SET linestring = (" + "SELECT ST_MakeLine(c.geom) AS way_line FROM (" + "SELECT n.geom AS geom FROM nodes n INNER JOIN way_nodes wn ON n.id = wn.node_id" + " WHERE (wn.way_id = w.id) ORDER BY wn.sequence_id" + ") c" + ")"; private DatabaseContext dbCtx; private DatabaseCapabilityChecker capabilityChecker; private boolean populateBbox; private boolean populateLinestring; /** * Creates a new instance. * * @param dbCtx * Provides access to the database. * @param populateBbox * If true, the bbox colum on the way table will be populated * after load. * @param populateLinestring * If true, the linestring column on the way table will be * populated after load. */ public IndexManager(DatabaseContext dbCtx, boolean populateBbox, boolean populateLinestring) { this.dbCtx = dbCtx; this.populateBbox = populateBbox; this.populateLinestring = populateLinestring; capabilityChecker = new DatabaseCapabilityChecker(dbCtx); } /** * Drops indexes and constraints in the database. */ public void prepareForLoad() { LOG.fine("Running pre-load SQL statements."); for (int i = 0; i < PRE_LOAD_SQL.length; i++) { LOG.finer("SQL: " + PRE_LOAD_SQL[i]); dbCtx.executeStatement(PRE_LOAD_SQL[i]); } if (capabilityChecker.isWayBboxSupported()) { LOG.fine("Running pre-load bbox SQL statements."); for (int i = 0; i < PRE_LOAD_SQL_WAY_BBOX.length; i++) { LOG.finer("SQL: " + PRE_LOAD_SQL_WAY_BBOX[i]); dbCtx.executeStatement(PRE_LOAD_SQL_WAY_BBOX[i]); } } if (capabilityChecker.isWayLinestringSupported()) { LOG.fine("Running pre-load linestring SQL statements."); for (int i = 0; i < PRE_LOAD_SQL_WAY_LINESTRING.length; i++) { LOG.finer("SQL: " + PRE_LOAD_SQL_WAY_LINESTRING[i]); dbCtx.executeStatement(PRE_LOAD_SQL_WAY_LINESTRING[i]); } } LOG.fine("Pre-load SQL statements complete."); } /** * Creates indexes in the database and populates derived columns. */ public void completeAfterLoad() { LOG.fine("Running post-load SQL."); for (int i = 0; i < POST_LOAD_SQL.length; i++) { LOG.finer("SQL: " + POST_LOAD_SQL[i]); dbCtx.executeStatement(POST_LOAD_SQL[i]); } if (capabilityChecker.isWayBboxSupported()) { LOG.fine("Running post-load bbox SQL statements."); if (populateBbox) { LOG.finer("SQL: " + POST_LOAD_SQL_POPULATE_WAY_BBOX); dbCtx.executeStatement(POST_LOAD_SQL_POPULATE_WAY_BBOX); } for (int i = 0; i < POST_LOAD_SQL_WAY_BBOX.length; i++) { LOG.finer("SQL: " + POST_LOAD_SQL_WAY_BBOX[i]); dbCtx.executeStatement(POST_LOAD_SQL_WAY_BBOX[i]); } } if (capabilityChecker.isWayLinestringSupported()) { LOG.fine("Running post-load linestring SQL statements."); if (populateLinestring) { LOG.finer("SQL: " + POST_LOAD_SQL_POPULATE_WAY_LINESTRING); dbCtx.executeStatement(POST_LOAD_SQL_POPULATE_WAY_LINESTRING); } for (int i = 0; i < POST_LOAD_SQL_WAY_LINESTRING.length; i++) { LOG.finer("SQL: " + POST_LOAD_SQL_WAY_LINESTRING[i]); dbCtx.executeStatement(POST_LOAD_SQL_WAY_LINESTRING[i]); } } } } MemberTypeValueMapper.java000066400000000000000000000044271253404521400367540ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; /** * This is a utility class for mapping between relation member type columns and * the corresponding entity type. * * @author Brett Henderson */ public class MemberTypeValueMapper { private static Map entityToMemberMap; private static Map memberToEntityMap; private static void addEntityTypeMapping(EntityType entityType, String memberType) { if (entityToMemberMap.containsKey(entityType)) { throw new OsmosisRuntimeException("Entity type (" + entityType + ") already has a mapping."); } entityToMemberMap.put(entityType, memberType); memberToEntityMap.put(memberType, entityType); } static { EntityType[] entityTypes; entityTypes = EntityType.values(); entityToMemberMap = new HashMap(entityTypes.length); memberToEntityMap = new HashMap(entityTypes.length); addEntityTypeMapping(EntityType.Bound, "B"); addEntityTypeMapping(EntityType.Node, "N"); addEntityTypeMapping(EntityType.Way, "W"); addEntityTypeMapping(EntityType.Relation, "R"); } /** * Returns the member type value corresponding to the specified entity type. * * @param entityType * The entity type. * @return The corresponding member type value. */ public String getMemberType(EntityType entityType) { if (entityToMemberMap.containsKey(entityType)) { return entityToMemberMap.get(entityType); } else { throw new OsmosisRuntimeException("The entity type " + entityType + " is not recognised."); } } /** * Returns the entity type value corresponding to the specified member type. * * @param memberType * The member type. * @return The corresponding entity type value. */ public EntityType getEntityType(String memberType) { if (memberToEntityMap.containsKey(memberType)) { return memberToEntityMap.get(memberType); } else { throw new OsmosisRuntimeException("The member type " + memberType + " is not recognised."); } } } NodeDao.java000066400000000000000000000064401253404521400340470ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.sql.PreparedStatement; import java.sql.SQLException; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.pgsimple.common.DatabaseContext; /** * Performs all node-specific db operations. * * @author Brett Henderson */ public class NodeDao extends EntityDao { private static final String SQL_UPDATE_WAY_BBOX = "UPDATE ways w SET bbox = (" + " SELECT ST_Envelope(ST_Collect(n.geom))" + " FROM nodes n INNER JOIN way_nodes wn ON wn.node_id = n.id" + " WHERE wn.way_id = w.id" + " )" + " WHERE w.id IN (" + " SELECT w.id FROM ways w INNER JOIN way_nodes wn ON w.id = wn.way_id WHERE wn.node_id = ? GROUP BY w.id" + " )"; private static final String SQL_UPDATE_WAY_LINESTRING = "UPDATE ways w SET linestring = (" + " SELECT ST_MakeLine(c.geom) AS way_line FROM (" + " SELECT n.geom AS geom FROM nodes n INNER JOIN way_nodes wn ON n.id = wn.node_id" + " WHERE (wn.way_id = w.id) ORDER BY wn.sequence_id" + " ) c" + " )" + " WHERE w.id IN (" + " SELECT w.id FROM ways w INNER JOIN way_nodes wn ON w.id = wn.way_id WHERE wn.node_id = ? GROUP BY w.id" + " )"; private DatabaseCapabilityChecker capabilityChecker; private PreparedStatement updateWayBboxStatement; private PreparedStatement updateWayLinestringStatement; /** * Creates a new instance. * * @param dbCtx * The database context to use for accessing the database. * @param actionDao * The dao to use for adding action records to the database. */ public NodeDao(DatabaseContext dbCtx, ActionDao actionDao) { super(dbCtx, new NodeMapper(), actionDao); capabilityChecker = new DatabaseCapabilityChecker(dbCtx); } /** * {@inheritDoc} */ @Override protected void loadFeatures(long entityId, Node entity) { // Nodes have no additional features. } /** * {@inheritDoc} */ @Override public void modifyEntity(Node entity) { super.modifyEntity(entity); if (capabilityChecker.isWayBboxSupported()) { if (updateWayBboxStatement == null) { updateWayBboxStatement = prepareStatement(SQL_UPDATE_WAY_BBOX); } try { int prmIndex; prmIndex = 1; updateWayBboxStatement.setLong(prmIndex++, entity.getId()); updateWayBboxStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Update bbox failed for node " + entity.getId() + "."); } } if (capabilityChecker.isWayLinestringSupported()) { if (updateWayLinestringStatement == null) { updateWayLinestringStatement = prepareStatement(SQL_UPDATE_WAY_LINESTRING); } try { int prmIndex; prmIndex = 1; updateWayLinestringStatement.setLong(prmIndex++, entity.getId()); updateWayLinestringStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Update linestring failed for node " + entity.getId() + "."); } } } /** * {@inheritDoc} */ @Override public ReleasableIterator iterate() { return new NodeReader(getDatabaseContext()); } } NodeMapper.java000066400000000000000000000050361253404521400345700ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Date; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.pgsimple.common.PointBuilder; import org.postgis.PGgeometry; import org.postgis.Point; /** * Reads and writes node attributes to jdbc classes. * * @author Brett Henderson */ public class NodeMapper extends EntityMapper { private PointBuilder pointBuilder; /** * Creates a new instance. */ public NodeMapper() { pointBuilder = new PointBuilder(); } /** * {@inheritDoc} */ @Override public String getEntityName() { return "node"; } /** * {@inheritDoc} */ @Override public ActionDataType getEntityType() { return ActionDataType.NODE; } /** * {@inheritDoc} */ @Override public Class getEntityClass() { return Node.class; } /** * {@inheritDoc} */ @Override protected String[] getTypeSpecificFieldNames() { return new String[] {"geom"}; } /** * {@inheritDoc} */ @Override public Node parseRecord(ResultSet resultSet) { try { PGgeometry geom; Point point; geom = (PGgeometry) resultSet.getObject("geom"); point = (Point) geom.getGeometry(); return new Node( new CommonEntityData( resultSet.getLong("id"), resultSet.getInt("version"), new Date(resultSet.getTimestamp("tstamp").getTime()), buildUser(resultSet), resultSet.getLong("changeset_id") ), point.y, point.x ); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to build a node from the current recordset row.", e); } } /** * {@inheritDoc} */ @Override public int populateEntityParameters(PreparedStatement statement, int initialIndex, Node node) { int prmIndex; // Populate the entity level parameters. prmIndex = populateCommonEntityParameters(statement, initialIndex, node); try { // Set the node level parameters. statement.setObject( prmIndex++, new PGgeometry(pointBuilder.createPoint(node.getLatitude(), node.getLongitude()))); } catch (SQLException e) { throw new OsmosisRuntimeException( "Unable to set a prepared statement parameter for node " + node.getId() + ".", e); } return prmIndex; } } NodeReader.java000066400000000000000000000021471253404521400345460ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.pgsimple.common.DatabaseContext; /** * Reads all nodes from a database ordered by their identifier. It combines the * output of the node table readers to produce fully configured node objects. * * @author Brett Henderson */ public class NodeReader extends EntityReader { /** * Creates a new instance. * * @param dbCtx * The database context to use for accessing the database. */ public NodeReader(DatabaseContext dbCtx) { super(dbCtx, new NodeMapper()); } /** * Creates a new instance. * * @param dbCtx * The database context to use for accessing the database. * @param constraintTable * The table containing a column named id defining the list of * entities to be returned. */ public NodeReader(DatabaseContext dbCtx, String constraintTable) { super(dbCtx, new NodeMapper(), constraintTable); } } PostgreSqlDatasetContext.java000066400000000000000000000405651253404521400375220ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.postgis.PGgeometry; import org.postgis.Point; import org.postgis.Polygon; import org.openstreetmap.osmosis.core.OsmosisConstants; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainerIterator; import org.openstreetmap.osmosis.core.container.v0_6.DatasetContext; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityManager; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainerIterator; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainerIterator; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainerIterator; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.lifecycle.ReleasableContainer; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.pgsimple.common.DatabaseContext; import org.openstreetmap.osmosis.pgsimple.common.PolygonBuilder; import org.openstreetmap.osmosis.pgsimple.common.SchemaVersionValidator; import org.openstreetmap.osmosis.pgsimple.v0_6.PostgreSqlVersionConstants; import org.openstreetmap.osmosis.core.store.MultipleSourceIterator; import org.openstreetmap.osmosis.core.store.ReleasableAdaptorForIterator; import org.openstreetmap.osmosis.core.store.UpcastIterator; /** * Provides read-only access to a PostgreSQL dataset store. Each thread * accessing the store must create its own reader. It is important that all * iterators obtained from this reader are released before releasing the reader * itself. * * @author Brett Henderson */ public class PostgreSqlDatasetContext implements DatasetContext { private static final Logger LOG = Logger.getLogger(PostgreSqlDatasetContext.class.getName()); private DatabaseLoginCredentials loginCredentials; private DatabasePreferences preferences; private DatabaseCapabilityChecker capabilityChecker; private boolean initialized; private DatabaseContext dbCtx; private UserDao userDao; private NodeDao nodeDao; private WayDao wayDao; private RelationDao relationDao; private PostgreSqlEntityManager nodeManager; private PostgreSqlEntityManager wayManager; private PostgreSqlEntityManager relationManager; private PolygonBuilder polygonBuilder; private ReleasableContainer releasableContainer; /** * Creates a new instance. * * @param loginCredentials * Contains all information required to connect to the database. * @param preferences * Contains preferences configuring database behaviour. */ public PostgreSqlDatasetContext(DatabaseLoginCredentials loginCredentials, DatabasePreferences preferences) { this.loginCredentials = loginCredentials; this.preferences = preferences; polygonBuilder = new PolygonBuilder(); releasableContainer = new ReleasableContainer(); initialized = false; } /** * Initialises the database connection and associated data access objects. */ private void initialize() { if (dbCtx == null) { ActionDao actionDao; dbCtx = new DatabaseContext(loginCredentials); new SchemaVersionValidator(dbCtx, preferences).validateVersion( PostgreSqlVersionConstants.SCHEMA_VERSION); capabilityChecker = new DatabaseCapabilityChecker(dbCtx); actionDao = releasableContainer.add(new ActionDao(dbCtx)); userDao = releasableContainer.add(new UserDao(dbCtx, actionDao)); nodeDao = releasableContainer.add(new NodeDao(dbCtx, actionDao)); wayDao = releasableContainer.add(new WayDao(dbCtx, actionDao)); relationDao = releasableContainer.add(new RelationDao(dbCtx, actionDao)); nodeManager = new PostgreSqlEntityManager(nodeDao, userDao); wayManager = new PostgreSqlEntityManager(wayDao, userDao); relationManager = new PostgreSqlEntityManager(relationDao, userDao); } initialized = true; } /** * {@inheritDoc} */ @Override @Deprecated public Node getNode(long id) { return getNodeManager().getEntity(id); } /** * {@inheritDoc} */ @Override @Deprecated public Way getWay(long id) { return getWayManager().getEntity(id); } /** * {@inheritDoc} */ @Override @Deprecated public Relation getRelation(long id) { return getRelationManager().getEntity(id); } /** * {@inheritDoc} */ @Override public EntityManager getNodeManager() { if (!initialized) { initialize(); } return nodeManager; } /** * {@inheritDoc} */ @Override public EntityManager getWayManager() { if (!initialized) { initialize(); } return wayManager; } /** * {@inheritDoc} */ @Override public EntityManager getRelationManager() { if (!initialized) { initialize(); } return relationManager; } /** * {@inheritDoc} */ @Override public ReleasableIterator iterate() { List bounds; List> sources; if (!initialized) { initialize(); } // Build the bounds list. bounds = new ArrayList(); bounds.add(new Bound("Osmosis " + OsmosisConstants.VERSION)); sources = new ArrayList>(); sources.add(new UpcastIterator( new BoundContainerIterator(new ReleasableAdaptorForIterator(bounds.iterator())))); sources.add(new UpcastIterator( new NodeContainerIterator(nodeDao.iterate()))); sources.add(new UpcastIterator( new WayContainerIterator(wayDao.iterate()))); sources.add(new UpcastIterator( new RelationContainerIterator(relationDao.iterate()))); return new MultipleSourceIterator(sources); } /** * {@inheritDoc} */ @Override public ReleasableIterator iterateBoundingBox( double left, double right, double top, double bottom, boolean completeWays) { List bounds; PreparedStatement preparedStatement = null; int prmIndex; Point[] bboxPoints; Polygon bboxPolygon; MemberTypeValueMapper memberTypeValueMapper; int rowCount; List> resultSets; if (!initialized) { initialize(); } // Build the bounds list. bounds = new ArrayList(); bounds.add(new Bound(right, left, top, bottom, "Osmosis " + OsmosisConstants.VERSION)); try { // PostgreSQL sometimes incorrectly chooses to perform full table scans, these options // prevent this. Note that this is not recommended practice according to documentation // but fixing this would require modifying the table statistics gathering // configuration to produce better plans. dbCtx.executeStatement("SET enable_seqscan = false"); dbCtx.executeStatement("SET enable_mergejoin = false"); dbCtx.executeStatement("SET enable_hashjoin = false"); // Create a temporary table capable of holding node ids. LOG.finer("Creating node id temp table."); dbCtx.executeStatement("CREATE TEMPORARY TABLE box_node_list (id bigint PRIMARY KEY) ON COMMIT DROP"); // Create a temporary table capable of holding way ids. LOG.finer("Creating way id temp table."); dbCtx.executeStatement("CREATE TEMPORARY TABLE box_way_list (id bigint PRIMARY KEY) ON COMMIT DROP"); // Create a temporary table capable of holding relation ids. LOG.finer("Creating relation id temp table."); dbCtx.executeStatement("CREATE TEMPORARY TABLE box_relation_list (id bigint PRIMARY KEY) ON COMMIT DROP"); // Build a polygon representing the bounding box. // Sample box for query testing may be: // GeomFromText('POLYGON((144.93912192855174 -37.82981987499741, // 144.93912192855174 -37.79310006709244, 144.98188026000003 // -37.79310006709244, 144.98188026000003 -37.82981987499741, // 144.93912192855174 -37.82981987499741))', -1) bboxPoints = new Point[5]; bboxPoints[0] = new Point(left, bottom); bboxPoints[1] = new Point(left, top); bboxPoints[2] = new Point(right, top); bboxPoints[3] = new Point(right, bottom); bboxPoints[4] = new Point(left, bottom); bboxPolygon = polygonBuilder.createPolygon(bboxPoints); // Instantiate the mapper for converting between entity types and // member type values. memberTypeValueMapper = new MemberTypeValueMapper(); // Select all nodes inside the box into the node temp table. LOG.finer("Selecting all node ids inside bounding box."); preparedStatement = dbCtx.prepareStatement( "INSERT INTO box_node_list SELECT id FROM nodes WHERE (geom && ?)"); prmIndex = 1; preparedStatement.setObject(prmIndex++, new PGgeometry(bboxPolygon)); rowCount = preparedStatement.executeUpdate(); preparedStatement.close(); preparedStatement = null; LOG.finer(rowCount + " rows affected."); // Select all ways inside the bounding box into the way temp table. if (capabilityChecker.isWayLinestringSupported()) { LOG.finer("Selecting all way ids inside bounding box using way linestring geometry."); // We have full way geometry available so select ways // overlapping the requested bounding box. preparedStatement = dbCtx.prepareStatement( "INSERT INTO box_way_list " + "SELECT id FROM ways w where w.linestring && ?" ); prmIndex = 1; preparedStatement.setObject(prmIndex++, new PGgeometry(bboxPolygon)); } else if (capabilityChecker.isWayBboxSupported()) { LOG.finer("Selecting all way ids inside bounding box using dynamically built" + " way linestring with way bbox indexing."); // The inner query selects the way id and node coordinates for // all ways constrained by the way bounding box which is // indexed. // The middle query converts the way node coordinates into // linestrings. // The outer query constrains the query to the linestrings // inside the bounding box. These aren't indexed but the inner // query way bbox constraint will minimise the unnecessary data. preparedStatement = dbCtx.prepareStatement( "INSERT INTO box_way_list " + "SELECT way_id FROM (" + "SELECT c.way_id AS way_id, ST_MakeLine(c.geom) AS way_line FROM (" + "SELECT w.id AS way_id, n.geom AS geom FROM nodes n" + " INNER JOIN way_nodes wn ON n.id = wn.node_id" + " INNER JOIN ways w ON wn.way_id = w.id" + " WHERE (w.bbox && ?) ORDER BY wn.way_id, wn.sequence_id" + ") c " + "GROUP BY c.way_id" + ") w " + "WHERE (w.way_line && ?)" ); prmIndex = 1; preparedStatement.setObject(prmIndex++, new PGgeometry(bboxPolygon)); preparedStatement.setObject(prmIndex++, new PGgeometry(bboxPolygon)); } else { LOG.finer("Selecting all way ids inside bounding box using already selected nodes."); // No way bbox support is available so select ways containing // the selected nodes. preparedStatement = dbCtx.prepareStatement( "INSERT INTO box_way_list " + "SELECT wn.way_id FROM way_nodes wn INNER JOIN box_node_list n ON wn.node_id = n.id" + " GROUP BY wn.way_id" ); } rowCount = preparedStatement.executeUpdate(); preparedStatement.close(); preparedStatement = null; LOG.finer(rowCount + " rows affected."); // Select all relations containing the nodes or ways into the relation table. LOG.finer("Selecting all relation ids containing selected nodes or ways."); preparedStatement = dbCtx.prepareStatement( "INSERT INTO box_relation_list (" + "SELECT rm.relation_id AS relation_id FROM relation_members rm" + " INNER JOIN box_node_list n ON rm.member_id = n.id WHERE rm.member_type = ? " + "UNION " + "SELECT rm.relation_id AS relation_id FROM relation_members rm" + " INNER JOIN box_way_list w ON rm.member_id = w.id WHERE rm.member_type = ?" + ")" ); prmIndex = 1; preparedStatement.setString(prmIndex++, memberTypeValueMapper.getMemberType(EntityType.Node)); preparedStatement.setString(prmIndex++, memberTypeValueMapper.getMemberType(EntityType.Way)); rowCount = preparedStatement.executeUpdate(); preparedStatement.close(); preparedStatement = null; LOG.finer(rowCount + " rows affected."); // Include all relations containing the current relations into the // relation table and repeat until no more inclusions occur. do { LOG.finer("Selecting parent relations of selected relations."); preparedStatement = dbCtx.prepareStatement( "INSERT INTO box_relation_list " + "SELECT rm.relation_id AS relation_id FROM relation_members rm" + " INNER JOIN box_relation_list r ON rm.member_id = r.id WHERE rm.member_type = ? " + "EXCEPT " + "SELECT id AS relation_id FROM box_relation_list" ); prmIndex = 1; preparedStatement.setString(prmIndex++, memberTypeValueMapper.getMemberType(EntityType.Relation)); rowCount = preparedStatement.executeUpdate(); preparedStatement.close(); preparedStatement = null; LOG.finer(rowCount + " rows affected."); } while (rowCount > 0); // If complete ways is set, select all nodes contained by the ways into the node temp table. if (completeWays) { LOG.finer("Selecting all node ids for selected ways."); preparedStatement = dbCtx.prepareStatement( "INSERT INTO box_node_list " + "SELECT wn.node_id AS id FROM way_nodes wn INNER JOIN box_way_list bw ON wn.way_id = bw.id " + "EXCEPT " + "SELECT id AS node_id FROM box_node_list" ); prmIndex = 1; rowCount = preparedStatement.executeUpdate(); preparedStatement.close(); preparedStatement = null; LOG.finer(rowCount + " rows affected."); } // Analyse the temporary tables to give the query planner the best chance of producing good queries. dbCtx.executeStatement("ANALYZE box_node_list"); dbCtx.executeStatement("ANALYZE box_way_list"); dbCtx.executeStatement("ANALYZE box_relation_list"); // Create iterators for the selected records for each of the entity types. LOG.finer("Iterating over results."); resultSets = new ArrayList>(); resultSets.add( new UpcastIterator( new BoundContainerIterator(new ReleasableAdaptorForIterator(bounds.iterator())))); resultSets.add( new UpcastIterator( new NodeContainerIterator(new NodeReader(dbCtx, "box_node_list")))); resultSets.add( new UpcastIterator( new WayContainerIterator(new WayReader(dbCtx, "box_way_list")))); resultSets.add( new UpcastIterator( new RelationContainerIterator(new RelationReader(dbCtx, "box_relation_list")))); // Merge all readers into a single result iterator and return. return new MultipleSourceIterator(resultSets); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to perform bounding box queries.", e); } finally { if (preparedStatement != null) { try { preparedStatement.close(); } catch (SQLException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to close prepared statement.", e); } } } } /** * {@inheritDoc} */ @Override public void complete() { if (dbCtx != null) { dbCtx.commit(); } } /** * {@inheritDoc} */ @Override public void release() { releasableContainer.release(); releasableContainer.clear(); if (dbCtx != null) { dbCtx.release(); dbCtx = null; } } } PostgreSqlEntityManager.java000066400000000000000000000053201253404521400373250ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.util.HashSet; import java.util.Set; import org.openstreetmap.osmosis.core.container.v0_6.EntityManager; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.pgsimple.common.NoSuchRecordException; /** * Provides postgres entity manager support allowing entities to be manipulated via a common dataset * interface. * * @author Brett Henderson * * @param * The entity type to be supported. */ public class PostgreSqlEntityManager implements EntityManager { private EntityDao entityDao; private UserDao userDao; private Set userSet; /** * Creates a new instance. * * @param entityDao * The dao allowing manipulation of a specific entity type. * @param userDao * The user dao allowing user entries to be updated or created. */ public PostgreSqlEntityManager(EntityDao entityDao, UserDao userDao) { this.entityDao = entityDao; this.userDao = userDao; userSet = new HashSet(); } /** * Writes the specified user to the database. * * @param user * The user to write. */ private void writeUser(OsmUser user) { // Entities without a user assigned should not be written. if (!OsmUser.NONE.equals(user)) { // Users will only be updated in the database once per changeset // run. if (!userSet.contains(user.getId())) { int userId; OsmUser existingUser; userId = user.getId(); try { existingUser = userDao.getUser(userId); if (!user.equals(existingUser)) { userDao.updateUser(user); } } catch (NoSuchRecordException e) { userDao.addUser(user); } userSet.add(user.getId()); } } } /** * {@inheritDoc} */ @Override public void addEntity(T entity) { writeUser(entity.getUser()); entityDao.addEntity(entity); } /** * {@inheritDoc} */ @Override public boolean exists(long id) { return entityDao.exists(id); } /** * {@inheritDoc} */ @Override public T getEntity(long id) { return entityDao.getEntity(id); } /** * {@inheritDoc} */ @Override public ReleasableIterator iterate() { return entityDao.iterate(); } /** * {@inheritDoc} */ @Override public void modifyEntity(T entity) { writeUser(entity.getUser()); entityDao.modifyEntity(entity); } /** * {@inheritDoc} */ @Override public void removeEntity(long entityId) { entityDao.removeEntity(entityId); } } RelationDao.java000066400000000000000000000053521253404521400347400ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.util.ArrayList; import java.util.List; import org.openstreetmap.osmosis.core.database.DbOrderedFeature; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.pgsimple.common.DatabaseContext; /** * Performs all relation-specific db operations. * * @author Brett Henderson */ public class RelationDao extends EntityDao { private EntityFeatureDao> relationMemberDao; /** * Creates a new instance. * * @param dbCtx * The database context to use for accessing the database. * @param actionDao * The dao to use for adding action records to the database. */ public RelationDao(DatabaseContext dbCtx, ActionDao actionDao) { super(dbCtx, new RelationMapper(), actionDao); relationMemberDao = new EntityFeatureDao>( dbCtx, new RelationMemberMapper()); } /** * {@inheritDoc} */ @Override protected void loadFeatures(long entityId, Relation entity) { entity.getMembers().addAll(relationMemberDao.getAllRaw(entityId)); } /** * Adds the specified relation member list to the database. * * @param entityId * The identifier of the entity to add these features to. * @param memberList * The list of features to add. */ private void addMembers(long entityId, List memberList) { List> dbList; dbList = new ArrayList>(memberList.size()); for (int i = 0; i < memberList.size(); i++) { dbList.add(new DbOrderedFeature(entityId, memberList.get(i), i)); } relationMemberDao.addAll(dbList); } /** * {@inheritDoc} */ @Override public void addEntity(Relation entity) { super.addEntity(entity); addMembers(entity.getId(), entity.getMembers()); } /** * {@inheritDoc} */ @Override public void modifyEntity(Relation entity) { long relationId; super.modifyEntity(entity); relationId = entity.getId(); relationMemberDao.removeList(relationId); addMembers(entity.getId(), entity.getMembers()); } /** * {@inheritDoc} */ @Override public void removeEntity(long entityId) { relationMemberDao.removeList(entityId); super.removeEntity(entityId); } /** * {@inheritDoc} */ @Override public ReleasableIterator iterate() { return new RelationReader(getDatabaseContext()); } } RelationMapper.java000066400000000000000000000034441253404521400354610ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Date; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; /** * Reads and writes relation attributes to jdbc classes. * * @author Brett Henderson */ public class RelationMapper extends EntityMapper { /** * {@inheritDoc} */ @Override public String getEntityName() { return "relation"; } /** * {@inheritDoc} */ @Override public ActionDataType getEntityType() { return ActionDataType.RELATION; } /** * {@inheritDoc} */ @Override public Class getEntityClass() { return Relation.class; } /** * {@inheritDoc} */ @Override protected String[] getTypeSpecificFieldNames() { return new String[] {}; } /** * {@inheritDoc} */ @Override public Relation parseRecord(ResultSet resultSet) { try { return new Relation( new CommonEntityData( resultSet.getLong("id"), resultSet.getInt("version"), new Date(resultSet.getTimestamp("tstamp").getTime()), buildUser(resultSet), resultSet.getLong("changeset_id") ) ); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to build a relation from the current recordset row.", e); } } /** * {@inheritDoc} */ @Override public int populateEntityParameters(PreparedStatement statement, int initialIndex, Relation relation) { // Populate the entity level parameters. return populateCommonEntityParameters(statement, initialIndex, relation); } } RelationMemberMapper.java000066400000000000000000000076371253404521400366210ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.database.DbOrderedFeature; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; /** * Reads and writes relation members to jdbc classes. * * @author Brett Henderson */ public class RelationMemberMapper extends EntityFeatureMapper> { private MemberTypeValueMapper memberTypeValueMapper; /** * Creates a new instance. */ public RelationMemberMapper() { memberTypeValueMapper = new MemberTypeValueMapper(); } /** * {@inheritDoc} */ @Override public String getParentEntityName() { return "relation"; } /** * {@inheritDoc} */ @Override public String getEntityName() { return "relation_members"; } /** * {@inheritDoc} */ @Override public String getSqlSelect(boolean filterByEntityId, boolean orderBy) { StringBuilder resultSql; resultSql = new StringBuilder(); resultSql.append("SELECT relation_id AS entity_id, member_id, member_type, member_role, sequence_id FROM "); resultSql.append("relation_members f"); if (filterByEntityId) { resultSql.append(" WHERE entity_id = ?"); } if (orderBy) { resultSql.append(getSqlDefaultOrderBy()); } return resultSql.toString(); } /** * {@inheritDoc} */ @Override public String getSqlDefaultOrderBy() { return super.getSqlDefaultOrderBy() + ", sequence_id"; } /** * {@inheritDoc} */ @Override public String getSqlInsert(int rowCount) { StringBuilder resultSql; resultSql = new StringBuilder(); resultSql.append("INSERT INTO relation_members ("); resultSql.append("relation_id, member_id, member_type, member_role, sequence_id) VALUES "); for (int row = 0; row < rowCount; row++) { if (row > 0) { resultSql.append(", "); } resultSql.append("(?, ?, ?, ?, ?)"); } return resultSql.toString(); } /** * {@inheritDoc} */ @Override public String getSqlDelete(boolean filterByEntityId) { StringBuilder resultSql; resultSql = new StringBuilder(); resultSql.append("DELETE FROM relation_members"); if (filterByEntityId) { resultSql.append(" WHERE ").append("relation_id = ?"); } return resultSql.toString(); } /** * {@inheritDoc} */ @Override public DbOrderedFeature buildEntity(ResultSet resultSet) { try { return new DbOrderedFeature( resultSet.getLong("entity_id"), new RelationMember( resultSet.getLong("member_id"), memberTypeValueMapper.getEntityType(resultSet.getString("member_type")), resultSet.getString("member_role") ), resultSet.getInt("sequence_id") ); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to build a relation member from the current recordset row.", e); } } /** * {@inheritDoc} */ @Override public int populateEntityParameters( PreparedStatement statement, int initialIndex, DbOrderedFeature entityFeature) { try { int prmIndex; RelationMember relationMember; relationMember = entityFeature.getFeature(); prmIndex = initialIndex; statement.setLong(prmIndex++, entityFeature.getEntityId()); statement.setLong(prmIndex++, relationMember.getMemberId()); statement.setString(prmIndex++, memberTypeValueMapper.getMemberType(relationMember.getMemberType())); statement.setString(prmIndex++, relationMember.getMemberRole()); statement.setInt(prmIndex++, entityFeature.getSequenceId()); return prmIndex; } catch (SQLException e) { throw new OsmosisRuntimeException( "Unable to populate relation member parameters for relation " + entityFeature.getEntityId() + ".", e ); } } } RelationReader.java000066400000000000000000000060501253404521400354330ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.util.ArrayList; import java.util.List; import org.openstreetmap.osmosis.core.database.DbFeature; import org.openstreetmap.osmosis.core.database.DbOrderedFeature; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.core.store.PeekableIterator; import org.openstreetmap.osmosis.pgsimple.common.DatabaseContext; /** * Reads all relations from a database ordered by their identifier. It combines the * output of the relation table readers to produce fully configured relation objects. * * @author Brett Henderson */ public class RelationReader extends EntityReader { private PeekableIterator> relationMemberReader; /** * Creates a new instance. * * @param dbCtx * The database context to use for accessing the database. */ public RelationReader(DatabaseContext dbCtx) { super(dbCtx, new RelationMapper()); relationMemberReader = new PeekableIterator>( new EntityFeatureTableReader>( dbCtx, new RelationMemberMapper()) ); } /** * Creates a new instance. * * @param dbCtx * The database context to use for accessing the database. * @param constraintTable * The table containing a column named id defining the list of * entities to be returned. */ public RelationReader(DatabaseContext dbCtx, String constraintTable) { super(dbCtx, new RelationMapper(), constraintTable); relationMemberReader = new PeekableIterator>( new EntityFeatureTableReader>( dbCtx, new RelationMemberMapper(), constraintTable) ); } /** * {@inheritDoc} */ @Override protected void populateEntityFeatures(Relation entity) { long relationId; List> relationMembers; super.populateEntityFeatures(entity); relationId = entity.getId(); // Skip all relation members that are from a lower relation. while (relationMemberReader.hasNext()) { DbFeature wayNode; wayNode = relationMemberReader.peekNext(); if (wayNode.getEntityId() < relationId) { relationMemberReader.next(); } else { break; } } // Load all members matching this version of the relation. relationMembers = new ArrayList>(); while (relationMemberReader.hasNext() && relationMemberReader.peekNext().getEntityId() == relationId) { relationMembers.add(relationMemberReader.next()); } for (DbFeature dbRelationMember : relationMembers) { entity.getMembers().add(dbRelationMember.getFeature()); } } /** * {@inheritDoc} */ @Override public void release() { super.release(); relationMemberReader.release(); } } TagMapper.java000066400000000000000000000067721253404521400344260ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.database.DbFeature; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; /** * Reads and writes tags to jdbc classes. * * @author Brett Henderson */ public class TagMapper extends EntityFeatureMapper> { private String parentEntityName; /** * Creates a new instance. * * @param parentEntityName * The name of the parent entity. This is used to generate SQL * statements for the correct tag table name. */ public TagMapper(String parentEntityName) { this.parentEntityName = parentEntityName; } /** * {@inheritDoc} */ @Override public String getParentEntityName() { return parentEntityName; } /** * {@inheritDoc} */ @Override public String getEntityName() { return parentEntityName + "_tags"; } /** * {@inheritDoc} */ @Override public String getSqlSelect(boolean filterByEntityId, boolean orderBy) { StringBuilder resultSql; resultSql = new StringBuilder(); resultSql.append("SELECT ").append(parentEntityName).append("_id AS entity_id, k, v FROM "); resultSql.append(parentEntityName).append("_tags f"); if (filterByEntityId) { resultSql.append(" WHERE ").append(parentEntityName).append("_id = ?"); } if (orderBy) { resultSql.append(getSqlDefaultOrderBy()); } return resultSql.toString(); } /** * {@inheritDoc} */ @Override public String getSqlInsert(int rowCount) { StringBuilder resultSql; resultSql = new StringBuilder(); resultSql.append("INSERT INTO ").append(parentEntityName).append("_tags ("); resultSql.append(parentEntityName).append("_id, k, v) VALUES "); for (int row = 0; row < rowCount; row++) { if (row > 0) { resultSql.append(", "); } resultSql.append("(?, ?, ?)"); } return resultSql.toString(); } /** * {@inheritDoc} */ @Override public String getSqlDelete(boolean filterByEntityId) { StringBuilder resultSql; resultSql = new StringBuilder(); resultSql.append("DELETE FROM ").append(parentEntityName).append("_tags"); if (filterByEntityId) { resultSql.append(" WHERE ").append(parentEntityName).append("_id = ?"); } return resultSql.toString(); } /** * {@inheritDoc} */ @Override public DbFeature buildEntity(ResultSet resultSet) { try { return new DbFeature( resultSet.getLong("entity_id"), new Tag( resultSet.getString("k"), resultSet.getString("v") ) ); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to build a tag from the current recordset row.", e); } } /** * {@inheritDoc} */ @Override public int populateEntityParameters(PreparedStatement statement, int initialIndex, DbFeature entityFeature) { try { int prmIndex; Tag tag; tag = entityFeature.getFeature(); prmIndex = initialIndex; statement.setLong(prmIndex++, entityFeature.getEntityId()); statement.setString(prmIndex++, tag.getKey()); statement.setString(prmIndex++, tag.getValue()); return prmIndex; } catch (SQLException e) { throw new OsmosisRuntimeException( "Unable to populate tag parameters for entity " + parentEntityName + " " + entityFeature.getEntityId() + "." ); } } } TempCopyFileset.java000066400000000000000000000061441253404521400356130ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.lifecycle.Releasable; /** * A COPY fileset implementation that uses temporary files. * * @author Brett Henderson * */ public class TempCopyFileset implements CopyFileset, Releasable { private static final Logger LOG = Logger.getLogger(TempCopyFileset.class.getName()); private ArrayList tmpFiles; private File userFile; private File nodeFile; private File nodeTagFile; private File wayFile; private File wayTagFile; private File wayNodeFile; private File relationFile; private File relationTagFile; private File relationMemberFile; private boolean initialized; /** * Creates a new instance. */ public TempCopyFileset() { tmpFiles = new ArrayList(); initialized = false; } private File createTempFile(String suffix) { try { File tmpFile; tmpFile = File.createTempFile("copy", suffix); tmpFiles.add(tmpFile); return tmpFile; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to create COPY temp file.", e); } } private void initialize() { if (!initialized) { userFile = createTempFile("u"); nodeFile = createTempFile("n"); nodeTagFile = createTempFile("nt"); wayFile = createTempFile("w"); wayTagFile = createTempFile("wt"); wayNodeFile = createTempFile("wn"); relationFile = createTempFile("r"); relationTagFile = createTempFile("rt"); relationMemberFile = createTempFile("rm"); initialized = true; } } /** * {@inheritDoc} */ @Override public File getNodeFile() { initialize(); return nodeFile; } /** * {@inheritDoc} */ @Override public File getNodeTagFile() { initialize(); return nodeTagFile; } /** * {@inheritDoc} */ @Override public File getRelationFile() { initialize(); return relationFile; } /** * {@inheritDoc} */ @Override public File getRelationMemberFile() { initialize(); return relationMemberFile; } /** * {@inheritDoc} */ @Override public File getRelationTagFile() { initialize(); return relationTagFile; } /** * {@inheritDoc} */ @Override public File getUserFile() { initialize(); return userFile; } /** * {@inheritDoc} */ @Override public File getWayFile() { initialize(); return wayFile; } /** * {@inheritDoc} */ @Override public File getWayNodeFile() { initialize(); return wayNodeFile; } /** * {@inheritDoc} */ @Override public File getWayTagFile() { initialize(); return wayTagFile; } /** * {@inheritDoc} */ @Override public void release() { for (File tmpFile : tmpFiles) { if (!tmpFile.delete()) { // We cannot throw an exception within a release statement. LOG.warning("Unable to delete file " + tmpFile); } } tmpFiles.clear(); initialized = false; } } UserDao.java000066400000000000000000000105321253404521400340750ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.pgsimple.common.BaseDao; import org.openstreetmap.osmosis.pgsimple.common.DatabaseContext; import org.openstreetmap.osmosis.pgsimple.common.NoSuchRecordException; /** * Performs all user-specific db operations. * * @author Brett Henderson */ public class UserDao extends BaseDao { private static final Logger LOG = Logger.getLogger(UserDao.class.getName()); private static final String SELECT_USER = "SELECT id, name FROM users WHERE id = ?"; private static final String INSERT_USER = "INSERT INTO users(id, name) VALUES(?, ?)"; private static final String UPDATE_USER = "UPDATE users SET name = ? WHERE id = ?"; private PreparedStatement selectUserStatement; private PreparedStatement insertUserStatement; private PreparedStatement updateUserStatement; private ActionDao actionDao; /** * Creates a new instance. * * @param dbCtx * The database context to use for accessing the database. * @param actionDao * The dao to use for adding action records to the database. */ public UserDao(DatabaseContext dbCtx, ActionDao actionDao) { super(dbCtx); this.actionDao = actionDao; } /** * Builds a user from the current result set row. * * @param resultSet * The result set. * @return The newly loaded user. */ private OsmUser buildUser(ResultSet resultSet) { try { return new OsmUser( resultSet.getInt("id"), resultSet.getString("name") ); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to build a user from the current recordset row.", e); } } /** * Loads the specified way from the database. * * @param userId * The unique identifier of the user. * @return The loaded user. */ public OsmUser getUser(long userId) { ResultSet resultSet = null; OsmUser user; if (selectUserStatement == null) { selectUserStatement = prepareStatement(SELECT_USER); } try { selectUserStatement.setLong(1, userId); resultSet = selectUserStatement.executeQuery(); if (!resultSet.next()) { throw new NoSuchRecordException("User " + userId + " doesn't exist."); } user = buildUser(resultSet); resultSet.close(); resultSet = null; return user; } catch (SQLException e) { throw new OsmosisRuntimeException("Query failed for user " + userId + "."); } finally { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to close the result set.", e); } } } } /** * Adds the specified user to the database. * * @param user * The user to add. */ public void addUser(OsmUser user) { int prmIndex; if (insertUserStatement == null) { insertUserStatement = prepareStatement(INSERT_USER); } prmIndex = 1; try { insertUserStatement.setInt(prmIndex++, user.getId()); insertUserStatement.setString(prmIndex++, user.getName()); insertUserStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException( "Unable to insert user " + user.getId() + ".", e); } actionDao.addAction(ActionDataType.USER, ChangesetAction.CREATE, user.getId()); } /** * Updates the specified user record in the database. * * @param user * The user to update. */ public void updateUser(OsmUser user) { int prmIndex; if (updateUserStatement == null) { updateUserStatement = prepareStatement(UPDATE_USER); } prmIndex = 1; try { updateUserStatement.setString(prmIndex++, user.getName()); updateUserStatement.setInt(prmIndex++, user.getId()); updateUserStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException( "Unable to update user " + user.getId() + ".", e); } actionDao.addAction(ActionDataType.USER, ChangesetAction.MODIFY, user.getId()); } } WayDao.java000066400000000000000000000112351253404521400337200ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.database.DbOrderedFeature; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.pgsimple.common.DatabaseContext; /** * Performs all way-specific db operations. * * @author Brett Henderson */ public class WayDao extends EntityDao { private static final String SQL_UPDATE_WAY_BBOX = "UPDATE ways SET bbox = (" + " SELECT ST_Envelope(ST_Collect(geom))" + " FROM nodes JOIN way_nodes ON way_nodes.node_id = nodes.id" + " WHERE way_nodes.way_id = ways.id" + " )" + " WHERE ways.id = ?"; private static final String SQL_UPDATE_WAY_LINESTRING = "UPDATE ways w SET linestring = (" + " SELECT ST_MakeLine(c.geom) AS way_line FROM (" + " SELECT n.geom AS geom FROM nodes n INNER JOIN way_nodes wn ON n.id = wn.node_id" + " WHERE (wn.way_id = w.id) ORDER BY wn.sequence_id" + " ) c" + " )" + " WHERE w.id = ?"; private DatabaseCapabilityChecker capabilityChecker; private EntityFeatureDao> wayNodeDao; private PreparedStatement updateWayBboxStatement; private PreparedStatement updateWayLinestringStatement; /** * Creates a new instance. * * @param dbCtx * The database context to use for accessing the database. * @param actionDao * The dao to use for adding action records to the database. */ public WayDao(DatabaseContext dbCtx, ActionDao actionDao) { super(dbCtx, new WayMapper(), actionDao); capabilityChecker = new DatabaseCapabilityChecker(dbCtx); wayNodeDao = new EntityFeatureDao>(dbCtx, new WayNodeMapper()); } /** * {@inheritDoc} */ @Override protected void loadFeatures(long entityId, Way entity) { entity.getWayNodes().addAll(wayNodeDao.getAllRaw(entityId)); } /** * Adds the specified way node list to the database. * * @param entityId * The identifier of the entity to add these features to. * @param wayNodeList * The list of features to add. */ private void addWayNodeList(long entityId, List wayNodeList) { List> dbList; dbList = new ArrayList>(wayNodeList.size()); for (int i = 0; i < wayNodeList.size(); i++) { dbList.add(new DbOrderedFeature(entityId, wayNodeList.get(i), i)); } wayNodeDao.addAll(dbList); } /** * Updates the bounding box column for the specified way. * * @param wayId * The way bounding box. */ private void updateWayGeometries(long wayId) { if (capabilityChecker.isWayBboxSupported()) { if (updateWayBboxStatement == null) { updateWayBboxStatement = prepareStatement(SQL_UPDATE_WAY_BBOX); } try { int prmIndex; prmIndex = 1; updateWayBboxStatement.setLong(prmIndex++, wayId); updateWayBboxStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Update bbox failed for way " + wayId + "."); } } if (capabilityChecker.isWayLinestringSupported()) { if (updateWayLinestringStatement == null) { updateWayLinestringStatement = prepareStatement(SQL_UPDATE_WAY_LINESTRING); } try { int prmIndex; prmIndex = 1; updateWayLinestringStatement.setLong(prmIndex++, wayId); updateWayLinestringStatement.executeUpdate(); } catch (SQLException e) { throw new OsmosisRuntimeException("Update linestring failed for way " + wayId + "."); } } } /** * {@inheritDoc} */ @Override public void addEntity(Way entity) { super.addEntity(entity); addWayNodeList(entity.getId(), entity.getWayNodes()); updateWayGeometries(entity.getId()); } /** * {@inheritDoc} */ @Override public void modifyEntity(Way entity) { long wayId; super.modifyEntity(entity); wayId = entity.getId(); wayNodeDao.removeList(wayId); addWayNodeList(entity.getId(), entity.getWayNodes()); updateWayGeometries(entity.getId()); } /** * {@inheritDoc} */ @Override public void removeEntity(long entityId) { wayNodeDao.removeList(entityId); super.removeEntity(entityId); } /** * {@inheritDoc} */ @Override public ReleasableIterator iterate() { return new WayReader(getDatabaseContext()); } } WayGeometryBuilder.java000066400000000000000000000136111253404521400363170ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.util.ArrayList; import java.util.List; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.openstreetmap.osmosis.core.lifecycle.Releasable; import org.openstreetmap.osmosis.pgsimple.common.CompactPersistentNodeLocationStore; import org.openstreetmap.osmosis.pgsimple.common.InMemoryNodeLocationStore; import org.openstreetmap.osmosis.pgsimple.common.NodeLocation; import org.openstreetmap.osmosis.pgsimple.common.NodeLocationStore; import org.openstreetmap.osmosis.pgsimple.common.NodeLocationStoreType; import org.openstreetmap.osmosis.pgsimple.common.PersistentNodeLocationStore; import org.postgis.LineString; import org.postgis.LinearRing; import org.postgis.Point; import org.postgis.Polygon; /** * Caches a set of node latitudes and longitudes and uses these to calculate the * geometries for ways. * * @author Brett Henderson */ public class WayGeometryBuilder implements Releasable { /** * Stores the locations of nodes so that they can be used to build the way * geometries. */ protected NodeLocationStore locationStore; /** * Creates a new instance. * * @param storeType * The type of storage to use for holding node locations. */ public WayGeometryBuilder(NodeLocationStoreType storeType) { if (NodeLocationStoreType.InMemory.equals(storeType)) { locationStore = new InMemoryNodeLocationStore(); } else if (NodeLocationStoreType.TempFile.equals(storeType)) { locationStore = new PersistentNodeLocationStore(); } else if (NodeLocationStoreType.CompactTempFile.equals(storeType)) { locationStore = new CompactPersistentNodeLocationStore(); } else { throw new OsmosisRuntimeException("The store type " + storeType + " is not recognized."); } } /** * Adds the location of the node to the internal store. * * @param node * The node to add. */ public void addNodeLocation(Node node) { locationStore.addLocation(node.getId(), new NodeLocation(node.getLongitude(), node.getLatitude())); } /** * Get NodeLocation from internal store. * * @param nodeId * Id of the node we want the location for. * @return Location of node */ public NodeLocation getNodeLocation(long nodeId) { return locationStore.getNodeLocation(nodeId); } private Polygon createWayBbox(double left, double right, double bottom, double top) { Point[] points; LinearRing ring; Polygon bbox; points = new Point[5]; points[0] = new Point(left, bottom); points[1] = new Point(left, top); points[2] = new Point(right, top); points[3] = new Point(right, bottom); points[4] = new Point(left, bottom); ring = new LinearRing(points); bbox = new Polygon(new LinearRing[] {ring}); bbox.srid = 4326; return bbox; } /** * Creates a linestring from a list of points. * * @param points * The points making up the line. * @return The linestring. */ public LineString createLinestring(List points) { LineString lineString; lineString = new LineString(points.toArray(new Point[]{})); lineString.srid = 4326; return lineString; } /** * @param nodeId * Id of the node. * @return Point object */ public Point createPoint(long nodeId) { NodeLocation nodeLocation = locationStore.getNodeLocation(nodeId); Point point = new Point(nodeLocation.getLongitude(), nodeLocation.getLatitude()); point.srid = 4326; return point; } /** * Builds a bounding box geometry object from the node references in the * specified way. Unknown nodes will be ignored. * * @param way * The way to create the bounding box for. * @return The bounding box surrounding the way. */ public Polygon createWayBbox(Way way) { double left; double right; double top; double bottom; boolean nodesFound; nodesFound = false; left = 0; right = 0; bottom = 0; top = 0; for (WayNode wayNode : way.getWayNodes()) { NodeLocation nodeLocation; double longitude; double latitude; nodeLocation = locationStore.getNodeLocation(wayNode.getNodeId()); longitude = nodeLocation.getLongitude(); latitude = nodeLocation.getLatitude(); if (nodeLocation.isValid()) { if (nodesFound) { if (longitude < left) { left = longitude; } if (longitude > right) { right = longitude; } if (latitude < bottom) { bottom = latitude; } if (latitude > top) { top = latitude; } } else { left = longitude; right = longitude; bottom = latitude; top = latitude; nodesFound = true; } } } return createWayBbox(left, right, bottom, top); } /** * Builds a linestring geometry object from the node references in the * specified way. Unknown nodes will be ignored. * * @param way * The way to create the linestring for. * @return The linestring representing the way. */ public LineString createWayLinestring(Way way) { List linePoints; int numValidNodes = 0; linePoints = new ArrayList(); for (WayNode wayNode : way.getWayNodes()) { NodeLocation nodeLocation; nodeLocation = locationStore.getNodeLocation(wayNode.getNodeId()); if (nodeLocation.isValid()) { numValidNodes++; linePoints.add(new Point(nodeLocation.getLongitude(), nodeLocation.getLatitude())); } else { return null; } } if (numValidNodes >= 2) { return createLinestring(linePoints); } else { return null; } } /** * {@inheritDoc} */ @Override public void release() { locationStore.release(); } } WayMapper.java000066400000000000000000000071651253404521400344500ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.postgis.Geometry; import org.postgis.PGgeometry; /** * Reads and writes way attributes to jdbc classes. * * @author Brett Henderson */ public class WayMapper extends EntityMapper { private boolean supportBboxColumn; private boolean supportLinestringColumn; /** * Creates a new instance. */ public WayMapper() { supportBboxColumn = false; } /** * Creates a new instance. * * @param supportBboxColumn * If true, the bounding box column will be included in updates. * @param supportLinestringColumn * If true, the linestring column will be included in updates. */ public WayMapper(boolean supportBboxColumn, boolean supportLinestringColumn) { this.supportBboxColumn = supportBboxColumn; this.supportLinestringColumn = supportLinestringColumn; } /** * {@inheritDoc} */ @Override public String getEntityName() { return "way"; } /** * {@inheritDoc} */ @Override public ActionDataType getEntityType() { return ActionDataType.WAY; } /** * {@inheritDoc} */ @Override public Class getEntityClass() { return Way.class; } /** * {@inheritDoc} */ @Override protected String[] getTypeSpecificFieldNames() { List fieldNames; fieldNames = new ArrayList(); if (supportBboxColumn) { fieldNames.add("bbox"); } if (supportLinestringColumn) { fieldNames.add("linestring"); } return fieldNames.toArray(new String[]{}); } /** * {@inheritDoc} */ @Override public Way parseRecord(ResultSet resultSet) { try { return new Way( new CommonEntityData( resultSet.getLong("id"), resultSet.getInt("version"), new Date(resultSet.getTimestamp("tstamp").getTime()), buildUser(resultSet), resultSet.getLong("changeset_id") ) ); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to build a way from the current recordset row.", e); } } /** * {@inheritDoc} */ @Override public int populateEntityParameters(PreparedStatement statement, int initialIndex, Way way) { // Populate the entity level parameters. return populateCommonEntityParameters(statement, initialIndex, way); } /** * Sets entity values as bind variable parameters to an entity insert query. * * @param statement * The prepared statement to add the values to. * @param initialIndex * The offset index of the first variable to set. * @param way * The entity containing the data to be inserted. * @param geometries * The geometries to store against the way. * @return The current parameter offset. */ public int populateEntityParameters( PreparedStatement statement, int initialIndex, Way way, List geometries) { int prmIndex; prmIndex = populateEntityParameters(statement, initialIndex, way); try { for (int i = 0; i < geometries.size(); i++) { statement.setObject(prmIndex++, new PGgeometry(geometries.get(i))); } } catch (SQLException e) { throw new OsmosisRuntimeException( "Unable to set the bbox for way " + way.getId() + ".", e ); } return prmIndex; } } WayNodeMapper.java000066400000000000000000000063411253404521400352510ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.database.DbOrderedFeature; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; /** * Reads and writes way nodes to jdbc classes. * * @author Brett Henderson */ public class WayNodeMapper extends EntityFeatureMapper> { /** * {@inheritDoc} */ @Override public String getParentEntityName() { return "way"; } /** * {@inheritDoc} */ @Override public String getEntityName() { return "way_nodes"; } /** * {@inheritDoc} */ @Override public String getSqlSelect(boolean filterByEntityId, boolean orderBy) { StringBuilder resultSql; resultSql = new StringBuilder(); resultSql.append("SELECT way_id AS entity_id, node_id, sequence_id FROM "); resultSql.append("way_nodes f"); if (filterByEntityId) { resultSql.append(" WHERE entity_id = ?"); } if (orderBy) { resultSql.append(getSqlDefaultOrderBy()); } return resultSql.toString(); } /** * {@inheritDoc} */ @Override public String getSqlDefaultOrderBy() { return super.getSqlDefaultOrderBy() + ", sequence_id"; } /** * {@inheritDoc} */ @Override public String getSqlInsert(int rowCount) { StringBuilder resultSql; resultSql = new StringBuilder(); resultSql.append("INSERT INTO way_nodes ("); resultSql.append("way_id, node_id, sequence_id) VALUES "); for (int row = 0; row < rowCount; row++) { if (row > 0) { resultSql.append(", "); } resultSql.append("(?, ?, ?)"); } return resultSql.toString(); } /** * {@inheritDoc} */ @Override public String getSqlDelete(boolean filterByEntityId) { StringBuilder resultSql; resultSql = new StringBuilder(); resultSql.append("DELETE FROM way_nodes"); if (filterByEntityId) { resultSql.append(" WHERE ").append("way_id = ?"); } return resultSql.toString(); } /** * {@inheritDoc} */ @Override public DbOrderedFeature buildEntity(ResultSet resultSet) { try { return new DbOrderedFeature( resultSet.getLong("entity_id"), new WayNode( resultSet.getLong("node_id") ), resultSet.getInt("sequence_id") ); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to build a way node from the current recordset row.", e); } } /** * {@inheritDoc} */ @Override public int populateEntityParameters( PreparedStatement statement, int initialIndex, DbOrderedFeature entityFeature) { try { int prmIndex; WayNode wayNode; wayNode = entityFeature.getFeature(); prmIndex = initialIndex; statement.setLong(prmIndex++, entityFeature.getEntityId()); statement.setLong(prmIndex++, wayNode.getNodeId()); statement.setInt(prmIndex++, entityFeature.getSequenceId()); return prmIndex; } catch (SQLException e) { throw new OsmosisRuntimeException( "Unable to populate way node parameters for way " + entityFeature.getEntityId() + ".", e ); } } } WayReader.java000066400000000000000000000056341253404521400344250ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.openstreetmap.osmosis.core.database.DbOrderedFeature; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.openstreetmap.osmosis.core.store.PeekableIterator; import org.openstreetmap.osmosis.pgsimple.common.DatabaseContext; /** * Reads all ways from a database ordered by their identifier. It combines the * output of the way table readers to produce fully configured way objects. * * @author Brett Henderson */ public class WayReader extends EntityReader { private PeekableIterator> wayNodeReader; /** * Creates a new instance. * * @param dbCtx * The database context to use for accessing the database. */ public WayReader(DatabaseContext dbCtx) { super(dbCtx, new WayMapper()); wayNodeReader = new PeekableIterator>( new EntityFeatureTableReader>(dbCtx, new WayNodeMapper()) ); } /** * Creates a new instance. * * @param dbCtx * The database context to use for accessing the database. * @param constraintTable * The table containing a column named id defining the list of * entities to be returned. */ public WayReader(DatabaseContext dbCtx, String constraintTable) { super(dbCtx, new WayMapper(), constraintTable); wayNodeReader = new PeekableIterator>( new EntityFeatureTableReader>( dbCtx, new WayNodeMapper(), constraintTable) ); } /** * {@inheritDoc} */ @Override protected void populateEntityFeatures(Way entity) { long wayId; List> wayNodes; super.populateEntityFeatures(entity); wayId = entity.getId(); // Skip all way nodes that are from a lower way. while (wayNodeReader.hasNext()) { DbOrderedFeature wayNode; wayNode = wayNodeReader.peekNext(); if (wayNode.getEntityId() < wayId) { wayNodeReader.next(); } else { break; } } // Load all nodes matching this version of the way. wayNodes = new ArrayList>(); while (wayNodeReader.hasNext() && wayNodeReader.peekNext().getEntityId() == wayId) { wayNodes.add(wayNodeReader.next()); } // The underlying query sorts node references by way id but not // by their sequence number. Collections.sort(wayNodes, new DbOrderedFeatureComparator()); for (DbOrderedFeature dbWayNode : wayNodes) { entity.getWayNodes().add(dbWayNode.getFeature()); } } /** * {@inheritDoc} */ @Override public void release() { super.release(); wayNodeReader.release(); } } osmosis-0.44.1/osmosis-pgsimple/src/main/resources/000077500000000000000000000000001253404521400223335ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/main/resources/osmosis-plugins.conf000066400000000000000000000000671253404521400263600ustar00rootroot00000000000000org.openstreetmap.osmosis.pgsimple.PgSimplePluginLoaderosmosis-0.44.1/osmosis-pgsimple/src/test/000077500000000000000000000000001253404521400203545ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/test/java/000077500000000000000000000000001253404521400212755ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/test/java/org/000077500000000000000000000000001253404521400220645ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/test/java/org/openstreetmap/000077500000000000000000000000001253404521400247525ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/test/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400264465ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/test/java/org/openstreetmap/osmosis/pgsimple/000077500000000000000000000000001253404521400302665ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/test/java/org/openstreetmap/osmosis/pgsimple/v0_6/000077500000000000000000000000001253404521400310405ustar00rootroot00000000000000DatasetDriver.java000066400000000000000000000047241253404521400343740ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/test/java/org/openstreetmap/osmosis/pgsimple/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.TimeZone; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.Dataset; import org.openstreetmap.osmosis.core.container.v0_6.DatasetContext; import org.openstreetmap.osmosis.core.container.v0_6.EntityManager; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.task.v0_6.DatasetSink; /** * Performs queries and modifications to exercise the pgsql dataset implementation. * * @author Brett Henderson */ public class DatasetDriver implements DatasetSink { private Date buildDate(String utcString) { SimpleDateFormat dateFormat; dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); try { return dateFormat.parse(utcString); } catch (ParseException e) { throw new OsmosisRuntimeException("The date string (" + utcString + ") could not be parsed.", e); } } /** * {@inheritDoc} */ @Override public void process(Dataset dataset) { DatasetContext dsCtx = dataset.createReader(); try { EntityManager nodeManager = dsCtx.getNodeManager(); OsmUser user; Node node; // Create the user for edits to be performed under. This is an existing user with an // updated name. user = new OsmUser(10, "user10b"); // Modify node 1 to add a new tag. node = nodeManager.getEntity(1).getWriteableInstance(); node.setUser(user); node.getTags().add(new Tag("change", "new tag")); nodeManager.modifyEntity(node); // Delete node 6. nodeManager.removeEntity(6); // Add node 7 using the NONE user. node = new Node(new CommonEntityData(7, 16, buildDate("2008-01-02 18:19:20"), OsmUser.NONE, 93), -11, -12); node.getTags().addAll( Arrays.asList(new Tag[]{new Tag("created_by", "Me7"), new Tag("change", "new node")})); nodeManager.addEntity(node); dsCtx.complete(); } finally { dsCtx.release(); } } /** * {@inheritDoc} */ @Override public void release() { // Do nothing. } } DatasetDriverFactory.java000066400000000000000000000015011253404521400357120ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/test/java/org/openstreetmap/osmosis/pgsimple/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.DatasetSinkManager; /** * The task manager factory for reading the entire contents of a dataset. * * @author Brett Henderson */ public class DatasetDriverFactory extends TaskManagerFactory { /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { return new DatasetSinkManager( taskConfig.getId(), new DatasetDriver(), taskConfig.getPipeArgs() ); } } DatasetDriverPlugin.java000066400000000000000000000013731253404521400355500ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/test/java/org/openstreetmap/osmosis/pgsimple/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.plugin.PluginLoader; /** * Registers the dataset driver test task. * * @author Brett Henderson */ public class DatasetDriverPlugin implements PluginLoader { /** * {@inheritDoc} */ @Override public Map loadTaskFactories() { HashMap factoryMap; factoryMap = new HashMap(); factoryMap.put("drive-dataset", new DatasetDriverFactory()); return factoryMap; } } PostgreSqlTest.java000066400000000000000000000145321253404521400345740ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/test/java/org/openstreetmap/osmosis/pgsimple/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6; import java.io.File; import java.io.IOException; import org.junit.Test; import org.openstreetmap.osmosis.core.Osmosis; import org.openstreetmap.osmosis.testutil.AbstractDataTest; /** * Tests for PostgreSQL tasks. * * @author Brett Henderson */ public class PostgreSqlTest extends AbstractDataTest { private File getAuthFile() { return dataUtils.createDataFile("db.pgsql.authfile", "v0_6/pgsql-authfile.txt"); } /** * A basic test loading an osm file into a pgsql database, then dumping it * again and verifying that it is identical. * * @throws IOException * if any file operations fail. */ @Test public void testLoadAndDump() throws IOException { File authFile; File inputFile; File outputFile; // Generate input files. authFile = getAuthFile(); inputFile = dataUtils.createDataFile("v0_6/db-snapshot.osm"); outputFile = dataUtils.newFile(); // Remove all existing data from the database. Osmosis.run( new String [] { "-q", "--truncate-pgsimp-0.6", "authFile=" + authFile.getPath() } ); // Load the database with a dataset. Osmosis.run( new String [] { "-q", "--read-xml-0.6", inputFile.getPath(), "--write-pgsimp-0.6", "authFile=" + authFile.getPath() } ); // Dump the database to an osm file. Osmosis.run( new String [] { "-q", "--read-pgsimp-0.6", "authFile=" + authFile.getPath(), "--dataset-dump-0.6", "--tag-sort-0.6", "--write-xml-0.6", outputFile.getPath() } ); // Validate that the output file matches the input file. dataUtils.compareFiles(inputFile, outputFile); } /** * A basic test loading an osm file into a pgsql database using the COPY * file approach, then dumping it again and verifying that it is identical. * * @throws IOException * if any file operations fail. */ @Test public void testFastLoadAndDump() throws IOException { File authFile; File inputFile; File outputFile; // Generate input files. authFile = getAuthFile(); inputFile = dataUtils.createDataFile("v0_6/db-snapshot.osm"); outputFile = dataUtils.newFile(); // Remove all existing data from the database. Osmosis.run( new String [] { "-q", "--truncate-pgsimp-0.6", "authFile=" + authFile.getPath() } ); // Load the database with a dataset. Osmosis.run( new String [] { "-q", "--read-xml-0.6", inputFile.getPath(), "--fast-write-pgsimp-0.6", "authFile=" + authFile.getPath() } ); // Dump the database to an osm file. Osmosis.run( new String [] { "-q", "--read-pgsimp-0.6", "authFile=" + authFile.getPath(), "--dataset-dump-0.6", "--tag-sort-0.6", "--write-xml-0.6", outputFile.getPath() } ); // Validate that the output file matches the input file. dataUtils.compareFiles(inputFile, outputFile); } /** * A test loading an osm file into a pgsql database, then applying a * changeset, then dumping it again and verifying the output is as expected. * * @throws IOException * if any file operations fail. */ @Test public void testChangeset() throws IOException { File authFile; File snapshotFile; File changesetFile; File expectedResultFile; File actualResultFile; // Generate input files. authFile = getAuthFile(); snapshotFile = dataUtils.createDataFile("v0_6/db-snapshot.osm"); changesetFile = dataUtils.createDataFile("v0_6/db-changeset.osc"); expectedResultFile = dataUtils.createDataFile("v0_6/db-changeset-expected.osm"); actualResultFile = dataUtils.newFile(); // Remove all existing data from the database. Osmosis.run( new String [] { "-q", "--truncate-pgsimp-0.6", "authFile=" + authFile.getPath() } ); // Load the database with the snapshot file. Osmosis.run( new String [] { "-q", "--read-xml-0.6", snapshotFile.getPath(), "--write-pgsimp-0.6", "authFile=" + authFile.getPath() } ); // Apply the changeset file to the database. Osmosis.run( new String [] { "-q", "--read-xml-change-0.6", changesetFile.getPath(), "--write-pgsimp-change-0.6", "authFile=" + authFile.getPath() } ); // Dump the database to an osm file. Osmosis.run( new String [] { "-q", "--read-pgsimp-0.6", "authFile=" + authFile.getPath(), "--dataset-dump-0.6", "--tag-sort-0.6", "--write-xml-0.6", actualResultFile.getPath() } ); // Validate that the dumped file matches the expected result. dataUtils.compareFiles(expectedResultFile, actualResultFile); } /** * A test loading an osm file into a pgsql database, then making some modifications via the * dataset api, then dumping it again and verifying the output is as expected. * * @throws IOException * if any file operations fail. */ @Test public void testDataset() throws IOException { File authFile; File snapshotFile; File expectedResultFile; File actualResultFile; // Generate input files. authFile = getAuthFile(); snapshotFile = dataUtils.createDataFile("v0_6/db-snapshot.osm"); expectedResultFile = dataUtils.createDataFile("v0_6/db-dataset-expected.osm"); actualResultFile = dataUtils.newFile(); // Remove all existing data from the database. Osmosis.run( new String [] { "-q", "--truncate-pgsimp-0.6", "authFile=" + authFile.getPath() } ); // Load the database with the snapshot file. Osmosis.run( new String [] { "-q", "--read-xml-0.6", snapshotFile.getPath(), "--write-pgsimp-0.6", "authFile=" + authFile.getPath() } ); // Invoke the dataset driver task task to manipulate the database. Osmosis.run( new String [] { "-q", "-p", DatasetDriverPlugin.class.getName(), "--read-pgsimp-0.6", "authFile=" + authFile.getPath(), "--drive-dataset" } ); // Dump the database to an osm file. Osmosis.run( new String [] { "-q", "--read-pgsimp-0.6", "authFile=" + authFile.getPath(), "--dataset-dump-0.6", "--tag-sort-0.6", "--write-xml-0.6", actualResultFile.getPath() } ); // Validate that the dumped file matches the expected result. dataUtils.compareFiles(expectedResultFile, actualResultFile); } } osmosis-0.44.1/osmosis-pgsimple/src/test/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl/000077500000000000000000000000001253404521400320015ustar00rootroot00000000000000NodeLocationStoreTest.java000066400000000000000000000052311253404521400370210ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/test/java/org/openstreetmap/osmosis/pgsimple/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsimple.v0_6.impl; import org.junit.Assert; import org.junit.Test; import org.openstreetmap.osmosis.pgsimple.common.InMemoryNodeLocationStore; import org.openstreetmap.osmosis.pgsimple.common.NodeLocation; import org.openstreetmap.osmosis.pgsimple.common.NodeLocationStore; import org.openstreetmap.osmosis.pgsimple.common.PersistentNodeLocationStore; import org.openstreetmap.osmosis.core.util.FixedPrecisionCoordinateConvertor; /** * Tests the node location store implementations. * * @author Brett Hendersons */ public class NodeLocationStoreTest { private void testStoreImplementation(NodeLocationStore store) { // Add a large number of locations to the store. for (int i = 0; i < 100000; i++) { double longitude; double latitude; // Stores typically use fixed precision storage therefore ensure we // have a good spread of values. // The longitude and latitude must be different values to ensure they don't get mixed up. longitude = FixedPrecisionCoordinateConvertor.convertToDouble(1 << (i % 32)); latitude = FixedPrecisionCoordinateConvertor.convertToDouble(1 << ((i + 1) % 32)); // Add the location to the store but leave every node invalid. store.addLocation(i * 2, new NodeLocation(longitude, latitude)); } // Verify that the data from the store matches. for (int i = 0; i < 100000; i++) { double longitude; double latitude; NodeLocation location; // Stores typically use fixed precision storage therefore ensure we // have a good spread of values. // The longitude and latitude must be different values to ensure they don't get mixed up. longitude = FixedPrecisionCoordinateConvertor.convertToDouble(1 << (i % 32)); latitude = FixedPrecisionCoordinateConvertor.convertToDouble(1 << ((i + 1) % 32)); location = store.getNodeLocation(i * 2); Assert.assertTrue("The node location should be valid.", location.isValid()); Assert.assertEquals("The longitude is incorrect.", longitude, location.getLongitude(), 0); Assert.assertEquals("The latitude is incorrect.", latitude, location.getLatitude(), 0); location = store.getNodeLocation((i * 2) + 1); Assert.assertFalse("The node location should be invalid.", location.isValid()); } store.release(); } /** * Tests the temporary file implementation. */ @Test public void testTempFile() { testStoreImplementation(new PersistentNodeLocationStore()); } /** * Tests the in-memory implementation. */ @Test public void testInMemory() { testStoreImplementation(new InMemoryNodeLocationStore()); } } osmosis-0.44.1/osmosis-pgsimple/src/test/resources/000077500000000000000000000000001253404521400223665ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/test/resources/data/000077500000000000000000000000001253404521400232775ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/test/resources/data/template/000077500000000000000000000000001253404521400251125ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/test/resources/data/template/v0_6/000077500000000000000000000000001253404521400256645ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsimple/src/test/resources/data/template/v0_6/db-changeset-expected.osm000066400000000000000000000037221253404521400325330ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-pgsimple/src/test/resources/data/template/v0_6/db-changeset.osc000066400000000000000000000030721253404521400307200ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-pgsimple/src/test/resources/data/template/v0_6/db-dataset-expected.osm000066400000000000000000000040361253404521400322160ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-pgsimple/src/test/resources/data/template/v0_6/db-snapshot.osm000066400000000000000000000037261253404521400306360ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-pgsimple/src/test/resources/data/template/v0_6/pgsql-authfile.txt000066400000000000000000000001041253404521400313450ustar00rootroot00000000000000host=localhost database=pgosmsimp06_test user=osm password=password osmosis-0.44.1/osmosis-pgsnapshot/000077500000000000000000000000001253404521400171545ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/.checkstyle000066400000000000000000000010051253404521400213070ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-pgsnapshot/.gitignore000066400000000000000000000000531253404521400211420ustar00rootroot00000000000000.classpath .project .settings /bin /build osmosis-0.44.1/osmosis-pgsnapshot/build.gradle000066400000000000000000000013361253404521400214360ustar00rootroot00000000000000configurations { // Exclude unnecessary postgis stub classes. all*.exclude group: 'org.postgis', module: 'postgis-stubs' } dependencies { compile project(':osmosis-core') compile project(':osmosis-hstore-jdbc') compile group: 'commons-dbcp', name: 'commons-dbcp', version: dependencyVersionCommonsDbcp compile group: 'org.postgis', name: 'postgis-jdbc', version: dependencyVersionPostGis compile group: 'org.springframework', name: 'spring-jdbc', version: dependencyVersionSpring compile group: 'org.postgresql', name: 'postgresql', version: dependencyVersionPostgreSql testCompile project(':osmosis-dataset') testCompile project(':osmosis-testutil') testCompile project(':osmosis-xml') } osmosis-0.44.1/osmosis-pgsnapshot/src/000077500000000000000000000000001253404521400177435ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/000077500000000000000000000000001253404521400206675ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/000077500000000000000000000000001253404521400216105ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/000077500000000000000000000000001253404521400223775ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/000077500000000000000000000000001253404521400252655ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400267615ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/000077500000000000000000000000001253404521400311475ustar00rootroot00000000000000PgSnapshotPluginLoader.java000066400000000000000000000041511253404521400363300ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.plugin.PluginLoader; import org.openstreetmap.osmosis.pgsnapshot.v0_6.PostgreSqlChangeWriterFactory; import org.openstreetmap.osmosis.pgsnapshot.v0_6.PostgreSqlCopyWriterFactory; import org.openstreetmap.osmosis.pgsnapshot.v0_6.PostgreSqlDatasetReaderFactory; import org.openstreetmap.osmosis.pgsnapshot.v0_6.PostgreSqlDumpWriterFactory; import org.openstreetmap.osmosis.pgsnapshot.v0_6.PostgreSqlTruncatorFactory; /** * The plugin loader for the PostgreSQL Snapshot Schema tasks. * * @author Brett Henderson */ public class PgSnapshotPluginLoader implements PluginLoader { /** * {@inheritDoc} */ @Override public Map loadTaskFactories() { Map factoryMap; factoryMap = new HashMap(); factoryMap.put("write-pgsql", new PostgreSqlCopyWriterFactory()); factoryMap.put("wp", new PostgreSqlCopyWriterFactory()); factoryMap.put("truncate-pgsql", new PostgreSqlTruncatorFactory()); factoryMap.put("tp", new PostgreSqlTruncatorFactory()); factoryMap.put("write-pgsql-dump", new PostgreSqlDumpWriterFactory()); factoryMap.put("wpd", new PostgreSqlDumpWriterFactory()); factoryMap.put("read-pgsql", new PostgreSqlDatasetReaderFactory()); factoryMap.put("rp", new PostgreSqlDatasetReaderFactory()); factoryMap.put("write-pgsql-change", new PostgreSqlChangeWriterFactory()); factoryMap.put("wpc", new PostgreSqlChangeWriterFactory()); factoryMap.put("write-pgsql-0.6", new PostgreSqlCopyWriterFactory()); factoryMap.put("truncate-pgsql-0.6", new PostgreSqlTruncatorFactory()); factoryMap.put("write-pgsql-dump-0.6", new PostgreSqlDumpWriterFactory()); factoryMap.put("read-pgsql-0.6", new PostgreSqlDatasetReaderFactory()); factoryMap.put("write-pgsql-change-0.6", new PostgreSqlChangeWriterFactory()); return factoryMap; } } osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/common/000077500000000000000000000000001253404521400324375ustar00rootroot00000000000000CompactPersistentNodeLocation.java000066400000000000000000000030041253404521400411660ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.common; import org.openstreetmap.osmosis.core.store.StoreClassRegister; import org.openstreetmap.osmosis.core.store.StoreReader; import org.openstreetmap.osmosis.core.store.StoreWriter; import org.openstreetmap.osmosis.core.store.Storeable; /** * The compact persistent node location store persists instances of this class. * * @author Brett Henderson */ public class CompactPersistentNodeLocation implements Storeable { private NodeLocation nodeLocation; /** * Creates a new instance. * * @param nodeLocation The node location details. */ public CompactPersistentNodeLocation(NodeLocation nodeLocation) { this.nodeLocation = nodeLocation; } /** * Creates a new instance. * * @param sr * The store to read state from. * @param scr * Maintains the mapping between classes and their identifiers within the store. */ public CompactPersistentNodeLocation(StoreReader sr, StoreClassRegister scr) { nodeLocation = new NodeLocation(sr.readDouble(), sr.readDouble()); } /** * {@inheritDoc} */ @Override public void store(StoreWriter writer, StoreClassRegister storeClassRegister) { writer.writeDouble(nodeLocation.getLongitude()); writer.writeDouble(nodeLocation.getLatitude()); } /** * Gets the node location details. * @return The node location. */ public NodeLocation getNodeLocation() { return nodeLocation; } } CompactPersistentNodeLocationStore.java000066400000000000000000000037421253404521400422140ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.common; import org.openstreetmap.osmosis.core.store.IndexedObjectStore; import org.openstreetmap.osmosis.core.store.IndexedObjectStoreReader; import org.openstreetmap.osmosis.core.store.NoSuchIndexElementException; import org.openstreetmap.osmosis.core.store.SingleClassObjectSerializationFactory; /** * A file-based node location store implementation. This differs from the normal * file-based implementation in that it consumes disk space proportionally to * the number of nodes being managed. This is more efficient for smaller data * sets, but less efficient when processing a full planet. * * @author Brett Henderson */ public class CompactPersistentNodeLocationStore implements NodeLocationStore { private IndexedObjectStore nodeLocations; private IndexedObjectStoreReader nodeLocationsReader; /** * Creates a new instance. */ public CompactPersistentNodeLocationStore() { nodeLocations = new IndexedObjectStore( new SingleClassObjectSerializationFactory(CompactPersistentNodeLocation.class), "nodeLocation"); } /** * {@inheritDoc} */ @Override public void addLocation(long nodeId, NodeLocation nodeLocation) { nodeLocations.add(nodeId, new CompactPersistentNodeLocation(nodeLocation)); } /** * {@inheritDoc} */ @Override public NodeLocation getNodeLocation(long nodeId) { if (nodeLocationsReader == null) { nodeLocations.complete(); nodeLocationsReader = nodeLocations.createReader(); } try { return nodeLocationsReader.get(nodeId).getNodeLocation(); } catch (NoSuchIndexElementException e) { return new NodeLocation(); } } /** * {@inheritDoc} */ @Override public void release() { if (nodeLocationsReader != null) { nodeLocationsReader.release(); } nodeLocations.release(); } } CopyFileWriter.java000066400000000000000000000174641253404521400361460ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.common; import java.io.BufferedOutputStream; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.postgis.Geometry; import org.postgis.binary.BinaryWriter; import org.postgresql.util.PGobject; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.lifecycle.Completable; /** * This class provides the capability to write a file that contains data for a * database COPY statement for loading a single table into the database. * * @author Brett Henderson */ public class CopyFileWriter implements Completable { private static Logger log = Logger.getLogger(CopyFileWriter.class.getName()); private File file; private boolean initialized; private BufferedWriter writer; private boolean midRecord; private SimpleDateFormat dateFormat; private BinaryWriter postgisBinaryWriter; /** * Creates a new instance. * * @param file * The file to write. */ public CopyFileWriter(File file) { this.file = file; midRecord = false; dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ"); postgisBinaryWriter = new BinaryWriter(); } /** * Adds a field separator if required. * * @throws IOException * if the field cannot be written. */ private void separateField() throws IOException { if (midRecord) { writer.write('\t'); } else { midRecord = true; } } /** * Writes data to the output file. * * @param data * The data to be written. */ public void writeField(boolean data) { initialize(); try { separateField(); if (data) { writer.write("t"); } else { writer.write("f"); } } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write value (" + data + ")", e); } } /** * Writes data to the output file. * * @param data * The data to be written. */ public void writeField(int data) { initialize(); try { separateField(); writer.write(Integer.toString(data)); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write value (" + data + ")", e); } } /** * Writes data to the output file. * * @param data * The data to be written. */ public void writeField(long data) { initialize(); try { separateField(); writer.write(Long.toString(data)); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write value (" + data + ")", e); } } /** * Inserts escape sequences needed to make a String suitable for writing to * a COPY file. * * @param data * The raw data string. * @return The escaped string. */ private String escapeString(String data) { StringBuilder result; char[] dataArray; if (data == null) { return "\\N"; } result = new StringBuilder(data.length()); dataArray = data.toCharArray(); for (int i = 0; i < dataArray.length; i++) { char currentChar; currentChar = dataArray[i]; switch (currentChar) { case '\\': // Slash result.append("\\\\"); break; case 8: // Backspace result.append("\\b"); break; case 12: // Form feed result.append("\\f"); break; case 10: // Newline result.append("\\n"); break; case 13: // Carriage return result.append("\\r"); break; case 9: // Tab result.append("\\t"); break; case 11: // Vertical tab result.append("\\v"); break; default: result.append(currentChar); } } return result.toString(); } /** * Writes data to the output file. * * @param data * The data to be written. */ public void writeField(String data) { initialize(); try { separateField(); writer.write(escapeString(data)); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write value (" + data + ")", e); } } /** * Writes data to the output file. * * @param data * The data to be written. */ public void writeField(Date data) { initialize(); try { separateField(); writer.write(dateFormat.format(data)); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write value (" + data + ")", e); } } /** * Writes data to the output file. * * @param data * The data to be written. */ public void writeField(Geometry data) { initialize(); try { separateField(); if (data == null) { writer.write(escapeString(null)); } else { writer.write(postgisBinaryWriter.writeHexed(data)); } } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write value (" + data + ")", e); } } /** * Writes data to the output file. * * @param data * The data to be written. */ public void writeField(PGobject data) { initialize(); try { separateField(); writer.write(escapeString(data.getValue())); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write value (" + data + ")", e); } } /** * Writes data to the output file. * * @param data * The data to be written. */ public void writeField(List data) { initialize(); try { separateField(); writer.write("{"); for (int i = 0; i < data.size(); i++) { if (i > 0) { writer.write(","); } writer.write(Long.toString(data.get(i))); } writer.write("}"); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write value (" + data + ")", e); } } /** * Writes a new line in the output file. */ public void endRecord() { try { writer.newLine(); midRecord = false; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to end record.", e); } } /** * Initialises the output file for writing. This must be called by * sub-classes before any writing is performed. This method may be called * multiple times without adverse affect allowing sub-classes to invoke it * every time they perform processing. */ private void initialize() { if (!initialized) { OutputStream outStream = null; try { outStream = new FileOutputStream(file); writer = new BufferedWriter( new OutputStreamWriter(new BufferedOutputStream(outStream, 65536), "UTF-8")); outStream = null; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to open file for writing.", e); } finally { if (outStream != null) { try { outStream.close(); } catch (Exception e) { log.log(Level.SEVERE, "Unable to close output stream.", e); } outStream = null; } } initialized = true; } } /** * Flushes all changes to file. */ public void complete() { initialize(); try { if (midRecord) { throw new OsmosisRuntimeException("The current record has not been ended."); } if (writer != null) { writer.close(); } } catch (IOException e) { throw new OsmosisRuntimeException("Unable to complete writing to the data stream.", e); } finally { initialized = false; writer = null; } } /** * Cleans up any open file handles. */ public void release() { try { try { if (writer != null) { writer.close(); } } catch (IOException e) { log.log(Level.SEVERE, "Unable to close writer.", e); } } finally { initialized = false; writer = null; } } } DataSourceManager.java000066400000000000000000000105461253404521400365560ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.common; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.logging.Level; import java.util.logging.Logger; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSource; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.lifecycle.Releasable; /** * Creates or obtains a datasource and manages its lifecycle based on the login * credentials provided. * * @author Brett Henderson */ public final class DataSourceManager implements Releasable { private static final Logger LOG = Logger.getLogger(DataSourceManager.class.getName()); private DataSource dataSource; private BasicDataSource localDataSource; private DatabaseLoginCredentials credentials; /** * Creates a new instance. * * @param credentials * Contains all information required to connect to the database. */ public DataSourceManager(DatabaseLoginCredentials credentials) { this.credentials = credentials; } private void createDataSource() { localDataSource = new BasicDataSource(); localDataSource.setDriverClassName("org.postgresql.Driver"); localDataSource.setUrl("jdbc:postgresql://" + credentials.getHost() + "/" + credentials.getDatabase() /*+ "?loglevel=2"*/); localDataSource.setUsername(credentials.getUser()); localDataSource.setPassword(credentials.getPassword()); dataSource = localDataSource; } private void loadDatasource() { InitialContext cxt; String jndiLocation; jndiLocation = credentials.getDatasourceJndiLocation(); try { cxt = new InitialContext(); } catch (NamingException e) { throw new OsmosisRuntimeException("Unable to create an initial JNDI context.", e); } try { dataSource = (DataSource) cxt.lookup(jndiLocation); } catch (NamingException e) { throw new OsmosisRuntimeException("Unable to locate the datasource (" + jndiLocation + ")", e); } } private Connection createConnectionFromDriverManager() { try { // Register the database driver. try { Class.forName("org.postgresql.Driver"); } catch (ClassNotFoundException e) { throw new OsmosisRuntimeException("Unable to find database driver.", e); } return DriverManager.getConnection( "jdbc:postgresql://" + credentials.getHost() + "/" + credentials.getDatabase(), // + "?logLevel=2" credentials.getUser(), credentials.getPassword() ); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to establish a new database connection.", e); } } /** * Obtains a data source. * * @return The database source. */ public DataSource getDataSource() { if (dataSource == null) { String jndiLocation; jndiLocation = credentials.getDatasourceJndiLocation(); if (jndiLocation != null) { LOG.finer("Retrieving a data source from JNDI."); loadDatasource(); } else { LOG.finer("Creating a new locally managed data source."); createDataSource(); } } return dataSource; } /** * Obtains a single connection. * * @return The connection. */ public Connection getConnection() { String jndiLocation; Connection connection; jndiLocation = credentials.getDatasourceJndiLocation(); if (dataSource == null && jndiLocation != null) { LOG.finer("Retrieving a data source from JNDI."); loadDatasource(); } if (dataSource == null) { LOG.finer("Creating a new database connection from DriverManager."); connection = createConnectionFromDriverManager(); } else { try { connection = dataSource.getConnection(); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to obtain a connection from the datasource.", e); } } return connection; } /** * {@inheritDoc} */ @Override public void release() { if (localDataSource != null) { try { localDataSource.close(); } catch (SQLException e) { LOG.log(Level.WARNING, "Unable to cleanup the database connection pool.", e); } localDataSource = null; dataSource = null; } } } DatabaseContext.java000066400000000000000000000227171253404521400363050ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.common; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.util.logging.Level; import java.util.logging.Logger; import javax.sql.DataSource; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.postgresql.copy.CopyManager; import org.postgresql.core.BaseConnection; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.jdbc.datasource.DataSourceUtils; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.DefaultTransactionDefinition; import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionTemplate; /** * This class manages the lifecycle of JDBC objects to minimise the risk of connection leaks and to * support a consistent approach to database access. * * @author Brett Henderson */ public class DatabaseContext { private static final Logger LOG = Logger.getLogger(DatabaseContext.class.getName()); private DataSourceManager dataSourceManager; private DataSource dataSource; private PlatformTransactionManager txnManager; private TransactionTemplate txnTemplate; private TransactionStatus transaction; private JdbcTemplate jdbcTemplate; /** * Creates a new instance. * * @param loginCredentials Contains all information required to connect to the database. */ public DatabaseContext(DatabaseLoginCredentials loginCredentials) { dataSourceManager = new DataSourceManager(loginCredentials); dataSource = dataSourceManager.getDataSource(); txnManager = new DataSourceTransactionManager(dataSource); txnTemplate = new TransactionTemplate(txnManager); jdbcTemplate = new JdbcTemplate(dataSource); setStatementFetchSizeForStreaming(); } /** * Begins a new database transaction. This is not required if * executeWithinTransaction is being used. */ public void beginTransaction() { if (transaction != null) { throw new OsmosisRuntimeException("A transaction is already active."); } transaction = txnManager.getTransaction(new DefaultTransactionDefinition()); } /** * Commits an existing database transaction. */ public void commitTransaction() { if (transaction == null) { throw new OsmosisRuntimeException("No transaction is currently active."); } try { txnManager.commit(transaction); } finally { transaction = null; } } /** * Gets the jdbc template which provides access to database functions. * * @return The jdbc template. */ public JdbcTemplate getJdbcTemplate() { return jdbcTemplate; } /** * Invokes the provided callback code within a transaction. * * @param txnCallback * The logic to be invoked within a transaction. * @param * The return type of the transaction callback. * * @return The result. */ public Object executeWithinTransaction(TransactionCallback txnCallback) { return txnTemplate.execute(txnCallback); } private void setStatementFetchSizeForStreaming() { jdbcTemplate.setFetchSize(10000); } /** * Releases all database resources. This method is guaranteed not to throw transactions and * should always be called in a finally block whenever this class is used. */ public void release() { if (transaction != null) { try { txnManager.rollback(transaction); } finally { transaction = null; } } dataSourceManager.release(); } /** * Indicates if the specified column exists in the database. * * @param tableName The table to check for. * @param columnName The column to check for. * @return True if the column exists, false otherwise. */ public boolean doesColumnExist(String tableName, String columnName) { ResultSet resultSet = null; boolean result; try { Connection connection; LOG.finest("Checking if column {" + columnName + "} in table {" + tableName + "} exists."); // This connection may not be freed if an exception occurs. It's a small chance and the // additional code to avoid it is cumbersome. connection = DataSourceUtils.getConnection(dataSource); resultSet = connection.getMetaData().getColumns(null, null, tableName, columnName); result = resultSet.next(); resultSet.close(); resultSet = null; DataSourceUtils.releaseConnection(connection, dataSource); return result; } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to check for the existence of column " + tableName + "." + columnName + ".", e); } finally { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to close column existence result set.", e); } } } } /** * Indicates if the specified table exists in the database. * * @param tableName The table to check for. * @return True if the table exists, false otherwise. */ public boolean doesTableExist(String tableName) { ResultSet resultSet = null; boolean result; try { Connection connection; LOG.finest("Checking if table {" + tableName + "} exists."); // This connection may not be freed if an exception occurs. It's a small chance and the // additional code to avoid it is cumbersome. connection = DataSourceUtils.getConnection(dataSource); resultSet = connection.getMetaData().getTables(null, null, tableName, new String[] {"TABLE"}); result = resultSet.next(); resultSet.close(); resultSet = null; DataSourceUtils.releaseConnection(connection, dataSource); return result; } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to check for the existence of table " + tableName + ".", e); } finally { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to close table existence result set.", e); } } } } /** * Loads a table from a COPY file. * * @param copyFile * The file to be loaded. * @param tableName * The table to load the data into. * @param columns * The columns to be loaded (optional). */ public void loadCopyFile(File copyFile, String tableName, String ... columns) { CopyManager copyManager; InputStream inStream = null; try { StringBuilder copyStatement; InputStream bufferedInStream; Connection conn; copyStatement = new StringBuilder(); copyStatement.append("COPY "); copyStatement.append(tableName); if (columns.length > 0) { copyStatement.append('('); for (int i = 0; i < columns.length; i++) { if (i > 0) { copyStatement.append(','); } copyStatement.append(columns[i]); } copyStatement.append(')'); } copyStatement.append(" FROM STDIN"); inStream = new FileInputStream(copyFile); bufferedInStream = new BufferedInputStream(inStream, 65536); conn = DataSourceUtils.getConnection(dataSource); try { copyManager = new CopyManager(conn.unwrap(BaseConnection.class)); copyManager.copyIn(copyStatement.toString(), bufferedInStream); } finally { DataSourceUtils.releaseConnection(conn, dataSource); } inStream.close(); inStream = null; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to process COPY file " + copyFile + ".", e); } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to process COPY file " + copyFile + ".", e); } finally { if (inStream != null) { try { inStream.close(); } catch (IOException e) { LOG.log(Level.SEVERE, "Unable to close COPY file.", e); } inStream = null; } } } /** * Enforces cleanup of any remaining resources during garbage collection. This is a safeguard * and should not be required if release is called appropriately. * * @throws Throwable If a problem occurs during finalization. */ @Override protected void finalize() throws Throwable { release(); super.finalize(); } } InMemoryNodeLocationStore.java000066400000000000000000000116601253404521400403020ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.common; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.util.FixedPrecisionCoordinateConvertor; /** * An in-memory node location store implementation. * * @author Brett Henderson */ public class InMemoryNodeLocationStore implements NodeLocationStore { private static final Logger LOG = Logger.getLogger(InMemoryNodeLocationStore.class.getName()); private static final int NODE_DATA_SIZE = 9; private static final int BUFFER_ELEMENT_COUNT = 131072; private static final int BUFFER_SIZE = NODE_DATA_SIZE * BUFFER_ELEMENT_COUNT; private List buffers; private NodeLocation invalidNodeLocation; /** * Creates a new instance. */ public InMemoryNodeLocationStore() { buffers = new ArrayList(); invalidNodeLocation = new NodeLocation(); } /** * Writes a summary of the current memory consumption at the specified * logging level. * * @param level * The logging level to write the summary at. */ private void logMemoryConsumption(Level level) { if (LOG.isLoggable(level)) { Runtime runtime; long totalUsed; double percentageUsed; long maxMemory; DecimalFormat percentageFormat; runtime = Runtime.getRuntime(); percentageFormat = new DecimalFormat("#0.##"); // Calculate the percentage of memory currently used. percentageUsed = ((double) runtime.totalMemory()) / runtime.maxMemory() * 100; totalUsed = ((long) buffers.size()) * BUFFER_SIZE / 1048576; maxMemory = runtime.maxMemory() / 1048576; LOG.log( level, "The store contains " + buffers.size() + " buffers of " + (BUFFER_SIZE / 1024) + "KB, total " + totalUsed + "MB."); LOG.log( level, "The JVM is using " + percentageFormat.format(percentageUsed) + "% of the maximum " + maxMemory + "MB of memory."); } } /** * Writes the specified integer to a buffer. * * @param value * The integer to write. * @param buffer * The destination buffer. * @param initialOffset * The buffer offset to begin writing at. */ private void writeIntToBuffer(int value, byte[] buffer, int initialOffset) { int offset; offset = initialOffset; buffer[offset++] = (byte) (value >>> 24); buffer[offset++] = (byte) (value >>> 16); buffer[offset++] = (byte) (value >>> 8); buffer[offset++] = (byte) value; } /** * Reads an integer from a buffer. * * @param buffer * The buffer to read from. * @param initialOffset * The buffer offset to begin reading from. * @return The integer. */ private int readIntFromBuffer(byte[] buffer, int initialOffset) { int offset; offset = initialOffset; return ( buffer[offset++] << 24) + ((buffer[offset++] & 0xFF) << 16) + ((buffer[offset++] & 0xFF) << 8) + (buffer[offset++] & 0xFF); } /** * {@inheritDoc} */ @Override public void addLocation(long nodeId, NodeLocation nodeLocation) { int bufferIndex; byte[] buffer; int bufferOffset; bufferIndex = (int) (nodeId / BUFFER_ELEMENT_COUNT); while (bufferIndex >= buffers.size()) { buffer = new byte[BUFFER_SIZE]; buffers.add(buffer); logMemoryConsumption(Level.FINER); } buffer = buffers.get(bufferIndex); bufferOffset = (int) ((nodeId - (bufferIndex * BUFFER_ELEMENT_COUNT)) * NODE_DATA_SIZE); buffer[bufferOffset++] = 1; writeIntToBuffer( FixedPrecisionCoordinateConvertor.convertToFixed(nodeLocation.getLongitude()), buffer, bufferOffset); bufferOffset += 4; writeIntToBuffer( FixedPrecisionCoordinateConvertor.convertToFixed(nodeLocation.getLatitude()), buffer, bufferOffset); bufferOffset += 4; } /** * {@inheritDoc} */ @Override public NodeLocation getNodeLocation(long nodeId) { NodeLocation nodeLocation; int bufferIndex; nodeLocation = invalidNodeLocation; bufferIndex = (int) (nodeId / BUFFER_ELEMENT_COUNT); if (bufferIndex < buffers.size()) { byte[] buffer; int bufferOffset; byte validFlag; buffer = buffers.get(bufferIndex); bufferOffset = (int) ((nodeId - (bufferIndex * BUFFER_ELEMENT_COUNT)) * NODE_DATA_SIZE); validFlag = buffer[bufferOffset++]; if (validFlag != 0) { int longitude; int latitude; longitude = readIntFromBuffer(buffer, bufferOffset); bufferOffset += 4; latitude = readIntFromBuffer(buffer, bufferOffset); bufferOffset += 4; nodeLocation = new NodeLocation( FixedPrecisionCoordinateConvertor.convertToDouble(longitude), FixedPrecisionCoordinateConvertor.convertToDouble(latitude) ); } } return nodeLocation; } /** * {@inheritDoc} */ @Override public void release() { logMemoryConsumption(Level.FINE); } } NoSuchRecordException.java000066400000000000000000000030331253404521400374370ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.common; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * A runtime exception indicating that the requested database record doesn't exist. * * @author Brett Henderson */ public class NoSuchRecordException extends OsmosisRuntimeException { private static final long serialVersionUID = 1L; /** * Constructs a new exception with null as its detail message. */ public NoSuchRecordException() { super(); } /** * Constructs a new exception with the specified detail message. The * cause is not initialized, and may subsequently be initialized by * a call to {@link #initCause}. * * @param message the detail message. */ public NoSuchRecordException(String message) { super(message); } /** * Constructs a new exception with the specified cause and a detail * message of (cause==null ? null : cause.toString()) (which * typically contains the class and detail message of cause). * * @param cause the cause. */ public NoSuchRecordException(Throwable cause) { super(cause); } /** * Constructs a new exception with the specified detail message and * cause. * * @param message the detail message. * @param cause the cause. */ public NoSuchRecordException(String message, Throwable cause) { super(message, cause); } } NodeLocation.java000066400000000000000000000024041253404521400356010ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.common; /** * Represents the minimal geo-spatial information associated with a node. * * @author Brett Henderson */ public class NodeLocation { private boolean valid; private double longitude; private double latitude; /** * Creates a new empty instance which is marked as invalid. */ public NodeLocation() { this.valid = false; } /** * Creates a new instance with populated location details. * * @param longitude * The longitude of the node. * @param latitude * The latitude of the node. */ public NodeLocation(double longitude, double latitude) { this.valid = true; this.longitude = longitude; this.latitude = latitude; } /** * Indicates if the node is valid. A node may be invalid if it does not * exist. * * @return The valid flag. */ public boolean isValid() { return valid; } /** * Gets the longitude of the node. * * @return The node longitude. */ public double getLongitude() { return longitude; } /** * Gets the latitude of the node. * * @return The node latitude. */ public double getLatitude() { return latitude; } } NodeLocationStore.java000066400000000000000000000016661253404521400366270ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.common; import org.openstreetmap.osmosis.core.lifecycle.Releasable; /** * A node location store is used for caching node locations that are * subsequently used to build way geometries. * * @author Brett Henderson */ public interface NodeLocationStore extends Releasable { /** * Adds the specified node location details. * * @param nodeId * The node identifier. * @param nodeLocation * The geo-spatial location details. */ void addLocation(long nodeId, NodeLocation nodeLocation); /** * Gets the location details of the specified node. * * @param nodeId * The node identifier. * @return The geo-spatial location details. If the node doesn't exist, the * valid flag will be set to false. */ NodeLocation getNodeLocation(long nodeId); } NodeLocationStoreType.java000066400000000000000000000014031253404521400374560ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.common; /** * Defines the different node location store implementations available. * * @author Brett Henderson */ public enum NodeLocationStoreType { /** * An in-memory node location store holds all information in memory. This * typically requires a very large JVM heap space. */ InMemory, /** * A temporary file based node location store holds all information in a temporary file on disk. */ TempFile, /** * A temporary file based node location store holds all information in a * temporary file on disk. This is optimised for small datasets, and is less * efficient for large datasets. */ CompactTempFile } PersistentNodeLocationStore.java000066400000000000000000000154171253404521400407070ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.common; import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.Arrays; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.store.BufferedRandomAccessFileInputStream; import org.openstreetmap.osmosis.core.store.StorageStage; import org.openstreetmap.osmosis.core.util.FixedPrecisionCoordinateConvertor; /** * A file-based node location store implementation. * * @author Brett Henderson */ public class PersistentNodeLocationStore implements NodeLocationStore { private static final Logger LOG = Logger.getLogger(PersistentNodeLocationStore.class.getName()); private static final int ZERO_BUFFER_SIZE = 1024 * 1024; private static final int NODE_DATA_SIZE = 9; private File nodeStorageFile; private StorageStage stage; private long lastNodeId; private FileOutputStream fileOutStream; private DataOutputStream dataOutStream; private BufferedRandomAccessFileInputStream fileInStream; private DataInputStream dataInStream; private long currentFileOffset; private byte[] zeroBuffer; private NodeLocation invalidNodeLocation; /** * Creates a new instance. */ public PersistentNodeLocationStore() { stage = StorageStage.NotStarted; lastNodeId = Long.MIN_VALUE; zeroBuffer = new byte[ZERO_BUFFER_SIZE]; Arrays.fill(zeroBuffer, (byte) 0); invalidNodeLocation = new NodeLocation(); } private void initializeAddStage() { // We can't add if we've passed the add stage. if (stage.compareTo(StorageStage.Add) > 0) { throw new OsmosisRuntimeException("Cannot add to storage in stage " + stage + "."); } // If we're not up to the add stage, initialise for adding. if (stage.compareTo(StorageStage.Add) < 0) { try { nodeStorageFile = File.createTempFile("nodelatlon", null); fileOutStream = new FileOutputStream(nodeStorageFile); dataOutStream = new DataOutputStream(new BufferedOutputStream(fileOutStream, 65536)); currentFileOffset = 0; stage = StorageStage.Add; } catch (IOException e) { throw new OsmosisRuntimeException( "Unable to create object stream writing to temporary file " + nodeStorageFile + ".", e); } } } private void initializeReadingStage() { // If we're already in the reading stage, do nothing. if (stage.compareTo(StorageStage.Reading) == 0) { return; } // If we've been released, we can't iterate. if (stage.compareTo(StorageStage.Released) >= 0) { throw new OsmosisRuntimeException("Cannot read from node storage in stage " + stage + "."); } // If no data was written, writing should be initialized before reading. if (stage.compareTo(StorageStage.NotStarted) <= 0) { initializeAddStage(); } // If we're in the add stage, close the output streams. if (stage.compareTo(StorageStage.Add) == 0) { try { dataOutStream.close(); fileOutStream.close(); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to close output stream.", e); } finally { dataOutStream = null; fileOutStream = null; } try { fileInStream = new BufferedRandomAccessFileInputStream(nodeStorageFile); dataInStream = new DataInputStream(fileInStream); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to open the node data file " + nodeStorageFile + ".", e); } stage = StorageStage.Reading; } } /** * {@inheritDoc} */ @Override public void addLocation(long nodeId, NodeLocation nodeLocation) { long requiredFileOffset; initializeAddStage(); // We can only add nodes in sorted order. if (nodeId <= lastNodeId) { throw new OsmosisRuntimeException( "The node id of " + nodeId + " must be greater than the previous id of " + lastNodeId + "." ); } lastNodeId = nodeId; try { // Write zeros to the file where no node data is available. requiredFileOffset = nodeId * NODE_DATA_SIZE; if (requiredFileOffset > currentFileOffset) { while (currentFileOffset < requiredFileOffset) { long offsetDifference; offsetDifference = requiredFileOffset - currentFileOffset; if (offsetDifference > ZERO_BUFFER_SIZE) { offsetDifference = ZERO_BUFFER_SIZE; } dataOutStream.write(zeroBuffer, 0, (int) offsetDifference); currentFileOffset += offsetDifference; } } // Write the node data. Prefix with a non-zero byte to identify that // data is available for this node. dataOutStream.writeByte(1); dataOutStream.writeInt(FixedPrecisionCoordinateConvertor.convertToFixed(nodeLocation.getLongitude())); dataOutStream.writeInt(FixedPrecisionCoordinateConvertor.convertToFixed(nodeLocation.getLatitude())); currentFileOffset += NODE_DATA_SIZE; } catch (IOException e) { throw new OsmosisRuntimeException( "Unable to write node location data to node storage file " + nodeStorageFile + ".", e ); } } /** * {@inheritDoc} */ @Override public NodeLocation getNodeLocation(long nodeId) { NodeLocation nodeLocation; long offset; initializeReadingStage(); offset = nodeId * NODE_DATA_SIZE; nodeLocation = invalidNodeLocation; if (offset < currentFileOffset) { try { byte validFlag; fileInStream.seek(offset); validFlag = dataInStream.readByte(); if (validFlag != 0) { nodeLocation = new NodeLocation( FixedPrecisionCoordinateConvertor.convertToDouble(dataInStream.readInt()), FixedPrecisionCoordinateConvertor.convertToDouble(dataInStream.readInt()) ); } } catch (IOException e) { throw new OsmosisRuntimeException("Unable to read node information from the node storage file.", e); } } return nodeLocation; } /** * {@inheritDoc} */ @Override public void release() { if (fileOutStream != null) { try { fileOutStream.close(); } catch (Exception e) { // We cannot throw an exception within a release method. LOG.log(Level.WARNING, "Unable to close file output stream.", e); } fileOutStream = null; } if (fileInStream != null) { try { fileInStream.close(); } catch (Exception e) { // We cannot throw an exception within a release method. LOG.log(Level.WARNING, "Unable to close file input stream.", e); } fileInStream = null; } if (nodeStorageFile != null) { if (!nodeStorageFile.delete()) { // We cannot throw an exception within a release method. LOG.warning("Unable to delete file " + nodeStorageFile); } nodeStorageFile = null; } } } PointBuilder.java000066400000000000000000000013321253404521400356220ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.common; import org.postgis.Point; /** * Builds PostGIS Point objects based on a set of coordinates. * * @author Brett Henderson */ public class PointBuilder { /** * Creates a PostGIS Point object corresponding to the provided coordinates. * * @param latitude * The latitude measured in degrees. * @param longitude * The longitude measured in degrees. * @return The Point object. */ public Point createPoint(double latitude, double longitude) { Point result; result = new Point(longitude, latitude); result.srid = 4326; return result; } } PolygonBuilder.java000066400000000000000000000013421253404521400361610ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.common; import org.postgis.LinearRing; import org.postgis.Point; import org.postgis.Polygon; /** * Builds PostGIS Polygon objects based on a series of points. * * @author Brett Henderson */ public class PolygonBuilder { /** * Creates a PostGIS Polygon object corresponding to the provided Point * list. * * @param points * The points to build a polygon from. * @return The Polygon object. */ public Polygon createPolygon(Point[] points) { Polygon result; result = new Polygon(new LinearRing[] {new LinearRing(points)}); result.srid = 4326; return result; } } RowMapperRowCallbackListener.java000066400000000000000000000024101253404521400407470ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.common; import java.sql.ResultSet; import java.sql.SQLException; import org.openstreetmap.osmosis.core.database.RowMapperListener; import org.springframework.jdbc.core.RowCallbackHandler; import org.springframework.jdbc.core.RowMapper; /** * Combines the functionality of Spring RowMapper and RowCallbackHandler allowing a single RowMapper * implementation to be used for streaming operations. * * @author Brett Henderson * * @param * The entity type to be supported. */ public class RowMapperRowCallbackListener implements RowCallbackHandler { private RowMapper rowMapper; private RowMapperListener listener; /** * Creates a new instance. * * @param rowMapper * The row mapper used to convert rows into objects. * @param listener * The receiver of created records. */ public RowMapperRowCallbackListener(RowMapper rowMapper, RowMapperListener listener) { this.rowMapper = rowMapper; this.listener = listener; } /** * {@inheritDoc} */ @Override public void processRow(ResultSet rs) throws SQLException { listener.process(rowMapper.mapRow(rs, 0), rs); } } SchemaVersionValidator.java000066400000000000000000000040051253404521400376360ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.common; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.springframework.jdbc.core.JdbcTemplate; /** * Reads the version number stored in the schema_info table and verifies that it * matches the expected version. * * @author Brett Henderson */ public class SchemaVersionValidator { private static final String SELECT_SQL = "SELECT version FROM schema_info"; private DatabasePreferences preferences; private JdbcTemplate jdbcTemplate; private boolean validated; /** * Creates a new instance. * * @param jdbcTemplate * Provides access to the database. * @param preferences * The database preferences. */ public SchemaVersionValidator(JdbcTemplate jdbcTemplate, DatabasePreferences preferences) { this.jdbcTemplate = jdbcTemplate; this.preferences = preferences; } /** * Validates that the version number of the schema matches the expected * version. This method caches the result allowing it to be called multiple * times without a performance penalty. * * @param expectedVersion * The expected version number. */ public void validateVersion(int expectedVersion) { if (!validated) { validateDBVersion(expectedVersion); validated = true; } } /** * Performs the database lookup and validates the expected version. * * @param expectedVersion * The expected version number. */ private void validateDBVersion(int expectedVersion) { if (preferences.getValidateSchemaVersion()) { int dbVersion; dbVersion = jdbcTemplate.queryForObject(SELECT_SQL, Integer.class); if (dbVersion != expectedVersion) { throw new OsmosisRuntimeException( "The database schema version of " + dbVersion + " does not match the expected version of " + expectedVersion + "." ); } } } } osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/000077500000000000000000000000001253404521400317215ustar00rootroot00000000000000PostgreSqlChangeWriter.java000066400000000000000000000072271253404521400371230ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.task.common.ChangeAction; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.pgsnapshot.common.DatabaseContext; import org.openstreetmap.osmosis.pgsnapshot.common.SchemaVersionValidator; import org.openstreetmap.osmosis.pgsnapshot.v0_6.impl.ActionChangeWriter; import org.openstreetmap.osmosis.pgsnapshot.v0_6.impl.ChangeWriter; /** * A change sink writing to database tables. This aims to be suitable for * running at regular intervals with database overhead proportional to changeset * size. * * @author Brett Henderson */ public class PostgreSqlChangeWriter implements ChangeSink { private ChangeWriter changeWriter; private Map actionWriterMap; private DatabaseContext dbCtx; private SchemaVersionValidator schemaVersionValidator; private boolean initialized; /** * Creates a new instance. * * @param loginCredentials * Contains all information required to connect to the database. * @param preferences * Contains preferences configuring database behaviour. * @param keepInvalidWays * If true, zero and single node ways are kept. Otherwise they are * silently dropped to avoid putting invalid geometries into the * database which can cause problems with postgis functions. */ public PostgreSqlChangeWriter(DatabaseLoginCredentials loginCredentials, DatabasePreferences preferences, boolean keepInvalidWays) { dbCtx = new DatabaseContext(loginCredentials); changeWriter = new ChangeWriter(dbCtx); actionWriterMap = new HashMap(); actionWriterMap.put(ChangeAction.Create, new ActionChangeWriter(changeWriter, ChangeAction.Create, keepInvalidWays)); actionWriterMap.put(ChangeAction.Modify, new ActionChangeWriter(changeWriter, ChangeAction.Modify, keepInvalidWays)); actionWriterMap.put(ChangeAction.Delete, new ActionChangeWriter(changeWriter, ChangeAction.Delete, keepInvalidWays)); schemaVersionValidator = new SchemaVersionValidator(dbCtx.getJdbcTemplate(), preferences); initialized = false; } private void initialize() { if (!initialized) { dbCtx.beginTransaction(); initialized = true; } } /** * {@inheritDoc} */ public void initialize(Map metaData) { // Do nothing. } /** * {@inheritDoc} */ public void process(ChangeContainer change) { ChangeAction action; initialize(); // Verify that the schema version is supported. schemaVersionValidator.validateVersion(PostgreSqlVersionConstants.SCHEMA_VERSION); action = change.getAction(); if (!actionWriterMap.containsKey(action)) { throw new OsmosisRuntimeException("The action " + action + " is unrecognized."); } // Process the entity using the action writer appropriate for the change // action. change.getEntityContainer().process(actionWriterMap.get(action)); } /** * {@inheritDoc} */ public void complete() { initialize(); changeWriter.complete(); dbCtx.commitTransaction(); } /** * {@inheritDoc} */ public void release() { changeWriter.release(); dbCtx.release(); } } PostgreSqlChangeWriterFactory.java000066400000000000000000000027701253404521400404510ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.database.DatabaseTaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.v0_6.ChangeSinkManager; /** * The task manager factory for a database change writer. * * @author Brett Henderson */ public class PostgreSqlChangeWriterFactory extends DatabaseTaskManagerFactory { private static final String ARG_KEEP_INVALID_WAYS = "keepInvalidWays"; private static final boolean DEFAULT_KEEP_INVALID_WAYS = true; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { DatabaseLoginCredentials loginCredentials; DatabasePreferences preferences; // Get the task arguments. loginCredentials = getDatabaseLoginCredentials(taskConfig); preferences = getDatabasePreferences(taskConfig); boolean keepInvalidWays = getBooleanArgument(taskConfig, ARG_KEEP_INVALID_WAYS, DEFAULT_KEEP_INVALID_WAYS); return new ChangeSinkManager( taskConfig.getId(), new PostgreSqlChangeWriter( loginCredentials, preferences, keepInvalidWays ), taskConfig.getPipeArgs() ); } } PostgreSqlCopyWriter.java000066400000000000000000000102671253404521400366460ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6; import java.util.Map; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.pgsnapshot.common.DatabaseContext; import org.openstreetmap.osmosis.pgsnapshot.common.NodeLocationStoreType; import org.openstreetmap.osmosis.pgsnapshot.v0_6.impl.CopyFilesetBuilder; import org.openstreetmap.osmosis.pgsnapshot.v0_6.impl.CopyFilesetLoader; import org.openstreetmap.osmosis.pgsnapshot.v0_6.impl.DatabaseCapabilityChecker; import org.openstreetmap.osmosis.pgsnapshot.v0_6.impl.TempCopyFileset; /** * An OSM data sink for storing all data to a database using the COPY command. * This task is intended for writing to an empty database. * * @author Brett Henderson */ public class PostgreSqlCopyWriter implements Sink { private static final Logger LOG = Logger.getLogger(PostgreSqlCopyWriter.class.getName()); private CopyFilesetBuilder copyFilesetBuilder; private CopyFilesetLoader copyFilesetLoader; private TempCopyFileset copyFileset; private DatabaseLoginCredentials loginCredentials; private DatabasePreferences preferences; private NodeLocationStoreType storeType; private boolean populateBbox; private boolean populateLinestring; private boolean keepInvalidWays; private boolean initialized; /** * Creates a new instance. * * @param loginCredentials * Contains all information required to connect to the database. * @param preferences * Contains preferences configuring database behaviour. * @param storeType * The node location storage type used by the geometry builders. * @param keepInvalidWays * If true, zero and single node ways are kept. Otherwise they are * silently dropped to avoid putting invalid geometries into the * database which can cause problems with postgis functions. */ public PostgreSqlCopyWriter( DatabaseLoginCredentials loginCredentials, DatabasePreferences preferences, NodeLocationStoreType storeType, boolean keepInvalidWays) { this.loginCredentials = loginCredentials; this.preferences = preferences; this.storeType = storeType; this.keepInvalidWays = keepInvalidWays; copyFileset = new TempCopyFileset(); } private void initialize() { if (!initialized) { DatabaseContext dbCtx; DatabaseCapabilityChecker capabilityChecker; LOG.fine("Initializing the database and temporary processing files."); dbCtx = new DatabaseContext(loginCredentials); try { capabilityChecker = new DatabaseCapabilityChecker(dbCtx); populateBbox = capabilityChecker.isWayBboxSupported(); populateLinestring = capabilityChecker.isWayLinestringSupported(); } finally { dbCtx.release(); } copyFilesetBuilder = new CopyFilesetBuilder(copyFileset, populateBbox, populateLinestring, storeType, keepInvalidWays); copyFilesetLoader = new CopyFilesetLoader(loginCredentials, preferences, copyFileset); LOG.fine("Processing input data, building geometries and creating database load files."); initialized = true; } } /** * {@inheritDoc} */ public void initialize(Map metaData) { // Do nothing. } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { initialize(); copyFilesetBuilder.process(entityContainer); } /** * Writes any buffered data to the files, then loads the files into the database. */ public void complete() { initialize(); copyFilesetBuilder.complete(); LOG.fine("All data has been received, beginning database load."); copyFilesetLoader.run(); LOG.fine("Processing complete."); } /** * Releases all database resources. */ public void release() { if (copyFilesetBuilder != null) { copyFilesetBuilder.release(); copyFilesetBuilder = null; } copyFileset.release(); initialized = false; } } PostgreSqlCopyWriterFactory.java000066400000000000000000000037001253404521400401700ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.database.DatabaseTaskManagerFactory; import org.openstreetmap.osmosis.pgsnapshot.common.NodeLocationStoreType; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkManager; /** * The task manager factory for a database writer using the PostgreSQL COPY method. * * @author Brett Henderson */ public class PostgreSqlCopyWriterFactory extends DatabaseTaskManagerFactory { private static final String ARG_NODE_LOCATION_STORE_TYPE = "nodeLocationStoreType"; private static final String DEFAULT_NODE_LOCATION_STORE_TYPE = "CompactTempFile"; private static final String ARG_KEEP_INVALID_WAYS = "keepInvalidWays"; private static final boolean DEFAULT_KEEP_INVALID_WAYS = true; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { DatabaseLoginCredentials loginCredentials; DatabasePreferences preferences; NodeLocationStoreType storeType; boolean keepInvalidWays; // Get the task arguments. loginCredentials = getDatabaseLoginCredentials(taskConfig); preferences = getDatabasePreferences(taskConfig); storeType = Enum.valueOf( NodeLocationStoreType.class, getStringArgument(taskConfig, ARG_NODE_LOCATION_STORE_TYPE, DEFAULT_NODE_LOCATION_STORE_TYPE)); keepInvalidWays = getBooleanArgument(taskConfig, ARG_KEEP_INVALID_WAYS, DEFAULT_KEEP_INVALID_WAYS); return new SinkManager( taskConfig.getId(), new PostgreSqlCopyWriter(loginCredentials, preferences, storeType, keepInvalidWays), taskConfig.getPipeArgs() ); } } PostgreSqlDatasetReader.java000066400000000000000000000034471253404521400372510ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6; import org.openstreetmap.osmosis.core.container.v0_6.Dataset; import org.openstreetmap.osmosis.core.container.v0_6.DatasetContext; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.pgsnapshot.v0_6.impl.PostgreSqlDatasetContext; import org.openstreetmap.osmosis.core.task.v0_6.DatasetSink; import org.openstreetmap.osmosis.core.task.v0_6.RunnableDatasetSource; /** * An OSM dataset source exposing generic access to a custom PostgreSQL database. * * @author Brett Henderson */ public class PostgreSqlDatasetReader implements RunnableDatasetSource, Dataset { private DatasetSink datasetSink; private DatabaseLoginCredentials loginCredentials; private DatabasePreferences preferences; /** * Creates a new instance. * * @param loginCredentials * Contains all information required to connect to the database. * @param preferences * Contains preferences configuring database behaviour. */ public PostgreSqlDatasetReader(DatabaseLoginCredentials loginCredentials, DatabasePreferences preferences) { this.loginCredentials = loginCredentials; this.preferences = preferences; } /** * {@inheritDoc} */ @Override public void setDatasetSink(DatasetSink datasetSink) { this.datasetSink = datasetSink; } /** * {@inheritDoc} */ @Override public void run() { try { datasetSink.process(this); } finally { datasetSink.release(); } } /** * {@inheritDoc} */ @Override public DatasetContext createReader() { return new PostgreSqlDatasetContext(loginCredentials, preferences); } } PostgreSqlDatasetReaderFactory.java000066400000000000000000000023541253404521400405750ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.database.DatabaseTaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.v0_6.RunnableDatasetSourceManager; /** * The task manager factory for a database reader. * * @author Brett Henderson */ public class PostgreSqlDatasetReaderFactory extends DatabaseTaskManagerFactory { /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { DatabaseLoginCredentials loginCredentials; DatabasePreferences preferences; // Get the task arguments. loginCredentials = getDatabaseLoginCredentials(taskConfig); preferences = getDatabasePreferences(taskConfig); return new RunnableDatasetSourceManager( taskConfig.getId(), new PostgreSqlDatasetReader(loginCredentials, preferences), taskConfig.getPipeArgs() ); } } PostgreSqlDumpWriter.java000066400000000000000000000053331253404521400366370ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6; import java.io.File; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.pgsnapshot.common.NodeLocationStoreType; import org.openstreetmap.osmosis.pgsnapshot.v0_6.impl.DirectoryCopyFileset; import org.openstreetmap.osmosis.pgsnapshot.v0_6.impl.CopyFilesetBuilder; import org.openstreetmap.osmosis.core.task.v0_6.Sink; /** * An OSM data sink for storing all data to database dump files. This task is * intended for populating an empty database. * * @author Brett Henderson */ public class PostgreSqlDumpWriter implements Sink { private CopyFilesetBuilder copyFilesetBuilder; /** * Creates a new instance. * * @param filePrefix * The prefix to prepend to all generated file names. * @param enableBboxBuilder * If true, the way bbox geometry is built during processing * instead of relying on the database to build them after import. * This increases processing but is faster than relying on the * database. * @param enableLinestringBuilder * If true, the way linestring geometry is built during * processing instead of relying on the database to build them * after import. This increases processing but is faster than * relying on the database. * @param storeType * The node location storage type used by the geometry builders. * @param keepInvalidWays * If true, zero and single node ways are kept. Otherwise they are * silently dropped to avoid putting invalid geometries into the * database which can cause problems with postgis functions. */ public PostgreSqlDumpWriter( File filePrefix, boolean enableBboxBuilder, boolean enableLinestringBuilder, NodeLocationStoreType storeType, boolean keepInvalidWays) { DirectoryCopyFileset copyFileset; copyFileset = new DirectoryCopyFileset(filePrefix); copyFilesetBuilder = new CopyFilesetBuilder(copyFileset, enableBboxBuilder, enableLinestringBuilder, storeType, keepInvalidWays); } /** * {@inheritDoc} */ public void initialize(Map metaData) { // Do nothing. } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { copyFilesetBuilder.process(entityContainer); } /** * Writes any buffered data to the database and commits. */ public void complete() { copyFilesetBuilder.complete(); } /** * Releases all database resources. */ public void release() { copyFilesetBuilder.release(); } } PostgreSqlDumpWriterFactory.java000066400000000000000000000051531253404521400401670ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6; import java.io.File; import org.openstreetmap.osmosis.pgsnapshot.common.NodeLocationStoreType; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkManager; /** * The task manager factory for a database dump writer. * * @author Brett Henderson */ public class PostgreSqlDumpWriterFactory extends TaskManagerFactory { private static final String ARG_ENABLE_BBOX_BUILDER = "enableBboxBuilder"; private static final String ARG_ENABLE_LINESTRING_BUILDER = "enableLinestringBuilder"; private static final String ARG_KEEP_INVALID_WAYS = "keepInvalidWays"; private static final String ARG_FILE_NAME = "directory"; private static final String ARG_NODE_LOCATION_STORE_TYPE = "nodeLocationStoreType"; private static final boolean DEFAULT_ENABLE_BBOX_BUILDER = false; private static final boolean DEFAULT_ENABLE_LINESTRING_BUILDER = false; private static final boolean DEFAULT_KEEP_INVALID_WAYS = true; private static final String DEFAULT_FILE_PREFIX = "pgimport"; private static final String DEFAULT_NODE_LOCATION_STORE_TYPE = "CompactTempFile"; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String filePrefixString; File filePrefix; boolean enableBboxBuilder; boolean enableLinestringBuilder; boolean keepInvalidWays; NodeLocationStoreType storeType; // Get the task arguments. filePrefixString = getStringArgument( taskConfig, ARG_FILE_NAME, DEFAULT_FILE_PREFIX); enableBboxBuilder = getBooleanArgument( taskConfig, ARG_ENABLE_BBOX_BUILDER, DEFAULT_ENABLE_BBOX_BUILDER); enableLinestringBuilder = getBooleanArgument( taskConfig, ARG_ENABLE_LINESTRING_BUILDER, DEFAULT_ENABLE_LINESTRING_BUILDER); keepInvalidWays = getBooleanArgument(taskConfig, ARG_KEEP_INVALID_WAYS, DEFAULT_KEEP_INVALID_WAYS); storeType = Enum.valueOf( NodeLocationStoreType.class, getStringArgument(taskConfig, ARG_NODE_LOCATION_STORE_TYPE, DEFAULT_NODE_LOCATION_STORE_TYPE)); // Create a file object representing the directory from the file name provided. filePrefix = new File(filePrefixString); return new SinkManager( taskConfig.getId(), new PostgreSqlDumpWriter( filePrefix, enableBboxBuilder, enableLinestringBuilder, storeType, keepInvalidWays), taskConfig.getPipeArgs() ); } } PostgreSqlTruncator.java000066400000000000000000000047461253404521400365250ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.task.common.RunnableTask; import org.openstreetmap.osmosis.pgsnapshot.common.DatabaseContext; import org.openstreetmap.osmosis.pgsnapshot.common.SchemaVersionValidator; /** * A standalone OSM task with no inputs or outputs that truncates tables in a * PostgreSQL database. This is used for removing all existing data from tables. * * @author Brett Henderson */ public class PostgreSqlTruncator implements RunnableTask { private static final Logger LOG = Logger.getLogger(PostgreSqlTruncator.class.getName()); // These tables will be truncated. private static final String[] SQL_TABLE_NAMES = { "actions", "users", "nodes", "node_tags", "ways", "way_tags", "way_nodes", "relations", "relation_tags", "relation_members" }; private DatabaseContext dbCtx; private SchemaVersionValidator schemaVersionValidator; /** * Creates a new instance. * * @param loginCredentials * Contains all information required to connect to the database. * @param preferences * Contains preferences configuring database behaviour. */ public PostgreSqlTruncator(DatabaseLoginCredentials loginCredentials, DatabasePreferences preferences) { dbCtx = new DatabaseContext(loginCredentials); schemaVersionValidator = new SchemaVersionValidator(dbCtx.getJdbcTemplate(), preferences); } /** * Truncates all data from the database. */ public void run() { try { schemaVersionValidator.validateVersion(PostgreSqlVersionConstants.SCHEMA_VERSION); dbCtx.beginTransaction(); LOG.fine("Truncating tables."); for (int i = 0; i < SQL_TABLE_NAMES.length; i++) { if (dbCtx.doesTableExist(SQL_TABLE_NAMES[i])) { LOG.finer("Truncating table " + SQL_TABLE_NAMES[i] + "."); dbCtx.getJdbcTemplate().update("TRUNCATE " + SQL_TABLE_NAMES[i]); } else { LOG.finer("Skipping table " + SQL_TABLE_NAMES[i] + " which doesn't exist in the current schema."); } } LOG.fine("Committing changes."); dbCtx.commitTransaction(); LOG.fine("Vacuuming database."); dbCtx.getJdbcTemplate().update("VACUUM ANALYZE"); LOG.fine("Complete."); } finally { dbCtx.release(); } } } PostgreSqlTruncatorFactory.java000066400000000000000000000016461253404521400400510ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6; import org.openstreetmap.osmosis.core.database.DatabaseTaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.common.RunnableTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; /** * The task manager factory for a database table truncator. * * @author Brett Henderson */ public class PostgreSqlTruncatorFactory extends DatabaseTaskManagerFactory { /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { return new RunnableTaskManager( taskConfig.getId(), new PostgreSqlTruncator( getDatabaseLoginCredentials(taskConfig), getDatabasePreferences(taskConfig) ), taskConfig.getPipeArgs() ); } } PostgreSqlVersionConstants.java000066400000000000000000000007521253404521400400570ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6; /** * Defines constants specific to the specific schema version. * * @author Brett Henderson */ public final class PostgreSqlVersionConstants { private PostgreSqlVersionConstants() { // This class cannot be instantiated. } /** * Defines the schema version number currently supported. */ public static final int SCHEMA_VERSION = 6; } osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl/000077500000000000000000000000001253404521400326625ustar00rootroot00000000000000ActionChangeWriter.java000066400000000000000000000037761253404521400372030ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityProcessor; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.task.common.ChangeAction; /** * Writes entities to a database according to a specific action. * * @author Brett Henderson */ public class ActionChangeWriter implements EntityProcessor { private ChangeWriter changeWriter; private ChangeAction action; private boolean keepInvalidWays; /** * Creates a new instance. * * @param changeWriter * The underlying change writer. * @param action * The action to apply to all writes. * @param keepInvalidWays * If true, zero and single node ways are kept. Otherwise they are * silently dropped to avoid putting invalid geometries into the * database which can cause problems with postgis functions. */ public ActionChangeWriter(ChangeWriter changeWriter, ChangeAction action, boolean keepInvalidWays) { this.changeWriter = changeWriter; this.action = action; this.keepInvalidWays = keepInvalidWays; } /** * {@inheritDoc} */ public void process(BoundContainer bound) { // Do nothing. } /** * {@inheritDoc} */ public void process(NodeContainer nodeContainer) { changeWriter.write(nodeContainer.getEntity(), action); } /** * {@inheritDoc} */ public void process(WayContainer wayContainer) { changeWriter.write(wayContainer.getEntity(), action, keepInvalidWays); } /** * {@inheritDoc} */ public void process(RelationContainer relationContainer) { changeWriter.write(relationContainer.getEntity(), action); } } ActionDao.java000066400000000000000000000030131253404521400353040ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import org.openstreetmap.osmosis.pgsnapshot.common.DatabaseContext; import org.springframework.jdbc.core.JdbcTemplate; /** * Performs all action db operations. * * @author Brett Henderson */ public class ActionDao { private static final String SQL_INSERT = "INSERT INTO actions(data_type, action, id) VALUES(?, ?, ?)"; private static final String SQL_TRUNCATE = "TRUNCATE actions"; private JdbcTemplate jdbcTemplate; private DatabaseCapabilityChecker capabilityChecker; /** * Creates a new instance. * * @param dbCtx * The database context to use for accessing the database. */ public ActionDao(DatabaseContext dbCtx) { jdbcTemplate = dbCtx.getJdbcTemplate(); capabilityChecker = new DatabaseCapabilityChecker(dbCtx); } /** * Adds the specified action to the database. * * @param dataType The type of data being represented by this action. * @param action The action being performed on the data. * @param id The identifier of the data. */ public void addAction(ActionDataType dataType, ChangesetAction action, long id) { if (capabilityChecker.isActionSupported()) { jdbcTemplate.update(SQL_INSERT, dataType.getDatabaseValue(), action.getDatabaseValue(), id); } } /** * Removes all action records. */ public void truncate() { if (capabilityChecker.isActionSupported()) { jdbcTemplate.update(SQL_TRUNCATE); } } } ActionDataType.java000066400000000000000000000013151253404521400363170ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; /** * Defines all the data types supported by the action table. * * @author Brett Henderson */ public enum ActionDataType { /** * A user record. */ USER("U"), /** * A node entity. */ NODE("N"), /** * A way entity. */ WAY("W"), /** * A relation entity. */ RELATION("R"); private final String dbValue; private ActionDataType(String dbValue) { this.dbValue = dbValue; } /** * Returns the database value representing this action. * * @return The database value. */ public String getDatabaseValue() { return dbValue; } } ChangeWriter.java000066400000000000000000000143541253404521400360370ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashSet; import java.util.Set; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.task.common.ChangeAction; import org.openstreetmap.osmosis.pgsnapshot.common.DatabaseContext; import org.openstreetmap.osmosis.pgsnapshot.common.NoSuchRecordException; import org.springframework.jdbc.core.CallableStatementCreator; import org.springframework.jdbc.core.SqlParameter; /** * Writes changes to a database. * * @author Brett Henderson */ public class ChangeWriter { private DatabaseContext dbCtx; private ActionDao actionDao; private UserDao userDao; private NodeDao nodeDao; private WayDao wayDao; private RelationDao relationDao; private Set userSet; /** * Creates a new instance. * * @param dbCtx * The database context to use for accessing the database. */ public ChangeWriter(DatabaseContext dbCtx) { this.dbCtx = dbCtx; actionDao = new ActionDao(dbCtx); userDao = new UserDao(dbCtx, actionDao); nodeDao = new NodeDao(dbCtx, actionDao); wayDao = new WayDao(dbCtx, actionDao); relationDao = new RelationDao(dbCtx, actionDao); userSet = new HashSet(); } /** * Writes the specified user to the database. * * @param user * The user to write. */ private void writeUser(OsmUser user) { // Entities without a user assigned should not be written. if (!OsmUser.NONE.equals(user)) { // Users will only be updated in the database once per changeset // run. if (!userSet.contains(user.getId())) { int userId; OsmUser existingUser; userId = user.getId(); try { existingUser = userDao.getUser(userId); if (!user.equals(existingUser)) { userDao.updateUser(user); } } catch (NoSuchRecordException e) { userDao.addUser(user); } userSet.add(user.getId()); } } } /** * Performs any validation and pre-processing required for all entity types. */ private void processEntityPrerequisites(Entity entity) { // We can't write an entity with a null timestamp. if (entity.getTimestamp() == null) { throw new OsmosisRuntimeException("Entity(" + entity.getType() + ") " + entity.getId() + " does not have a timestamp set."); } // Process the user data. writeUser(entity.getUser()); } /** * Writes the specified node change to the database. * * @param node * The node to be written. * @param action * The change to be applied. */ public void write(Node node, ChangeAction action) { processEntityPrerequisites(node); // If this is a create or modify, we must create or modify the records // in the database. Note that we don't use the input source to // distinguish between create and modify, we make this determination // based on our current data set. if (ChangeAction.Create.equals(action) || ChangeAction.Modify.equals(action)) { if (nodeDao.exists(node.getId())) { nodeDao.modifyEntity(node); } else { nodeDao.addEntity(node); } } else { // Remove the node from the database. nodeDao.removeEntity(node.getId()); } } /** * Writes the specified way change to the database. * * @param way * The way to be written. * @param action * The change to be applied. * @param keepInvalidWays * If true, zero and single node ways are kept. Otherwise they are * silently dropped to avoid putting invalid geometries into the * database which can cause problems with postgis functions. */ public void write(Way way, ChangeAction action, boolean keepInvalidWays) { processEntityPrerequisites(way); // If this is a create or modify, we must create or modify the records // in the database. Note that we don't use the input source to // distinguish between create and modify, we make this determination // based on our current data set. if (ChangeAction.Create.equals(action) || ChangeAction.Modify.equals(action)) { if (wayDao.exists(way.getId())) { if (way.getWayNodes().size() >= 2 || keepInvalidWays) { wayDao.modifyEntity(way); } else { wayDao.removeEntity(way.getId()); } } else { if (way.getWayNodes().size() >= 2 || keepInvalidWays) { wayDao.addEntity(way); } } } else { // Remove the way from the database. wayDao.removeEntity(way.getId()); } } /** * Writes the specified relation change to the database. * * @param relation * The relation to be written. * @param action * The change to be applied. */ public void write(Relation relation, ChangeAction action) { processEntityPrerequisites(relation); // If this is a create or modify, we must create or modify the records // in the database. Note that we don't use the input source to // distinguish between create and modify, we make this determination // based on our current data set. if (ChangeAction.Create.equals(action) || ChangeAction.Modify.equals(action)) { if (relationDao.exists(relation.getId())) { relationDao.modifyEntity(relation); } else { relationDao.addEntity(relation); } } else { // Remove the relation from the database. relationDao.removeEntity(relation.getId()); } } /** * Performs post-change database updates. */ public void complete() { dbCtx.getJdbcTemplate().call( new CallableStatementCreator() { @Override public CallableStatement createCallableStatement(Connection con) throws SQLException { return con.prepareCall("{call osmosisUpdate()}"); } }, new ArrayList()); // Clear all action records. actionDao.truncate(); } /** * Releases all resources. */ public void release() { // Nothing to do. } } ChangesetAction.java000066400000000000000000000015641253404521400365130ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; /** * Defines the values for the "action" columns in the pgsql schema. These * actions define what activity has been performed on an entity during * application of a changeset. * * @author Brett Henderson */ public enum ChangesetAction { /** * No entity is unchanged. */ NONE("N"), /** * The entity has been added. */ CREATE("C"), /** * The entity has been modified. */ MODIFY("M"), /** * The entity has been deleted. */ DELETE("D"); private final String dbValue; private ChangesetAction(String dbValue) { this.dbValue = dbValue; } /** * Returns the database value representing this action. * * @return The database value. */ public String getDatabaseValue() { return dbValue; } } CopyFileset.java000066400000000000000000000017641253404521400357040ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.io.File; /** * A copy fileset is a collection of files in the PostgreSQL "COPY" format that * can be used to populate the database. * * @author Brett Henderson */ public interface CopyFileset { /** * Gets the user table file. * * @return The user table file. */ File getUserFile(); /** * Gets the node table file. * * @return The node table file. */ File getNodeFile(); /** * Gets the way table file. * * @return The way table file. */ File getWayFile(); /** * Gets the way node table file. * * @return The way node table file. */ File getWayNodeFile(); /** * Gets the relation table file. * * @return The relation table file. */ File getRelationFile(); /** * Gets the relation member table file. * * @return The relation member table file. */ File getRelationMemberFile(); } CopyFilesetBuilder.java000066400000000000000000000206351253404521400372110ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityProcessor; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.openstreetmap.osmosis.core.lifecycle.CompletableContainer; import org.openstreetmap.osmosis.pgsnapshot.common.CopyFileWriter; import org.openstreetmap.osmosis.pgsnapshot.common.NodeLocationStoreType; import org.openstreetmap.osmosis.pgsnapshot.common.PointBuilder; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.hstore.PGHStore; /** * An OSM data sink for storing all data to a set of database dump files. These * files can be used for populating an empty database. * * @author Brett Henderson */ public class CopyFilesetBuilder implements Sink, EntityProcessor { private boolean enableBboxBuilder; private boolean enableLinestringBuilder; private boolean keepInvalidWays; private WayGeometryBuilder wayGeometryBuilder; private CompletableContainer writerContainer; private MemberTypeValueMapper memberTypeValueMapper; private CopyFileWriter userWriter; private CopyFileWriter nodeWriter; private CopyFileWriter wayWriter; private CopyFileWriter wayNodeWriter; private CopyFileWriter relationWriter; private CopyFileWriter relationMemberWriter; private PointBuilder pointBuilder; private Set userSet; /** * Creates a new instance. * * @param copyFileset * The set of COPY files to be populated. * @param enableBboxBuilder * If true, the way bbox geometry is built during processing * instead of relying on the database to build them after import. * This increases processing but is faster than relying on the * database. * @param enableLinestringBuilder * If true, the way linestring geometry is built during * processing instead of relying on the database to build them * after import. This increases processing but is faster than * relying on the database. * @param storeType * The node location storage type used by the geometry builders. * @param keepInvalidWays * If true, zero and single node ways are kept. Otherwise they are * silently dropped to avoid putting invalid geometries into the * database which can cause problems with postgis functions. */ public CopyFilesetBuilder( CopyFileset copyFileset, boolean enableBboxBuilder, boolean enableLinestringBuilder, NodeLocationStoreType storeType, boolean keepInvalidWays) { this.enableBboxBuilder = enableBboxBuilder; this.enableLinestringBuilder = enableLinestringBuilder; this.keepInvalidWays = keepInvalidWays; writerContainer = new CompletableContainer(); userWriter = writerContainer.add(new CopyFileWriter(copyFileset.getUserFile())); nodeWriter = writerContainer.add(new CopyFileWriter(copyFileset.getNodeFile())); wayWriter = writerContainer.add(new CopyFileWriter(copyFileset.getWayFile())); wayNodeWriter = writerContainer.add(new CopyFileWriter(copyFileset.getWayNodeFile())); relationWriter = writerContainer.add(new CopyFileWriter(copyFileset.getRelationFile())); relationMemberWriter = writerContainer.add(new CopyFileWriter(copyFileset.getRelationMemberFile())); pointBuilder = new PointBuilder(); wayGeometryBuilder = new WayGeometryBuilder(storeType); memberTypeValueMapper = new MemberTypeValueMapper(); memberTypeValueMapper = new MemberTypeValueMapper(); userSet = new HashSet(); } /** * {@inheritDoc} */ public void initialize(Map metaData) { // Do nothing. } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { OsmUser user; // Write a user entry if the user doesn't already exist. user = entityContainer.getEntity().getUser(); if (!user.equals(OsmUser.NONE)) { if (!userSet.contains(user.getId())) { userWriter.writeField(user.getId()); userWriter.writeField(user.getName()); userWriter.endRecord(); userSet.add(user.getId()); } } // Process the entity itself. entityContainer.process(this); } /** * {@inheritDoc} */ public void process(BoundContainer boundContainer) { // Do nothing. } private PGHStore buildTags(Entity entity) { PGHStore tags; tags = new PGHStore(); for (Tag tag : entity.getTags()) { tags.put(tag.getKey(), tag.getValue()); } return tags; } /** * {@inheritDoc} */ public void process(NodeContainer nodeContainer) { Node node; node = nodeContainer.getEntity(); nodeWriter.writeField(node.getId()); nodeWriter.writeField(node.getVersion()); nodeWriter.writeField(node.getUser().getId()); nodeWriter.writeField(node.getTimestamp()); nodeWriter.writeField(node.getChangesetId()); nodeWriter.writeField(buildTags(node)); nodeWriter.writeField(pointBuilder.createPoint(node.getLatitude(), node.getLongitude())); nodeWriter.endRecord(); if (enableBboxBuilder || enableLinestringBuilder) { wayGeometryBuilder.addNodeLocation(node); } } /** * {@inheritDoc} */ public void process(WayContainer wayContainer) { Way way; int sequenceId; List nodeIds; way = wayContainer.getEntity(); nodeIds = new ArrayList(way.getWayNodes().size()); for (WayNode wayNode : way.getWayNodes()) { nodeIds.add(wayNode.getNodeId()); } // Keep invalid ways out of the database if desired by the user if (way.getWayNodes().size() > 1 || keepInvalidWays) { wayWriter.writeField(way.getId()); wayWriter.writeField(way.getVersion()); wayWriter.writeField(way.getUser().getId()); wayWriter.writeField(way.getTimestamp()); wayWriter.writeField(way.getChangesetId()); wayWriter.writeField(buildTags(way)); wayWriter.writeField(nodeIds); if (enableBboxBuilder) { wayWriter.writeField(wayGeometryBuilder.createWayBbox(way)); } if (enableLinestringBuilder) { wayWriter.writeField(wayGeometryBuilder.createWayLinestring(way)); } wayWriter.endRecord(); sequenceId = 0; for (WayNode wayNode : way.getWayNodes()) { wayNodeWriter.writeField(way.getId()); wayNodeWriter.writeField(wayNode.getNodeId()); wayNodeWriter.writeField(sequenceId++); wayNodeWriter.endRecord(); } } } /** * {@inheritDoc} */ public void process(RelationContainer relationContainer) { Relation relation; int memberSequenceId; relation = relationContainer.getEntity(); relationWriter.writeField(relation.getId()); relationWriter.writeField(relation.getVersion()); relationWriter.writeField(relation.getUser().getId()); relationWriter.writeField(relation.getTimestamp()); relationWriter.writeField(relation.getChangesetId()); relationWriter.writeField(buildTags(relation)); relationWriter.endRecord(); memberSequenceId = 0; for (RelationMember member : relation.getMembers()) { relationMemberWriter.writeField(relation.getId()); relationMemberWriter.writeField(member.getMemberId()); relationMemberWriter.writeField(memberTypeValueMapper.getMemberType(member.getMemberType())); relationMemberWriter.writeField(member.getMemberRole()); relationMemberWriter.writeField(memberSequenceId++); relationMemberWriter.endRecord(); } } /** * Writes any buffered data to the database and commits. */ public void complete() { writerContainer.complete(); } /** * Releases all resources. */ public void release() { writerContainer.release(); wayGeometryBuilder.release(); } } CopyFilesetLoader.java000066400000000000000000000101771253404521400370310ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.pgsnapshot.common.DatabaseContext; import org.openstreetmap.osmosis.pgsnapshot.common.SchemaVersionValidator; import org.openstreetmap.osmosis.pgsnapshot.v0_6.PostgreSqlVersionConstants; /** * Loads a COPY fileset into a database. * * @author Brett Henderson */ public class CopyFilesetLoader implements Runnable { private static final Logger LOG = Logger.getLogger(CopyFilesetLoader.class.getName()); private static String[] appendColumn(String[] columns, String newColumn) { String[] result; result = new String[columns.length + 1]; System.arraycopy(columns, 0, result, 0, columns.length); result[columns.length] = newColumn; return result; } private static final String[] COMMON_COLUMNS = {"id", "version", "user_id", "tstamp", "changeset_id", "tags"}; private static final String[] NODE_COLUMNS = appendColumn(COMMON_COLUMNS, "geom"); private static final String[] WAY_COLUMNS = appendColumn(COMMON_COLUMNS, "nodes"); private static final String[] RELATION_COLUMNS = COMMON_COLUMNS; private DatabaseLoginCredentials loginCredentials; private DatabasePreferences preferences; private CopyFileset copyFileset; /** * Creates a new instance. * * @param loginCredentials * Contains all information required to connect to the database. * @param preferences * Contains preferences configuring database behaviour. * @param copyFileset * The set of COPY files to be loaded into the database. */ public CopyFilesetLoader(DatabaseLoginCredentials loginCredentials, DatabasePreferences preferences, CopyFileset copyFileset) { this.loginCredentials = loginCredentials; this.preferences = preferences; this.copyFileset = copyFileset; } /** * Reads all data from the database and send it to the sink. */ public void run() { DatabaseContext dbCtx = new DatabaseContext(loginCredentials); try { DatabaseCapabilityChecker capabilityChecker; IndexManager indexManager; String[] wayColumns; dbCtx.beginTransaction(); capabilityChecker = new DatabaseCapabilityChecker(dbCtx); new SchemaVersionValidator(dbCtx.getJdbcTemplate(), preferences) .validateVersion(PostgreSqlVersionConstants.SCHEMA_VERSION); wayColumns = WAY_COLUMNS; if (capabilityChecker.isWayBboxSupported()) { wayColumns = appendColumn(wayColumns, "bbox"); } if (capabilityChecker.isWayLinestringSupported()) { wayColumns = appendColumn(wayColumns, "linestring"); } indexManager = new IndexManager(dbCtx, false, false); // Drop all constraints and indexes. indexManager.prepareForLoad(); LOG.finer("Loading users."); dbCtx.loadCopyFile(copyFileset.getUserFile(), "users"); LOG.finer("Loading nodes."); dbCtx.loadCopyFile(copyFileset.getNodeFile(), "nodes", NODE_COLUMNS); LOG.finer("Loading ways."); dbCtx.loadCopyFile(copyFileset.getWayFile(), "ways", wayColumns); LOG.finer("Loading way nodes."); dbCtx.loadCopyFile(copyFileset.getWayNodeFile(), "way_nodes"); LOG.finer("Loading relations."); dbCtx.loadCopyFile(copyFileset.getRelationFile(), "relations", RELATION_COLUMNS); LOG.finer("Loading relation members."); dbCtx.loadCopyFile(copyFileset.getRelationMemberFile(), "relation_members"); LOG.finer("Committing changes."); LOG.fine("Data load complete."); // Add all constraints and indexes. indexManager.completeAfterLoad(); dbCtx.commitTransaction(); LOG.fine("Clustering database."); dbCtx.getJdbcTemplate().update("CLUSTER"); LOG.fine("Vacuuming database."); dbCtx.getJdbcTemplate().update("VACUUM ANALYZE"); LOG.fine("Complete."); } finally { dbCtx.release(); } } } DatabaseCapabilityChecker.java000066400000000000000000000032261253404521400404440ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import org.openstreetmap.osmosis.pgsnapshot.common.DatabaseContext; /** * Provides information about which features a database supports. * * @author Brett Henderson */ public class DatabaseCapabilityChecker { private DatabaseContext dbCtx; private boolean initialized; private boolean isActionSupported; private boolean isWayBboxSupported; private boolean isWayLinestringSupported; /** * Creates a new instance. * * @param dbCtx The database context to use for accessing the database. */ public DatabaseCapabilityChecker(DatabaseContext dbCtx) { this.dbCtx = dbCtx; initialized = false; } private void initialize() { if (!initialized) { isActionSupported = dbCtx.doesTableExist("actions"); isWayBboxSupported = dbCtx.doesColumnExist("ways", "bbox"); isWayLinestringSupported = dbCtx.doesColumnExist("ways", "linestring"); initialized = true; } } /** * Indicates if action support is available. * * @return True if supported, otherwise false. */ public boolean isActionSupported() { initialize(); return isActionSupported; } /** * Indicates if way bounding box support is available. * * @return True if supported, otherwise false. */ public boolean isWayBboxSupported() { initialize(); return isWayBboxSupported; } /** * Indicates if way linestring support is available. * * @return True if supported, otherwise false. */ public boolean isWayLinestringSupported() { initialize(); return isWayLinestringSupported; } } DbOrderedFeatureComparator.java000066400000000000000000000016431253404521400406500ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.util.Comparator; import org.openstreetmap.osmosis.core.database.DbOrderedFeature; import org.openstreetmap.osmosis.core.store.Storeable; /** * Compares way nodes to allow them to be sorted by way id then sequence * number. * * @author Brett Henderson * @param * The encapsulated feature type. */ public class DbOrderedFeatureComparator implements Comparator> { /** * {@inheritDoc} */ public int compare(DbOrderedFeature o1, DbOrderedFeature o2) { long way1Id; long way2Id; way1Id = o1.getEntityId(); way2Id = o2.getEntityId(); if (way1Id != way2Id) { if (way1Id < way2Id) { return -1; } else { return 1; } } return o1.getSequenceId() - o2.getSequenceId(); } } DirectoryCopyFileset.java000066400000000000000000000032371253404521400375660ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.io.File; /** * A COPY fileset implementation that defines fixed filenames within a specified * directory. * * @author Brett Henderson * */ public class DirectoryCopyFileset implements CopyFileset { private static final String USER_SUFFIX = "users.txt"; private static final String NODE_SUFFIX = "nodes.txt"; private static final String WAY_SUFFIX = "ways.txt"; private static final String WAY_NODE_SUFFIX = "way_nodes.txt"; private static final String RELATION_SUFFIX = "relations.txt"; private static final String RELATION_MEMBER_SUFFIX = "relation_members.txt"; private File directory; /** * Creates a new instance. * * @param directory * The directory to store all files in. */ public DirectoryCopyFileset(File directory) { this.directory = directory; } /** * {@inheritDoc} */ @Override public File getNodeFile() { return new File(directory, NODE_SUFFIX); } /** * {@inheritDoc} */ @Override public File getRelationFile() { return new File(directory, RELATION_SUFFIX); } /** * {@inheritDoc} */ @Override public File getRelationMemberFile() { return new File(directory, RELATION_MEMBER_SUFFIX); } /** * {@inheritDoc} */ @Override public File getUserFile() { return new File(directory, USER_SUFFIX); } /** * {@inheritDoc} */ @Override public File getWayFile() { return new File(directory, WAY_SUFFIX); } /** * {@inheritDoc} */ @Override public File getWayNodeFile() { return new File(directory, WAY_NODE_SUFFIX); } } EntityDao.java000066400000000000000000000177621253404521400353630ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.util.HashMap; import java.util.List; import java.util.Map; import org.openstreetmap.osmosis.core.database.FeaturePopulator; import org.openstreetmap.osmosis.core.database.SortingStoreRowMapperListener; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.lifecycle.ReleasableContainer; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.sort.common.FileBasedSort; import org.openstreetmap.osmosis.core.sort.v0_6.EntityByTypeThenIdComparator; import org.openstreetmap.osmosis.core.sort.v0_6.EntitySubClassComparator; import org.openstreetmap.osmosis.core.store.SingleClassObjectSerializationFactory; import org.openstreetmap.osmosis.core.store.StoreReleasingIterator; import org.openstreetmap.osmosis.pgsnapshot.common.NoSuchRecordException; import org.openstreetmap.osmosis.pgsnapshot.common.RowMapperRowCallbackListener; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; /** * Provides functionality common to all top level entity daos. * * @author Brett Henderson * @param * The entity type to be supported. */ public abstract class EntityDao { private JdbcTemplate jdbcTemplate; private NamedParameterJdbcTemplate namedParameterJdbcTemplate; private ActionDao actionDao; private EntityMapper entityMapper; /** * Creates a new instance. * * @param jdbcTemplate * Provides access to the database. * @param entityMapper * Provides entity type specific JDBC support. * @param actionDao * The dao to use for adding action records to the database. */ protected EntityDao(JdbcTemplate jdbcTemplate, EntityMapper entityMapper, ActionDao actionDao) { this.jdbcTemplate = jdbcTemplate; this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate); this.entityMapper = entityMapper; this.actionDao = actionDao; } /** * Gets the entity mapper implementation. * * @return The entity mapper. */ protected EntityMapper getEntityMapper() { return entityMapper; } /** * Checks if the specified entity exists in the database. * * @param entityId * The unique identifier of the entity. * @return True if the entity exists in the database. */ public boolean exists(long entityId) { return jdbcTemplate.queryForObject(entityMapper.getSqlSelectCount(true), Integer.class, entityId) > 0; } /** * Loads the specified entity from the database. * * @param entityId * The unique identifier of the entity. * @return The loaded entity. */ public T getEntity(long entityId) { T entity; try { entity = jdbcTemplate.queryForObject(entityMapper.getSqlSelect(true, false), entityMapper.getRowMapper(), entityId); } catch (EmptyResultDataAccessException e) { throw new NoSuchRecordException(entityMapper.getEntityName() + " " + entityId + " doesn't exist.", e); } return entity; } /** * Adds the specified entity to the database. * * @param entity * The entity to add. */ public void addEntity(T entity) { Map args; args = new HashMap(); entityMapper.populateEntityParameters(args, entity); namedParameterJdbcTemplate.update(entityMapper.getSqlInsert(1), args); actionDao.addAction(entityMapper.getEntityType(), ChangesetAction.CREATE, entity.getId()); } /** * Updates the specified entity details in the database. * * @param entity * The entity to update. */ public void modifyEntity(T entity) { Map args; args = new HashMap(); entityMapper.populateEntityParameters(args, entity); namedParameterJdbcTemplate.update(entityMapper.getSqlUpdate(true), args); actionDao.addAction(entityMapper.getEntityType(), ChangesetAction.MODIFY, entity.getId()); } /** * Removes the specified entity from the database. * * @param entityId * The id of the entity to remove. */ public void removeEntity(long entityId) { Map args; args = new HashMap(); args.put("id", entityId); namedParameterJdbcTemplate.update(entityMapper.getSqlDelete(true), args); actionDao.addAction(entityMapper.getEntityType(), ChangesetAction.DELETE, entityId); } private ReleasableIterator getFeaturelessEntity(String tablePrefix) { FileBasedSort sortingStore; sortingStore = new FileBasedSort( new SingleClassObjectSerializationFactory(entityMapper.getEntityClass()), new EntitySubClassComparator(new EntityByTypeThenIdComparator()), true); try { String sql; SortingStoreRowMapperListener storeListener; RowMapperRowCallbackListener rowCallbackListener; ReleasableIterator resultIterator; sql = entityMapper.getSqlSelect(tablePrefix, false, false); // Sends all received data into the object store. storeListener = new SortingStoreRowMapperListener(sortingStore); // Converts result set rows into objects and passes them into the store. rowCallbackListener = new RowMapperRowCallbackListener(entityMapper.getRowMapper(), storeListener); // Perform the query passing the row mapper chain to process rows in a streamy fashion. jdbcTemplate.query(sql, rowCallbackListener); // Open a iterator on the store that will release the store upon completion. resultIterator = new StoreReleasingIterator(sortingStore.iterate(), sortingStore); // The store itself shouldn't be released now that it has been attached to the iterator. sortingStore = null; return resultIterator; } finally { if (sortingStore != null) { sortingStore.release(); } } } /** * Gets the feature populators for the entity type. * * @param tablePrefix * The prefix for the entity table name. This allows another table to be queried if * necessary such as a temporary results table. * @return The feature populators. */ protected abstract List> getFeaturePopulators(String tablePrefix); /** * Returns an iterator providing access to all entities in the database. * * @param tablePrefix * The prefix for the entity table name. This allows another table to be queried if * necessary such as a temporary results table. * @return The entity iterator. */ public ReleasableIterator iterate(String tablePrefix) { ReleasableContainer releasableContainer; releasableContainer = new ReleasableContainer(); try { ReleasableIterator entityIterator; List> featurePopulators; // Create the featureless entity iterator but also store it temporarily in the // releasable container so that it will get freed if we fail during retrieval of feature // populators. entityIterator = releasableContainer.add(getFeaturelessEntity(tablePrefix)); // Retrieve the feature populators also adding them to the temporary releasable container. featurePopulators = getFeaturePopulators(tablePrefix); for (FeaturePopulator featurePopulator : featurePopulators) { releasableContainer.add(featurePopulator); } // Build an entity reader capable of merging all sources together. entityIterator = new EntityReader(entityIterator, featurePopulators); // The sources are now all attached to the history reader so we don't want to release // them in the finally block. releasableContainer.clear(); return entityIterator; } finally { releasableContainer.release(); } } /** * Returns an iterator providing access to all entities in the database. * * @return The entity iterator. */ public ReleasableIterator iterate() { return iterate(""); } } EntityFeatureDao.java000066400000000000000000000061321253404521400366640ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.database.DbFeature; import org.openstreetmap.osmosis.core.store.Storeable; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; /** * Provides functionality common to all entity feature daos. * * @author Brett Henderson * @param * The entity feature type to be supported. * @param * The entity feature database wrapper type to be used. */ public class EntityFeatureDao> { private EntityFeatureMapper entityFeatureMapper; private JdbcTemplate jdbcTemplate; private NamedParameterJdbcTemplate namedParameterJdbcTemplate; /** * Creates a new instance. * * @param jdbcTemplate * Provides access to the database. * @param entityFeatureMapper * Provides entity type specific JDBC support. */ protected EntityFeatureDao(JdbcTemplate jdbcTemplate, EntityFeatureMapper entityFeatureMapper) { this.jdbcTemplate = jdbcTemplate; this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate); this.entityFeatureMapper = entityFeatureMapper; } /** * Loads all instances of this feature for the specified entity from the database. * * @param entityId * The unique identifier of the entity. * @return All instances of this feature type for the entity. */ public Collection getAll(long entityId) { return jdbcTemplate.query(entityFeatureMapper.getSqlSelect("", true, true), new Object[] {entityId}, entityFeatureMapper.getRowMapper()); } /** * Loads all instances of this feature for the specified entity from the database. * * @param entityId * The unique identifier of the entity. * @return All instances of this feature type for the entity. */ public Collection getAllRaw(long entityId) { Collection dbFeatures; Collection rawFeatures; dbFeatures = getAll(entityId); rawFeatures = new ArrayList(dbFeatures.size()); for (Tdb dbFeature : dbFeatures) { rawFeatures.add(dbFeature.getFeature()); } return rawFeatures; } /** * Adds the specified features to the database. * * @param features * The features to add. */ public void addAll(Collection features) { Map args; args = new HashMap(); for (Tdb feature : features) { args.clear(); entityFeatureMapper.populateParameters(args, feature); namedParameterJdbcTemplate.update(entityFeatureMapper.getSqlInsert(1), args); } } /** * Removes the specified feature list from the database. * * @param entityId * The id of the entity to remove. */ public void removeList(long entityId) { jdbcTemplate.update(entityFeatureMapper.getSqlDelete(true), entityId); } } EntityFeatureMapper.java000066400000000000000000000052361253404521400374110ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.util.Map; import org.springframework.jdbc.core.RowMapper; /** * Provides functionality common to all entity feature mapper implementations. * * @author Brett Henderson * @param * The type of feature to be built. */ public abstract class EntityFeatureMapper { /** * Returns the name of the entity features entity type. * * @return The parent entity name. */ public abstract String getParentEntityName(); /** * Returns the name of the entity feature. This is used for error messages. * * @return The entity name. */ public abstract String getEntityName(); /** * Provides a default SQL ORDER BY clause suitable for this entity feature. * * @return The ORDER BY clause. */ public String getSqlDefaultOrderBy() { return " ORDER BY entity_id"; } /** * Returns the row mapper implementation for this entity type. * * @return The row mapper. */ public abstract RowMapper getRowMapper(); /** * The SQL SELECT statement for retrieving entity feature details. * * @param tablePrefix * The prefix for the entity table name. This allows another table to be queried if * necessary such as a temporary results table. * @param filterByEntityId * If true, a WHERE clause will be added filtering by the entity * id column. * @param orderBy * If true, a default ORDER BY clause will be added ordering by * the entity id column at a minimum and possibly other fields * depending on implementation. * @return The SQL string. */ public abstract String getSqlSelect(String tablePrefix, boolean filterByEntityId, boolean orderBy); /** * The SQL INSERT statement for adding features. * * @param rowCount * The number of rows to insert in a single statement. * @return The SQL string. */ public abstract String getSqlInsert(int rowCount); /** * The SQL DELETE statement for deleting entity features. * * @param filterByEntityId * If true, a WHERE clause will be added filtering by the entity * id column. * @return The SQL String. */ public abstract String getSqlDelete(boolean filterByEntityId); /** * Sets values as bind variable parameters to an insert query. * * @param args * The bind variable arguments to be updated. * @param feature * The entity containing the data to be inserted. */ public abstract void populateParameters(Map args, T feature); } EntityMapper.java000066400000000000000000000171501253404521400360730ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.sql.Timestamp; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.springframework.jdbc.core.RowMapper; /** * Provides functionality common to all database entity builder implementations. * * @author Brett Henderson * @param * The entity type to be supported. */ public abstract class EntityMapper { /** * Returns the name of the entity to substitute into SQL statements. This is * a low-tech way of making the queries type independent. * * @return The entity name as defined in the database schema. */ public abstract String getEntityName(); /** * Returns the action data type of the entity. * * @return The action type. */ public abstract ActionDataType getEntityType(); /** * Returns the class type for the entity. * * @return The entity type class. */ public abstract Class getEntityClass(); /** * Returns the row mapper implementation for this entity type. * * @return The row mapper. */ public abstract RowMapper getRowMapper(); /** * The SQL SELECT statement for counting entities. It will return a count of * matching records. * * @param filterByEntityId * If true, a WHERE clause will be added filtering by the entity * id column. * @return The SQL string. */ public String getSqlSelectCount(boolean filterByEntityId) { StringBuilder resultSql; resultSql = new StringBuilder(); resultSql.append("SELECT Count(e.*) AS count FROM " + getEntityName() + "s e"); if (filterByEntityId) { resultSql.append(" WHERE e.id = ?"); } return resultSql.toString(); } /** * Produces an array of additional column names specific to this entity type * to be returned by entity queries. * * @return The column names. */ protected abstract String[] getTypeSpecificFieldNames(); /** * The SQL SELECT statement for retrieving entity details. * * @param filterByEntityId * If true, a WHERE clause will be added filtering by the entity * id column. * @param orderByEntityId * If true, an ORDER BY clause will be added ordering by the * entity id column. * @return The SQL string. */ public String getSqlSelect(boolean filterByEntityId, boolean orderByEntityId) { return getSqlSelect("", filterByEntityId, orderByEntityId); } /** * The SQL SELECT statement for retrieving entity details. * * @param tablePrefix * The prefix for the entity table name. This allows another table to be queried if * necessary such as a temporary results table. * @param filterByEntityId * If true, a WHERE clause will be added filtering by the entity id column. * @param orderByEntityId * If true, an ORDER BY clause will be added ordering by the entity id column. * @return The SQL string. */ public String getSqlSelect(String tablePrefix, boolean filterByEntityId, boolean orderByEntityId) { StringBuilder resultSql; resultSql = new StringBuilder(); resultSql.append("SELECT e.id, e.version, e.user_id, u.name AS user_name, e.tstamp, e.changeset_id, e.tags"); for (String fieldName : Arrays.asList(getTypeSpecificFieldNames())) { resultSql.append(", ").append(fieldName); } resultSql.append(" FROM "); resultSql.append(tablePrefix).append(getEntityName()).append("s e"); resultSql.append(" LEFT OUTER JOIN users u ON e.user_id = u.id"); if (filterByEntityId) { resultSql.append(" WHERE e.id = ?"); } if (orderByEntityId) { resultSql.append(" ORDER BY e.id"); } return resultSql.toString(); } /** * The SQL INSERT statement for adding entities. * * @param rowCount * The number of rows to insert in a single statement. * @return The SQL string. */ public String getSqlInsert(int rowCount) { String[] typeSpecificFieldNames; StringBuilder resultSql; typeSpecificFieldNames = getTypeSpecificFieldNames(); resultSql = new StringBuilder(); resultSql.append("INSERT INTO ").append(getEntityName()).append("s"); resultSql.append("(id, version, user_id, tstamp, changeset_id, tags"); for (String fieldName : Arrays.asList(typeSpecificFieldNames)) { resultSql.append(", ").append(fieldName); } resultSql.append(") VALUES "); for (int row = 0; row < rowCount; row++) { if (row > 0) { resultSql.append(", "); } resultSql.append("(:id, :version, :userId, :timestamp, :changesetId, :tags"); for (int i = 0; i < typeSpecificFieldNames.length; i++) { resultSql.append(", :").append(typeSpecificFieldNames[i]); } resultSql.append(")"); } return resultSql.toString(); } /** * The SQL UPDATE statement for updating entity details. * * @param filterByEntityId * If true, a WHERE clause will be added filtering by the entity * id column. * @return The SQL String. */ public String getSqlUpdate(boolean filterByEntityId) { StringBuilder resultSql; resultSql = new StringBuilder(); resultSql.append("UPDATE ").append(getEntityName()) .append("s SET id = :id, version = :version, user_id = :userId," + " tstamp = :timestamp, changeset_id = :changesetId, tags = :tags"); for (String fieldName : Arrays.asList(getTypeSpecificFieldNames())) { resultSql.append(", ").append(fieldName).append(" = :").append(fieldName); } if (filterByEntityId) { resultSql.append(" WHERE id = :id"); } return resultSql.toString(); } /** * The SQL UPDATE statement for logically deleting entities. * * @param filterByEntityId * If true, a WHERE clause will be added filtering by the entity * id column. * @return The SQL String. */ public String getSqlDelete(boolean filterByEntityId) { StringBuilder resultSql; resultSql = new StringBuilder(); resultSql.append("DELETE FROM ").append(getEntityName()).append("s"); if (filterByEntityId) { resultSql.append(" WHERE id = :id"); } return resultSql.toString(); } /** * Sets common entity values as bind variable parameters to an entity insert query. * * @param args * The bind variable arguments to be updated. * @param entity * The entity containing the data to be inserted. */ protected void populateCommonEntityParameters(Map args, Entity entity) { Map tags; // We can't write an entity with a null timestamp. if (entity.getTimestamp() == null) { throw new OsmosisRuntimeException( "Entity(" + entity.getType() + ") " + entity.getId() + " does not have a timestamp set."); } tags = new HashMap(entity.getTags().size()); for (Tag tag : entity.getTags()) { tags.put(tag.getKey(), tag.getValue()); } args.put("id", entity.getId()); args.put("version", entity.getVersion()); args.put("userId", entity.getUser().getId()); args.put("timestamp", new Timestamp(entity.getTimestamp().getTime())); args.put("changesetId", entity.getChangesetId()); args.put("tags", tags); } /** * Sets entity values as bind variable parameters to an entity insert query. * * @param args * The bind variable arguments to be updated. * @param entity * The entity containing the data to be inserted. */ public abstract void populateEntityParameters(Map args, T entity); } EntityReader.java000066400000000000000000000052261253404521400360520ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.util.List; import java.util.NoSuchElementException; import org.openstreetmap.osmosis.core.database.FeaturePopulator; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.lifecycle.ReleasableContainer; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; /** * Provides a single iterator based on data provided by underlying iterators from each of the * underlying entity and feature iterators. Each underlying iterator provides one component of the * overall entity. * * @param * The type of entity provided by this iterator. */ public class EntityReader implements ReleasableIterator { private boolean nextValueLoaded; private ReleasableContainer releasableContainer; private ReleasableIterator entityIterator; private List> featurePopulators; private T nextValue; /** * Creates a new instance. * * @param entityIterator * The entity source. * @param featurePopulators * Populators to add entity specific features to the generated entities. */ public EntityReader(ReleasableIterator entityIterator, List> featurePopulators) { releasableContainer = new ReleasableContainer(); this.entityIterator = releasableContainer.add(entityIterator); for (FeaturePopulator featurePopulator : featurePopulators) { releasableContainer.add(featurePopulator); } this.featurePopulators = featurePopulators; } /** * Consolidates the output of all readers so that entities are fully * populated. * * @return An entity record where the entity is fully populated. */ private T readNextEntity() { T entity; entity = entityIterator.next(); // Add entity type specific features to the entity. for (FeaturePopulator populator : featurePopulators) { populator.populateFeatures(entity); } return entity; } /** * {@inheritDoc} */ public boolean hasNext() { if (!nextValueLoaded && entityIterator.hasNext()) { nextValue = readNextEntity(); nextValueLoaded = true; } return nextValueLoaded; } /** * {@inheritDoc} */ public T next() { T result; if (!hasNext()) { throw new NoSuchElementException(); } result = nextValue; nextValueLoaded = false; return result; } /** * {@inheritDoc} */ public void remove() { throw new UnsupportedOperationException(); } /** * {@inheritDoc} */ public void release() { releasableContainer.release(); } } EntityRowMapper.java000066400000000000000000000045641253404521400365700ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Collection; import java.util.Date; import java.util.Map; import java.util.Map.Entry; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.springframework.jdbc.core.RowMapper; /** * Maps database rows into Entity objects. * * @author Brett Henderson * @param * The entity type to be supported. */ public abstract class EntityRowMapper implements RowMapper { /** * Creates a new user record based upon the current result set row. * * @param resultSet * The result set to read from. * @return The newly build user object. */ private OsmUser buildUser(ResultSet resultSet) { try { int userId; OsmUser user; userId = resultSet.getInt("user_id"); if (userId == OsmUser.NONE.getId()) { user = OsmUser.NONE; } else { user = new OsmUser( userId, resultSet.getString("user_name") ); } return user; } catch (SQLException e) { throw new OsmosisRuntimeException("Unable to build a user from the current recordset row.", e); } } /** * Retrieves the data common to all entities. * * @param rs * The result set. * @throws SQLException * if a database error is encountered. * @return The common entity data. */ @SuppressWarnings("unchecked") protected CommonEntityData mapCommonEntityData(ResultSet rs) throws SQLException { CommonEntityData entityData; Map dbTags; Collection tags; entityData = new CommonEntityData( rs.getLong("id"), rs.getInt("version"), new Date(rs.getTimestamp("tstamp").getTime()), buildUser(rs), rs.getLong("changeset_id") ); dbTags = (Map) rs.getObject("tags"); if (dbTags != null) { tags = entityData.getTags(); for (Entry tagEntry : dbTags.entrySet()) { tags.add(new Tag(tagEntry.getKey(), tagEntry.getValue())); } } return entityData; } } FeaturePopulatorImpl.java000066400000000000000000000037171253404521400376010ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import org.openstreetmap.osmosis.core.database.DbFeature; import org.openstreetmap.osmosis.core.database.FeatureCollectionLoader; import org.openstreetmap.osmosis.core.database.FeaturePopulator; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.store.PeekableIterator; import org.openstreetmap.osmosis.core.store.Storeable; /** * Populates entities with their features using a sorted data source. * * @param * The type of entity to be populated. * @param * The type of feature to be added. * @param * The database feature class type. This is extensible to allow other attributes to be * added to features such as a sequence number. */ public class FeaturePopulatorImpl> implements FeaturePopulator { private PeekableIterator source; private FeatureCollectionLoader featureLoader; /** * Creates a new instance. * * @param source * The feature source. * @param featureLoader * Provides access to the feature collection within the entity. */ public FeaturePopulatorImpl(ReleasableIterator source, FeatureCollectionLoader featureLoader) { this.source = new PeekableIterator(source); this.featureLoader = featureLoader; } /** * {@inheritDoc} */ @Override public void populateFeatures(Te entity) { // Add all applicable tags to the entity. while (source.hasNext() && source.peekNext().getEntityId() == entity.getId()) { featureLoader.getFeatureCollection(entity).add(source.next().getFeature()); } } /** * {@inheritDoc} */ @Override public void release() { source.release(); } } IndexManager.java000066400000000000000000000131541253404521400360140ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.util.logging.Logger; import org.openstreetmap.osmosis.pgsnapshot.common.DatabaseContext; import org.springframework.jdbc.core.JdbcTemplate; /** * Drops and creates indexes in support of bulk load activities. * * @author Brett Henderson */ public class IndexManager { private static final Logger LOG = Logger.getLogger(IndexManager.class.getName()); private static final String[] PRE_LOAD_SQL = { "ALTER TABLE users DROP CONSTRAINT pk_users", "ALTER TABLE nodes DROP CONSTRAINT pk_nodes", "ALTER TABLE ways DROP CONSTRAINT pk_ways", "ALTER TABLE way_nodes DROP CONSTRAINT pk_way_nodes", "ALTER TABLE relations DROP CONSTRAINT pk_relations", "ALTER TABLE relation_members DROP CONSTRAINT pk_relation_members", "DROP INDEX idx_nodes_geom", "DROP INDEX idx_way_nodes_node_id", "DROP INDEX idx_relation_members_member_id_and_type" }; private static final String[] PRE_LOAD_SQL_WAY_BBOX = { "DROP INDEX idx_ways_bbox" }; private static final String[] PRE_LOAD_SQL_WAY_LINESTRING = { "DROP INDEX idx_ways_linestring" }; private static final String[] POST_LOAD_SQL = { "ALTER TABLE ONLY users ADD CONSTRAINT pk_users PRIMARY KEY (id)", "ALTER TABLE ONLY nodes ADD CONSTRAINT pk_nodes PRIMARY KEY (id)", "ALTER TABLE ONLY ways ADD CONSTRAINT pk_ways PRIMARY KEY (id)", "ALTER TABLE ONLY way_nodes ADD CONSTRAINT pk_way_nodes PRIMARY KEY (way_id, sequence_id)", "ALTER TABLE ONLY relations ADD CONSTRAINT pk_relations PRIMARY KEY (id)", "ALTER TABLE ONLY relation_members ADD CONSTRAINT pk_relation_members PRIMARY KEY (relation_id, sequence_id)", "CREATE INDEX idx_nodes_geom ON nodes USING gist (geom)", "CREATE INDEX idx_way_nodes_node_id ON way_nodes USING btree (node_id)", "CREATE INDEX idx_relation_members_member_id_and_type ON relation_members USING btree (member_id, member_type)" }; private static final String[] POST_LOAD_SQL_WAY_BBOX = { "CREATE INDEX idx_ways_bbox ON ways USING gist (bbox)" }; private static final String[] POST_LOAD_SQL_WAY_LINESTRING = { "CREATE INDEX idx_ways_linestring ON ways USING gist (linestring)" }; private static final String POST_LOAD_SQL_POPULATE_WAY_BBOX = "UPDATE ways SET bbox = (" + "SELECT ST_Envelope(ST_Collect(geom)) FROM nodes JOIN way_nodes ON way_nodes.node_id = nodes.id" + " WHERE way_nodes.way_id = ways.id" + ")"; private static final String POST_LOAD_SQL_POPULATE_WAY_LINESTRING = "UPDATE ways w SET linestring = (" + "SELECT ST_MakeLine(c.geom) AS way_line FROM (" + "SELECT n.geom AS geom FROM nodes n INNER JOIN way_nodes wn ON n.id = wn.node_id" + " WHERE (wn.way_id = w.id) ORDER BY wn.sequence_id" + ") c" + ")"; private JdbcTemplate jdbcTemplate; private DatabaseCapabilityChecker capabilityChecker; private boolean populateBbox; private boolean populateLinestring; /** * Creates a new instance. * * @param dbCtx * Provides access to the database. * @param populateBbox * If true, the bbox colum on the way table will be populated * after load. * @param populateLinestring * If true, the linestring column on the way table will be * populated after load. */ public IndexManager(DatabaseContext dbCtx, boolean populateBbox, boolean populateLinestring) { this.populateBbox = populateBbox; this.populateLinestring = populateLinestring; jdbcTemplate = dbCtx.getJdbcTemplate(); capabilityChecker = new DatabaseCapabilityChecker(dbCtx); } /** * Drops indexes and constraints in the database. */ public void prepareForLoad() { LOG.fine("Running pre-load SQL statements."); for (int i = 0; i < PRE_LOAD_SQL.length; i++) { LOG.finer("SQL: " + PRE_LOAD_SQL[i]); jdbcTemplate.update(PRE_LOAD_SQL[i]); } if (capabilityChecker.isWayBboxSupported()) { LOG.fine("Running pre-load bbox SQL statements."); for (int i = 0; i < PRE_LOAD_SQL_WAY_BBOX.length; i++) { LOG.finer("SQL: " + PRE_LOAD_SQL_WAY_BBOX[i]); jdbcTemplate.update(PRE_LOAD_SQL_WAY_BBOX[i]); } } if (capabilityChecker.isWayLinestringSupported()) { LOG.fine("Running pre-load linestring SQL statements."); for (int i = 0; i < PRE_LOAD_SQL_WAY_LINESTRING.length; i++) { LOG.finer("SQL: " + PRE_LOAD_SQL_WAY_LINESTRING[i]); jdbcTemplate.update(PRE_LOAD_SQL_WAY_LINESTRING[i]); } } LOG.fine("Pre-load SQL statements complete."); } /** * Creates indexes in the database and populates derived columns. */ public void completeAfterLoad() { LOG.fine("Running post-load SQL."); for (int i = 0; i < POST_LOAD_SQL.length; i++) { LOG.finer("SQL: " + POST_LOAD_SQL[i]); jdbcTemplate.update(POST_LOAD_SQL[i]); } if (capabilityChecker.isWayBboxSupported()) { LOG.fine("Running post-load bbox SQL statements."); if (populateBbox) { LOG.finer("SQL: " + POST_LOAD_SQL_POPULATE_WAY_BBOX); jdbcTemplate.update(POST_LOAD_SQL_POPULATE_WAY_BBOX); } for (int i = 0; i < POST_LOAD_SQL_WAY_BBOX.length; i++) { LOG.finer("SQL: " + POST_LOAD_SQL_WAY_BBOX[i]); jdbcTemplate.update(POST_LOAD_SQL_WAY_BBOX[i]); } } if (capabilityChecker.isWayLinestringSupported()) { LOG.fine("Running post-load linestring SQL statements."); if (populateLinestring) { LOG.finer("SQL: " + POST_LOAD_SQL_POPULATE_WAY_LINESTRING); jdbcTemplate.update(POST_LOAD_SQL_POPULATE_WAY_LINESTRING); } for (int i = 0; i < POST_LOAD_SQL_WAY_LINESTRING.length; i++) { LOG.finer("SQL: " + POST_LOAD_SQL_WAY_LINESTRING[i]); jdbcTemplate.update(POST_LOAD_SQL_WAY_LINESTRING[i]); } } } } MemberTypeValueMapper.java000066400000000000000000000044311253404521400376630ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; /** * This is a utility class for mapping between relation member type columns and * the corresponding entity type. * * @author Brett Henderson */ public class MemberTypeValueMapper { private static Map entityToMemberMap; private static Map memberToEntityMap; private static void addEntityTypeMapping(EntityType entityType, String memberType) { if (entityToMemberMap.containsKey(entityType)) { throw new OsmosisRuntimeException("Entity type (" + entityType + ") already has a mapping."); } entityToMemberMap.put(entityType, memberType); memberToEntityMap.put(memberType, entityType); } static { EntityType[] entityTypes; entityTypes = EntityType.values(); entityToMemberMap = new HashMap(entityTypes.length); memberToEntityMap = new HashMap(entityTypes.length); addEntityTypeMapping(EntityType.Bound, "B"); addEntityTypeMapping(EntityType.Node, "N"); addEntityTypeMapping(EntityType.Way, "W"); addEntityTypeMapping(EntityType.Relation, "R"); } /** * Returns the member type value corresponding to the specified entity type. * * @param entityType * The entity type. * @return The corresponding member type value. */ public String getMemberType(EntityType entityType) { if (entityToMemberMap.containsKey(entityType)) { return entityToMemberMap.get(entityType); } else { throw new OsmosisRuntimeException("The entity type " + entityType + " is not recognised."); } } /** * Returns the entity type value corresponding to the specified member type. * * @param memberType * The member type. * @return The corresponding entity type value. */ public EntityType getEntityType(String memberType) { if (memberToEntityMap.containsKey(memberType)) { return memberToEntityMap.get(memberType); } else { throw new OsmosisRuntimeException("The member type " + memberType + " is not recognised."); } } } NodeDao.java000066400000000000000000000046531253404521400347670ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.util.Collections; import java.util.List; import org.openstreetmap.osmosis.core.database.FeaturePopulator; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.pgsnapshot.common.DatabaseContext; import org.springframework.jdbc.core.JdbcTemplate; /** * Performs all node-specific db operations. * * @author Brett Henderson */ public class NodeDao extends EntityDao { private static final String SQL_UPDATE_WAY_BBOX = "UPDATE ways w SET bbox = (" + " SELECT ST_Envelope(ST_Collect(n.geom))" + " FROM nodes n INNER JOIN way_nodes wn ON wn.node_id = n.id" + " WHERE wn.way_id = w.id" + " )" + " WHERE w.id IN (" + " SELECT w.id FROM ways w INNER JOIN way_nodes wn ON w.id = wn.way_id WHERE wn.node_id = ? GROUP BY w.id" + " )"; private static final String SQL_UPDATE_WAY_LINESTRING = "UPDATE ways w SET linestring = (" + " SELECT ST_MakeLine(c.geom) AS way_line FROM (" + " SELECT n.geom AS geom FROM nodes n INNER JOIN way_nodes wn ON n.id = wn.node_id" + " WHERE (wn.way_id = w.id) ORDER BY wn.sequence_id" + " ) c" + " )" + " WHERE w.id IN (" + " SELECT w.id FROM ways w INNER JOIN way_nodes wn ON w.id = wn.way_id WHERE wn.node_id = ? GROUP BY w.id" + " )"; private JdbcTemplate jdbcTemplate; private DatabaseCapabilityChecker capabilityChecker; /** * Creates a new instance. * * @param dbCtx * The database context to use for accessing the database. * @param actionDao * The dao to use for adding action records to the database. */ public NodeDao(DatabaseContext dbCtx, ActionDao actionDao) { super(dbCtx.getJdbcTemplate(), new NodeMapper(), actionDao); jdbcTemplate = dbCtx.getJdbcTemplate(); capabilityChecker = new DatabaseCapabilityChecker(dbCtx); } /** * {@inheritDoc} */ @Override public void modifyEntity(Node entity) { super.modifyEntity(entity); if (capabilityChecker.isWayBboxSupported()) { jdbcTemplate.update(SQL_UPDATE_WAY_BBOX, entity.getId()); } if (capabilityChecker.isWayLinestringSupported()) { jdbcTemplate.update(SQL_UPDATE_WAY_LINESTRING, entity.getId()); } } /** * {@inheritDoc} */ @Override protected List> getFeaturePopulators(String tablePrefix) { return Collections.emptyList(); } } NodeMapper.java000066400000000000000000000027321253404521400355040ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.util.Map; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.pgsnapshot.common.PointBuilder; import org.postgis.PGgeometry; import org.springframework.jdbc.core.RowMapper; /** * Reads and writes node attributes to jdbc classes. * * @author Brett Henderson */ public class NodeMapper extends EntityMapper { private PointBuilder pointBuilder; /** * Creates a new instance. */ public NodeMapper() { pointBuilder = new PointBuilder(); } /** * {@inheritDoc} */ @Override public String getEntityName() { return "node"; } /** * {@inheritDoc} */ @Override public ActionDataType getEntityType() { return ActionDataType.NODE; } /** * {@inheritDoc} */ @Override public Class getEntityClass() { return Node.class; } /** * {@inheritDoc} */ @Override protected String[] getTypeSpecificFieldNames() { return new String[] {"geom"}; } /** * {@inheritDoc} */ @Override public void populateEntityParameters(Map args, Node entity) { populateCommonEntityParameters(args, entity); args.put("geom", new PGgeometry(pointBuilder.createPoint(entity.getLatitude(), entity.getLongitude()))); } /** * {@inheritDoc} */ @Override public RowMapper getRowMapper() { return new NodeRowMapper(); } } NodeRowMapper.java000066400000000000000000000013601253404521400361700ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.sql.ResultSet; import java.sql.SQLException; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.postgis.PGgeometry; import org.postgis.Point; /** * Maps database rows into Node objects. * * @author Brett Henderson */ public class NodeRowMapper extends EntityRowMapper { /** * {@inheritDoc} */ @Override public Node mapRow(ResultSet rs, int rowNumber) throws SQLException { PGgeometry geom; Point point; geom = (PGgeometry) rs.getObject("geom"); point = (Point) geom.getGeometry(); return new Node(mapCommonEntityData(rs), point.y, point.x); } } PostgreSqlDatasetContext.java000066400000000000000000000366541253404521400404420ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisConstants; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainerIterator; import org.openstreetmap.osmosis.core.container.v0_6.DatasetContext; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityManager; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainerIterator; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainerIterator; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainerIterator; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.store.MultipleSourceIterator; import org.openstreetmap.osmosis.core.store.ReleasableAdaptorForIterator; import org.openstreetmap.osmosis.core.store.UpcastIterator; import org.openstreetmap.osmosis.pgsnapshot.common.DatabaseContext; import org.openstreetmap.osmosis.pgsnapshot.common.PolygonBuilder; import org.openstreetmap.osmosis.pgsnapshot.common.SchemaVersionValidator; import org.openstreetmap.osmosis.pgsnapshot.v0_6.PostgreSqlVersionConstants; import org.postgis.PGgeometry; import org.postgis.Point; import org.postgis.Polygon; import org.springframework.jdbc.core.JdbcTemplate; /** * Provides read-only access to a PostgreSQL dataset store. Each thread * accessing the store must create its own reader. It is important that all * iterators obtained from this reader are released before releasing the reader * itself. * * @author Brett Henderson */ public class PostgreSqlDatasetContext implements DatasetContext { private static final Logger LOG = Logger.getLogger(PostgreSqlDatasetContext.class.getName()); private DatabaseLoginCredentials loginCredentials; private DatabasePreferences preferences; private DatabaseCapabilityChecker capabilityChecker; private boolean initialized; private DatabaseContext dbCtx; private JdbcTemplate jdbcTemplate; private UserDao userDao; private NodeDao nodeDao; private WayDao wayDao; private RelationDao relationDao; private PostgreSqlEntityManager nodeManager; private PostgreSqlEntityManager wayManager; private PostgreSqlEntityManager relationManager; private PolygonBuilder polygonBuilder; /** * Creates a new instance. * * @param loginCredentials * Contains all information required to connect to the database. * @param preferences * Contains preferences configuring database behaviour. */ public PostgreSqlDatasetContext(DatabaseLoginCredentials loginCredentials, DatabasePreferences preferences) { this.loginCredentials = loginCredentials; this.preferences = preferences; polygonBuilder = new PolygonBuilder(); initialized = false; } /** * Initialises the database connection and associated data access objects. */ private void initialize() { if (dbCtx == null) { ActionDao actionDao; dbCtx = new DatabaseContext(loginCredentials); jdbcTemplate = dbCtx.getJdbcTemplate(); dbCtx.beginTransaction(); new SchemaVersionValidator(jdbcTemplate, preferences).validateVersion( PostgreSqlVersionConstants.SCHEMA_VERSION); capabilityChecker = new DatabaseCapabilityChecker(dbCtx); actionDao = new ActionDao(dbCtx); userDao = new UserDao(dbCtx, actionDao); nodeDao = new NodeDao(dbCtx, actionDao); wayDao = new WayDao(dbCtx, actionDao); relationDao = new RelationDao(dbCtx, actionDao); nodeManager = new PostgreSqlEntityManager(nodeDao, userDao); wayManager = new PostgreSqlEntityManager(wayDao, userDao); relationManager = new PostgreSqlEntityManager(relationDao, userDao); } initialized = true; } /** * {@inheritDoc} */ @Override @Deprecated public Node getNode(long id) { return getNodeManager().getEntity(id); } /** * {@inheritDoc} */ @Override @Deprecated public Way getWay(long id) { return getWayManager().getEntity(id); } /** * {@inheritDoc} */ @Override @Deprecated public Relation getRelation(long id) { return getRelationManager().getEntity(id); } /** * {@inheritDoc} */ @Override public EntityManager getNodeManager() { if (!initialized) { initialize(); } return nodeManager; } /** * {@inheritDoc} */ @Override public EntityManager getWayManager() { if (!initialized) { initialize(); } return wayManager; } /** * {@inheritDoc} */ @Override public EntityManager getRelationManager() { if (!initialized) { initialize(); } return relationManager; } /** * {@inheritDoc} */ @Override public ReleasableIterator iterate() { List bounds; List> sources; if (!initialized) { initialize(); } // Build the bounds list. bounds = new ArrayList(); bounds.add(new Bound("Osmosis " + OsmosisConstants.VERSION)); sources = new ArrayList>(); sources.add(new UpcastIterator( new BoundContainerIterator(new ReleasableAdaptorForIterator(bounds.iterator())))); sources.add(new UpcastIterator( new NodeContainerIterator(nodeDao.iterate()))); sources.add(new UpcastIterator( new WayContainerIterator(wayDao.iterate()))); sources.add(new UpcastIterator( new RelationContainerIterator(relationDao.iterate()))); return new MultipleSourceIterator(sources); } /** * {@inheritDoc} */ @Override public ReleasableIterator iterateBoundingBox( double left, double right, double top, double bottom, boolean completeWays) { List bounds; Point[] bboxPoints; Polygon bboxPolygon; int rowCount; List> resultSets; if (!initialized) { initialize(); } // Build the bounds list. bounds = new ArrayList(); bounds.add(new Bound(right, left, top, bottom, "Osmosis " + OsmosisConstants.VERSION)); // PostgreSQL sometimes incorrectly chooses to perform full table scans, these options // prevent this. Note that this is not recommended practice according to documentation // but fixing this would require modifying the table statistics gathering // configuration to produce better plans. jdbcTemplate.update("SET enable_seqscan = false"); jdbcTemplate.update("SET enable_mergejoin = false"); jdbcTemplate.update("SET enable_hashjoin = false"); // Build a polygon representing the bounding box. // Sample box for query testing may be: // GeomFromText('POLYGON((144.93912192855174 -37.82981987499741, // 144.93912192855174 -37.79310006709244, 144.98188026000003 // -37.79310006709244, 144.98188026000003 -37.82981987499741, // 144.93912192855174 -37.82981987499741))', -1) bboxPoints = new Point[5]; bboxPoints[0] = new Point(left, bottom); bboxPoints[1] = new Point(left, top); bboxPoints[2] = new Point(right, top); bboxPoints[3] = new Point(right, bottom); bboxPoints[4] = new Point(left, bottom); bboxPolygon = polygonBuilder.createPolygon(bboxPoints); // Select all nodes inside the box into the node temp table. LOG.finer("Selecting all nodes inside bounding box."); rowCount = jdbcTemplate.update( "CREATE TEMPORARY TABLE bbox_nodes ON COMMIT DROP AS" + " SELECT * FROM nodes WHERE (geom && ?)", new PGgeometry(bboxPolygon)); LOG.finer("Adding a primary key to the temporary nodes table."); jdbcTemplate.update("ALTER TABLE ONLY bbox_nodes ADD CONSTRAINT pk_bbox_nodes PRIMARY KEY (id)"); LOG.finer("Updating query analyzer statistics on the temporary nodes table."); jdbcTemplate.update("ANALYZE bbox_nodes"); // Select all ways inside the bounding box into the way temp table. if (capabilityChecker.isWayLinestringSupported()) { LOG.finer("Selecting all ways inside bounding box using way linestring geometry."); // We have full way geometry available so select ways // overlapping the requested bounding box. rowCount = jdbcTemplate.update( "CREATE TEMPORARY TABLE bbox_ways ON COMMIT DROP AS" + " SELECT * FROM ways WHERE (linestring && ?)", new PGgeometry(bboxPolygon)); } else if (capabilityChecker.isWayBboxSupported()) { LOG.finer("Selecting all ways inside bounding box using dynamically built" + " way linestring with way bbox indexing."); // The inner query selects the way id and node coordinates for // all ways constrained by the way bounding box which is // indexed. // The middle query converts the way node coordinates into // linestrings. // The outer query constrains the query to the linestrings // inside the bounding box. These aren't indexed but the inner // query way bbox constraint will minimise the unnecessary data. rowCount = jdbcTemplate.update( "CREATE TEMPORARY TABLE bbox_ways ON COMMIT DROP AS" + " SELECT w.* FROM (" + "SELECT c.id AS id, First(c.version) AS version, First(c.user_id) AS user_id," + " First(c.tstamp) AS tstamp, First(c.changeset_id) AS changeset_id, First(c.tags) AS tags," + " First(c.nodes) AS nodes, ST_MakeLine(c.geom) AS way_line FROM (" + "SELECT w.*, n.geom AS geom FROM nodes n" + " INNER JOIN way_nodes wn ON n.id = wn.node_id" + " INNER JOIN ways w ON wn.way_id = w.id" + " WHERE (w.bbox && ?) ORDER BY wn.way_id, wn.sequence_id" + ") c " + "GROUP BY c.id" + ") w " + "WHERE (w.way_line && ?)", new PGgeometry(bboxPolygon), new PGgeometry(bboxPolygon) ); } else { LOG.finer("Selecting all way ids inside bounding box using already selected nodes."); // No way bbox support is available so select ways containing // the selected nodes. rowCount = jdbcTemplate.update( "CREATE TEMPORARY TABLE bbox_ways ON COMMIT DROP AS" + " SELECT w.* FROM ways w" + " INNER JOIN (" + " SELECT wn.way_id FROM way_nodes wn" + " INNER JOIN bbox_nodes n ON wn.node_id = n.id GROUP BY wn.way_id" + ") wids ON w.id = wids.way_id" ); } LOG.finer(rowCount + " rows affected."); LOG.finer("Adding a primary key to the temporary ways table."); jdbcTemplate.update("ALTER TABLE ONLY bbox_ways ADD CONSTRAINT pk_bbox_ways PRIMARY KEY (id)"); LOG.finer("Updating query analyzer statistics on the temporary ways table."); jdbcTemplate.update("ANALYZE bbox_ways"); // Select all relations containing the nodes or ways into the relation table. LOG.finer("Selecting all relation ids containing selected nodes or ways."); rowCount = jdbcTemplate.update( "CREATE TEMPORARY TABLE bbox_relations ON COMMIT DROP AS" + " SELECT r.* FROM relations r" + " INNER JOIN (" + " SELECT relation_id FROM (" + " SELECT rm.relation_id AS relation_id FROM relation_members rm" + " INNER JOIN bbox_nodes n ON rm.member_id = n.id WHERE rm.member_type = 'N' " + " UNION " + " SELECT rm.relation_id AS relation_id FROM relation_members rm" + " INNER JOIN bbox_ways w ON rm.member_id = w.id WHERE rm.member_type = 'W'" + " ) rids GROUP BY relation_id" + ") rids ON r.id = rids.relation_id" ); LOG.finer(rowCount + " rows affected."); LOG.finer("Adding a primary key to the temporary relations table."); jdbcTemplate.update("ALTER TABLE ONLY bbox_relations ADD CONSTRAINT pk_bbox_relations PRIMARY KEY (id)"); LOG.finer("Updating query analyzer statistics on the temporary relations table."); jdbcTemplate.update("ANALYZE bbox_relations"); // Include all relations containing the current relations into the // relation table and repeat until no more inclusions occur. do { LOG.finer("Selecting parent relations of selected relations."); rowCount = jdbcTemplate.update( "INSERT INTO bbox_relations " + "SELECT r.* FROM relations r INNER JOIN (" + " SELECT rm.relation_id FROM relation_members rm" + " INNER JOIN bbox_relations br ON rm.member_id = br.id" + " WHERE rm.member_type = 'R' AND NOT EXISTS (" + " SELECT * FROM bbox_relations br2 WHERE rm.relation_id = br2.id" + " ) GROUP BY rm.relation_id" + ") rids ON r.id = rids.relation_id" ); LOG.finer(rowCount + " rows affected."); } while (rowCount > 0); LOG.finer("Updating query analyzer statistics on the temporary relations table."); jdbcTemplate.update("ANALYZE bbox_relations"); // If complete ways is set, select all nodes contained by the ways into the node temp table. if (completeWays) { LOG.finer("Selecting all nodes for selected ways."); jdbcTemplate.update("CREATE TEMPORARY TABLE bbox_way_nodes (id bigint) ON COMMIT DROP"); jdbcTemplate.queryForList("SELECT unnest_bbox_way_nodes()"); jdbcTemplate.update( "CREATE TEMPORARY TABLE bbox_missing_way_nodes ON COMMIT DROP AS " + "SELECT buwn.id FROM (SELECT DISTINCT bwn.id FROM bbox_way_nodes bwn) buwn " + "WHERE NOT EXISTS (" + " SELECT * FROM bbox_nodes WHERE id = buwn.id" + ");" ); jdbcTemplate.update("ALTER TABLE ONLY bbox_missing_way_nodes" + " ADD CONSTRAINT pk_bbox_missing_way_nodes PRIMARY KEY (id)"); jdbcTemplate.update("ANALYZE bbox_missing_way_nodes"); rowCount = jdbcTemplate.update("INSERT INTO bbox_nodes " + "SELECT n.* FROM nodes n INNER JOIN bbox_missing_way_nodes bwn ON n.id = bwn.id;"); LOG.finer(rowCount + " rows affected."); } LOG.finer("Updating query analyzer statistics on the temporary nodes table."); jdbcTemplate.update("ANALYZE bbox_nodes"); // Create iterators for the selected records for each of the entity types. LOG.finer("Iterating over results."); resultSets = new ArrayList>(); resultSets.add( new UpcastIterator( new BoundContainerIterator(new ReleasableAdaptorForIterator(bounds.iterator())))); resultSets.add( new UpcastIterator( new NodeContainerIterator(nodeDao.iterate("bbox_")))); resultSets.add( new UpcastIterator( new WayContainerIterator(wayDao.iterate("bbox_")))); resultSets.add( new UpcastIterator( new RelationContainerIterator(relationDao.iterate("bbox_")))); // Merge all readers into a single result iterator and return. return new MultipleSourceIterator(resultSets); } /** * {@inheritDoc} */ @Override public void complete() { dbCtx.commitTransaction(); } /** * {@inheritDoc} */ @Override public void release() { if (dbCtx != null) { dbCtx.release(); dbCtx = null; } } } PostgreSqlEntityManager.java000066400000000000000000000053241253404521400402450ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.util.HashSet; import java.util.Set; import org.openstreetmap.osmosis.core.container.v0_6.EntityManager; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.pgsnapshot.common.NoSuchRecordException; /** * Provides postgres entity manager support allowing entities to be manipulated via a common dataset * interface. * * @author Brett Henderson * * @param * The entity type to be supported. */ public class PostgreSqlEntityManager implements EntityManager { private EntityDao entityDao; private UserDao userDao; private Set userSet; /** * Creates a new instance. * * @param entityDao * The dao allowing manipulation of a specific entity type. * @param userDao * The user dao allowing user entries to be updated or created. */ public PostgreSqlEntityManager(EntityDao entityDao, UserDao userDao) { this.entityDao = entityDao; this.userDao = userDao; userSet = new HashSet(); } /** * Writes the specified user to the database. * * @param user * The user to write. */ private void writeUser(OsmUser user) { // Entities without a user assigned should not be written. if (!OsmUser.NONE.equals(user)) { // Users will only be updated in the database once per changeset // run. if (!userSet.contains(user.getId())) { int userId; OsmUser existingUser; userId = user.getId(); try { existingUser = userDao.getUser(userId); if (!user.equals(existingUser)) { userDao.updateUser(user); } } catch (NoSuchRecordException e) { userDao.addUser(user); } userSet.add(user.getId()); } } } /** * {@inheritDoc} */ @Override public void addEntity(T entity) { writeUser(entity.getUser()); entityDao.addEntity(entity); } /** * {@inheritDoc} */ @Override public boolean exists(long id) { return entityDao.exists(id); } /** * {@inheritDoc} */ @Override public T getEntity(long id) { return entityDao.getEntity(id); } /** * {@inheritDoc} */ @Override public ReleasableIterator iterate() { return entityDao.iterate(); } /** * {@inheritDoc} */ @Override public void modifyEntity(T entity) { writeUser(entity.getUser()); entityDao.modifyEntity(entity); } /** * {@inheritDoc} */ @Override public void removeEntity(long entityId) { entityDao.removeEntity(entityId); } } RelationDao.java000066400000000000000000000141441253404521400356530ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.util.ArrayList; import java.util.List; import org.openstreetmap.osmosis.core.database.DbFeature; import org.openstreetmap.osmosis.core.database.DbOrderedFeature; import org.openstreetmap.osmosis.core.database.FeaturePopulator; import org.openstreetmap.osmosis.core.database.RelationMemberCollectionLoader; import org.openstreetmap.osmosis.core.database.SortingStoreRowMapperListener; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.sort.common.FileBasedSort; import org.openstreetmap.osmosis.core.store.SingleClassObjectSerializationFactory; import org.openstreetmap.osmosis.core.store.StoreReleasingIterator; import org.openstreetmap.osmosis.core.store.UpcastIterator; import org.openstreetmap.osmosis.pgsnapshot.common.DatabaseContext; import org.openstreetmap.osmosis.pgsnapshot.common.RowMapperRowCallbackListener; import org.springframework.jdbc.core.JdbcTemplate; /** * Performs all relation-specific db operations. * * @author Brett Henderson */ public class RelationDao extends EntityDao { private JdbcTemplate jdbcTemplate; private EntityFeatureDao> relationMemberDao; private RelationMemberMapper relationMemberMapper; /** * Creates a new instance. * * @param dbCtx * The database context to use for accessing the database. * @param actionDao * The dao to use for adding action records to the database. */ public RelationDao(DatabaseContext dbCtx, ActionDao actionDao) { super(dbCtx.getJdbcTemplate(), new RelationMapper(), actionDao); jdbcTemplate = dbCtx.getJdbcTemplate(); relationMemberMapper = new RelationMemberMapper(); relationMemberDao = new EntityFeatureDao>( dbCtx.getJdbcTemplate(), relationMemberMapper); } private void loadFeatures(long entityId, Relation entity) { entity.getMembers().addAll(relationMemberDao.getAllRaw(entityId)); } /** * {@inheritDoc} */ @Override public Relation getEntity(long entityId) { Relation entity; entity = super.getEntity(entityId); loadFeatures(entityId, entity); return entity; } /** * Adds the specified relation member list to the database. * * @param entityId * The identifier of the entity to add these features to. * @param memberList * The list of features to add. */ private void addMembers(long entityId, List memberList) { List> dbList; dbList = new ArrayList>(memberList.size()); for (int i = 0; i < memberList.size(); i++) { dbList.add(new DbOrderedFeature(entityId, memberList.get(i), i)); } relationMemberDao.addAll(dbList); } /** * {@inheritDoc} */ @Override public void addEntity(Relation entity) { super.addEntity(entity); addMembers(entity.getId(), entity.getMembers()); } /** * {@inheritDoc} */ @Override public void modifyEntity(Relation entity) { long relationId; super.modifyEntity(entity); relationId = entity.getId(); relationMemberDao.removeList(relationId); addMembers(entity.getId(), entity.getMembers()); } /** * {@inheritDoc} */ @Override public void removeEntity(long entityId) { relationMemberDao.removeList(entityId); super.removeEntity(entityId); } private ReleasableIterator> getRelationMembers(String tablePrefix) { FileBasedSort> sortingStore = new FileBasedSort>( new SingleClassObjectSerializationFactory(DbOrderedFeature.class), new DbOrderedFeatureComparator(), true); try { String sql; SortingStoreRowMapperListener> storeListener; RowMapperRowCallbackListener> rowCallbackListener; ReleasableIterator> resultIterator; sql = relationMemberMapper.getSqlSelect(tablePrefix, false, false); // Sends all received data into the object store. storeListener = new SortingStoreRowMapperListener>(sortingStore); // Converts result set rows into objects and passes them into the store. rowCallbackListener = new RowMapperRowCallbackListener>( relationMemberMapper.getRowMapper(), storeListener); // Perform the query passing the row mapper chain to process rows in a streamy fashion. jdbcTemplate.query(sql, rowCallbackListener); // Open a iterator on the store that will release the store upon completion. resultIterator = new StoreReleasingIterator>(sortingStore.iterate(), sortingStore); // The store itself shouldn't be released now that it has been attached to the iterator. sortingStore = null; return resultIterator; } finally { if (sortingStore != null) { sortingStore.release(); } } } /** * {@inheritDoc} */ @Override protected List> getFeaturePopulators(String tablePrefix) { ReleasableIterator> relationMemberIterator; List> featurePopulators; featurePopulators = new ArrayList>(); // Get the way nodes for the selected entities. relationMemberIterator = new UpcastIterator, DbOrderedFeature>( getRelationMembers(tablePrefix)); // Wrap the way node source into a feature populator that can attach them to their // owning ways. featurePopulators.add( new FeaturePopulatorImpl>( relationMemberIterator, new RelationMemberCollectionLoader())); return featurePopulators; } } RelationMapper.java000066400000000000000000000022431253404521400363710ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.util.Map; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.springframework.jdbc.core.RowMapper; /** * Reads and writes relation attributes to jdbc classes. * * @author Brett Henderson */ public class RelationMapper extends EntityMapper { /** * {@inheritDoc} */ @Override public String getEntityName() { return "relation"; } /** * {@inheritDoc} */ @Override public ActionDataType getEntityType() { return ActionDataType.RELATION; } /** * {@inheritDoc} */ @Override public Class getEntityClass() { return Relation.class; } /** * {@inheritDoc} */ @Override protected String[] getTypeSpecificFieldNames() { return new String[] {}; } /** * {@inheritDoc} */ @Override public void populateEntityParameters(Map args, Relation entity) { populateCommonEntityParameters(args, entity); } /** * {@inheritDoc} */ @Override public RowMapper getRowMapper() { return new RelationRowMapper(); } } RelationMemberMapper.java000066400000000000000000000064501253404521400375250ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.util.Map; import org.openstreetmap.osmosis.core.database.DbOrderedFeature; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.springframework.jdbc.core.RowMapper; /** * Reads and writes relation members to jdbc classes. * * @author Brett Henderson */ public class RelationMemberMapper extends EntityFeatureMapper> { private MemberTypeValueMapper memberTypeValueMapper; /** * Creates a new instance. */ public RelationMemberMapper() { memberTypeValueMapper = new MemberTypeValueMapper(); } /** * {@inheritDoc} */ @Override public String getParentEntityName() { return "relation"; } /** * {@inheritDoc} */ @Override public String getEntityName() { return "relation_members"; } /** * {@inheritDoc} */ @Override public String getSqlSelect(String tablePrefix, boolean filterByEntityId, boolean orderBy) { StringBuilder resultSql; resultSql = new StringBuilder(); resultSql.append("SELECT relation_id AS entity_id, member_id, member_type, member_role, sequence_id FROM "); resultSql.append("relation_members f"); if (!tablePrefix.isEmpty()) { resultSql.append(" INNER JOIN ").append(tablePrefix).append(getParentEntityName()) .append("s e ON f.").append(getParentEntityName()).append("_id = e.id"); } if (filterByEntityId) { resultSql.append(" WHERE relation_id = ?"); } if (orderBy) { resultSql.append(getSqlDefaultOrderBy()); } return resultSql.toString(); } /** * {@inheritDoc} */ @Override public String getSqlDefaultOrderBy() { return super.getSqlDefaultOrderBy() + ", sequence_id"; } /** * {@inheritDoc} */ @Override public String getSqlInsert(int rowCount) { StringBuilder resultSql; resultSql = new StringBuilder(); resultSql.append("INSERT INTO relation_members ("); resultSql.append("relation_id, member_id, member_type, member_role, sequence_id) VALUES "); for (int row = 0; row < rowCount; row++) { if (row > 0) { resultSql.append(", "); } resultSql.append("(:relationId, :memberId, :memberType, :memberRole, :sequenceId)"); } return resultSql.toString(); } /** * {@inheritDoc} */ @Override public String getSqlDelete(boolean filterByEntityId) { StringBuilder resultSql; resultSql = new StringBuilder(); resultSql.append("DELETE FROM relation_members"); if (filterByEntityId) { resultSql.append(" WHERE ").append("relation_id = ?"); } return resultSql.toString(); } /** * {@inheritDoc} */ @Override public void populateParameters(Map args, DbOrderedFeature feature) { RelationMember relationMember; relationMember = feature.getFeature(); args.put("relationId", feature.getEntityId()); args.put("memberId", relationMember.getMemberId()); args.put("memberType", memberTypeValueMapper.getMemberType(relationMember.getMemberType())); args.put("memberRole", relationMember.getMemberRole()); args.put("sequenceId", feature.getSequenceId()); } /** * {@inheritDoc} */ @Override public RowMapper> getRowMapper() { return new RelationMemberRowMapper(); } } RelationMemberRowMapper.java000066400000000000000000000022331253404521400402100ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.sql.ResultSet; import java.sql.SQLException; import org.openstreetmap.osmosis.core.database.DbOrderedFeature; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.springframework.jdbc.core.RowMapper; /** * Maps database rows into relation member database objects. * * @author Brett Henderson */ public class RelationMemberRowMapper implements RowMapper> { private MemberTypeValueMapper memberTypeValueMapper; /** * Creates a new instance. */ public RelationMemberRowMapper() { memberTypeValueMapper = new MemberTypeValueMapper(); } /** * {@inheritDoc} */ @Override public DbOrderedFeature mapRow(ResultSet rs, int rowNumber) throws SQLException { return new DbOrderedFeature( rs.getLong("entity_id"), new RelationMember( rs.getLong("member_id"), memberTypeValueMapper.getEntityType(rs.getString("member_type")), rs.getString("member_role") ), rs.getInt("sequence_id") ); } } RelationRowMapper.java000066400000000000000000000011031253404521400370530ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.sql.ResultSet; import java.sql.SQLException; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; /** * Maps database rows into Relation objects. * * @author Brett Henderson */ public class RelationRowMapper extends EntityRowMapper { /** * {@inheritDoc} */ @Override public Relation mapRow(ResultSet rs, int rowNumber) throws SQLException { return new Relation(mapCommonEntityData(rs)); } } TempCopyFileset.java000066400000000000000000000050641253404521400365270ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.lifecycle.Releasable; /** * A COPY fileset implementation that uses temporary files. * * @author Brett Henderson * */ public class TempCopyFileset implements CopyFileset, Releasable { private static final Logger LOG = Logger.getLogger(TempCopyFileset.class.getName()); private ArrayList tmpFiles; private File userFile; private File nodeFile; private File wayFile; private File wayNodeFile; private File relationFile; private File relationMemberFile; private boolean initialized; /** * Creates a new instance. */ public TempCopyFileset() { tmpFiles = new ArrayList(); initialized = false; } private File createTempFile(String suffix) { try { File tmpFile; tmpFile = File.createTempFile("copy", suffix); tmpFiles.add(tmpFile); return tmpFile; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to create COPY temp file.", e); } } private void initialize() { if (!initialized) { userFile = createTempFile("u"); nodeFile = createTempFile("n"); wayFile = createTempFile("w"); wayNodeFile = createTempFile("wn"); relationFile = createTempFile("r"); relationMemberFile = createTempFile("rm"); initialized = true; } } /** * {@inheritDoc} */ @Override public File getNodeFile() { initialize(); return nodeFile; } /** * {@inheritDoc} */ @Override public File getRelationFile() { initialize(); return relationFile; } /** * {@inheritDoc} */ @Override public File getRelationMemberFile() { initialize(); return relationMemberFile; } /** * {@inheritDoc} */ @Override public File getUserFile() { initialize(); return userFile; } /** * {@inheritDoc} */ @Override public File getWayFile() { initialize(); return wayFile; } /** * {@inheritDoc} */ @Override public File getWayNodeFile() { initialize(); return wayNodeFile; } /** * {@inheritDoc} */ @Override public void release() { for (File tmpFile : tmpFiles) { if (!tmpFile.delete()) { // We cannot throw an exception within a release statement. LOG.warning("Unable to delete file " + tmpFile); } } tmpFiles.clear(); initialized = false; } } UserDao.java000066400000000000000000000045441253404521400350170ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.pgsnapshot.common.DatabaseContext; import org.openstreetmap.osmosis.pgsnapshot.common.NoSuchRecordException; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; /** * Performs all user-specific db operations. * * @author Brett Henderson */ public class UserDao { private static final String SELECT_USER = "SELECT id, name FROM users WHERE id = ?"; private static final String INSERT_USER = "INSERT INTO users(id, name) VALUES(?, ?)"; private static final String UPDATE_USER = "UPDATE users SET name = ? WHERE id = ?"; private JdbcTemplate jdbcTemplate; private ActionDao actionDao; private UserRowMapper rowMapper; /** * Creates a new instance. * * @param dbCtx * The database context to use for accessing the database. * @param actionDao * The dao to use for adding action records to the database. */ public UserDao(DatabaseContext dbCtx, ActionDao actionDao) { this.actionDao = actionDao; jdbcTemplate = dbCtx.getJdbcTemplate(); rowMapper = new UserRowMapper(); } /** * Loads the specified way from the database. * * @param userId * The unique identifier of the user. * @return The loaded user. */ public OsmUser getUser(long userId) { OsmUser user; try { user = jdbcTemplate.queryForObject(SELECT_USER, rowMapper, userId); } catch (EmptyResultDataAccessException e) { throw new NoSuchRecordException("User " + userId + " doesn't exist.", e); } return user; } /** * Adds the specified user to the database. * * @param user * The user to add. */ public void addUser(OsmUser user) { jdbcTemplate.update(INSERT_USER, user.getId(), user.getName()); actionDao.addAction(ActionDataType.USER, ChangesetAction.CREATE, user.getId()); } /** * Updates the specified user record in the database. * * @param user * The user to update. */ public void updateUser(OsmUser user) { jdbcTemplate.update(UPDATE_USER, user.getName(), user.getId()); actionDao.addAction(ActionDataType.USER, ChangesetAction.MODIFY, user.getId()); } } UserRowMapper.java000066400000000000000000000011621253404521400362210ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.sql.ResultSet; import java.sql.SQLException; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.springframework.jdbc.core.RowMapper; /** * Maps database rows into User objects. * * @author Brett Henderson */ public class UserRowMapper implements RowMapper { /** * {@inheritDoc} */ @Override public OsmUser mapRow(ResultSet rs, int rowNumber) throws SQLException { return new OsmUser(rs.getInt("id"), rs.getString("name")); } } WayDao.java000066400000000000000000000075401253404521400346400ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.openstreetmap.osmosis.core.database.DbOrderedFeature; import org.openstreetmap.osmosis.core.database.FeaturePopulator; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.openstreetmap.osmosis.pgsnapshot.common.DatabaseContext; import org.springframework.jdbc.core.JdbcTemplate; /** * Performs all way-specific db operations. * * @author Brett Henderson */ public class WayDao extends EntityDao { private static final String SQL_UPDATE_WAY_BBOX = "UPDATE ways SET bbox = (" + " SELECT ST_Envelope(ST_Collect(geom))" + " FROM nodes JOIN way_nodes ON way_nodes.node_id = nodes.id" + " WHERE way_nodes.way_id = ways.id" + " )" + " WHERE ways.id = ?"; private static final String SQL_UPDATE_WAY_LINESTRING = "UPDATE ways w SET linestring = (" + " SELECT ST_MakeLine(c.geom) AS way_line FROM (" + " SELECT n.geom AS geom FROM nodes n INNER JOIN way_nodes wn ON n.id = wn.node_id" + " WHERE (wn.way_id = w.id) ORDER BY wn.sequence_id" + " ) c" + " )" + " WHERE w.id = ?"; private JdbcTemplate jdbcTemplate; private DatabaseCapabilityChecker capabilityChecker; private EntityFeatureDao> wayNodeDao; private WayNodeMapper wayNodeMapper; /** * Creates a new instance. * * @param dbCtx * The database context to use for accessing the database. * @param actionDao * The dao to use for adding action records to the database. */ public WayDao(DatabaseContext dbCtx, ActionDao actionDao) { super(dbCtx.getJdbcTemplate(), new WayMapper(), actionDao); jdbcTemplate = dbCtx.getJdbcTemplate(); capabilityChecker = new DatabaseCapabilityChecker(dbCtx); wayNodeMapper = new WayNodeMapper(); wayNodeDao = new EntityFeatureDao>(jdbcTemplate, wayNodeMapper); } /** * Adds the specified way node list to the database. * * @param entityId * The identifier of the entity to add these features to. * @param wayNodeList * The list of features to add. */ private void addWayNodeList(long entityId, List wayNodeList) { List> dbList; dbList = new ArrayList>(wayNodeList.size()); for (int i = 0; i < wayNodeList.size(); i++) { dbList.add(new DbOrderedFeature(entityId, wayNodeList.get(i), i)); } wayNodeDao.addAll(dbList); } /** * Updates the bounding box column for the specified way. * * @param wayId * The way bounding box. */ private void updateWayGeometries(long wayId) { if (capabilityChecker.isWayBboxSupported()) { jdbcTemplate.update(SQL_UPDATE_WAY_BBOX, wayId); } if (capabilityChecker.isWayLinestringSupported()) { jdbcTemplate.update(SQL_UPDATE_WAY_LINESTRING, wayId); } } /** * {@inheritDoc} */ @Override public void addEntity(Way entity) { super.addEntity(entity); addWayNodeList(entity.getId(), entity.getWayNodes()); updateWayGeometries(entity.getId()); } /** * {@inheritDoc} */ @Override public void modifyEntity(Way entity) { long wayId; super.modifyEntity(entity); wayId = entity.getId(); wayNodeDao.removeList(wayId); addWayNodeList(entity.getId(), entity.getWayNodes()); updateWayGeometries(entity.getId()); } /** * {@inheritDoc} */ @Override public void removeEntity(long entityId) { wayNodeDao.removeList(entityId); super.removeEntity(entityId); } /** * {@inheritDoc} */ @Override protected List> getFeaturePopulators(String tablePrefix) { return Collections.emptyList(); } } WayGeometryBuilder.java000066400000000000000000000134541253404521400372400ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.util.ArrayList; import java.util.List; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.openstreetmap.osmosis.core.lifecycle.Releasable; import org.openstreetmap.osmosis.pgsnapshot.common.CompactPersistentNodeLocationStore; import org.openstreetmap.osmosis.pgsnapshot.common.InMemoryNodeLocationStore; import org.openstreetmap.osmosis.pgsnapshot.common.NodeLocation; import org.openstreetmap.osmosis.pgsnapshot.common.NodeLocationStore; import org.openstreetmap.osmosis.pgsnapshot.common.NodeLocationStoreType; import org.openstreetmap.osmosis.pgsnapshot.common.PersistentNodeLocationStore; import org.postgis.LineString; import org.postgis.LinearRing; import org.postgis.Point; import org.postgis.Polygon; /** * Caches a set of node latitudes and longitudes and uses these to calculate the * geometries for ways. * * @author Brett Henderson */ public class WayGeometryBuilder implements Releasable { /** * Stores the locations of nodes so that they can be used to build the way * geometries. */ protected NodeLocationStore locationStore; /** * Creates a new instance. * * @param storeType * The type of storage to use for holding node locations. */ public WayGeometryBuilder(NodeLocationStoreType storeType) { if (NodeLocationStoreType.InMemory.equals(storeType)) { locationStore = new InMemoryNodeLocationStore(); } else if (NodeLocationStoreType.TempFile.equals(storeType)) { locationStore = new PersistentNodeLocationStore(); } else if (NodeLocationStoreType.CompactTempFile.equals(storeType)) { locationStore = new CompactPersistentNodeLocationStore(); } else { throw new OsmosisRuntimeException("The store type " + storeType + " is not recognized."); } } /** * Adds the location of the node to the internal store. * * @param node * The node to add. */ public void addNodeLocation(Node node) { locationStore.addLocation(node.getId(), new NodeLocation(node.getLongitude(), node.getLatitude())); } /** * Get NodeLocation from internal store. * * @param nodeId * Id of the node we want the location for. * @return Location of node */ public NodeLocation getNodeLocation(long nodeId) { return locationStore.getNodeLocation(nodeId); } private Polygon createWayBbox(double left, double right, double bottom, double top) { Point[] points; LinearRing ring; Polygon bbox; points = new Point[5]; points[0] = new Point(left, bottom); points[1] = new Point(left, top); points[2] = new Point(right, top); points[3] = new Point(right, bottom); points[4] = new Point(left, bottom); ring = new LinearRing(points); bbox = new Polygon(new LinearRing[] {ring}); bbox.srid = 4326; return bbox; } /** * Creates a linestring from a list of points. * * @param points * The points making up the line. * @return The linestring. */ public LineString createLinestring(List points) { LineString lineString; lineString = new LineString(points.toArray(new Point[]{})); lineString.srid = 4326; return lineString; } /** * @param nodeId * Id of the node. * @return Point object */ public Point createPoint(long nodeId) { NodeLocation nodeLocation = locationStore.getNodeLocation(nodeId); Point point = new Point(nodeLocation.getLongitude(), nodeLocation.getLatitude()); point.srid = 4326; return point; } /** * Builds a bounding box geometry object from the node references in the * specified way. Unknown nodes will be ignored. * * @param way * The way to create the bounding box for. * @return The bounding box surrounding the way. */ public Polygon createWayBbox(Way way) { double left; double right; double top; double bottom; boolean nodesFound; nodesFound = false; left = 0; right = 0; bottom = 0; top = 0; for (WayNode wayNode : way.getWayNodes()) { NodeLocation nodeLocation; double longitude; double latitude; nodeLocation = locationStore.getNodeLocation(wayNode.getNodeId()); longitude = nodeLocation.getLongitude(); latitude = nodeLocation.getLatitude(); if (nodeLocation.isValid()) { if (nodesFound) { if (longitude < left) { left = longitude; } if (longitude > right) { right = longitude; } if (latitude < bottom) { bottom = latitude; } if (latitude > top) { top = latitude; } } else { left = longitude; right = longitude; bottom = latitude; top = latitude; nodesFound = true; } } } return createWayBbox(left, right, bottom, top); } /** * Builds a linestring geometry object from the node references in the * specified way. Unknown nodes will be ignored. * * @param way * The way to create the linestring for. * @return The linestring representing the way. */ public LineString createWayLinestring(Way way) { List linePoints; linePoints = new ArrayList(); for (WayNode wayNode : way.getWayNodes()) { NodeLocation nodeLocation; nodeLocation = locationStore.getNodeLocation(wayNode.getNodeId()); if (nodeLocation.isValid()) { linePoints.add(new Point(nodeLocation.getLongitude(), nodeLocation.getLatitude())); } else { return null; } } return createLinestring(linePoints); } /** * {@inheritDoc} */ @Override public void release() { locationStore.release(); } } WayMapper.java000066400000000000000000000045301253404521400353550ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.springframework.jdbc.core.RowMapper; /** * Reads and writes way attributes to jdbc classes. * * @author Brett Henderson */ public class WayMapper extends EntityMapper { private boolean supportBboxColumn; private boolean supportLinestringColumn; /** * Creates a new instance. */ public WayMapper() { supportBboxColumn = false; } /** * Creates a new instance. * * @param supportBboxColumn * If true, the bounding box column will be included in updates. * @param supportLinestringColumn * If true, the linestring column will be included in updates. */ public WayMapper(boolean supportBboxColumn, boolean supportLinestringColumn) { this.supportBboxColumn = supportBboxColumn; this.supportLinestringColumn = supportLinestringColumn; } /** * {@inheritDoc} */ @Override public String getEntityName() { return "way"; } /** * {@inheritDoc} */ @Override public ActionDataType getEntityType() { return ActionDataType.WAY; } /** * {@inheritDoc} */ @Override public Class getEntityClass() { return Way.class; } /** * {@inheritDoc} */ @Override protected String[] getTypeSpecificFieldNames() { List fieldNames; fieldNames = new ArrayList(); fieldNames.add("nodes"); if (supportBboxColumn) { fieldNames.add("bbox"); } if (supportLinestringColumn) { fieldNames.add("linestring"); } return fieldNames.toArray(new String[]{}); } /** * {@inheritDoc} */ @Override public void populateEntityParameters(Map args, Way entity) { List wayNodes; long[] nodeIds; populateCommonEntityParameters(args, entity); wayNodes = entity.getWayNodes(); nodeIds = new long[wayNodes.size()]; for (int i = 0; i < nodeIds.length; i++) { nodeIds[i] = wayNodes.get(i).getNodeId(); } args.put("nodes", new WayNodesArray(nodeIds)); } /** * {@inheritDoc} */ @Override public RowMapper getRowMapper() { return new WayRowMapper(); } } WayNodeMapper.java000066400000000000000000000052741253404521400361710ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.util.Map; import org.openstreetmap.osmosis.core.database.DbOrderedFeature; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.springframework.jdbc.core.RowMapper; /** * Reads and writes way nodes to jdbc classes. * * @author Brett Henderson */ public class WayNodeMapper extends EntityFeatureMapper> { /** * {@inheritDoc} */ @Override public String getParentEntityName() { return "way"; } /** * {@inheritDoc} */ @Override public String getEntityName() { return "way_nodes"; } /** * {@inheritDoc} */ @Override public String getSqlSelect(String tablePrefix, boolean filterByEntityId, boolean orderBy) { StringBuilder resultSql; resultSql = new StringBuilder(); resultSql.append("SELECT way_id AS entity_id, node_id, sequence_id FROM "); resultSql.append("way_nodes f"); if (!tablePrefix.isEmpty()) { resultSql.append(" INNER JOIN ").append(tablePrefix).append(getParentEntityName()) .append("s e ON f.").append(getParentEntityName()).append("_id = e.id"); } if (filterByEntityId) { resultSql.append(" WHERE way_id = ?"); } if (orderBy) { resultSql.append(getSqlDefaultOrderBy()); } return resultSql.toString(); } /** * {@inheritDoc} */ @Override public String getSqlDefaultOrderBy() { return super.getSqlDefaultOrderBy() + ", sequence_id"; } /** * {@inheritDoc} */ @Override public String getSqlInsert(int rowCount) { StringBuilder resultSql; resultSql = new StringBuilder(); resultSql.append("INSERT INTO way_nodes ("); resultSql.append("way_id, node_id, sequence_id) VALUES "); for (int row = 0; row < rowCount; row++) { if (row > 0) { resultSql.append(", "); } resultSql.append("(:wayId, :nodeId, :sequenceId)"); } return resultSql.toString(); } /** * {@inheritDoc} */ @Override public String getSqlDelete(boolean filterByEntityId) { StringBuilder resultSql; resultSql = new StringBuilder(); resultSql.append("DELETE FROM way_nodes"); if (filterByEntityId) { resultSql.append(" WHERE ").append("way_id = ?"); } return resultSql.toString(); } /** * {@inheritDoc} */ @Override public void populateParameters(Map args, DbOrderedFeature feature) { args.put("wayId", feature.getEntityId()); args.put("nodeId", feature.getFeature().getNodeId()); args.put("sequenceId", feature.getSequenceId()); } /** * {@inheritDoc} */ @Override public RowMapper> getRowMapper() { return new WayNodeRowMapper(); } } WayNodeRowMapper.java000066400000000000000000000015051253404521400366520ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.sql.ResultSet; import java.sql.SQLException; import org.openstreetmap.osmosis.core.database.DbOrderedFeature; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.springframework.jdbc.core.RowMapper; /** * Maps database rows into way node database objects. * * @author Brett Henderson */ public class WayNodeRowMapper implements RowMapper> { /** * {@inheritDoc} */ @Override public DbOrderedFeature mapRow(ResultSet rs, int rowNumber) throws SQLException { return new DbOrderedFeature( rs.getLong("entity_id"), new WayNode( rs.getLong("node_id") ), rs.getInt("sequence_id") ); } } WayNodesArray.java000066400000000000000000000052771253404521400362110ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.sql.Array; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import java.util.Arrays; import java.util.Map; /** * Provides an Array implementation suitable for setting the way nodes column. * * @author Brett Henderson */ public class WayNodesArray implements Array { private static String arrayToString(long[] data) { StringBuilder result; if (data == null) { return null; } result = new StringBuilder(); result.append('{'); for (int i = 0; i < data.length; i++) { if (i > 0) { result.append(','); } result.append(data[i]); } result.append('}'); return result.toString(); } private final long[] data; private final String stringValue; /** * Creates a new instance. * * @param data * The array data. */ public WayNodesArray(long[] data) { this.data = data; this.stringValue = arrayToString(data); } /** * {@inheritDoc} */ public String toString() { return stringValue; } /** * {@inheritDoc} */ public Object getArray() throws SQLException { if (data != null) { return Arrays.copyOf(data, data.length); } else { return null; } } /** * {@inheritDoc} */ public Object getArray(Map> map) throws SQLException { return getArray(); } /** * {@inheritDoc} */ public Object getArray(long index, int count) throws SQLException { if (data != null) { return Arrays.copyOfRange(data, (int) index, (int) index + count); } else { return null; } } /** * {@inheritDoc} */ public Object getArray(long index, int count, Map> map) throws SQLException { return getArray(index, count); } /** * {@inheritDoc} */ public int getBaseType() throws SQLException { return Types.BIGINT; } /** * {@inheritDoc} */ public String getBaseTypeName() throws SQLException { return "int8"; } /** * {@inheritDoc} */ public ResultSet getResultSet() throws SQLException { throw new UnsupportedOperationException(); } /** * {@inheritDoc} */ public ResultSet getResultSet(Map> map) throws SQLException { throw new UnsupportedOperationException(); } /** * {@inheritDoc} */ public ResultSet getResultSet(long index, int count) throws SQLException { throw new UnsupportedOperationException(); } /** * {@inheritDoc} */ public ResultSet getResultSet(long index, int count, Map> map) throws SQLException { throw new UnsupportedOperationException(); } /** * {@inheritDoc} */ public void free() throws SQLException { } } WayRowMapper.java000066400000000000000000000017261253404521400360510ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.sql.Array; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; /** * Maps database rows into Way objects. * * @author Brett Henderson */ public class WayRowMapper extends EntityRowMapper { /** * {@inheritDoc} */ @Override public Way mapRow(ResultSet rs, int rowNumber) throws SQLException { Way way; Array nodeIdArray; Long[] nodeIds; List wayNodes; way = new Way(mapCommonEntityData(rs)); nodeIdArray = rs.getArray("nodes"); if (nodeIdArray != null) { nodeIds = (Long[]) nodeIdArray.getArray(); wayNodes = way.getWayNodes(); for (long nodeId : nodeIds) { wayNodes.add(new WayNode(nodeId)); } } return way; } } osmosis-0.44.1/osmosis-pgsnapshot/src/main/resources/000077500000000000000000000000001253404521400227015ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/main/resources/osmosis-plugins.conf000066400000000000000000000000731253404521400267230ustar00rootroot00000000000000org.openstreetmap.osmosis.pgsnapshot.PgSnapshotPluginLoaderosmosis-0.44.1/osmosis-pgsnapshot/src/test/000077500000000000000000000000001253404521400207225ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/test/java/000077500000000000000000000000001253404521400216435ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/test/java/org/000077500000000000000000000000001253404521400224325ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/test/java/org/openstreetmap/000077500000000000000000000000001253404521400253205ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/test/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400270145ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/test/java/org/openstreetmap/osmosis/pgsnapshot/000077500000000000000000000000001253404521400312025ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/test/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/000077500000000000000000000000001253404521400317545ustar00rootroot00000000000000DatasetDriver.java000066400000000000000000000047261253404521400353120ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/test/java/org/openstreetmap/osmosis/pgsnapshot/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.TimeZone; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.Dataset; import org.openstreetmap.osmosis.core.container.v0_6.DatasetContext; import org.openstreetmap.osmosis.core.container.v0_6.EntityManager; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.task.v0_6.DatasetSink; /** * Performs queries and modifications to exercise the pgsql dataset implementation. * * @author Brett Henderson */ public class DatasetDriver implements DatasetSink { private Date buildDate(String utcString) { SimpleDateFormat dateFormat; dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); try { return dateFormat.parse(utcString); } catch (ParseException e) { throw new OsmosisRuntimeException("The date string (" + utcString + ") could not be parsed.", e); } } /** * {@inheritDoc} */ @Override public void process(Dataset dataset) { DatasetContext dsCtx = dataset.createReader(); try { EntityManager nodeManager = dsCtx.getNodeManager(); OsmUser user; Node node; // Create the user for edits to be performed under. This is an existing user with an // updated name. user = new OsmUser(10, "user10b"); // Modify node 1 to add a new tag. node = nodeManager.getEntity(1).getWriteableInstance(); node.setUser(user); node.getTags().add(new Tag("change", "new tag")); nodeManager.modifyEntity(node); // Delete node 6. nodeManager.removeEntity(6); // Add node 7 using the NONE user. node = new Node(new CommonEntityData(7, 16, buildDate("2008-01-02 18:19:20"), OsmUser.NONE, 93), -11, -12); node.getTags().addAll( Arrays.asList(new Tag[]{new Tag("created_by", "Me7"), new Tag("change", "new node")})); nodeManager.addEntity(node); dsCtx.complete(); } finally { dsCtx.release(); } } /** * {@inheritDoc} */ @Override public void release() { // Do nothing. } } DatasetDriverFactory.java000066400000000000000000000015031253404521400366300ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/test/java/org/openstreetmap/osmosis/pgsnapshot/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.DatasetSinkManager; /** * The task manager factory for reading the entire contents of a dataset. * * @author Brett Henderson */ public class DatasetDriverFactory extends TaskManagerFactory { /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { return new DatasetSinkManager( taskConfig.getId(), new DatasetDriver(), taskConfig.getPipeArgs() ); } } DatasetDriverPlugin.java000066400000000000000000000013751253404521400364660ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/test/java/org/openstreetmap/osmosis/pgsnapshot/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.plugin.PluginLoader; /** * Registers the dataset driver test task. * * @author Brett Henderson */ public class DatasetDriverPlugin implements PluginLoader { /** * {@inheritDoc} */ @Override public Map loadTaskFactories() { HashMap factoryMap; factoryMap = new HashMap(); factoryMap.put("drive-dataset", new DatasetDriverFactory()); return factoryMap; } } PostgreSqlTest.java000066400000000000000000000146411253404521400355110ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/test/java/org/openstreetmap/osmosis/pgsnapshot/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6; import java.io.File; import java.io.IOException; import org.junit.Test; import org.openstreetmap.osmosis.core.Osmosis; import org.openstreetmap.osmosis.testutil.AbstractDataTest; /** * Tests for PostgreSQL tasks. * * @author Brett Henderson */ public class PostgreSqlTest extends AbstractDataTest { private File getAuthFile() { return dataUtils.createDataFile("db.pgsql.authfile", "v0_6/pgsql-authfile.txt"); } /** * A basic test loading an osm file into a pgsql database, then dumping it * again and verifying that it is identical. * * @throws IOException * if any file operations fail. */ @Test public void testLoadAndDump() throws IOException { File authFile; File inputFile; File outputFile; // Generate input files. authFile = getAuthFile(); inputFile = dataUtils.createDataFile("v0_6/db-snapshot.osm"); outputFile = dataUtils.newFile(); // Remove all existing data from the database. Osmosis.run( new String [] { "-q", "--truncate-pgsql-0.6", "authFile=" + authFile.getPath() } ); // Load the database with a dataset. Osmosis.run( new String [] { "-q", "--read-xml-0.6", inputFile.getPath(), "--write-pgsql-0.6", "authFile=" + authFile.getPath() } ); // Dump the database to an osm file. Osmosis.run( new String [] { "-q", "--read-pgsql-0.6", "authFile=" + authFile.getPath(), "--dataset-dump-0.6", "--tag-sort-0.6", "--write-xml-0.6", outputFile.getPath() } ); // Validate that the output file matches the input file. dataUtils.compareFiles(inputFile, outputFile); } /** * A test loading an osm file into a pgsql database, then applying a * changeset, then dumping it again and verifying the output is as expected. * * @throws IOException * if any file operations fail. */ @Test public void testChangeset() throws IOException { File authFile; File snapshotFile; File changesetFile; File expectedResultFile; File actualResultFile; // Generate input files. authFile = getAuthFile(); snapshotFile = dataUtils.createDataFile("v0_6/db-snapshot.osm"); changesetFile = dataUtils.createDataFile("v0_6/db-changeset.osc"); expectedResultFile = dataUtils.createDataFile("v0_6/db-changeset-expected.osm"); actualResultFile = dataUtils.newFile(); // Remove all existing data from the database. Osmosis.run( new String [] { "-q", "--truncate-pgsql-0.6", "authFile=" + authFile.getPath() } ); // Load the database with the snapshot file. Osmosis.run( new String [] { "-q", "--read-xml-0.6", snapshotFile.getPath(), "--write-pgsql-0.6", "authFile=" + authFile.getPath() } ); // Apply the changeset file to the database. Osmosis.run( new String [] { "-q", "--read-xml-change-0.6", changesetFile.getPath(), "--write-pgsql-change-0.6", "keepInvalidWays=false", "authFile=" + authFile.getPath() } ); // Dump the database to an osm file. Osmosis.run( new String [] { "-q", "--read-pgsql-0.6", "authFile=" + authFile.getPath(), "--dataset-dump-0.6", "--tag-sort-0.6", "--write-xml-0.6", actualResultFile.getPath() } ); // Validate that the dumped file matches the expected result. dataUtils.compareFiles(expectedResultFile, actualResultFile); } /** * A test loading an osm file into a pgsql database, then making some modifications via the * dataset api, then dumping it again and verifying the output is as expected. * * @throws IOException * if any file operations fail. */ @Test public void testDataset() throws IOException { File authFile; File snapshotFile; File expectedResultFile; File actualResultFile; // Generate input files. authFile = getAuthFile(); snapshotFile = dataUtils.createDataFile("v0_6/db-snapshot.osm"); expectedResultFile = dataUtils.createDataFile("v0_6/db-dataset-expected.osm"); actualResultFile = dataUtils.newFile(); // Remove all existing data from the database. Osmosis.run( new String [] { "-q", "--truncate-pgsql-0.6", "authFile=" + authFile.getPath() } ); // Load the database with the snapshot file. Osmosis.run( new String [] { "-q", "--read-xml-0.6", snapshotFile.getPath(), "--write-pgsql-0.6", "authFile=" + authFile.getPath() } ); // Invoke the dataset driver task task to manipulate the database. Osmosis.run( new String [] { "-q", "-p", DatasetDriverPlugin.class.getName(), "--read-pgsql-0.6", "authFile=" + authFile.getPath(), "--drive-dataset" } ); // Dump the database to an osm file. Osmosis.run( new String [] { "-q", "--read-pgsql-0.6", "authFile=" + authFile.getPath(), "--dataset-dump-0.6", "--tag-sort-0.6", "--write-xml-0.6", actualResultFile.getPath() } ); // Validate that the dumped file matches the expected result. dataUtils.compareFiles(expectedResultFile, actualResultFile); } /** * A test loading an osm file into a pgsql database, then reading it via a * dataset bounding box covering the entire planet and verifying the output * is as expected. * * @throws IOException * if any file operations fail. */ @Test public void testDatasetBoundingBox() throws IOException { File authFile; File inputFile; File outputFile; // Generate input files. authFile = getAuthFile(); inputFile = dataUtils.createDataFile("v0_6/db-snapshot.osm"); outputFile = dataUtils.newFile(); // Remove all existing data from the database. Osmosis.run( new String [] { "-q", "--truncate-pgsql-0.6", "authFile=" + authFile.getPath() } ); // Load the database with a dataset. Osmosis.run( new String [] { "-q", "--read-xml-0.6", inputFile.getPath(), "--write-pgsql-0.6", "authFile=" + authFile.getPath() } ); // Dump the database to an osm file. Osmosis.run( new String [] { "-q", "--read-pgsql-0.6", "authFile=" + authFile.getPath(), "--dataset-bounding-box-0.6", "completeWays=true", "--tag-sort-0.6", "--write-xml-0.6", outputFile.getPath() } ); // Validate that the output file matches the input file. dataUtils.compareFiles(inputFile, outputFile); } } osmosis-0.44.1/osmosis-pgsnapshot/src/test/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl/000077500000000000000000000000001253404521400327155ustar00rootroot00000000000000NodeLocationStoreTest.java000066400000000000000000000052431253404521400377400ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/test/java/org/openstreetmap/osmosis/pgsnapshot/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import org.junit.Assert; import org.junit.Test; import org.openstreetmap.osmosis.pgsnapshot.common.InMemoryNodeLocationStore; import org.openstreetmap.osmosis.pgsnapshot.common.NodeLocation; import org.openstreetmap.osmosis.pgsnapshot.common.NodeLocationStore; import org.openstreetmap.osmosis.pgsnapshot.common.PersistentNodeLocationStore; import org.openstreetmap.osmosis.core.util.FixedPrecisionCoordinateConvertor; /** * Tests the node location store implementations. * * @author Brett Hendersons */ public class NodeLocationStoreTest { private void testStoreImplementation(NodeLocationStore store) { // Add a large number of locations to the store. for (int i = 0; i < 100000; i++) { double longitude; double latitude; // Stores typically use fixed precision storage therefore ensure we // have a good spread of values. // The longitude and latitude must be different values to ensure they don't get mixed up. longitude = FixedPrecisionCoordinateConvertor.convertToDouble(1 << (i % 32)); latitude = FixedPrecisionCoordinateConvertor.convertToDouble(1 << ((i + 1) % 32)); // Add the location to the store but leave every node invalid. store.addLocation(i * 2, new NodeLocation(longitude, latitude)); } // Verify that the data from the store matches. for (int i = 0; i < 100000; i++) { double longitude; double latitude; NodeLocation location; // Stores typically use fixed precision storage therefore ensure we // have a good spread of values. // The longitude and latitude must be different values to ensure they don't get mixed up. longitude = FixedPrecisionCoordinateConvertor.convertToDouble(1 << (i % 32)); latitude = FixedPrecisionCoordinateConvertor.convertToDouble(1 << ((i + 1) % 32)); location = store.getNodeLocation(i * 2); Assert.assertTrue("The node location should be valid.", location.isValid()); Assert.assertEquals("The longitude is incorrect.", longitude, location.getLongitude(), 0); Assert.assertEquals("The latitude is incorrect.", latitude, location.getLatitude(), 0); location = store.getNodeLocation((i * 2) + 1); Assert.assertFalse("The node location should be invalid.", location.isValid()); } store.release(); } /** * Tests the temporary file implementation. */ @Test public void testTempFile() { testStoreImplementation(new PersistentNodeLocationStore()); } /** * Tests the in-memory implementation. */ @Test public void testInMemory() { testStoreImplementation(new InMemoryNodeLocationStore()); } } osmosis-0.44.1/osmosis-pgsnapshot/src/test/resources/000077500000000000000000000000001253404521400227345ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/test/resources/data/000077500000000000000000000000001253404521400236455ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/test/resources/data/template/000077500000000000000000000000001253404521400254605ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/test/resources/data/template/v0_6/000077500000000000000000000000001253404521400262325ustar00rootroot00000000000000osmosis-0.44.1/osmosis-pgsnapshot/src/test/resources/data/template/v0_6/db-changeset-expected.osm000066400000000000000000000041421253404521400330760ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-pgsnapshot/src/test/resources/data/template/v0_6/db-changeset.osc000066400000000000000000000032721253404521400312700ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-pgsnapshot/src/test/resources/data/template/v0_6/db-dataset-expected.osm000066400000000000000000000042561253404521400325700ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-pgsnapshot/src/test/resources/data/template/v0_6/db-snapshot.osm000066400000000000000000000041461253404521400312010ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-pgsnapshot/src/test/resources/data/template/v0_6/pgsql-authfile.txt000066400000000000000000000001041253404521400317130ustar00rootroot00000000000000host=localhost database=pgosmsnap06_test user=osm password=password osmosis-0.44.1/osmosis-replication-http/000077500000000000000000000000001253404521400202545ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/.checkstyle000066400000000000000000000010051253404521400224070ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-replication-http/.gitignore000066400000000000000000000000531253404521400222420ustar00rootroot00000000000000.classpath .project .settings /bin /build osmosis-0.44.1/osmosis-replication-http/build.gradle000066400000000000000000000004101253404521400225260ustar00rootroot00000000000000dependencies { compile project(':osmosis-core') compile project(':osmosis-replication') compile project(':osmosis-xml') compile group: 'org.jboss.netty', name: 'netty', version: dependencyVersionNetty testCompile project(':osmosis-testutil') } osmosis-0.44.1/osmosis-replication-http/readme.txt000066400000000000000000000017371253404521400222620ustar00rootroot00000000000000Notes for enhancements to replication. Split current --replicate-apidb task into two halves. * One half reads from the database and maintains a state file with transaction details. * No sequence number maintained here. * Move into the Osmosis-ApidbReplication project. * Second half writes to change files and writes state files with timestamp only. * Sequence number allocated sequentially and written to a global state file. * Move into the Osmosis-Replicate project. * Starts web server (optional). * Web server responds to URL http://:/sequenceNumber with current state number. * Web server responds to URL http://:/sequenceNumber/upToDate with current state number and keeps sending updated state numbers as they become available. Create a new --serve-replication task. * Connects to the above web server to track current sequence number. * Starts web server. * Web server responds to URL http://:/replicate with current state number. osmosis-0.44.1/osmosis-replication-http/src/000077500000000000000000000000001253404521400210435ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/000077500000000000000000000000001253404521400217675ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/000077500000000000000000000000001253404521400227105ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/000077500000000000000000000000001253404521400234775ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/000077500000000000000000000000001253404521400263655ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400300615ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/000077500000000000000000000000001253404521400332725ustar00rootroot00000000000000ReplicationHttpPluginLoader.java000066400000000000000000000031611253404521400414760ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.plugin.PluginLoader; import org.openstreetmap.osmosis.replicationhttp.v0_6.ReplicationDataClientFactory; import org.openstreetmap.osmosis.replicationhttp.v0_6.ReplicationDataServerFactory; import org.openstreetmap.osmosis.replicationhttp.v0_6.ReplicationSequenceServerFactory; /** * The plugin loader for the API Schema tasks. * * @author Brett Henderson */ public class ReplicationHttpPluginLoader implements PluginLoader { /** * {@inheritDoc} */ @Override public Map loadTaskFactories() { Map factoryMap; factoryMap = new HashMap(); factoryMap.put("receive-replication", new ReplicationDataClientFactory()); factoryMap.put("rr", new ReplicationDataClientFactory()); factoryMap.put("send-replication-data", new ReplicationDataServerFactory()); factoryMap.put("srd", new ReplicationDataServerFactory()); factoryMap.put("send-replication-sequence", new ReplicationSequenceServerFactory()); factoryMap.put("srs", new ReplicationSequenceServerFactory()); factoryMap.put("read-replication-0.6", new ReplicationDataClientFactory()); factoryMap.put("send-replication-data-0.6", new ReplicationDataServerFactory()); factoryMap.put("send-replication-sequence-0.6", new ReplicationSequenceServerFactory()); return factoryMap; } } 000077500000000000000000000000001253404521400337655ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6ReplicationDataClient.java000066400000000000000000000072411253404521400410360ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6; import java.net.InetSocketAddress; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSinkChangeSource; import org.openstreetmap.osmosis.core.task.v0_6.RunnableChangeSource; import org.openstreetmap.osmosis.replicationhttp.v0_6.impl.ReplicationDataClientChannelPipelineFactory; import org.openstreetmap.osmosis.replicationhttp.v0_6.impl.SequenceClient; import org.openstreetmap.osmosis.replicationhttp.v0_6.impl.SequenceClientRestartManager; /** * This task connects to a replication data server to obtain replication data, * then sends the replication data to the sink. This requires the change sink to * support the replication extensions allowing state persistence and multiple * invocations. * * @author Brett Henderson */ public class ReplicationDataClient implements RunnableChangeSource { private NoReleaseChangeSinkWrapper changeSinkWrapper; private InetSocketAddress serverAddress; private String pathPrefix; /** * Creates a new instance. * * @param serverAddress * The server to connect to. * @param pathPrefix * The base path to add to the URL. This is necessary if a data * server is sitting behind a proxy server that adds a prefix to * the request path. */ public ReplicationDataClient(InetSocketAddress serverAddress, String pathPrefix) { this.serverAddress = serverAddress; this.pathPrefix = pathPrefix; changeSinkWrapper = new NoReleaseChangeSinkWrapper(); } @Override public void setChangeSink(ChangeSink changeSink) { changeSinkWrapper.setChangeSink(changeSink); } @Override public void run() { try { // Create a sequence client restart manager so that our sequence // client continues processing in the face of temporary connectivity // issues. SequenceClientRestartManager clientRestartManager = new SequenceClientRestartManager(); // Create the client for receiving replication data. ReplicationDataClientChannelPipelineFactory pipelineFactory = new ReplicationDataClientChannelPipelineFactory( clientRestartManager.getControl(), changeSinkWrapper, serverAddress.getHostName(), pathPrefix); SequenceClient client = new SequenceClient(serverAddress, pipelineFactory); // Run the client and perform restarts if it fails. This call will // block. clientRestartManager.manageClient(client); } finally { changeSinkWrapper.realRelease(); } } /** * This acts as a proxy between the sequence client and the real change * sink. The primary purpose is to prevent the release method from being * called until all processing has completed. */ private static class NoReleaseChangeSinkWrapper implements ChangeSinkChangeSource { private ChangeSink changeSink; @Override public void setChangeSink(ChangeSink changeSink) { this.changeSink = changeSink; } @Override public void initialize(Map metaData) { changeSink.initialize(metaData); } @Override public void process(ChangeContainer change) { changeSink.process(change); } @Override public void complete() { changeSink.complete(); } @Override public void release() { // Do nothing. } /** * Called by the main replication data client when all processing is * complete. Unlike the release method which does nothing, this calls * the change sink release method. */ public void realRelease() { changeSink.release(); } } } ReplicationDataClientFactory.java000066400000000000000000000036721253404521400423720ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6; import java.net.InetSocketAddress; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.RunnableChangeSourceManager; /** * The task manager factory for a HTTP replication data client. * * @author Brett Henderson */ public class ReplicationDataClientFactory extends TaskManagerFactory { private static final String ARG_HOST = "host"; private static final String ARG_PORT = "port"; private static final String ARG_PATH_PREFIX = "pathPrefix"; private static final String DEFAULT_HOST = "localhost"; private static final int DEFAULT_PORT = 0; private static final String DEFAULT_PATH_PREFIX = ""; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String host; int port; StringBuilder basePath; // Get the task arguments. host = getStringArgument(taskConfig, ARG_HOST, DEFAULT_HOST); port = getIntegerArgument(taskConfig, ARG_PORT, DEFAULT_PORT); basePath = new StringBuilder(getStringArgument(taskConfig, ARG_PATH_PREFIX, DEFAULT_PATH_PREFIX)); // Ensure that the base path if it exists has a leading slash but no trailing slash. while (basePath.length() > 0 && basePath.charAt(0) == '/') { basePath.delete(0, 1); } while (basePath.length() > 0 && basePath.charAt(basePath.length() - 1) == '/') { basePath.delete(basePath.length() - 1, basePath.length()); } if (basePath.length() > 0) { basePath.insert(0, '/'); } return new RunnableChangeSourceManager( taskConfig.getId(), new ReplicationDataClient(new InetSocketAddress(host, port), basePath.toString()), taskConfig.getPipeArgs() ); } } ReplicationDataServer.java000066400000000000000000000073201253404521400410640ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6; import java.io.File; import java.net.InetSocketAddress; import java.net.MalformedURLException; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.task.common.RunnableTask; import org.openstreetmap.osmosis.replication.common.ServerStateReader; import org.openstreetmap.osmosis.replicationhttp.v0_6.impl.ReplicationDataServerChannelPipelineFactory; import org.openstreetmap.osmosis.replicationhttp.v0_6.impl.SequenceClient; import org.openstreetmap.osmosis.replicationhttp.v0_6.impl.SequenceClientRestartManager; import org.openstreetmap.osmosis.replicationhttp.v0_6.impl.SequenceNumberClientChannelPipelineFactory; import org.openstreetmap.osmosis.replicationhttp.v0_6.impl.SequenceNumberClientListener; import org.openstreetmap.osmosis.replicationhttp.v0_6.impl.SequenceServer; /** * This task creates a HTTP server that sends updated replication data to * clients. It is notified of updated sequence numbers as they occur by * connecting to a replication sequence server. * * @author Brett Henderson */ public class ReplicationDataServer implements RunnableTask { private int notificationPort; private File dataDirectory; private int port; /** * Creates a new instance. * * @param notificationPort * The port to connect to for notification updates. * @param dataDirectory * The location of the replication data and state files. * @param port * The port to listen on. */ public ReplicationDataServer(int notificationPort, File dataDirectory, int port) { this.notificationPort = notificationPort; this.dataDirectory = dataDirectory; this.port = port; } /** * Returns the port that is being used to listen for new connections. * * @return The port number. */ public int getPort() { return port; } private long getCurrentSequenceNumber() { try { return new ServerStateReader().getServerState(dataDirectory.toURI().toURL()).getSequenceNumber(); } catch (MalformedURLException e) { throw new OsmosisRuntimeException("Unable to get the current sequence number", e); } } @Override public void run() { // Instantiate the replication data server. final SequenceServer server = new SequenceServer(port, new ReplicationDataServerChannelPipelineFactory( dataDirectory)); // Configure a listener to send sequence number events from the // client to the server. SequenceNumberClientListener numberListener = new SequenceNumberClientListener() { @Override public void notifySequenceNumber(long sequenceNumber) { server.update(sequenceNumber); } }; // Create a sequence client restart manager so that our sequence // client continues processing in the face of temporary connectivity // issues. SequenceClientRestartManager clientRestartManager = new SequenceClientRestartManager(); // Create the client for receiving updated sequence numbers.. SequenceNumberClientChannelPipelineFactory channelPipelineFactory = new SequenceNumberClientChannelPipelineFactory( clientRestartManager.getControl(), numberListener, "localhost"); SequenceClient client = new SequenceClient(new InetSocketAddress(notificationPort), channelPipelineFactory); try { // Start the server with the current replication number. server.start(getCurrentSequenceNumber()); // Update the port. It may have been allocated dynamically if the // port was specified as 0. port = server.getPort(); // Run the client and perform restarts if it fails. This call will // block. clientRestartManager.manageClient(client); } finally { server.stop(); } } } ReplicationDataServerFactory.java000066400000000000000000000034001253404521400424070ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6; import java.io.File; import org.openstreetmap.osmosis.core.pipeline.common.RunnableTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; /** * The task manager factory for a replication sequence server. * * @author Brett Henderson */ public class ReplicationDataServerFactory extends TaskManagerFactory { private static final String ARG_NOTIFICATION_PORT = "notificationPort"; private static final String ARG_DATA_DIRECTORY = "dataDirectory"; private static final String ARG_PORT = "port"; private static final int DEFAULT_NOTIFICATION_PORT = 0; private static final String DEFAULT_DATA_DIRECTORY = "./"; private static final int DEFAULT_PORT = 0; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { int port; String dataDirectoryString; File dataDirectory; int notificationPort; // Get the task arguments. port = getIntegerArgument(taskConfig, ARG_PORT, DEFAULT_PORT); dataDirectoryString = getStringArgument(taskConfig, ARG_DATA_DIRECTORY, getDefaultStringArgument(taskConfig, DEFAULT_DATA_DIRECTORY)); notificationPort = getIntegerArgument(taskConfig, ARG_NOTIFICATION_PORT, DEFAULT_NOTIFICATION_PORT); // Convert argument strings to strongly typed objects. dataDirectory = new File(dataDirectoryString); return new RunnableTaskManager( taskConfig.getId(), new ReplicationDataServer(notificationPort, dataDirectory, port), taskConfig.getPipeArgs() ); } } ReplicationSequenceServer.java000066400000000000000000000070731253404521400417700ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSinkChangeSource; import org.openstreetmap.osmosis.replication.common.ReplicationState; import org.openstreetmap.osmosis.replicationhttp.v0_6.impl.SequenceNumberServerChannelPipelineFactory; import org.openstreetmap.osmosis.replicationhttp.v0_6.impl.SequenceServer; /** * This task creates a HTTP server that sends updated replication sequence * numbers to clients. It is notified of updated sequence numbers as they occur * by being inserted into the middle of a replication pipeline. * * @author Brett Henderson */ public class ReplicationSequenceServer implements ChangeSinkChangeSource { private static final Logger LOG = Logger.getLogger(ReplicationSequenceServer.class.getName()); private ChangeSink changeSink; private ReplicationState state; private long sequenceNumber; private SequenceServer server; private boolean serverStarted; /** * Creates a new instance. * * @param port * The port to listen on. */ public ReplicationSequenceServer(int port) { server = new SequenceServer(port, new SequenceNumberServerChannelPipelineFactory()); serverStarted = false; } @Override public void setChangeSink(ChangeSink changeSink) { this.changeSink = changeSink; } /** * Returns the port that is being used to listen for new connections. * * @return The port number. */ public int getPort() { return server.getPort(); } @Override public void initialize(Map metaData) { // Get the replication state from the upstream task. if (!metaData.containsKey(ReplicationState.META_DATA_KEY)) { throw new OsmosisRuntimeException("No replication state has been provided in metadata key " + ReplicationState.META_DATA_KEY + "."); } state = (ReplicationState) metaData.get(ReplicationState.META_DATA_KEY); // Call the downstream initialize which will among other things // initialise the state. changeSink.initialize(metaData); // We must only read from the state object during initialize and // complete because it may be updated by other threads at other times. sequenceNumber = state.getSequenceNumber(); // If the sequence id is still 0 then replication hasn't been fully // initialized and we can't start the server yet. if (sequenceNumber > 0 && !serverStarted) { // We can start the server now. We give it the previous sequence // number because the current one is still in progress. server.start(sequenceNumber - 1); serverStarted = true; } } @Override public void process(ChangeContainer change) { changeSink.process(change); } @Override public void complete() { changeSink.complete(); // The sink has completed persisting the replication so now we must // notify the server which will notify the listening clients. if (!serverStarted) { server.start(sequenceNumber); serverStarted = true; } else { server.update(sequenceNumber); } } @Override public void release() { changeSink.release(); if (serverStarted) { try { server.stop(); } catch (RuntimeException e) { LOG.log(Level.WARNING, "Replication sequence server stop failed.", e); } serverStarted = false; } } } ReplicationSequenceServerFactory.java000066400000000000000000000021621253404521400433120ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.ChangeSinkChangeSourceManager; /** * The task manager factory for a replication sequence server. * * @author Brett Henderson */ public class ReplicationSequenceServerFactory extends TaskManagerFactory { private static final String ARG_PORT = "port"; private static final int DEFAULT_PORT = 80; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { int port; // Get the task arguments. port = getIntegerArgument( taskConfig, ARG_PORT, getDefaultIntegerArgument(taskConfig, DEFAULT_PORT) ); return new ChangeSinkChangeSourceManager( taskConfig.getId(), new ReplicationSequenceServer(port), taskConfig.getPipeArgs() ); } } 000077500000000000000000000000001253404521400347265ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6/implChunkedDataReceiver.java000066400000000000000000000145531253404521400414410ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6.impl; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.util.CharsetUtil; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.lifecycle.Releasable; /** * Provides the ability to read data that has been broken into data chunks. Each * chunk is preceded by the number of bytes in the chunk followed by a carriage * return line feed pair. * * @author Brett Henderson */ public class ChunkedDataReceiver implements Releasable { private static final Logger LOG = Logger.getLogger(ChunkedDataReceiver.class.getName()); private ChannelBuffer buffer; private File tmpDataFile; private FileChannel tmpDataChannel; private List readyFiles; private boolean chunkInProgress; private long bytesRemaining; /** * Creates a new instance. */ public ChunkedDataReceiver() { buffer = ChannelBuffers.dynamicBuffer(); readyFiles = new ArrayList(); chunkInProgress = false; } /** * Attempts to read a chunk length header from the data currently in the * buffer. If a carriage return line feed pair is found, then the data * preceeding those characters will be converted to a number and returned. * If the carriage return line feed pair cannot be found, then -1 will be * returned to indicate that the data is not yet complete. * * @return The value of the chunk length header, or -1 if more data is * required. */ private long getChunkLength() { // Look for a carriage return line feed pair. for (int i = buffer.readerIndex() + 1; i < buffer.writerIndex(); i++) { if (buffer.getByte(i) == 0x0A) { if (buffer.getByte(i - 1) == 0x0D) { // All data between the reader index and one before i is the header. String chunkSizeString = buffer.toString(buffer.readerIndex(), i - buffer.readerIndex() - 1, CharsetUtil.UTF_8); long chunkSize = Long.parseLong(chunkSizeString); // Move the buffer past the current reader index. buffer.readerIndex(i + 1); return chunkSize; } } } return -1; } private void initializeChunk() { try { tmpDataFile = File.createTempFile("change", ".tmp"); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to create replication data temp file", e); } try { tmpDataChannel = new FileOutputStream(tmpDataFile).getChannel(); } catch (FileNotFoundException e) { throw new OsmosisRuntimeException("Unable to open chunk data temp file", e); } chunkInProgress = true; } private void writeToChunk(ChannelBuffer writeBuffer) { try { // We can only write the minimum of the number of bytes available // and the number of bytes remaining. The bytes available is an // integer so if all values are possible the minimum value will also // be an integer. int bytesToWrite = (int) Math.min(writeBuffer.readableBytes(), bytesRemaining); // Write the data to the chunk data file. tmpDataChannel.write(writeBuffer.toByteBuffer(writeBuffer.readerIndex(), bytesToWrite)); writeBuffer.skipBytes(bytesToWrite); bytesRemaining -= bytesToWrite; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write chunk data to temp file", e); } // Complete the chunk if it is complete. if (bytesRemaining <= 0) { try { tmpDataChannel.close(); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to close chunk data temp file", e); } readyFiles.add(tmpDataFile); tmpDataFile = null; chunkInProgress = false; } } private List createResultFileList() { List resultFiles = new ArrayList(readyFiles); readyFiles.clear(); return resultFiles; } /** * Processes the data in the input buffer. It requires each chunk of data to * be preceeded by a length header. Once all data within each chunk has been * read, a file will be produced which holds the contents of the chunk. When * no more data is available, all files resulting from the input data will * be returned. It is possible that 0 files will be returned. Any leftover * data not comprising a complete chunk will be retained internally until * the next call. * * @param inputBuffer * Add data in this buffer will be added. * @return All chunk data files completed during this call. */ public List processData(ChannelBuffer inputBuffer) { while (inputBuffer.readableBytes() > 0 || buffer.readableBytes() > 0) { // If there is no chunk in progress so the next data will be the // header. if (!chunkInProgress) { // Move all input data to our internal buffer so that we have a // single view of all available data. buffer.writeBytes(inputBuffer); bytesRemaining = getChunkLength(); if (bytesRemaining >= 0) { // We have read the chunk header, so now begin processing the // chunk body. initializeChunk(); } else { return createResultFileList(); } } // If we've reached this far we know a chunk is in progress so we // must write to the data file. We write from the internal buffer if // available, otherwise the input buffer. if (buffer.readableBytes() > 0) { writeToChunk(buffer); } else { writeToChunk(inputBuffer); } } return createResultFileList(); } /** * Gets the buffer. * * @return The buffer. */ public ChannelBuffer getBuffer() { return buffer; } @Override public void release() { if (tmpDataChannel != null) { try { tmpDataChannel.close(); } catch (IOException ex) { LOG.log(Level.WARNING, "Unable to close the current temporary chunk file", ex); } } if (tmpDataFile != null) { if (!tmpDataFile.delete()) { LOG.log(Level.WARNING, "Unable to delete the current temporary chunk file " + tmpDataFile); } } for (File readyFile : readyFiles) { if (!readyFile.delete()) { LOG.log(Level.WARNING, "Unable to delete the current temporary chunk file " + readyFile); } } readyFiles.clear(); } } ReplicationDataClientChannelPipelineFactory.java000066400000000000000000000027051253404521400463060ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6.impl; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; /** * Builds Netty channel pipelines for new connections to servers. * * @author Brett Henderson */ public class ReplicationDataClientChannelPipelineFactory extends SequenceClientChannelPipelineFactory { private ChangeSink changeSink; private String serverHost; private String pathPrefix; /** * Creates a new instance. * * @param control * Provides the Netty handlers with access to the controller. * @param changeSink * The destination for the replication data. * @param serverHost * The name of the host system running the sequence server. * @param pathPrefix * The base path to add to the URL. This is necessary if a data * server is sitting behind a proxy server that adds a prefix to * the request path. */ public ReplicationDataClientChannelPipelineFactory(SequenceClientControl control, ChangeSink changeSink, String serverHost, String pathPrefix) { super(control); this.changeSink = changeSink; this.serverHost = serverHost; this.pathPrefix = pathPrefix; } @Override protected SequenceClientHandler createHandler(SequenceClientControl control) { return new ReplicationDataClientHandler(control, changeSink, serverHost, pathPrefix); } } ReplicationDataClientHandler.java000066400000000000000000000157021253404521400432760ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6.impl; import java.io.File; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelStateEvent; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.RunnableChangeSource; import org.openstreetmap.osmosis.core.util.PropertiesPersister; import org.openstreetmap.osmosis.replication.common.ReplicationState; import org.openstreetmap.osmosis.xml.common.CompressionMethod; import org.openstreetmap.osmosis.xml.v0_6.XmlChangeReader; /** * Netty handler for receiving replication data and notifying listeners. * * @author Brett Henderson */ public class ReplicationDataClientHandler extends SequenceClientHandler { private static final Logger LOG = Logger.getLogger(ReplicationDataClientHandler.class.getName()); private ChangeSink changeSink; private String pathPrefix; private NoLifecycleChangeSinkWrapper noLifecycleChangeSink; private boolean sinkInitInvoked; private boolean replicationStateReceived; private ReplicationState replicationState; private ChunkedDataReceiver chunkReceiver; /** * Creates a new instance. * * @param control * Provides the Netty handlers with access to the controller. * @param changeSink * The destination for the replication data. * @param serverHost * The name of the host system running the sequence server. * @param pathPrefix * The base path to add to the URL. This is necessary if a data * server is sitting behind a proxy server that adds a prefix to * the request path. */ public ReplicationDataClientHandler(SequenceClientControl control, ChangeSink changeSink, String serverHost, String pathPrefix) { super(control, serverHost); this.changeSink = changeSink; this.pathPrefix = pathPrefix; noLifecycleChangeSink = new NoLifecycleChangeSinkWrapper(changeSink); sinkInitInvoked = false; replicationStateReceived = false; replicationState = null; chunkReceiver = new ChunkedDataReceiver(); } private void sendReplicationData(File chunkFile) { // Release all class level resources and prepare for passing the // replication data downstream. replicationState = null; replicationStateReceived = false; sinkInitInvoked = false; // Send the replication data downstream but don't call any lifecycle // methods on the change sink because we're managing those separately. if (chunkFile != null) { RunnableChangeSource changeReader = new XmlChangeReader(chunkFile, true, CompressionMethod.GZip); changeReader.setChangeSink(noLifecycleChangeSink); changeReader.run(); } changeSink.complete(); } private void invokeSinkInit() { replicationState = new ReplicationState(); Map metaData = new HashMap(1); metaData.put(ReplicationState.META_DATA_KEY, replicationState); changeSink.initialize(metaData); sinkInitInvoked = true; } @Override protected String getRequestUri() { // We need to know the last replication number that we have received on // a previous run. To do this we need to retrieve the replication state // from our downstream replication task by initializing. invokeSinkInit(); // The downstream task returns the next sequence number. long requestSequenceNumber = replicationState.getSequenceNumber(); return pathPrefix + "/replicationData/" + requestSequenceNumber + "/tail"; } private ReplicationState loadState(File stateFile) { PropertiesPersister persister = new PropertiesPersister(stateFile); ReplicationState state = new ReplicationState(); state.load(persister.loadMap()); return state; } @Override protected void processMessageData(ChannelBuffer buffer) { // Break the data down according to chunk alignment. List chunkFiles = chunkReceiver.processData(buffer); try { for (File chunkFile : chunkFiles) { if (!replicationStateReceived) { // We usually have to invoke the sink init, but if this is // during startup we may have already performed this step // while preparing our initial request. if (!sinkInitInvoked) { invokeSinkInit(); } // The first chunk contains the replication state stored in // properties format. ReplicationState serverReplicationState = loadState(chunkFile); if (LOG.isLoggable(Level.FINER)) { LOG.finer("Received replication state " + serverReplicationState.getSequenceNumber()); } // Validate that the server has sent us the expected state. if (serverReplicationState.getSequenceNumber() != replicationState.getSequenceNumber()) { throw new OsmosisRuntimeException("Received sequence number " + serverReplicationState.getSequenceNumber() + " from server, expected " + replicationState.getSequenceNumber()); } // Update the local state with server values. replicationState.setTimestamp(serverReplicationState.getTimestamp()); replicationStateReceived = true; // If this is replication 0, then we need to finish // processing now because the first sequence doesn't have // any data. if (replicationState.getSequenceNumber() == 0) { sendReplicationData(null); } } else { sendReplicationData(chunkFile); } } } finally { // Delete all chunk files. for (File chunkFile : chunkFiles) { if (!chunkFile.delete()) { LOG.log(Level.WARNING, "Unable to delete the current temporary chunk file " + chunkFile); } } } } @Override public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { // Release any half populated chunk files. chunkReceiver.release(); super.channelClosed(ctx, e); } /** * This acts as a proxy between the xml change reader and the real change * sink. The primary purpose is to only propagate calls to process because * the lifecycle methods initialize, complete and release are managed * separately. */ private static class NoLifecycleChangeSinkWrapper implements ChangeSink { private ChangeSink changeSink; /** * Creates a new instance. * * @param changeSink * The wrapped change sink. */ public NoLifecycleChangeSinkWrapper(ChangeSink changeSink) { this.changeSink = changeSink; } @Override public void initialize(Map metaData) { // Do nothing. } @Override public void process(ChangeContainer change) { changeSink.process(change); } @Override public void complete() { // Do nothing. } @Override public void release() { // Do nothing. } } } ReplicationDataServerChannelPipelineFactory.java000066400000000000000000000014551253404521400463370ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6.impl; import java.io.File; /** * Builds Netty channel pipelines for new client connections. * * @author Brett Henderson */ public class ReplicationDataServerChannelPipelineFactory extends SequenceServerChannelPipelineFactory { private File dataDirectory; /** * Creates a new instance. * * @param dataDirectory * The location of the replication data files. */ public ReplicationDataServerChannelPipelineFactory(File dataDirectory) { this.dataDirectory = dataDirectory; } @Override protected SequenceServerHandler createHandler(SequenceServerControl control) { return new ReplicationDataServerHandler(control, dataDirectory); } } ReplicationDataServerHandler.java000066400000000000000000000365521253404521400433340ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6.impl; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.LinkedList; import java.util.Queue; import java.util.TimeZone; import java.util.logging.Level; import java.util.logging.Logger; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.Channels; import org.jboss.netty.channel.WriteCompletionEvent; import org.jboss.netty.handler.codec.http.DefaultHttpChunk; import org.jboss.netty.handler.codec.http.HttpRequest; import org.jboss.netty.util.CharsetUtil; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.util.PropertiesPersister; import org.openstreetmap.osmosis.replication.common.ReplicationSequenceFormatter; import org.openstreetmap.osmosis.replication.common.ReplicationState; /** * A sequence server handler implementation that sends the replication data * associated with sequence numbers. * * @author Brett Henderson */ public class ReplicationDataServerHandler extends SequenceServerHandler { private static final Logger LOG = Logger.getLogger(ReplicationDataServerHandler.class.getName()); private static final String REQUEST_DATE_FORMAT = "yyyy-MM-dd-HH-mm-ss"; private static final int CHUNK_SIZE = 4096; private File dataDirectory; private ReplicationSequenceFormatter sequenceFormatter; private FileChannel chunkedFileChannel; private boolean fileSizeSent; private boolean includeData; private ChannelFuture sequenceFuture; /** * Creates a new instance. * * @param control * Provides the Netty handlers with access to the controller. * @param dataDirectory * The directory containing the replication data files. */ public ReplicationDataServerHandler(SequenceServerControl control, File dataDirectory) { super(control); this.dataDirectory = dataDirectory; sequenceFormatter = new ReplicationSequenceFormatter(9, 3); } private DateFormat getRequestDateParser() { SimpleDateFormat dateParser = new SimpleDateFormat(REQUEST_DATE_FORMAT); Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC")); dateParser.setCalendar(calendar); return dateParser; } private File getStateFile(long sequenceNumber) { return new File(dataDirectory, sequenceFormatter.getFormattedName(sequenceNumber, ".state.txt")); } private File getDataFile(long sequenceNumber) { return new File(dataDirectory, sequenceFormatter.getFormattedName(sequenceNumber, ".osc.gz")); } private ReplicationState getReplicationState(long sequenceNumber) { PropertiesPersister persister = new PropertiesPersister(getStateFile(sequenceNumber)); ReplicationState state = new ReplicationState(); state.load(persister.loadMap()); return state; } /** * Search through the replication state records and find the nearest * replication number with a timestamp earlier or equal to the requested * date. It is not sufficient to find the minimum known sequence record with * a timestamp greater than the requested date because there may be missing * replication records in between. * * @param lastDate * The last date known by the client. * @return The associated sequence number. */ private long getNextSequenceNumberByDate(Date lastDate) { long startBound = 0; long endBound = getControl().getLatestSequenceNumber(); // If the requested date is greater than or equal to the latest known // timestamp we should return our latest sequence number so that the // client will start receiving all new records as they arrive with // possibly some duplicated change records. if (lastDate.compareTo(getReplicationState(endBound).getTimestamp()) >= 0) { return endBound; } // Continue splitting our range in half until either we find the // requested record, or we only have one possibility remaining. while ((endBound - startBound) > 1) { // Calculate the current midpoint. long midPoint = startBound + ((endBound - startBound) / 2); // If the midpoint doesn't exist we need to reset the start bound to // the midpoint and search again. if (!getStateFile(midPoint).exists()) { startBound = midPoint; continue; } // If the midpoint timestamp is greater we search in the lower half, // otherwise the higher half. int comparison = lastDate.compareTo(getReplicationState(midPoint).getTimestamp()); if (comparison == 0) { // We have an exact match so stop processing now. return midPoint; } else if (comparison < 0) { // We will now search in the lower half of the search range. // Even though we know the midpoint is not the right value, we // include it in the next range because our search assumes that // the right sequence number is less than the end point. endBound = midPoint; } else { // We will now search in the upper half of the search range. // Even though the mid point has a timestamp less than the // requested value, it still may be the selected value if the // next timestamp is greater. startBound = midPoint; } } // We only have one possibility remaining which is the start bound. This // is the requested record if it exists and has a timestamp less than or // equal to that requested. if (getStateFile(startBound).exists() && lastDate.compareTo(getReplicationState(startBound).getTimestamp()) >= 0) { return startBound; } else { // We cannot find any replication records with an early enough date. // This typically means that replication records for that time // period either no longer exist or never existed. throw new ResourceGoneException(); } } private FileChannel openFileChannel(File file) { try { return new FileInputStream(file).getChannel(); } catch (FileNotFoundException e) { throw new OsmosisRuntimeException("Unable to open file " + file, e); } } private ChannelBuffer readFromFile(FileChannel fileChannel, int bytesToRead) { try { // Allocate a buffer for the data to be read. byte[] rawBuffer = new byte[bytesToRead]; // Copy data into the buffer using NIO. ByteBuffer nioBuffer = ByteBuffer.wrap(rawBuffer); for (int bytesRead = 0; bytesRead < bytesToRead;) { int lastBytesRead = fileChannel.read(nioBuffer); // We always expect to read data. if (lastBytesRead < 0) { throw new OsmosisRuntimeException("Unexpectedly reached the end of the replication data file"); } if (lastBytesRead == 0) { throw new OsmosisRuntimeException("Last read of the replication data file returned 0 bytes"); } bytesRead += lastBytesRead; } // Create and return a Netty buffer. return ChannelBuffers.wrappedBuffer(rawBuffer); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to read from the replication data file", e); } } private ChannelBuffer loadFile(File file) { FileChannel fileChannel = openFileChannel(file); try { if (fileChannel.size() > Integer.MAX_VALUE) { throw new OsmosisRuntimeException("Maximum file size supported is " + Integer.MAX_VALUE + " bytes"); } // Determine the size of the file. int fileSize = (int) fileChannel.size(); // Read the entire file. ChannelBuffer buffer = readFromFile(fileChannel, fileSize); // We no longer need access to the file. fileChannel.close(); return buffer; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to read from file " + file, e); } finally { try { fileChannel.close(); } catch (IOException e) { LOG.log(Level.WARNING, "Unable to close channel for file " + file, e); } } } private ChannelBuffer getFileChunk() { try { // Determine how many bytes are left in the file. long remaining = chunkedFileChannel.size() - chunkedFileChannel.position(); // We will only send up to our maximum chunk size. if (remaining > CHUNK_SIZE) { remaining = CHUNK_SIZE; } // Read the next data for the next chunk. ChannelBuffer buffer = readFromFile(chunkedFileChannel, (int) remaining); // Close the file if we've reached the end. if (chunkedFileChannel.position() >= chunkedFileChannel.size()) { chunkedFileChannel.close(); chunkedFileChannel = null; } return buffer; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to read from the replication data file", e); } } private ChannelBuffer buildChunkHeader(long chunkSize) { return ChannelBuffers.copiedBuffer(Long.toString(chunkSize) + "\r\n", CharsetUtil.UTF_8); } @Override protected void handleRequest(ChannelHandlerContext ctx, HttpRequest request) { final String replicationStateUri = "replicationState"; final String replicationDataUri = "replicationData"; final String textContentType = "text/plain"; final String dataContentType = "application/octet-stream"; // Split the request Uri into its path elements. String uri = request.getUri(); if (!uri.startsWith("/")) { throw new OsmosisRuntimeException("Uri doesn't start with a / character: " + uri); } Queue uriElements = new LinkedList(Arrays.asList(uri.split("/"))); uriElements.remove(); // First element is empty due to leading '/'. // First element must be either the replication state or replication // data uri which determines whether replication data will be included // or just the replication state. String contentType; if (uriElements.isEmpty()) { throw new ResourceNotFoundException(); } String requestTypeString = uriElements.remove(); if (replicationStateUri.equals(requestTypeString)) { contentType = textContentType; includeData = false; } else if (replicationDataUri.equals(requestTypeString)) { contentType = dataContentType; includeData = true; } else { throw new ResourceNotFoundException(); } /* * The next element determines which replication number to start from. * The request is one of "current" or N where is the last sequence * number received by the client. */ long nextSequenceNumber; if (uriElements.isEmpty()) { throw new ResourceNotFoundException(); } String sequenceStartString = uriElements.remove(); if ("current".equals(sequenceStartString)) { nextSequenceNumber = getControl().getLatestSequenceNumber(); } else { // Try to parse the sequence start string as a number. If that fails // try to parse as a date. try { nextSequenceNumber = Long.parseLong(sequenceStartString); } catch (NumberFormatException e) { try { Date lastDate = getRequestDateParser().parse(sequenceStartString); nextSequenceNumber = getNextSequenceNumberByDate(lastDate); } catch (ParseException e1) { throw new BadRequestException("Requested sequence number of " + sequenceStartString + " is not a number, or a date in format yyyy-MM-dd-HH-mm-ss."); } } } // If the next element exists and is "tail" it means that the client // wants to stay connected and receive updated sequences as they become // available. boolean follow; if (!uriElements.isEmpty()) { String tailElement = uriElements.remove(); if ("tail".equals(tailElement)) { follow = true; } else { throw new ResourceNotFoundException(); } } else { follow = false; } // Validate that that no more URI elements are available. if (!uriElements.isEmpty()) { throw new ResourceNotFoundException(); } // Begin sending replication sequence information to the client. if (LOG.isLoggable(Level.FINER)) { LOG.finer("New request details, includeData=" + includeData + ", sequenceNumber=" + nextSequenceNumber + ", tail=" + follow); } initiateSequenceWriting(ctx, contentType, nextSequenceNumber, follow); } @Override protected void writeSequence(ChannelHandlerContext ctx, ChannelFuture future, long sequenceNumber) { // We do not support sending new replication data until the previous // send has completed. if (chunkedFileChannel != null) { throw new OsmosisRuntimeException( "We cannot send new replication data until the previous write has completed"); } if (LOG.isLoggable(Level.FINEST)) { LOG.finest("Sequence being written, includeData=" + includeData + ", sequenceNumber=" + sequenceNumber); } // We must save the future to attach to the final write. sequenceFuture = future; // Get the name of the replication data file. File stateFile = getStateFile(sequenceNumber); File dataFile = getDataFile(sequenceNumber); // Load the contents of the state file. ChannelBuffer stateFileBuffer = loadFile(stateFile); // Add a chunk length header. stateFileBuffer = ChannelBuffers.wrappedBuffer(buildChunkHeader(stateFileBuffer.readableBytes()), stateFileBuffer); // Only include replication data if initially requested by the client // and if this is not sequence 0. if (includeData && sequenceNumber > 0) { // Open the data file read for sending. chunkedFileChannel = openFileChannel(dataFile); fileSizeSent = false; } /* * Send the state file to the client. If replication data is to be sent * we will continue when we receive completion information via the * writeComplete method. We must create a new future now if we have more * data coming because we don't want the future of the current event to * fire until we're completely finished processing. */ ChannelFuture writeFuture; if (chunkedFileChannel != null) { writeFuture = Channels.future(ctx.getChannel()); } else { writeFuture = sequenceFuture; } Channels.write(ctx, writeFuture, new DefaultHttpChunk(stateFileBuffer)); } @Override public void writeComplete(ChannelHandlerContext ctx, WriteCompletionEvent e) throws Exception { if (chunkedFileChannel != null) { // We have an open file channel so we are still sending replication // data. ChannelBuffer buffer; ChannelFuture future; if (!fileSizeSent) { // Send a chunk header containing the size of the file. ChannelBuffer fileSizeBuffer = buildChunkHeader(chunkedFileChannel.size()); fileSizeSent = true; future = Channels.future(ctx.getChannel()); buffer = fileSizeBuffer; } else { // Send the next chunk to the client. buffer = getFileChunk(); if (chunkedFileChannel != null) { future = Channels.future(ctx.getChannel()); } else { // This is the last write for this sequence so attach the original future. future = sequenceFuture; } } // Write the data to the channel. Channels.write(ctx, future, new DefaultHttpChunk(buffer)); } else { super.writeComplete(ctx, e); } } @Override public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { // Close the in-progress chunk file channel if it exists. if (chunkedFileChannel != null) { try { chunkedFileChannel.close(); } catch (IOException ex) { LOG.log(Level.WARNING, "Unable to close the replication data file.", ex); } chunkedFileChannel = null; } super.channelClosed(ctx, e); } } SequenceClient.java000066400000000000000000000056201253404521400405030ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6.impl; import java.net.InetSocketAddress; import java.util.concurrent.Executors; import org.jboss.netty.bootstrap.ClientBootstrap; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelFactory; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * This class creates a HTTP client that connects to a sequence server, listens * for updated sequences as they are received, and notifies any configured * listeners. * * @author Brett Henderson */ public class SequenceClient { private InetSocketAddress serverAddress; private SequenceClientChannelPipelineFactory channelPipelineFactory; /** * A flag used only by the external control thread to remember if the server * has been started or not. */ private boolean masterRunning; /** * The factory for all processing threads. */ private ChannelFactory factory; /** * The channel used to receive sequence updates from the server. */ private Channel channel; /** * Creates a new instance. * * @param serverAddress * The address of the sequence server providing notification of * updated sequence numbers. * @param channelPipelineFactory * The factory for creating channel pipelines for new client * connections. */ public SequenceClient(InetSocketAddress serverAddress, SequenceClientChannelPipelineFactory channelPipelineFactory) { this.serverAddress = serverAddress; this.channelPipelineFactory = channelPipelineFactory; } /** * Starts the client. */ public void start() { if (masterRunning) { throw new OsmosisRuntimeException("The server has already been started"); } // Mark the client as running. masterRunning = true; // Create the processing thread pools. factory = new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()); ClientBootstrap bootstrap = new ClientBootstrap(factory); bootstrap.setPipelineFactory(channelPipelineFactory); bootstrap.setOption("tcpNoDelay", true); bootstrap.setOption("keepAlive", true); ChannelFuture future = bootstrap.connect(serverAddress); // Get a reference to the channel. channel = future.getChannel(); // Wait for the connection attempt to complete. future.awaitUninterruptibly(); // Abort if the startup failed. if (!future.isSuccess()) { throw new OsmosisRuntimeException("Unable to launch sequence client."); } } /** * Stops the client. This must be called in all cases even if start failed. */ public void stop() { if (masterRunning) { channel.close().awaitUninterruptibly(); factory.releaseExternalResources(); masterRunning = false; } } } SequenceClientChannelPipelineFactory.java000066400000000000000000000024301253404521400450060ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6.impl; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelPipelineFactory; import org.jboss.netty.channel.Channels; import org.jboss.netty.handler.codec.http.HttpClientCodec; /** * Builds Netty channel pipelines for new connections to servers. * * * @author Brett Henderson */ public abstract class SequenceClientChannelPipelineFactory implements ChannelPipelineFactory { private SequenceClientControl centralControl; /** * Creates a new instance. * * @param control * Provides the Netty handlers with access to the controller. */ public SequenceClientChannelPipelineFactory(SequenceClientControl control) { this.centralControl = control; } /** * Creates a handler to be used for processing channel messages. * * @param control * The control object used to send event notifications. * @return The channel handler. */ protected abstract SequenceClientHandler createHandler(SequenceClientControl control); @Override public ChannelPipeline getPipeline() throws Exception { return Channels.pipeline(new HttpClientCodec(), createHandler(centralControl)); } } SequenceClientControl.java000066400000000000000000000007261253404521400420460ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6.impl; /** * This interface provides Netty handlers executing in worker threads with * access to sequence client control methods. * * @author Brett Henderson */ public interface SequenceClientControl { /** * Allows a Netty handler to tell the controller that the channel has been * closed. */ void channelClosed(); } SequenceClientHandler.java000066400000000000000000000101511253404521400417740ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6.impl; import java.nio.channels.ClosedChannelException; import java.util.logging.Level; import java.util.logging.Logger; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.Channels; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelHandler; import org.jboss.netty.handler.codec.http.DefaultHttpRequest; import org.jboss.netty.handler.codec.http.HttpChunk; import org.jboss.netty.handler.codec.http.HttpMethod; import org.jboss.netty.handler.codec.http.HttpRequest; import org.jboss.netty.handler.codec.http.HttpResponse; import org.jboss.netty.handler.codec.http.HttpResponseStatus; import org.jboss.netty.handler.codec.http.HttpVersion; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Netty handler for receiving replication sequence information and notifying * listeners. * * @author Brett Henderson */ public abstract class SequenceClientHandler extends SimpleChannelHandler { private static final Logger LOG = Logger.getLogger(SequenceClientHandler.class.getName()); private SequenceClientControl control; private String serverHost; private boolean midStream; private boolean active; /** * Creates a new instance. * * @param control * Provides the Netty handlers with access to the controller. * @param serverHost * The name of the host system running the sequence server. */ public SequenceClientHandler(SequenceClientControl control, String serverHost) { this.control = control; this.serverHost = serverHost; active = true; } /** * Gets the URI to request from the server to initialise message processing. * * @return The request URI. */ protected abstract String getRequestUri(); @Override public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { // Send a request to the server asking for sequence number // notifications. HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, getRequestUri()); request.addHeader("Host", serverHost); Channels.write(ctx, e.getFuture(), request); midStream = false; } /** * Processes the contents of a single HTTP chunk. * * @param buffer * The data contained in the chunk. */ protected abstract void processMessageData(ChannelBuffer buffer); @Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { if (active) { ChannelBuffer buffer; if (!midStream) { HttpResponse response = (HttpResponse) e.getMessage(); HttpResponseStatus status = response.getStatus(); if (!HttpResponseStatus.OK.equals(status)) { throw new OsmosisRuntimeException("Received a " + status + " response from the server."); } buffer = response.getContent(); midStream = true; } else { HttpChunk chunk = (HttpChunk) e.getMessage(); buffer = chunk.getContent(); } // Perform implementation specific processing of the buffer contents. if (buffer.readableBytes() > 0) { processMessageData(buffer); } } } @Override public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { control.channelClosed(); } @Override public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { // When we close the channel we may still continue to receive some // data. Flag that this should be ignored. active = false; // Get the cause of the exception. Throwable t = e.getCause(); // A ClosedChannelException occurs if the client disconnects and is not // an error scenario. if (!(t instanceof ClosedChannelException)) { LOG.log(Level.SEVERE, "Error during processing for channel " + ctx.getChannel() + ".", t); } // We must stop sending to this client if any errors occur during // processing. e.getChannel().close(); } } SequenceClientRestartManager.java000066400000000000000000000074301253404521400433440ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6.impl; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * This class encapsulates the functionality required to manage restarts of a * sequence client on failure. * * @author Brett Henderson */ public class SequenceClientRestartManager { private static final Logger LOG = Logger.getLogger(SequenceClientRestartManager.class.getName()); private static final int RESTART_DELAY = 60000; private Lock controlLock; private Condition controlCondition; private ClientControl control; private boolean clientRunning; /** * Creates a new instance. */ public SequenceClientRestartManager() { controlLock = new ReentrantLock(); controlCondition = controlLock.newCondition(); control = new ClientControl(); } /** * Either thread can call this method when they wish to wait until an update * has been performed by the other thread. */ private void waitForUpdate() { try { controlCondition.await(); } catch (InterruptedException e) { throw new OsmosisRuntimeException("Thread was interrupted.", e); } } /** * Either thread can call this method when they wish to signal the other * thread that an update has occurred. */ private void signalUpdate() { controlCondition.signal(); } /** * Returns a sequence client control object to be used when creating a new * sequence client. * * @return The sequence client controller. */ public SequenceClientControl getControl() { return control; } /** * Runs the sequence client and restarts it if it fails. This sequence * client must have been created using a control listener returned from the * getControl method of this object. * * @param sequenceClient * The sequence client to manage. */ public void manageClient(SequenceClient sequenceClient) { try { // Run the client within a loop to allow client restarts if // problems occur. while (true) { // Initialise the running flag. We must do this before we // start the client because the client thread will set it to // false when it finishes which may occur very soon after // starting. clientRunning = true; try { sequenceClient.start(); } catch (OsmosisRuntimeException e) { // The client startup failed, so log the exception and try // again in the next loop. LOG.warning("Unable to start the sequence client, will retry in " + RESTART_DELAY + " milliseconds."); } // Wait for the client to stop. try { controlLock.lock(); while (clientRunning) { waitForUpdate(); } } finally { controlLock.unlock(); } // Stop the client explicitly which will close any remaining // resources. sequenceClient.stop(); // Wait for 1 minute between connection failures. try { Thread.sleep(RESTART_DELAY); } catch (InterruptedException e) { throw new OsmosisRuntimeException("Thread sleep failed between sequence number client invocations", e); } } } finally { sequenceClient.stop(); } } /** * Internal class used to process event updates from the sequence number * client. * * @author Brett Henderson */ private class ClientControl implements SequenceClientControl { @Override public void channelClosed() { controlLock.lock(); try { // The client has failed. We need to tell the master thread so // that it can act accordingly (eg. restart the client). clientRunning = false; signalUpdate(); } finally { controlLock.unlock(); } } } } SequenceNumberClientChannelPipelineFactory.java000066400000000000000000000023311253404521400461570ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6.impl; /** * Builds Netty channel pipelines for new connections to servers. * * @author Brett Henderson */ public class SequenceNumberClientChannelPipelineFactory extends SequenceClientChannelPipelineFactory { private SequenceNumberClientListener sequenceNumberListener; private String serverHost; /** * Creates a new instance. * * @param control * Provides the Netty handlers with access to the controller. * @param sequenceNumberListener * This will be notified when new sequence numbers are received. * @param serverHost * The name of the host system running the sequence server. */ public SequenceNumberClientChannelPipelineFactory(SequenceClientControl control, SequenceNumberClientListener sequenceNumberListener, String serverHost) { super(control); this.serverHost = serverHost; this.sequenceNumberListener = sequenceNumberListener; } @Override protected SequenceClientHandler createHandler(SequenceClientControl control) { return new SequenceNumberClientHandler(control, sequenceNumberListener, serverHost); } } SequenceNumberClientHandler.java000066400000000000000000000034271253404521400431550ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6.impl; import java.util.logging.Level; import java.util.logging.Logger; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.util.CharsetUtil; /** * Netty handler for receiving replication sequence numbers and notifying * listeners. * * @author Brett Henderson */ public class SequenceNumberClientHandler extends SequenceClientHandler { private static final Logger LOG = Logger.getLogger(SequenceNumberClientHandler.class.getName()); private SequenceNumberClientListener sequenceNumberListener; /** * Creates a new instance. * * @param control * Provides the Netty handlers with access to the controller. * @param sequenceNumberListener * This will be notified when new sequence numbers are received. * @param serverHost * The name of the host system running the sequence server. */ public SequenceNumberClientHandler(SequenceClientControl control, SequenceNumberClientListener sequenceNumberListener, String serverHost) { super(control, serverHost); this.sequenceNumberListener = sequenceNumberListener; } @Override protected String getRequestUri() { return "/sequenceNumber/current/tail"; } @Override protected void processMessageData(ChannelBuffer buffer) { // The readable data is the sequence number in string form. String sequenceNumberString = buffer.toString(CharsetUtil.UTF_8); long sequenceNumber = Long.parseLong(sequenceNumberString); if (LOG.isLoggable(Level.FINEST)) { LOG.finest("Received sequence number " + sequenceNumber); } // Send the new sequence number notification. sequenceNumberListener.notifySequenceNumber(sequenceNumber); } } SequenceNumberClientListener.java000066400000000000000000000010511253404521400433540ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6.impl; /** * Used by SequenceNumberClientHandler to notify a listener about received * sequence numbers. * * @author Brett Henderson */ public interface SequenceNumberClientListener { /** * Allows a Netty handler to notify when a new sequence number has been * received. * * @param sequenceNumber * The received sequence number. */ void notifySequenceNumber(long sequenceNumber); } SequenceNumberServerChannelPipelineFactory.java000066400000000000000000000007611253404521400462140ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6.impl; /** * Builds Netty channel pipelines for new client connections. * * @author Brett Henderson */ public class SequenceNumberServerChannelPipelineFactory extends SequenceServerChannelPipelineFactory { @Override protected SequenceServerHandler createHandler(SequenceServerControl control) { return new SequenceNumberServerHandler(control); } } SequenceNumberServerHandler.java000066400000000000000000000073271253404521400432100ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6.impl; import java.util.Arrays; import java.util.LinkedList; import java.util.Queue; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.Channels; import org.jboss.netty.handler.codec.http.DefaultHttpChunk; import org.jboss.netty.handler.codec.http.HttpRequest; import org.jboss.netty.util.CharsetUtil; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * A sequence server handler implementation that sends the sequence number * itself. * * @author Brett Henderson */ public class SequenceNumberServerHandler extends SequenceServerHandler { /** * Creates a new instance. * * @param control * Provides the Netty handlers with access to the controller. */ public SequenceNumberServerHandler(SequenceServerControl control) { super(control); } @Override protected void handleRequest(ChannelHandlerContext ctx, HttpRequest request) { final String sequenceNumberUri = "sequenceNumber"; final String contentType = "text/plain"; // Split the request Uri into its path elements. String uri = request.getUri(); if (!uri.startsWith("/")) { throw new OsmosisRuntimeException("Uri doesn't start with a / character: " + uri); } Queue uriElements = new LinkedList(Arrays.asList(uri.split("/"))); // First element is empty due to leading '/', unless there is only a '/' // in which case there will be no elements. if (uriElements.size() > 0) { uriElements.remove(); } // First element must be the sequence number base uri. if (uriElements.isEmpty() || !sequenceNumberUri.equals(uriElements.remove())) { throw new ResourceNotFoundException(); } /* * The next element determines which replication number to start from. * The request is one of "current" or N where is the last sequence * number received by the client. */ long nextSequenceNumber; if (uriElements.isEmpty()) { throw new ResourceNotFoundException(); } String sequenceStartString = uriElements.remove(); if ("current".equals(sequenceStartString)) { nextSequenceNumber = getControl().getLatestSequenceNumber(); } else { try { nextSequenceNumber = Long.parseLong(sequenceStartString); } catch (NumberFormatException e) { throw new BadRequestException("Requested sequence number of " + sequenceStartString + " is not a number."); } } // If the next element exists and is "tail" it means that the client // wants to stay connected and receive updated sequences as they become // available. boolean follow; if (!uriElements.isEmpty()) { String tailElement = uriElements.remove(); if ("tail".equals(tailElement)) { follow = true; } else { throw new ResourceNotFoundException(); } } else { follow = false; } // Validate that that no more URI elements are available. if (!uriElements.isEmpty()) { throw new ResourceNotFoundException(); } // Begin sending replication sequence information to the client. initiateSequenceWriting(ctx, contentType, nextSequenceNumber, follow); } @Override protected void writeSequence(ChannelHandlerContext ctx, ChannelFuture future, long sequenceNumber) { // Convert the sequence to a string and then a buffer. ChannelBuffer buffer = ChannelBuffers.copiedBuffer(Long.toString(sequenceNumber), CharsetUtil.UTF_8); // Wrap the buffer in a HTTP chunk. DefaultHttpChunk chunk = new DefaultHttpChunk(buffer); // Pass the chunk downstream. Channels.write(ctx, future, chunk); } } SequenceServer.java000066400000000000000000000303311253404521400405300ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6.impl; import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Level; import java.util.logging.Logger; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelFactory; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelFutureListener; import org.jboss.netty.channel.group.ChannelGroup; import org.jboss.netty.channel.group.DefaultChannelGroup; import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * This class creates a HTTP server that sends updated replication sequences to * clients. Once started it is notified of updated sequence numbers as they * occur and will pass the sequence data to listening clients. The sequence data * is implementation dependent. * * @author Brett Henderson */ public class SequenceServer implements SequenceServerControl { private static final Logger LOG = Logger.getLogger(SequenceServer.class.getName()); private int port; private SequenceServerChannelPipelineFactory channelPipelineFactory; /** * Limits shared data access to one thread at a time. */ private Lock sharedLock; /** * A flag used to remember if the server has been started or not. */ private boolean serverStarted; private long sequenceNumber; private ChannelFactory factory; private ChannelGroup allChannels; private List waitingChannels; private ExecutorService sendService; private int totalRequests; /** * Creates a new instance. * * @param port * The port number to listen on. * @param channelPipelineFactory * The factory for creating channel pipelines for new client * connections. */ public SequenceServer(int port, SequenceServerChannelPipelineFactory channelPipelineFactory) { this.port = port; this.channelPipelineFactory = channelPipelineFactory; // Provide handlers with access to control functions. channelPipelineFactory.setControl(this); // Create the thread synchronisation primitives. sharedLock = new ReentrantLock(); // Create the list of channels waiting to be notified about a new // sequence. waitingChannels = new ArrayList(); } /** * Returns the port that the server is listening on. * * @return The listening port. */ public int getPort() { return port; } /** * Starts the server. * * @param initialSequenceNumber * The initial sequence number. */ public void start(long initialSequenceNumber) { sharedLock.lock(); try { if (serverStarted) { throw new OsmosisRuntimeException("The server has already been started"); } sequenceNumber = initialSequenceNumber; totalRequests = 0; // Create a channel group to hold all channels for use during // shutdown. allChannels = new DefaultChannelGroup("sequence-server"); // Create the processing thread pools. factory = new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()); // Launch the server. ServerBootstrap bootstrap = new ServerBootstrap(factory); bootstrap.setPipelineFactory(channelPipelineFactory); bootstrap.setOption("child.tcpNoDelay", true); bootstrap.setOption("child.keepAlive", true); Channel serverChannel = bootstrap.bind(new InetSocketAddress(port)); allChannels.add(serverChannel); // Get the port that the server is listening on. This may be // dynamically allocated if 0 was originally specified. InetSocketAddress address = (InetSocketAddress) serverChannel.getLocalAddress(); port = address.getPort(); if (LOG.isLoggable(Level.INFO)) { LOG.info("Server listening on port " + port); } /* * Create our own background sending thread. Initiating the send of * a sequence should be relatively light on CPU so one thread should * keep up with a large number of clients. However we may trigger a * large number of messages at once which might cause a * multi-threaded pool to spawn a large number of threads for very * short lived processing. */ sendService = Executors.newSingleThreadExecutor(); // Server startup has succeeded. serverStarted = true; } finally { sharedLock.unlock(); } } /** * Notifies that server of a new sequence number. * * @param newSequenceNumber * The new sequence number. */ public void update(long newSequenceNumber) { sharedLock.lock(); try { if (!serverStarted) { throw new OsmosisRuntimeException("The server has not been started"); } if (LOG.isLoggable(Level.FINER)) { LOG.finer("Updating with new sequence " + newSequenceNumber); } // Verify that the new sequence number is not less than the existing // sequence number. if (newSequenceNumber < sequenceNumber) { throw new OsmosisRuntimeException("Received sequence number " + newSequenceNumber + " from server, expected " + sequenceNumber + " or greater"); } long oldSequenceNumber = sequenceNumber; sequenceNumber = newSequenceNumber; // If the new sequence number is greater than our existing number // then we can send updates to our clients. if (oldSequenceNumber < sequenceNumber) { final long nextSequenceNumber = oldSequenceNumber + 1; /* * Create a new waiting channels list and process from the * original. This is necessary because some channels may get * added back in during processing causing a concurrent * modification exception. Due to the Netty implementation, if a * write operation completes before we get a chance to register * the completion listener, the listener will run within this * thread and that will mean the channel will need to be added * to the waiting list before we complete sending messages to * all the other channels. */ List existingWaitingChannels = waitingChannels; waitingChannels = new ArrayList(); for (final Channel channel : existingWaitingChannels) { if (LOG.isLoggable(Level.FINEST)) { LOG.finest("Waking up channel " + channel + " with sequence " + sequenceNumber); } // Submit the request via the worker thread. sendService.submit(new Runnable() { @Override public void run() { sendSequence(channel, nextSequenceNumber, true); } }); } } } finally { sharedLock.unlock(); } } /** * Stops the server. */ public void stop() { sharedLock.lock(); try { if (serverStarted) { // Shutdown our background worker thread. sendService.shutdownNow(); // Shutdown the Netty framework. allChannels.close().awaitUninterruptibly(); factory.releaseExternalResources(); // Clear our control flag. serverStarted = false; } } finally { sharedLock.unlock(); } } /** * Sends the specified sequence to the channel. If follow is specified, the * channel will be held open and follow up calls will be made to * determineNextChannelAction with this channel and sequence number when the * operation completes. If follow is not specified, the channel will be * closed when the operation completes. * * @param channel * The channel. * @param currentSequenceNumber * The sequence to be sent. * @param follow * If true, the channel will be held open and updated sequences * sent as they are arrive. */ private void sendSequence(final Channel channel, final long currentSequenceNumber, final boolean follow) { // Write the sequence number to the channel. ChannelFuture future = channel.write(currentSequenceNumber); if (follow) { // Upon completion of this write, check to see whether a new // sequence must be sent or whether we should wait for further // updates. future.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { // Only send more data if the write was successful. if (future.isSuccess()) { determineNextChannelAction(channel, currentSequenceNumber + 1, follow); } } }); } else { // Upon completion of this write, close the channel. future.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { channel.close(); } }); } } private void determineNextChannelActionImpl(Channel channel, long nextSequenceNumber, boolean follow) { long currentSequenceNumber; boolean sequenceAvailable; // We can only access the master sequence number and waiting channels // while we have the lock. sharedLock.lock(); try { currentSequenceNumber = sequenceNumber; // Check if the next sequence number is available yet. sequenceAvailable = nextSequenceNumber <= currentSequenceNumber; // If the sequence is not available, make sure that the client // hasn't requested a sequence number more than one past current. if (!sequenceAvailable) { if ((nextSequenceNumber - currentSequenceNumber) > 1) { channel.close(); throw new OsmosisRuntimeException("Requested sequence number " + nextSequenceNumber + " is more than 1 past current number " + currentSequenceNumber); } } // If the sequence isn't available we add the channel to the list // waiting for a new sequence notification. if (!sequenceAvailable) { if (LOG.isLoggable(Level.FINEST)) { LOG.finest("Next sequence " + nextSequenceNumber + " is not available yet so adding channel " + channel + " to waiting list."); } waitingChannels.add(channel); } } finally { sharedLock.unlock(); } // Send the sequence if it is available. if (sequenceAvailable) { if (LOG.isLoggable(Level.FINEST)) { LOG.finest("Next sequence " + nextSequenceNumber + " is available."); } sendSequence(channel, nextSequenceNumber, follow); } } /** * Allows a Netty handler to notify the controller that the channel is ready * for more data. If the controller has new sequence information available * it will send it, otherwise it will add the channel to the waiting list. * This method will perform execution in a background worker thread and will * return immediately. * * @param channel * The client channel. * @param nextSequenceNumber * The sequence number that the client needs to be sent next. * @param follow * If true, the channel will be held open and updated sequences * sent as they arrive. */ public void determineNextChannelAction(final Channel channel, final long nextSequenceNumber, final boolean follow) { /* * We submit new requests from our own worker thread instead of using * the Netty IO thread. This is not to free up IO threads because * initiating the send of a sequence is a relatively lightweight * operation. It is to avoid the situation where a Netty IO thread * encounters a stack overflow when it completes writing a sequence, * then finds another available and sends it, then finds another * available and so on in a recursive fashion. */ sendService.submit(new Runnable() { @Override public void run() { determineNextChannelActionImpl(channel, nextSequenceNumber, follow); } }); } @Override public long getLatestSequenceNumber() { // Get the current sequence number within the lock. sharedLock.lock(); try { return sequenceNumber; } finally { sharedLock.unlock(); } } @Override public void registerChannel(Channel channel) { // Update the total requests counter within the lock. sharedLock.lock(); try { totalRequests++; } finally { sharedLock.unlock(); } allChannels.add(channel); } @Override public ServerStatistics getStatistics() { // The all channels collection contains the server channel which must be // removed from the count to get the number of client connections. return new ServerStatistics(totalRequests, allChannels.size() - 1); } } SequenceServerChannelPipelineFactory.java000066400000000000000000000023711253404521400450420ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6.impl; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelPipelineFactory; import org.jboss.netty.channel.Channels; import org.jboss.netty.handler.codec.http.HttpServerCodec; /** * Builds Netty channel pipelines for new client connections. * * @author Brett Henderson */ public abstract class SequenceServerChannelPipelineFactory implements ChannelPipelineFactory { private SequenceServerControl centralControl; /** * Provides handlers with access to server control functions. * * @param control * The new control object. */ public void setControl(SequenceServerControl control) { this.centralControl = control; } /** * Creates a handler to be used for processing channel messages. * * @param control * The control object used to send event notifications. * @return The channel handler. */ protected abstract SequenceServerHandler createHandler(SequenceServerControl control); @Override public ChannelPipeline getPipeline() throws Exception { return Channels.pipeline(new HttpServerCodec(), createHandler(centralControl)); } } SequenceServerControl.java000066400000000000000000000031141253404521400420700ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6.impl; import org.jboss.netty.channel.Channel; /** * This interface provides Netty handlers executing in worker threads with * access to sequence server control methods. * * @author Brett Henderson */ public interface SequenceServerControl { /** * Allows a Netty handler to request the latest sequence number from the * controller. * * @return The latest sequence number. */ long getLatestSequenceNumber(); /** * Allows a Netty handler to notify the controller that the channel is ready * for more data. If the controller has new sequence information available * it will send it, otherwise it will add the channel to the waiting list. * * @param channel * The client channel. * @param nextSequenceNumber * The sequence number that the client needs to be sent next. * @param follow * If true, the channel will be held open and updated sequences * sent as they arrive. */ void determineNextChannelAction(Channel channel, long nextSequenceNumber, boolean follow); /** * Allows a Netty handler to register a channel with the main controller. * This allows the controller to close the channel when the server shuts * down. * * @param channel * The channel to be registered. */ void registerChannel(Channel channel); /** * Gets the runtime statistics of the server. * * @return The server statistics. */ ServerStatistics getStatistics(); } SequenceServerHandler.java000066400000000000000000000301231253404521400420250ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6.impl; import java.net.InetSocketAddress; import java.nio.channels.ClosedChannelException; import java.util.logging.Level; import java.util.logging.Logger; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelFutureListener; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.Channels; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelHandler; import org.jboss.netty.handler.codec.http.DefaultHttpResponse; import org.jboss.netty.handler.codec.http.HttpHeaders; import org.jboss.netty.handler.codec.http.HttpRequest; import org.jboss.netty.handler.codec.http.HttpResponseStatus; import org.jboss.netty.handler.codec.http.HttpVersion; import org.jboss.netty.util.CharsetUtil; /** * Netty handler for sending replication sequence numbers to clients. * * @author Brett Henderson */ public abstract class SequenceServerHandler extends SimpleChannelHandler { private static final Logger LOG = Logger.getLogger(SequenceServerHandler.class.getName()); private SequenceServerControl control; private long currentSequenceNumber; /** * Creates a new instance. * * @param control * Provides the Netty handlers with access to the controller. */ public SequenceServerHandler(SequenceServerControl control) { this.control = control; } /** * Gets the central control object. * * @return The controller. */ protected SequenceServerControl getControl() { return control; } @Override public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) { control.registerChannel(e.getChannel()); } /** * Writes a HTTP 404 response to the client. * * @param ctx * The Netty context. * @param requestedUri * The URI requested by the client. */ private void writeResourceNotFound(final ChannelHandlerContext ctx, String requestedUri) { // Write the HTTP header to the client. DefaultHttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_0, HttpResponseStatus.NOT_FOUND); response.addHeader("Content-Type", "text/plain"); // Send the 404 message to the client. ChannelBuffer buffer = ChannelBuffers.copiedBuffer("The requested resource does not exist: " + requestedUri, CharsetUtil.UTF_8); response.setContent(buffer); // Write the header. Use a new future because the future we've been // passed is for upstream. ChannelFuture headerFuture = Channels.future(ctx.getChannel()); Channels.write(ctx, headerFuture, response); // Wait for the previous operation to finish and then close the channel. headerFuture.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) { ctx.getChannel().close(); } }); } /** * Writes a HTTP 410 response to the client. * * @param ctx * The Netty context. * @param requestedUri * The URI requested by the client. */ private void writeResourceGone(final ChannelHandlerContext ctx, String requestedUri) { // Write the HTTP header to the client. DefaultHttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_0, HttpResponseStatus.GONE); response.addHeader("Content-Type", "text/plain"); // Send the 410 message to the client. ChannelBuffer buffer = ChannelBuffers.copiedBuffer("The requested resource is no longer available: " + requestedUri, CharsetUtil.UTF_8); response.setContent(buffer); // Write the header. Use a new future because the future we've been // passed is for upstream. ChannelFuture headerFuture = Channels.future(ctx.getChannel()); Channels.write(ctx, headerFuture, response); // Wait for the previous operation to finish and then close the channel. headerFuture.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) { ctx.getChannel().close(); } }); } /** * Writes a HTTP 400 response to the client. * * @param ctx * The Netty context. * @param requestedUri * The URI requested by the client. * @param errorMessage * Further information about why the request is bad. */ private void writeBadRequest(final ChannelHandlerContext ctx, String requestedUri, String errorMessage) { final String newLine = "\r\n"; // Write the HTTP header to the client. DefaultHttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_0, HttpResponseStatus.NOT_FOUND); response.addHeader("Content-Type", "text/plain"); // Send the 400 message to the client. StringBuilder messageBuilder = new StringBuilder(); messageBuilder.append("Bad Request").append(newLine); messageBuilder.append("Message: ").append(errorMessage).append(newLine); messageBuilder.append("Requested URI: ").append(requestedUri).append(newLine); ChannelBuffer buffer = ChannelBuffers.copiedBuffer(messageBuilder.toString(), CharsetUtil.UTF_8); response.setContent(buffer); // Write the header. Use a new future because the future we've been // passed is for upstream. ChannelFuture headerFuture = Channels.future(ctx.getChannel()); Channels.write(ctx, headerFuture, response); // Wait for the previous operation to finish and then close the channel. headerFuture.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) { ctx.getChannel().close(); } }); } /** * Writes server statistics to the client. * * @param ctx * The Netty context. */ private void writeStatistics(final ChannelHandlerContext ctx) { final String newLine = "\r\n"; ServerStatistics statistics = control.getStatistics(); // Write the HTTP header to the client. DefaultHttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_0, HttpResponseStatus.OK); response.addHeader("Content-Type", "text/plain"); // Send the statistics message to the client. StringBuilder messageBuilder = new StringBuilder(); messageBuilder.append("Server Statistics").append(newLine); messageBuilder.append("Total Requests: ").append(statistics.getTotalRequests()).append(newLine); messageBuilder.append("Active Connections: ").append(statistics.getActiveConnections()).append(newLine); ChannelBuffer buffer = ChannelBuffers.copiedBuffer(messageBuilder.toString(), CharsetUtil.UTF_8); response.setContent(buffer); // Write the header. Use a new future because the future we've been // passed is for upstream. ChannelFuture headerFuture = Channels.future(ctx.getChannel()); Channels.write(ctx, headerFuture, response); // Wait for the previous operation to finish and then close the channel. headerFuture.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) { ctx.getChannel().close(); } }); } /** * Writes sequence data to the client. If follow is set, it allows * continuous updates to be streamed to the client. * * @param ctx * The Netty context. * @param contentType * The content type to set on the HTTP response. * @param requestedSequenceNumber * The requested sequence number. Sending will start from this * number. * @param follow * If true, continuous updates will be sent to the client. */ protected void initiateSequenceWriting(final ChannelHandlerContext ctx, String contentType, final long requestedSequenceNumber, final boolean follow) { // Create the HTTP header to send to the client. DefaultHttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); response.addHeader("Content-Type", contentType); response.setChunked(true); response.addHeader(HttpHeaders.Names.TRANSFER_ENCODING, HttpHeaders.Values.CHUNKED); // Write the header. We must use a new future because the future we've // been passed is for upstream. ChannelFuture headerFuture = Channels.future(ctx.getChannel()); Channels.write(ctx, headerFuture, response); // Wait for the previous operation to finish and then start sending // sequence numbers to this channel. headerFuture.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (future.isSuccess()) { control.determineNextChannelAction(ctx.getChannel(), requestedSequenceNumber, follow); } } }); } /** * Parses the request and initialises the response processing, typically by * calling the writeSequence method. * * @param ctx * The Netty context. * @param request * The client request. */ protected abstract void handleRequest(ChannelHandlerContext ctx, HttpRequest request); @Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { // We have received a message from the client which is a HTTP request. HttpRequest request = (HttpRequest) e.getMessage(); InetSocketAddress remoteAddress = (InetSocketAddress) ctx.getChannel().getRemoteAddress(); if (LOG.isLoggable(Level.FINE)) { LOG.fine("Received new request from " + remoteAddress.getAddress().getHostAddress() + ":" + remoteAddress.getPort()); } // Process the HTTP request. try { // Check if this is a request to a generic URL. If it isn't // something we support then delegate to the specific handler. if (request.getUri().equals("/statistics")) { writeStatistics(ctx); } else { handleRequest(ctx, request); } } catch (ResourceNotFoundException ex) { writeResourceNotFound(ctx, request.getUri()); } catch (ResourceGoneException ex) { writeResourceGone(ctx, request.getUri()); } catch (BadRequestException ex) { writeBadRequest(ctx, request.getUri(), ex.getMessage()); } } /** * Convert the sequence number to sequence data and write to the channel. * * @param ctx * The channel handler context. * @param future * The future for current processing. * @param sequenceNumber * The sequence number to be written. */ protected abstract void writeSequence(ChannelHandlerContext ctx, ChannelFuture future, long sequenceNumber); @Override public void writeRequested(ChannelHandlerContext ctx, MessageEvent e) throws Exception { // The message event is a Long containing the sequence number. currentSequenceNumber = (Long) e.getMessage(); // Call the concrete implementation to convert the sequence to writable // data. writeSequence(ctx, e.getFuture(), currentSequenceNumber); } @Override public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { // Get the cause of the exception. Throwable t = e.getCause(); // A ClosedChannelException occurs if the client disconnects and is not // an error scenario. if (!(t instanceof ClosedChannelException)) { LOG.log(Level.SEVERE, "Error during processing for channel " + ctx.getChannel() + ".", t); } // We must stop sending to this client if any errors occur during // processing. e.getChannel().close(); } /** * Used during request parsing to notify that the requested URI could not be * found. */ protected static class ResourceNotFoundException extends RuntimeException { private static final long serialVersionUID = -1L; } /** * Used during request parsing to notify that the request is invalid in some * way. */ protected static class BadRequestException extends RuntimeException { private static final long serialVersionUID = -1L; /** * Creates a new instance. * * @param message * The error message. */ public BadRequestException(String message) { super(message); } } /** * Used during request parsing to notify that the requested URI is no longer * available. */ protected static class ResourceGoneException extends RuntimeException { private static final long serialVersionUID = -1L; } } ServerStatistics.java000066400000000000000000000020371253404521400411140ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/java/org/openstreetmap/osmosis/replicationhttp/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6.impl; /** * Captures statistics for a sequence server. * * @author Brett Henderson */ public class ServerStatistics { private int totalRequests; private int activeConnections; /** * Creates a new instance. * * @param totalRequests * The total requests handled by the server. * @param activeConnections * The current number of active connections. */ public ServerStatistics(int totalRequests, int activeConnections) { this.totalRequests = totalRequests; this.activeConnections = activeConnections; } /** * Gets the total number of requests handled by the server. * * @return The total number of requests. */ public int getTotalRequests() { return totalRequests; } /** * Gets the current number of active connections. * * @return The number of active connections. */ public int getActiveConnections() { return activeConnections; } } osmosis-0.44.1/osmosis-replication-http/src/main/resources/000077500000000000000000000000001253404521400240015ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/main/resources/osmosis-plugins.conf000066400000000000000000000001051253404521400300170ustar00rootroot00000000000000org.openstreetmap.osmosis.replicationhttp.ReplicationHttpPluginLoaderosmosis-0.44.1/osmosis-replication-http/src/test/000077500000000000000000000000001253404521400220225ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/test/java/000077500000000000000000000000001253404521400227435ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/test/java/org/000077500000000000000000000000001253404521400235325ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/test/java/org/openstreetmap/000077500000000000000000000000001253404521400264205ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/test/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400301145ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/test/java/org/openstreetmap/osmosis/replicationhttp/000077500000000000000000000000001253404521400333255ustar00rootroot00000000000000000077500000000000000000000000001253404521400340205ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/test/java/org/openstreetmap/osmosis/replicationhttp/v0_6MockReplicationDestination.java000066400000000000000000000050631253404521400421540ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/test/java/org/openstreetmap/osmosis/replicationhttp/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.replication.common.ReplicationState; /** * A mocked replication destination allowing the existing replication state to be loaded and the * current state maintained. All data processing calls such as process will be ignored. */ public class MockReplicationDestination implements ChangeSink { private boolean stateExists; private ReplicationState currentState; private Map storedState; /** * Creates a new instance with no state. */ public MockReplicationDestination() { stateExists = false; storedState = new HashMap(); } /** * Creates a new instance with an initial state. * * @param initialState * The initial replication state. */ public MockReplicationDestination(ReplicationState initialState) { this(); initialState.store(storedState); stateExists = true; } /** * {@inheritDoc} */ public void initialize(Map metaData) { // Get the replication state from the upstream task. if (!metaData.containsKey(ReplicationState.META_DATA_KEY)) { throw new OsmosisRuntimeException( "No replication state has been provided in metadata key " + ReplicationState.META_DATA_KEY + "."); } currentState = (ReplicationState) metaData.get(ReplicationState.META_DATA_KEY); // Initialise the state from the stored state if it exists and increment // the sequence number. if (stateExists) { currentState.load(storedState); currentState.setSequenceNumber(currentState.getSequenceNumber() + 1); } } /** * {@inheritDoc} */ @Override public void process(ChangeContainer change) { // Do nothing. } /** * {@inheritDoc} */ @Override public void complete() { currentState.store(storedState); stateExists = true; } /** * {@inheritDoc} */ @Override public void release() { // Do nothing. } /** * Returns the current state object tracked internally. This will be a state * object provided by a caller in the initialize method. It will remain * available after complete and release have been called. * * @return The current state. */ public ReplicationState getCurrentState() { return currentState; } } MockReplicationSource.java000066400000000000000000000050431253404521400411310ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/test/java/org/openstreetmap/osmosis/replicationhttp/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6; import java.util.Date; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.task.common.ChangeAction; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSource; import org.openstreetmap.osmosis.replication.common.ReplicationState; /** * This test task is used for driving test replication data through a * replication pipeline. * * @author Brett Henderson */ public class MockReplicationSource implements ChangeSource { private ChangeSink changeSink; @Override public void setChangeSink(ChangeSink changeSink) { this.changeSink = changeSink; } /** * Sends a replication sequence containing dummy data to the destination. */ public void sendSequence() { // Initialise the replication stream. ReplicationState state = new ReplicationState(); Map metaData = new HashMap(1); metaData.put(ReplicationState.META_DATA_KEY, state); changeSink.initialize(metaData); // Send the change data unless this is sequence 0 where no data is // allowed. We'll only send a single record for simplicity. if (state.getSequenceNumber() > 0) { // We'll do a create action on the first replication pass, and modify subsequently. ChangeAction action; if (state.getSequenceNumber() == 1) { action = ChangeAction.Create; } else { action = ChangeAction.Modify; } // Create a change record which data derived from the // replication sequence number itself. ChangeContainer change = new ChangeContainer(new NodeContainer(new Node(new CommonEntityData(10, (int) state.getSequenceNumber(), new Date(state.getSequenceNumber() * 1000), new OsmUser(11, "test"), state.getSequenceNumber() * 2), state.getSequenceNumber() * 3, state.getSequenceNumber() * 4)), action); // Send the record downstream. changeSink.process(change); } state.setTimestamp(new Date(state.getSequenceNumber() * 1000)); changeSink.complete(); } /** * Releases all downstream resources. */ public void release() { changeSink.release(); } } ReplicationSequenceServerTest.java000066400000000000000000000024131253404521400426540ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/test/java/org/openstreetmap/osmosis/replicationhttp/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6; import java.util.HashMap; import java.util.Map; import org.junit.Test; import org.openstreetmap.osmosis.replication.common.ReplicationState; import org.openstreetmap.osmosis.testutil.AbstractDataTest; /** * Tests the replication sequence server task. * * @author Brett Henderson */ public class ReplicationSequenceServerTest extends AbstractDataTest { /** * Very basic test that launches the server, runs several replication * iterations and then shuts down without connecting any clients. * * @throws InterruptedException * if processing is interrupted. */ @Test public void testStartupShutdown() throws InterruptedException { ReplicationSequenceServer server; server = new ReplicationSequenceServer(0); server.setChangeSink(new MockReplicationDestination()); try { for (int i = 0; i < 10; i++) { ReplicationState state = new ReplicationState(); Map metaData = new HashMap(); metaData.put(ReplicationState.META_DATA_KEY, state); server.initialize(metaData); Thread.sleep(10); server.complete(); } } finally { server.release(); } } } ReplicationTest.java000066400000000000000000000122231253404521400377740ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication-http/src/test/java/org/openstreetmap/osmosis/replicationhttp/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replicationhttp.v0_6; import java.io.File; import java.net.InetSocketAddress; import java.util.logging.ConsoleHandler; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.Logger; import org.junit.Assert; import org.junit.Test; import org.openstreetmap.osmosis.core.pipeline.common.TaskRunner; import org.openstreetmap.osmosis.replication.common.ReplicationSequenceFormatter; import org.openstreetmap.osmosis.replication.v0_6.ReplicationWriter; import org.openstreetmap.osmosis.testutil.AbstractDataTest; /** * Performs an end to end test of the HTTP replication classes. * * @author Brett Henderson */ public class ReplicationTest extends AbstractDataTest { /** * Configures logging to write all output to the console. */ private static void configureLoggingConsole() { Logger rootLogger; Handler consoleHandler; rootLogger = Logger.getLogger(""); // Remove any existing handlers. for (Handler handler : rootLogger.getHandlers()) { rootLogger.removeHandler(handler); } // Add a new console handler. consoleHandler = new ConsoleHandler(); consoleHandler.setLevel(Level.ALL); rootLogger.addHandler(consoleHandler); } /** * Configures the logging level. * * @param level * The new logging level to apply. */ private static void configureLoggingLevel(Level level) { Logger rootLogger; rootLogger = Logger.getLogger(""); // Set the required logging level. rootLogger.setLevel(level); // Set the JPF logger to one level lower. Logger.getLogger("org.java.plugin").setLevel(Level.WARNING); } /** * Single end to end test. * * @throws Exception * if an error occurs during processing. */ @Test public void test() throws Exception { final int sequenceCount = 100; long timerStart; // Due to the multi-threaded nature of this test, it may be necessary to // enable logging to diagnose problems. final boolean enableLogging = false; if (enableLogging) { configureLoggingConsole(); configureLoggingLevel(Level.FINEST); Logger.getLogger("org.openstreetmap.osmosis.replication.v0_6.ReplicationStateWriter").setLevel(Level.INFO); } // Create the primary replication data source. MockReplicationSource source = new MockReplicationSource(); // Create the sequence server for notifying when new sequence numbers // are available and connect it to the primary source. ReplicationSequenceServer sequenceServer = new ReplicationSequenceServer(0); source.setChangeSink(sequenceServer); // Create a replication data writer and receive data from the primary // data source (via the sequence server). File workingDir1 = dataUtils.newFolder(); sequenceServer.setChangeSink(new ReplicationWriter(workingDir1)); // Send sequence through the primary pipeline to ensure the // sequence server is running. source.sendSequence(); // Create a HTTP replication data server using the data from the // replication writer, and receive sequence number updates from the // sequence server. ReplicationDataServer dataServer = new ReplicationDataServer(sequenceServer.getPort(), workingDir1, 0); // Start the HTTP data server. TaskRunner serverRunner = new TaskRunner(dataServer, "data-server"); serverRunner.start(); /* * The server starts in another thread so we need to wait until it has * started. We will wait until the dynamically allocated port is * exported via the getPort method which occurs after server startup. */ timerStart = System.currentTimeMillis(); while (dataServer.getPort() == 0 && (System.currentTimeMillis() - timerStart < 10000)) { Thread.sleep(10); } Assert.assertFalse("Server port was not dynamically allocated.", sequenceServer.getPort() == 0); // Create a HTTP replication data client receiving data from the data // server. ReplicationDataClient dataClient = new ReplicationDataClient(new InetSocketAddress(dataServer.getPort()), ""); // Create a replication data writer to receiving data from the HTTP data // source. File workingDir2 = dataUtils.newFolder(); dataClient.setChangeSink(new ReplicationWriter(workingDir2)); // Start the HTTP data server and HTTP data client. TaskRunner clientRunner = new TaskRunner(dataClient, "data-client"); clientRunner.start(); // Send the test replication intervals. for (int i = 0; i < sequenceCount; i++) { source.sendSequence(); } // Wait for all the data to reach the destination. File finalStateFile = new File(workingDir2, new ReplicationSequenceFormatter(9, 3).getFormattedName( sequenceCount, ".state.txt")); timerStart = System.currentTimeMillis(); while (!finalStateFile.exists() && (System.currentTimeMillis() - timerStart < 10000)) { Thread.sleep(100); } // Verify that all of the replication sequences made it to the // destination. Assert.assertTrue("The state file for sequence " + sequenceCount + " doesn't exist.", finalStateFile.exists()); // Shut down the pipelines. clientRunner.interrupt(); serverRunner.interrupt(); clientRunner.join(); serverRunner.join(); source.release(); } } osmosis-0.44.1/osmosis-replication/000077500000000000000000000000001253404521400172775ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/.checkstyle000066400000000000000000000010051253404521400214320ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-replication/.gitignore000066400000000000000000000000531253404521400212650ustar00rootroot00000000000000.classpath .project .settings /bin /build osmosis-0.44.1/osmosis-replication/build.gradle000066400000000000000000000001761253404521400215620ustar00rootroot00000000000000dependencies { compile project(':osmosis-core') compile project(':osmosis-set') compile project(':osmosis-xml') } osmosis-0.44.1/osmosis-replication/src/000077500000000000000000000000001253404521400200665ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/000077500000000000000000000000001253404521400210125ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/000077500000000000000000000000001253404521400217335ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/000077500000000000000000000000001253404521400225225ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/000077500000000000000000000000001253404521400254105ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400271045ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/000077500000000000000000000000001253404521400314155ustar00rootroot00000000000000ReplicationPluginLoader.java000066400000000000000000000067761253404521400370000ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.plugin.PluginLoader; import org.openstreetmap.osmosis.replication.v0_6.IntervalDownloaderFactory; import org.openstreetmap.osmosis.replication.v0_6.IntervalDownloaderInitializerFactory; import org.openstreetmap.osmosis.replication.v0_6.ReplicationDownloaderFactory; import org.openstreetmap.osmosis.replication.v0_6.ReplicationDownloaderInitializerFactory; import org.openstreetmap.osmosis.replication.v0_6.ReplicationFileMergerFactory; import org.openstreetmap.osmosis.replication.v0_6.ReplicationFileMergerInitializerFactory; import org.openstreetmap.osmosis.replication.v0_6.ReplicationLagReaderFactory; import org.openstreetmap.osmosis.replication.v0_6.ReplicationToChangeWriterFactory; import org.openstreetmap.osmosis.replication.v0_6.ReplicationWriterFactory; /** * The plugin loader for the replication tasks. * * @author Brett Henderson */ public class ReplicationPluginLoader implements PluginLoader { /** * {@inheritDoc} */ @Override public Map loadTaskFactories() { Map factoryMap; factoryMap = new HashMap(); factoryMap.put("read-change-interval", new IntervalDownloaderFactory()); factoryMap.put("rci", new IntervalDownloaderFactory()); factoryMap.put("read-change-interval-init", new IntervalDownloaderInitializerFactory()); factoryMap.put("rcii", new IntervalDownloaderInitializerFactory()); factoryMap.put("read-replication-interval", new ReplicationDownloaderFactory()); factoryMap.put("rri", new ReplicationDownloaderFactory()); factoryMap.put("read-replication-interval-init", new ReplicationDownloaderInitializerFactory()); factoryMap.put("rrii", new ReplicationDownloaderInitializerFactory()); factoryMap.put("merge-replication-files", new ReplicationFileMergerFactory()); factoryMap.put("mrf", new ReplicationFileMergerFactory()); factoryMap.put("merge-replication-files-init", new ReplicationFileMergerInitializerFactory()); factoryMap.put("mrfi", new ReplicationFileMergerInitializerFactory()); factoryMap.put("read-replication-lag", new ReplicationLagReaderFactory()); factoryMap.put("rrl", new ReplicationLagReaderFactory()); factoryMap.put("write-replication", new ReplicationWriterFactory()); factoryMap.put("wr", new ReplicationWriterFactory()); factoryMap.put("replication-to-change", new ReplicationToChangeWriterFactory()); factoryMap.put("rtc", new ReplicationToChangeWriterFactory()); factoryMap.put("read-change-interval-0.6", new IntervalDownloaderFactory()); factoryMap.put("read-change-interval-init-0.6", new IntervalDownloaderInitializerFactory()); factoryMap.put("read-replication-interval-0.6", new ReplicationDownloaderFactory()); factoryMap.put("read-replication-interval-init-0.6", new ReplicationDownloaderInitializerFactory()); factoryMap.put("merge-replication-files-0.6", new ReplicationFileMergerFactory()); factoryMap.put("merge-replication-files-init-0.6", new ReplicationFileMergerInitializerFactory()); factoryMap.put("read-replication-lag-0.6", new ReplicationLagReaderFactory()); factoryMap.put("write-replication-0.6", new ReplicationWriterFactory()); factoryMap.put("replication-to-change-0.6", new ReplicationToChangeWriterFactory()); return factoryMap; } } osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/common/000077500000000000000000000000001253404521400327055ustar00rootroot00000000000000FileReplicationStore.java000066400000000000000000000047651253404521400375730ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.common; import java.io.File; import org.openstreetmap.osmosis.core.util.PropertiesPersister; import org.openstreetmap.osmosis.xml.common.CompressionMethod; import org.openstreetmap.osmosis.xml.v0_6.XmlChangeReader; import org.openstreetmap.osmosis.xml.v0_6.XmlChangeWriter; /** * A {@link ReplicationStore} implementation storing all data to the filesystem. * * @author Brett Henderson */ public class FileReplicationStore implements ReplicationStore { private static final String STATE_FILE = "state.txt"; private PropertiesPersister currentStatePersister; private ReplicationFileSequenceFormatter sequenceFormatter; private boolean saveCurrentState; /** * Creates a new instance. * * @param storeDirectory * The directory used to hold the contents of the store. * @param saveCurrentState * If true, the current state will be updated by the * {@link #saveState(ReplicationState)} operation as well as the * sequenced state. */ public FileReplicationStore(File storeDirectory, boolean saveCurrentState) { currentStatePersister = new PropertiesPersister(new File(storeDirectory, STATE_FILE)); sequenceFormatter = new ReplicationFileSequenceFormatter(storeDirectory); this.saveCurrentState = saveCurrentState; } @Override public ReplicationState getCurrentState() { ReplicationState state = new ReplicationState(); state.load(currentStatePersister.loadMap()); return state; } @Override public ReplicationState getState(long sequence) { File stateFile = sequenceFormatter.getFormattedName(sequence, ".state.txt"); return new ReplicationState(new PropertiesPersister(stateFile).loadMap()); } @Override public XmlChangeReader getData(long sequence) { File changeFile = sequenceFormatter.getFormattedName(sequence, ".osc.gz"); return new XmlChangeReader(changeFile, false, CompressionMethod.GZip); } @Override public void saveState(ReplicationState state) { File stateFile = sequenceFormatter.getFormattedName(state.getSequenceNumber(), ".state.txt"); new PropertiesPersister(stateFile).store(state.store()); if (saveCurrentState) { currentStatePersister.store(state.store()); } } @Override public XmlChangeWriter saveData(long sequence) { File changeFile = sequenceFormatter.getFormattedName(sequence, ".osc.gz"); return new XmlChangeWriter(changeFile, CompressionMethod.GZip); } } ReplicationFileSequenceFormatter.java000066400000000000000000000053321253404521400421220ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.common; import java.io.File; import java.util.StringTokenizer; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Formats replication sequence numbers into file names. */ public class ReplicationFileSequenceFormatter { private ReplicationSequenceFormatter sequenceFormatter; private File workingDirectory; /** * Creates a new instance. The minimum length and grouping length will default to 9 and 3 * respectively. * * @param workingDirectory * The directory from which to base all created files. */ public ReplicationFileSequenceFormatter(File workingDirectory) { this(workingDirectory, 9, 3); } /** * Creates a new instance. * * @param minimumLength * The minimum length file sequence string to generate. For example, setting a length * of 2 will generate sequence numbers from "00" to "99". * @param groupingLength * The number of characters to write before separating with a '/' character. Used for * creating sequence numbers to be written to files in a nested directory structure. * @param workingDirectory * The directory from which to base all created files. */ public ReplicationFileSequenceFormatter(File workingDirectory, int minimumLength, int groupingLength) { this.workingDirectory = workingDirectory; sequenceFormatter = new ReplicationSequenceFormatter(minimumLength, groupingLength); } /** * Formats the sequence number into a file name. Any sub-directories required will be * automatically created. * * @param sequenceNumber * The sequence number. * @param fileNameSuffix * The suffix to append to the end of the file name. * @return The formatted file. */ public File getFormattedName(long sequenceNumber, String fileNameSuffix) { String fileName; StringTokenizer pathTokenizer; File formattedPath; fileName = sequenceFormatter.getFormattedName(sequenceNumber, fileNameSuffix); pathTokenizer = new StringTokenizer(fileName, "/"); formattedPath = workingDirectory; while (pathTokenizer.hasMoreTokens()) { // Move to the next item in the path. formattedPath = new File(formattedPath, pathTokenizer.nextToken()); // If this is a directory within the path (ie. not the final element in the path) then // ensure it exists and create it if it doesn't exist. if (pathTokenizer.hasMoreTokens()) { if (!formattedPath.exists() && !formattedPath.mkdir()) { throw new OsmosisRuntimeException("Unable to create directory \"" + formattedPath + "\"."); } } } return formattedPath; } } ReplicationSequenceFormatter.java000066400000000000000000000040341253404521400413200ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.common; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.NumberFormat; import java.util.Locale; /** * Formats replication sequence numbers into file names. */ public class ReplicationSequenceFormatter { private NumberFormat sequenceFormat; /** * Creates a new instance. * * @param minimumLength * The minimum length file sequence string to generate. For example, setting a length * of 2 will generate sequence numbers from "00" to "99". * @param groupingLength * The number of characters to write before separating with a '/' character. Used for * creating sequence numbers to be written to files in a nested directory structure. */ public ReplicationSequenceFormatter(int minimumLength, int groupingLength) { DecimalFormatSymbols formatSymbols; StringBuilder formatString; formatSymbols = new DecimalFormatSymbols(Locale.US); formatSymbols.setGroupingSeparator('/'); formatString = new StringBuilder(); for (int i = 0; i < minimumLength || i <= groupingLength; i++) { if (i > 0 && groupingLength > 0 && i % groupingLength == 0) { formatString.append(','); } if (i < minimumLength) { formatString.append('0'); } else { formatString.append('#'); } } formatString.reverse(); this.sequenceFormat = new DecimalFormat(formatString.toString(), formatSymbols); } /** * Formats the sequence number into a file name. Any sub-directories required will be * automatically created. * * @param sequenceNumber * The sequence number. * @param fileNameSuffix * The suffix to append to the end of the file name. * @return The formatted file name. */ public String getFormattedName(long sequenceNumber, String fileNameSuffix) { String fileName; fileName = sequenceFormat.format(sequenceNumber) + fileNameSuffix; return fileName; } } ReplicationState.java000066400000000000000000000102241253404521400367420ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.common; import java.util.Date; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.time.DateFormatter; import org.openstreetmap.osmosis.core.time.DateParser; /** * Contains the state to be remembered between replication invocations. This * state ensures that no data is missed during replication, and ensures that * none is repeated except after certain failure situations. */ public class ReplicationState { /** * The key used when passing an instance through the pipeline as metadata. */ public static final String META_DATA_KEY = "replication.state"; private Date timestamp; private long sequenceNumber; /** * Creates a new instance with all values set to defaults. */ public ReplicationState() { this.timestamp = new Date(0); this.sequenceNumber = 0; } /** * Creates a new instance. * * @param timestamp * The maximum timestamp of data currently read from the database. * @param sequenceNumber * The replication sequence number. */ public ReplicationState(Date timestamp, long sequenceNumber) { this.timestamp = timestamp; this.sequenceNumber = sequenceNumber; } /** * Creates a new instance. * * @param properties * The properties to load state from. */ public ReplicationState(Map properties) { load(properties); } private String loadProperty(Map properties, String key) { if (!properties.containsKey(key)) { throw new OsmosisRuntimeException("The replication state doesn't contain a " + key + " property."); } return properties.get(key); } /** * Loads all state from the provided properties object. * * @param properties * The properties to be read. */ public void load(Map properties) { timestamp = new DateParser().parse(loadProperty(properties, "timestamp")); sequenceNumber = Long.parseLong(loadProperty(properties, "sequenceNumber")); } /** * Writes all state into the provided properties object. * * @param properties * The properties to be updated. */ public void store(Map properties) { properties.put("timestamp", new DateFormatter().format(timestamp)); properties.put("sequenceNumber", Long.toString(sequenceNumber)); } /** * Writes all state into a new properties object. * * @return The properties. */ public Map store() { Map properties = new HashMap(); store(properties); return properties; } /** * Gets the maximum timestamp of data currently read from the database. * * @return The timestamp. */ public Date getTimestamp() { return timestamp; } /** * Sets the maximum timestamp of data currently read from the database. * * @param timestamp * The timestamp. */ public void setTimestamp(Date timestamp) { this.timestamp = timestamp; } /** * Gets the replication sequence number. * * @return The sequence number. */ public long getSequenceNumber() { return sequenceNumber; } /** * Sets the replication sequence number. * * @param sequenceNumber * The sequence number. */ public void setSequenceNumber(long sequenceNumber) { this.sequenceNumber = sequenceNumber; } /** * {@inheritDoc} */ @Override public boolean equals(Object obj) { boolean result; if (obj instanceof ReplicationState) { ReplicationState compareState = (ReplicationState) obj; if (timestamp.equals(compareState.timestamp) && sequenceNumber == compareState.sequenceNumber) { result = true; } else { result = false; } } else { result = false; } return result; } /** * {@inheritDoc} */ @Override public int hashCode() { return (int) sequenceNumber + (int) timestamp.getTime(); } /** * {@inheritDoc} */ @Override public String toString() { return "ReplicationState(timestamp=" + timestamp + ", sequenceNumber=" + sequenceNumber + ")"; } } ReplicationStore.java000066400000000000000000000030021253404521400367520ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.common; import org.openstreetmap.osmosis.xml.v0_6.XmlChangeReader; import org.openstreetmap.osmosis.xml.v0_6.XmlChangeWriter; /** * Defines a store for replication data. * * @author Brett Henderson */ public interface ReplicationStore { /** * Gets the current replication state. This corresponds to the state of the * latest sequence in the store. * * @return The replication state. */ ReplicationState getCurrentState(); /** * Gets the state for the specified sequence. * * @param sequence * The sequence to be loaded. * @return The replication state. */ ReplicationState getState(long sequence); /** * Gets the data for the specified sequence. * * @param sequence * The sequence to be loaded. * @return The change reader. */ XmlChangeReader getData(long sequence); /** * Sets the state for the specified sequence. The current state may be * updated to match depending on the store configuration. This should only * be called after data has been successfully written. * * @param state * The replication state. */ void saveState(ReplicationState state); /** * Obtains an change writer used to save the replication data for the * specified sequence. * * @param sequence * The sequence to be saved. * @return The change writer. */ XmlChangeWriter saveData(long sequence); } ServerStateReader.java000066400000000000000000000073271253404521400370740ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.common; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.OsmosisConstants; /** * Retrieves replication state files from the server hosting replication data. */ public class ServerStateReader { private static final Logger LOG = Logger.getLogger(ServerStateReader.class.getName()); private static final String SERVER_STATE_FILE = "state.txt"; private static final String SEQUENCE_STATE_FILE_SUFFIX = ".state.txt"; private ReplicationSequenceFormatter sequenceFormatter; /** * Creates a new instance. */ public ServerStateReader() { sequenceFormatter = new ReplicationSequenceFormatter(9, 3); } /** * Retrieves the latest state from the server. * * @param baseUrl * The url of the directory containing change files. * @return The state. */ public ReplicationState getServerState(URL baseUrl) { return getServerState(baseUrl, SERVER_STATE_FILE); } /** * Retrieves the specified state from the server. * * @param baseUrl * The url of the directory containing change files. * @param sequenceNumber * The sequence number of the state to be retrieved from the server. * @return The state. */ public ReplicationState getServerState(URL baseUrl, long sequenceNumber) { return getServerState(baseUrl, sequenceFormatter.getFormattedName(sequenceNumber, SEQUENCE_STATE_FILE_SUFFIX)); } /** * Retrieves the specified state from the server. * * @param baseUrl * The url of the directory containing change files. * @param stateFile * The state file to be retrieved. * @return The state. */ private ReplicationState getServerState(URL baseUrl, String stateFile) { URL stateUrl; InputStream stateStream = null; try { stateUrl = new URL(baseUrl, stateFile); } catch (MalformedURLException e) { throw new OsmosisRuntimeException("The server timestamp URL could not be created.", e); } try { BufferedReader reader; Properties stateProperties; Map stateMap; ReplicationState state; URLConnection connection = stateUrl.openConnection(); connection.setReadTimeout(15 * 60 * 1000); // timeout 15 minutes connection.setConnectTimeout(15 * 60 * 1000); // timeout 15 minutes connection.setRequestProperty("User-Agent", "Osmosis/" + OsmosisConstants.VERSION); stateStream = connection.getInputStream(); reader = new BufferedReader(new InputStreamReader(stateStream)); stateProperties = new Properties(); stateProperties.load(reader); stateMap = new HashMap(); for (Entry property : stateProperties.entrySet()) { stateMap.put((String) property.getKey(), (String) property.getValue()); } state = new ReplicationState(stateMap); stateStream.close(); stateStream = null; return state; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to read the state from the server.", e); } finally { try { if (stateStream != null) { stateStream.close(); } } catch (IOException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to close state stream.", e); } } } } TimestampTracker.java000066400000000000000000000073571253404521400367640ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.common; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.Date; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.time.DateFormatter; import org.openstreetmap.osmosis.core.time.DateParser; /** * Maintains the time that the extraction process has reached. It persists the * time across invocations using a file. * * @author Brett Henderson */ public class TimestampTracker { private static final Logger LOG = Logger.getLogger(TimestampTracker.class.getName()); private File timestampFile; private File newTimestampFile; private DateParser dateParser; private DateFormatter dateFormatter; /** * Creates a new instance. * * @param timestampFile * The location of the file containing the persisted timestamp. * @param newTimestampFile * The location of the temp file to use when updating the * persisted timestamp to make the update atomic. */ public TimestampTracker(File timestampFile, File newTimestampFile) { this.timestampFile = timestampFile; this.newTimestampFile = newTimestampFile; dateParser = new DateParser(); dateFormatter = new DateFormatter(); } /** * Renames the new timestamp file to the current file deleting the current * file if it exists. */ private void renameNewFileToCurrent() { // Make sure we have a new timestamp file. if (!newTimestampFile.exists()) { throw new OsmosisRuntimeException("Can't rename non-existent file " + newTimestampFile + "."); } // Delete the existing timestamp file if it exists. if (timestampFile.exists()) { if (!timestampFile.delete()) { throw new OsmosisRuntimeException("Unable to delete file " + timestampFile + "."); } } // Rename the new file to the existing file. if (!newTimestampFile.renameTo(timestampFile)) { throw new OsmosisRuntimeException( "Unable to rename file " + newTimestampFile + " to " + timestampFile + "."); } } /** * Retrieve the current time. * * @return The time. */ public Date getTime() { FileReader fileReader = null; try { BufferedReader reader; Date result; fileReader = new FileReader(timestampFile); reader = new BufferedReader(fileReader); result = dateParser.parse(reader.readLine()); fileReader.close(); fileReader = null; return result; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to read the time from file " + timestampFile + ".", e); } finally { if (fileReader != null) { try { fileReader.close(); } catch (Exception e) { LOG.log(Level.WARNING, "Unable to close time file " + timestampFile + ".", e); } } } } /** * Update the stored time. * * @param time * The time to set. */ public void setTime(Date time) { FileWriter fileWriter = null; try { BufferedWriter writer; fileWriter = new FileWriter(newTimestampFile); writer = new BufferedWriter(fileWriter); writer.write(dateFormatter.format(time)); writer.close(); renameNewFileToCurrent(); } catch (IOException e) { throw new OsmosisRuntimeException( "Unable to write the time to temporary file " + newTimestampFile + ".", e); } finally { if (fileWriter != null) { try { fileWriter.close(); } catch (Exception e) { LOG.log(Level.WARNING, "Unable to close temporary time file " + newTimestampFile + ".", e); } } } } } osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/000077500000000000000000000000001253404521400321675ustar00rootroot00000000000000BaseReplicationDownloader.java000066400000000000000000000316401253404521400400420ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.v0_6; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.util.Collections; import java.util.Date; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.OsmosisConstants; import org.openstreetmap.osmosis.core.task.common.RunnableTask; import org.openstreetmap.osmosis.core.util.FileBasedLock; import org.openstreetmap.osmosis.core.util.PropertiesPersister; import org.openstreetmap.osmosis.replication.common.ReplicationSequenceFormatter; import org.openstreetmap.osmosis.replication.common.ReplicationState; import org.openstreetmap.osmosis.replication.common.ServerStateReader; import org.openstreetmap.osmosis.replication.v0_6.impl.ReplicationDownloaderConfiguration; import org.openstreetmap.osmosis.xml.common.CompressionMethod; import org.openstreetmap.osmosis.xml.v0_6.XmlChangeReader; /** * This class downloads a set of replication files from a HTTP server and tracks the progress of * which files have already been processed. The actual processing of changeset files is performed by * sub-classes. This class forms the basis of a replication mechanism. * * @author Brett Henderson */ public abstract class BaseReplicationDownloader implements RunnableTask { private static final Logger LOG = Logger.getLogger(BaseReplicationDownloader.class.getName()); private static final String LOCK_FILE = "download.lock"; private static final String CONFIG_FILE = "configuration.txt"; private static final String LOCAL_STATE_FILE = "state.txt"; private File workingDirectory; private ReplicationSequenceFormatter sequenceFormatter; private ServerStateReader serverStateReader; /** * Creates a new instance. * * @param workingDirectory * The directory containing configuration and tracking files. */ public BaseReplicationDownloader(File workingDirectory) { this.workingDirectory = workingDirectory; sequenceFormatter = new ReplicationSequenceFormatter(9, 3); serverStateReader = new ServerStateReader(); } /** * Provides sub-classes with access to the working directory. * * @return The working directory for the task. */ protected File getWorkingDirectory() { return workingDirectory; } /** * Downloads the file from the server with the specified name and writes it * to a local temporary file. * * @param fileName * The name of the file to download. * @param baseUrl * The url of the directory containing change files. * @return The temporary file containing the downloaded data. */ private File downloadReplicationFile(String fileName, URL baseUrl) { URL changesetUrl; InputStream inputStream = null; OutputStream outputStream = null; try { changesetUrl = new URL(baseUrl, fileName); } catch (MalformedURLException e) { throw new OsmosisRuntimeException("The server file URL could not be created.", e); } try { BufferedInputStream source; BufferedOutputStream sink; File outputFile; byte[] buffer; // Open an input stream for the changeset file on the server. URLConnection connection = changesetUrl.openConnection(); connection.setReadTimeout(15 * 60 * 1000); // timeout 15 minutes connection.setConnectTimeout(15 * 60 * 1000); // timeout 15 minutes connection.setRequestProperty("User-Agent", "Osmosis/" + OsmosisConstants.VERSION); inputStream = connection.getInputStream(); source = new BufferedInputStream(inputStream, 65536); // Create a temporary file to write the data to. outputFile = File.createTempFile("change", null); // Open a output stream for the destination file. outputStream = new FileOutputStream(outputFile); sink = new BufferedOutputStream(outputStream, 65536); // Download the file. buffer = new byte[65536]; for (int bytesRead = source.read(buffer); bytesRead > 0; bytesRead = source.read(buffer)) { sink.write(buffer, 0, bytesRead); } sink.flush(); // Clean up all file handles. inputStream.close(); inputStream = null; outputStream.close(); outputStream = null; return outputFile; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to read the changeset file " + fileName + " from the server.", e); } finally { try { if (inputStream != null) { inputStream.close(); } } catch (IOException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to changeset download stream.", e); } try { if (outputStream != null) { outputStream.close(); } } catch (IOException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to changeset output stream.", e); } } } private void processReplicationFile(File replicationFile, ReplicationState replicationState) { try { XmlChangeReader xmlReader; // Send the contents of the replication file to the sink but suppress the complete // and release methods. xmlReader = new XmlChangeReader(replicationFile, true, CompressionMethod.GZip); // Delegate to the sub-class to process the xml. processChangeset(xmlReader, replicationState); } finally { if (!replicationFile.delete()) { LOG.warning("Unable to delete file " + replicationFile.getName()); } } } /** * Determines the maximum timestamp of data to be downloaded during this invocation. This may be * overriden by sub-classes, but the sub-classes must call this implemention first and then * limit the maximum timestamp further if needed. A sub-class may never increase the maximum * timestamp beyond that calculated by this method. * * @param configuration * The configuration. * @param serverTimestamp * The timestamp of the latest data on the server. * @param localTimestamp * The timestamp of the most recently downloaded data. * @return The maximum timestamp for this invocation. */ protected Date calculateMaximumTimestamp(ReplicationDownloaderConfiguration configuration, Date serverTimestamp, Date localTimestamp) { Date maximumTimestamp; maximumTimestamp = serverTimestamp; // Limit the duration according to the maximum defined in the configuration. if (configuration.getMaxInterval() > 0) { if ((serverTimestamp.getTime() - localTimestamp.getTime()) > configuration.getMaxInterval()) { maximumTimestamp = new Date(localTimestamp.getTime() + configuration.getMaxInterval()); } } LOG.finer("Maximum timestamp is " + maximumTimestamp); return maximumTimestamp; } private ReplicationState download(ReplicationDownloaderConfiguration configuration, ReplicationState serverState, ReplicationState initialLocalState) { URL baseUrl; ReplicationState localState; Date maximumDownloadTimestamp; localState = initialLocalState; // Determine the location of download files. baseUrl = configuration.getBaseUrl(); // Determine the maximum timestamp that can be downloaded. maximumDownloadTimestamp = calculateMaximumTimestamp(configuration, serverState.getTimestamp(), localState.getTimestamp()); LOG.fine("The maximum timestamp to be downloaded is " + maximumDownloadTimestamp + "."); // Download all files and send their contents to the sink. while (localState.getSequenceNumber() < serverState.getSequenceNumber()) { File replicationFile; long sequenceNumber; ReplicationState fileReplicationState; // Check to see if our local state has already reached the maximum // allowable timestamp. This will typically occur if a job is run // again before new data becomes available, or if an implementation // of this class (eg. ReplicationFileMerger) is waiting for a full // time period of data to become available before processing. if (localState.getTimestamp().compareTo(maximumDownloadTimestamp) >= 0) { break; } // Calculate the next sequence number. sequenceNumber = localState.getSequenceNumber() + 1; LOG.finer("Processing replication sequence " + sequenceNumber + "."); // Get the state associated with the next file. fileReplicationState = serverStateReader.getServerState(baseUrl, sequenceNumber); // Ensure that the next state is within the allowable timestamp // range. We must stop if the next data takes us beyond the maximum // timestamp. This will either occur if a maximum download time // duration limit has been imposed, or if a time-aligned boundary // has been reached. if (fileReplicationState.getTimestamp().compareTo(maximumDownloadTimestamp) > 0) { // We will always allow at least one replication interval // through to deal with the case where a single interval exceeds // the maximum duration. This can happen if the source data has // a long time gap between two intervals due to system downtime. if (localState.getSequenceNumber() != initialLocalState.getSequenceNumber()) { break; } } // Download the next replication file to a temporary file. replicationFile = downloadReplicationFile(sequenceFormatter.getFormattedName(sequenceNumber, ".osc.gz"), baseUrl); // Process the file and send its contents to the sink. processReplicationFile(replicationFile, fileReplicationState); // Update the local state to reflect the file state just processed. localState = fileReplicationState; } return localState; } private void runImpl() { try { ReplicationDownloaderConfiguration configuration; ReplicationState serverState; ReplicationState localState; PropertiesPersister localStatePersistor; // Instantiate utility objects. configuration = new ReplicationDownloaderConfiguration(new File(workingDirectory, CONFIG_FILE)); // Obtain the server state. LOG.fine("Reading current server state."); serverState = serverStateReader.getServerState(configuration.getBaseUrl()); // Build the local state persister which is used for both loading and storing local state. localStatePersistor = new PropertiesPersister(new File(workingDirectory, LOCAL_STATE_FILE)); // Begin processing. processInitialize(Collections.emptyMap()); // If local state isn't available we need to copy server state to be the initial local state // then exit. if (localStatePersistor.exists()) { localState = new ReplicationState(localStatePersistor.loadMap()); // Download and process the replication files. localState = download(configuration, serverState, localState); } else { localState = serverState; processInitializeState(localState); } // Commit downstream changes. processComplete(); // Persist the local state. localStatePersistor.store(localState.store()); } finally { processRelease(); } } /** * This is called prior to any processing being performed. It allows any * setup activities to be performed. * * @param metaData * The meta data associated with this processing request (empty * in the current implementation). */ protected abstract void processInitialize(Map metaData); /** * Invoked once during the first execution run to allow initialisation based on the initial * replication state downloaded from the server. * * @param initialState * The first server state. */ protected abstract void processInitializeState(ReplicationState initialState); /** * Processes the changeset. * * @param xmlReader * The changeset reader initialised to point to the changeset file. * @param replicationState * The replication state associated with the changeset file. */ protected abstract void processChangeset(XmlChangeReader xmlReader, ReplicationState replicationState); /** * This is implemented by sub-classes and is called when all changesets have been processed. * This should perform any completion tasks such as committing changes to a database. */ protected abstract void processComplete(); /** * This is implemented by sub-classes and is called and the completion of all processing * regardless of whether it was successful or not. This should perform any cleanup tasks such as * closing files or releasing database connections. */ protected abstract void processRelease(); /** * {@inheritDoc} */ @Override public void run() { FileBasedLock fileLock; fileLock = new FileBasedLock(new File(workingDirectory, LOCK_FILE)); try { fileLock.lock(); runImpl(); fileLock.unlock(); } finally { fileLock.release(); } } } IntervalDownloader.java000066400000000000000000000310421253404521400365560ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.v0_6; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.OsmosisConstants; import org.openstreetmap.osmosis.core.merge.common.ConflictResolutionMethod; import org.openstreetmap.osmosis.core.pipeline.common.TaskRunner; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.RunnableChangeSource; import org.openstreetmap.osmosis.core.time.DateParser; import org.openstreetmap.osmosis.core.util.FileBasedLock; import org.openstreetmap.osmosis.replication.common.TimestampTracker; import org.openstreetmap.osmosis.replication.v0_6.impl.ChangesetFileNameFormatter; import org.openstreetmap.osmosis.replication.v0_6.impl.IntervalDownloaderConfiguration; import org.openstreetmap.osmosis.set.v0_6.ChangeMerger; import org.openstreetmap.osmosis.xml.common.CompressionMethod; import org.openstreetmap.osmosis.xml.v0_6.XmlChangeReader; /** * Downloads a set of change files from a HTTP server, and merges them into a * single output stream. It tracks the intervals covered by the current files * and stores the current timestamp between invocations forming the basis of a * replication mechanism. * * @author Brett Henderson */ public class IntervalDownloader implements RunnableChangeSource { private static final Logger LOG = Logger.getLogger(IntervalDownloader.class.getName()); private static final String LOCK_FILE = "download.lock"; private static final String CONFIG_FILE = "configuration.txt"; private static final String TSTAMP_FILE = "timestamp.txt"; private static final String TSTAMP_NEW_FILE = "timestamp-new.txt"; private static final String SERVER_TSTAMP_FILE = "timestamp.txt"; private ChangeSink changeSink; private String taskId; private File workingDirectory; private DateParser dateParser; /** * Creates a new instance. * * @param taskId * The identifier for the task, this is required because the * names of threads created by this task will use this name as a * prefix. * @param workingDirectory * The directory containing configuration and tracking files. */ public IntervalDownloader(String taskId, File workingDirectory) { this.taskId = taskId; this.workingDirectory = workingDirectory; dateParser = new DateParser(); } /** * {@inheritDoc} */ @Override public void setChangeSink(ChangeSink changeSink) { this.changeSink = changeSink; } /** * Retrieves the latest timestamp from the server. * * @param baseUrl * The url of the directory containing change files. * @return The timestamp. */ private Date getServerTimestamp(URL baseUrl) { URL timestampUrl; InputStream timestampStream = null; try { timestampUrl = new URL(baseUrl, SERVER_TSTAMP_FILE); } catch (MalformedURLException e) { throw new OsmosisRuntimeException("The server timestamp URL could not be created.", e); } try { BufferedReader reader; Date result; URLConnection connection = timestampUrl.openConnection(); connection.setReadTimeout(15 * 60 * 1000); // timeout 15 minutes connection.setConnectTimeout(15 * 60 * 1000); // timeout 15 minutes connection.setRequestProperty("User-Agent", "Osmosis/" + OsmosisConstants.VERSION); timestampStream = connection.getInputStream(); reader = new BufferedReader(new InputStreamReader(timestampStream)); result = dateParser.parse(reader.readLine()); timestampStream.close(); timestampStream = null; return result; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to read the timestamp from the server.", e); } finally { try { if (timestampStream != null) { timestampStream.close(); } } catch (IOException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to close timestamp stream.", e); } } } /** * Downloads the file from the server with the specified name and writes it * to a local temporary file. * * @param fileName * The name of the file to download. * @param baseUrl * The url of the directory containing change files. * @return The temporary file containing the downloaded data. */ private File downloadChangesetFile(String fileName, URL baseUrl) { URL changesetUrl; InputStream inputStream = null; OutputStream outputStream = null; try { changesetUrl = new URL(baseUrl, fileName); } catch (MalformedURLException e) { throw new OsmosisRuntimeException("The server file URL could not be created.", e); } try { BufferedInputStream source; BufferedOutputStream sink; File outputFile; byte[] buffer; // Open an input stream for the changeset file on the server. URLConnection connection = changesetUrl.openConnection(); connection.setReadTimeout(15 * 60 * 1000); // timeout 15 minutes connection.setConnectTimeout(15 * 60 * 1000); // timeout 15 minutes inputStream = connection.getInputStream(); source = new BufferedInputStream(inputStream, 65536); // Create a temporary file to write the data to. outputFile = File.createTempFile("change", null); // Open a output stream for the destination file. outputStream = new FileOutputStream(outputFile); sink = new BufferedOutputStream(outputStream, 65536); // Download the file. buffer = new byte[65536]; for (int bytesRead = source.read(buffer); bytesRead > 0; bytesRead = source.read(buffer)) { sink.write(buffer, 0, bytesRead); } sink.flush(); // Clean up all file handles. inputStream.close(); inputStream = null; outputStream.close(); outputStream = null; return outputFile; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to read the changeset file " + fileName + " from the server.", e); } finally { try { if (inputStream != null) { inputStream.close(); } } catch (IOException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to changeset download stream.", e); } try { if (outputStream != null) { outputStream.close(); } } catch (IOException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "Unable to changeset output stream.", e); } } } /** * Downloads the changeset files from the server and writes their contents * to the output task. */ private void download() { IntervalDownloaderConfiguration configuration; TimestampTracker timestampTracker; ChangesetFileNameFormatter fileNameFormatter; Date currentTime; Date maximumTime; URL baseUrl; int maxDownloadCount; int downloadCount; ArrayList tmpFileList; ArrayList tasks; ArrayList taskRunners; boolean tasksSuccessful; // Instantiate utility objects. configuration = new IntervalDownloaderConfiguration(new File(workingDirectory, CONFIG_FILE)); timestampTracker = new TimestampTracker( new File(workingDirectory, TSTAMP_FILE), new File(workingDirectory, TSTAMP_NEW_FILE) ); fileNameFormatter = new ChangesetFileNameFormatter( configuration.getChangeFileBeginFormat(), configuration.getChangeFileEndFormat() ); // Create the base url. try { baseUrl = new URL(configuration.getBaseUrl()); } catch (MalformedURLException e) { throw new OsmosisRuntimeException( "Unable to convert URL string (" + configuration.getBaseUrl() + ") into a URL.", e); } tmpFileList = new ArrayList(); // Load the current time from the timestamp tracking file. currentTime = timestampTracker.getTime(); // Load the latest timestamp from the server. maximumTime = getServerTimestamp(baseUrl); // Process until all files have been retrieved from the server. maxDownloadCount = configuration.getMaxDownloadCount(); downloadCount = 0; while ((maxDownloadCount == 0 || downloadCount < maxDownloadCount) && currentTime.before(maximumTime)) { Date nextTime; String downloadFileName; // Calculate the end of the next time interval. nextTime = new Date(currentTime.getTime() + configuration.getIntervalLength()); // Generate the filename to be retrieved from the server. downloadFileName = fileNameFormatter.generateFileName(currentTime, nextTime); // Download the changeset from the server. tmpFileList.add(downloadChangesetFile(downloadFileName, baseUrl)); // Move the current time to the next interval. currentTime = nextTime; // Increment the current download count. downloadCount++; } // Generate a set of tasks for loading the change files and merge them // into a single change stream. tasks = new ArrayList(); for (File tmpFile : tmpFileList) { XmlChangeReader changeReader; // Generate a change reader task for the current task. changeReader = new XmlChangeReader( tmpFile, true, CompressionMethod.GZip ); // If tasks already exist, a change merge task must be used to merge // existing output with this task output, otherwise this task can be // added to the list directly. if (tasks.size() > 0) { ChangeMerger changeMerger; // Create a new change merger merging the last task output with the current task. changeMerger = new ChangeMerger(ConflictResolutionMethod.LatestSource, 10); // Connect the inputs of this merger to the most recent change // output and the new change output. tasks.get(tasks.size() - 1).setChangeSink(changeMerger.getChangeSink(0)); changeReader.setChangeSink(changeMerger.getChangeSink(1)); tasks.add(changeReader); tasks.add(changeMerger); } else { tasks.add(changeReader); } } // We only need to execute sub-threads if tasks exist, otherwise we must // notify the sink that we have completed. if (tasks.size() > 0) { // Connect the last task to the change sink. tasks.get(tasks.size() - 1).setChangeSink(changeSink); // Create task runners for each of the tasks to provide thread // management. taskRunners = new ArrayList(tasks.size()); for (int i = 0; i < tasks.size(); i++) { taskRunners.add(new TaskRunner(tasks.get(i), "Thread-" + taskId + "-worker" + i)); } // Launch all of the tasks. for (int i = 0; i < taskRunners.size(); i++) { TaskRunner taskRunner; taskRunner = taskRunners.get(i); LOG.fine("Launching changeset worker + " + i + " in a new thread."); taskRunner.start(); } // Wait for all the tasks to complete. tasksSuccessful = true; for (int i = 0; i < taskRunners.size(); i++) { TaskRunner taskRunner; taskRunner = taskRunners.get(i); LOG.fine("Waiting for changeset worker " + i + " to complete."); try { taskRunner.join(); } catch (InterruptedException e) { // We are already in an error condition so log and continue. LOG.log(Level.WARNING, "The wait for task completion was interrupted.", e); } if (!taskRunner.isSuccessful()) { LOG.log(Level.SEVERE, "Changeset worker " + i + " failed", taskRunner.getException()); tasksSuccessful = false; } } } else { changeSink.complete(); tasksSuccessful = true; } // Remove the temporary files. for (File tmpFile : tmpFileList) { if (!tmpFile.delete()) { LOG.warning("Unable to delete file " + tmpFile.getName()); } } if (!tasksSuccessful) { throw new OsmosisRuntimeException("One or more changeset workers failed."); } // Update the timestamp tracker. timestampTracker.setTime(currentTime); } /** * {@inheritDoc} */ @Override public void run() { FileBasedLock fileLock; fileLock = new FileBasedLock(new File(workingDirectory, LOCK_FILE)); try { changeSink.initialize(Collections.emptyMap()); fileLock.lock(); download(); fileLock.unlock(); } finally { changeSink.release(); fileLock.release(); } } } IntervalDownloaderFactory.java000066400000000000000000000026131253404521400401100ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.v0_6; import java.io.File; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.RunnableChangeSourceManager; /** * The task manager factory for a change downloader. * * @author Brett Henderson */ public class IntervalDownloaderFactory extends TaskManagerFactory { private static final String ARG_WORKING_DIRECTORY = "workingDirectory"; private static final String DEFAULT_WORKING_DIRECTORY = "./"; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String workingDirectoryString; File workingDirectory; // Get the task arguments. workingDirectoryString = getStringArgument( taskConfig, ARG_WORKING_DIRECTORY, getDefaultStringArgument(taskConfig, DEFAULT_WORKING_DIRECTORY) ); // Convert argument strings to strongly typed objects. workingDirectory = new File(workingDirectoryString); return new RunnableChangeSourceManager( taskConfig.getId(), new IntervalDownloader( taskConfig.getId(), workingDirectory ), taskConfig.getPipeArgs() ); } } IntervalDownloaderInitializer.java000066400000000000000000000056041253404521400407670ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.v0_6; import java.io.File; import java.util.Date; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.task.common.RunnableTask; import org.openstreetmap.osmosis.core.util.FileBasedLock; import org.openstreetmap.osmosis.core.util.ResourceFileManager; import org.openstreetmap.osmosis.replication.common.TimestampTracker; /** * Downloads a set of change files from a HTTP server, and merges them into a * single output stream. It tracks the intervals covered by the current files * and stores the current timestamp between invocations forming the basis of a * replication mechanism. * * @author Brett Henderson */ public class IntervalDownloaderInitializer implements RunnableTask { private static final String LOCK_FILE_NAME = "download.lock"; private static final String CONFIG_FILE_NAME = "configuration.txt"; private static final String TSTAMP_FILE_NAME = "timestamp.txt"; private static final String TSTAMP_NEW_FILE_NAME = "timestamp-new.txt"; private static final String CONFIG_RESOURCE = "impl/intervalConfiguration.txt"; private File workingDirectory; private Date initialDate; /** * Creates a new instance. * * @param workingDirectory * The directory containing configuration and tracking files. * @param initialDate * The date to begin changeset downloads from. */ public IntervalDownloaderInitializer(File workingDirectory, Date initialDate) { this.workingDirectory = workingDirectory; this.initialDate = initialDate; } /** * Initializes a working directory. */ private void initializeDirectory() { File configFile; File timestampFile; File newTimestampFile; ResourceFileManager resourceFileManager; // Instantiate utility objects. resourceFileManager = new ResourceFileManager(); // Build file objects from file names. configFile = new File(workingDirectory, CONFIG_FILE_NAME); timestampFile = new File(workingDirectory, TSTAMP_FILE_NAME); newTimestampFile = new File(workingDirectory, TSTAMP_NEW_FILE_NAME); if (configFile.exists()) { throw new OsmosisRuntimeException("Config file " + CONFIG_FILE_NAME + " already exists."); } resourceFileManager.copyResourceToFile(getClass(), CONFIG_RESOURCE, configFile); if (timestampFile.exists()) { throw new OsmosisRuntimeException("Timestamp file " + TSTAMP_FILE_NAME + " already exists."); } new TimestampTracker(timestampFile, newTimestampFile).setTime(initialDate); } /** * {@inheritDoc} */ @Override public void run() { FileBasedLock fileLock; fileLock = new FileBasedLock(new File(workingDirectory, LOCK_FILE_NAME)); try { fileLock.lock(); initializeDirectory(); fileLock.unlock(); } finally { fileLock.release(); } } } IntervalDownloaderInitializerFactory.java000066400000000000000000000031671253404521400423210ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.v0_6; import java.io.File; import java.util.Date; import java.util.TimeZone; import org.openstreetmap.osmosis.core.pipeline.common.RunnableTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; /** * The task manager factory for a change download initializer. * * @author Brett Henderson */ public class IntervalDownloaderInitializerFactory extends TaskManagerFactory { private static final String ARG_WORKING_DIRECTORY = "workingDirectory"; private static final String ARG_INITIAL_DATE = "initialDate"; private static final String DEFAULT_WORKING_DIRECTORY = "./"; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String workingDirectoryString; Date initialDate; File workingDirectory; // Get the task arguments. workingDirectoryString = getStringArgument( taskConfig, ARG_WORKING_DIRECTORY, getDefaultStringArgument(taskConfig, DEFAULT_WORKING_DIRECTORY) ); initialDate = getDateArgument(taskConfig, ARG_INITIAL_DATE, TimeZone.getTimeZone("UTC")); // Convert argument strings to strongly typed objects. workingDirectory = new File(workingDirectoryString); return new RunnableTaskManager( taskConfig.getId(), new IntervalDownloaderInitializer( workingDirectory, initialDate ), taskConfig.getPipeArgs() ); } } ReplicationDownloader.java000066400000000000000000000067431253404521400372550ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.v0_6; import java.io.File; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.sort.v0_6.ChangeForStreamableApplierComparator; import org.openstreetmap.osmosis.core.sort.v0_6.ChangeSorter; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.RunnableChangeSource; import org.openstreetmap.osmosis.replication.common.ReplicationState; import org.openstreetmap.osmosis.xml.v0_6.XmlChangeReader; /** * Downloads a set of replication files from a HTTP server, and merges them into a * single output stream. It tracks the intervals covered by the current files * and stores the current timestamp between invocations forming the basis of a * replication mechanism. * * @author Brett Henderson */ public class ReplicationDownloader extends BaseReplicationDownloader implements RunnableChangeSource { private ChangeSorter changeSorter; /** * Creates a new instance. * * @param workingDirectory * The directory containing configuration and tracking files. */ public ReplicationDownloader(File workingDirectory) { super(workingDirectory); // We will sort all contents prior to sending to the sink. This adds overhead that may not // always be required, but provides consistent behaviour. changeSorter = new ChangeSorter(new ChangeForStreamableApplierComparator()); } /** * {@inheritDoc} */ @Override public void setChangeSink(ChangeSink changeSink) { changeSorter.setChangeSink(changeSink); } /** * {@inheritDoc} */ @Override protected void processInitialize(Map metaData) { changeSorter.initialize(metaData); } /** * {@inheritDoc} */ @Override protected void processInitializeState(ReplicationState initialState) { // We don't allow automatic state file initialization for replication // downloading. This is the most common task used by end users to // retrieve replication information. It is very rare that a user would // want to begin from the latest server state file. In most cases // they'll want to begin processing from a known point in time. throw new OsmosisRuntimeException("The local state.txt file doesn't exist." + " See http://wiki.openstreetmap.org/wiki/Osmosis/Detailed_Usage" + "#--read-replication-interval-init_.28--rrii.29" + " for more details on how to create the state.txt file."); } /** * {@inheritDoc} */ @Override protected void processChangeset(XmlChangeReader xmlReader, ReplicationState replicationState) { final ChangeSink localChangeSink = changeSorter; xmlReader.setChangeSink(new ChangeSink() { private ChangeSink suppressedChangeSink = localChangeSink; @Override public void initialize(Map metaData) { // Suppress the call. } @Override public void process(ChangeContainer change) { suppressedChangeSink.process(change); } @Override public void complete() { // Suppress the call. } @Override public void release() { // Suppress the call. } }); xmlReader.run(); } /** * {@inheritDoc} */ @Override protected void processComplete() { changeSorter.complete(); } /** * {@inheritDoc} */ @Override protected void processRelease() { changeSorter.release(); } } ReplicationDownloaderFactory.java000066400000000000000000000025441253404521400406000ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.v0_6; import java.io.File; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.RunnableChangeSourceManager; /** * The task manager factory for a replication file downloader. */ public class ReplicationDownloaderFactory extends TaskManagerFactory { private static final String ARG_WORKING_DIRECTORY = "workingDirectory"; private static final String DEFAULT_WORKING_DIRECTORY = "./"; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String workingDirectoryString; File workingDirectory; // Get the task arguments. workingDirectoryString = getStringArgument( taskConfig, ARG_WORKING_DIRECTORY, getDefaultStringArgument(taskConfig, DEFAULT_WORKING_DIRECTORY) ); // Convert argument strings to strongly typed objects. workingDirectory = new File(workingDirectoryString); return new RunnableChangeSourceManager( taskConfig.getId(), new ReplicationDownloader( workingDirectory ), taskConfig.getPipeArgs() ); } } ReplicationDownloaderInitializer.java000066400000000000000000000042051253404521400414500ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.v0_6; import java.io.File; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.task.common.RunnableTask; import org.openstreetmap.osmosis.core.util.FileBasedLock; import org.openstreetmap.osmosis.core.util.ResourceFileManager; /** * Downloads a set of replication files from a HTTP server, and merges them into a * single output stream. It tracks the intervals covered by the current files * and stores the current timestamp between invocations forming the basis of a * replication mechanism. * * @author Brett Henderson */ public class ReplicationDownloaderInitializer implements RunnableTask { private static final String LOCK_FILE_NAME = "download.lock"; private static final String CONFIG_FILE_NAME = "configuration.txt"; private static final String CONFIG_RESOURCE = "impl/replicationDownloaderConfiguration.txt"; private File workingDirectory; /** * Creates a new instance. * * @param workingDirectory * The directory containing configuration and tracking files. */ public ReplicationDownloaderInitializer(File workingDirectory) { this.workingDirectory = workingDirectory; } /** * Initializes a working directory. */ private void initializeDirectory() { File configFile; ResourceFileManager resourceFileManager; // Instantiate utility objects. resourceFileManager = new ResourceFileManager(); // Build file objects from file names. configFile = new File(workingDirectory, CONFIG_FILE_NAME); if (configFile.exists()) { throw new OsmosisRuntimeException("Config file " + CONFIG_FILE_NAME + " already exists."); } resourceFileManager.copyResourceToFile(getClass(), CONFIG_RESOURCE, configFile); } /** * {@inheritDoc} */ @Override public void run() { FileBasedLock fileLock; fileLock = new FileBasedLock(new File(workingDirectory, LOCK_FILE_NAME)); try { fileLock.lock(); initializeDirectory(); fileLock.unlock(); } finally { fileLock.release(); } } } ReplicationDownloaderInitializerFactory.java000066400000000000000000000025661253404521400430100ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.v0_6; import java.io.File; import org.openstreetmap.osmosis.core.pipeline.common.RunnableTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; /** * The task manager factory for a replication file download initializer. */ public class ReplicationDownloaderInitializerFactory extends TaskManagerFactory { private static final String ARG_WORKING_DIRECTORY = "workingDirectory"; private static final String DEFAULT_WORKING_DIRECTORY = "./"; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String workingDirectoryString; File workingDirectory; // Get the task arguments. workingDirectoryString = getStringArgument( taskConfig, ARG_WORKING_DIRECTORY, getDefaultStringArgument(taskConfig, DEFAULT_WORKING_DIRECTORY) ); // Convert argument strings to strongly typed objects. workingDirectory = new File(workingDirectoryString); return new RunnableTaskManager( taskConfig.getId(), new ReplicationDownloaderInitializer( workingDirectory ), taskConfig.getPipeArgs() ); } } ReplicationFileMerger.java000066400000000000000000000236651253404521400372020ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.v0_6; import java.io.File; import java.util.Date; import java.util.Map; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.sort.v0_6.ChangeForStreamableApplierComparator; import org.openstreetmap.osmosis.core.sort.v0_6.ChangeSorter; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.replication.common.FileReplicationStore; import org.openstreetmap.osmosis.replication.common.ReplicationState; import org.openstreetmap.osmosis.replication.common.ReplicationStore; import org.openstreetmap.osmosis.replication.v0_6.impl.ReplicationDownloaderConfiguration; import org.openstreetmap.osmosis.replication.v0_6.impl.ReplicationFileMergerConfiguration; import org.openstreetmap.osmosis.xml.v0_6.XmlChangeReader; import org.openstreetmap.osmosis.xml.v0_6.XmlChangeWriter; /** * Consumes the files in a replication directory and combines them into larger * replication files grouped by a time interval. This allows replication files * created at regular intervals to be combined into larger files for more * efficient consumption where latency is less of an issue. */ public class ReplicationFileMerger extends BaseReplicationDownloader { private static final Logger LOG = Logger.getLogger(ReplicationFileMerger.class.getName()); private static final String DATA_DIRECTORY = "data"; private static final String CONFIG_FILE = "configuration.txt"; private boolean sinkActive; private ChangeSink changeSink; private ReplicationState currentDataState; private ReplicationStore replicationStore; /** * Creates a new instance. * * @param workingDirectory * The directory containing configuration and tracking files. */ public ReplicationFileMerger(File workingDirectory) { super(workingDirectory); replicationStore = new FileReplicationStore(new File(getWorkingDirectory(), DATA_DIRECTORY), true); sinkActive = false; } private Date alignDateToIntervalBoundary(Date requestedDate, long intervalLength) { long remainder; remainder = requestedDate.getTime() % intervalLength; if (remainder > 0) { return new Date(requestedDate.getTime() - remainder); } else { return requestedDate; } } /** * {@inheritDoc} */ @Override protected Date calculateMaximumTimestamp(ReplicationDownloaderConfiguration configuration, Date serverTimestamp, Date localTimestamp) { Date maximumTimestamp; long intervalLength; // Read the current persisted state. currentDataState = replicationStore.getCurrentState(); // Get the default maximum timestamp according to base calculations. maximumTimestamp = super.calculateMaximumTimestamp(configuration, serverTimestamp, localTimestamp); // Align the maximum timestamp to an interval boundary. intervalLength = getConfiguration().getIntervalLength(); if (intervalLength > 0) { maximumTimestamp = alignDateToIntervalBoundary(maximumTimestamp, intervalLength); // For the first sequence file, we make sure we make sure that the // maximum timestamp is // ahead of the data timestamp. If it isn't, we move the maximum // timestamp backwards by // one interval to address the case where the local timestamp is // behind the data // timestamp causing some data to be downloaded and processed. if (currentDataState.getSequenceNumber() == 0) { if (maximumTimestamp.compareTo(currentDataState.getTimestamp()) <= 0) { maximumTimestamp = new Date(maximumTimestamp.getTime() - intervalLength); } } } // If the maximum timestamp exceeds the current local timestamp, but // does not exceed the current data timestamp then we shouldn't perform // any processing. If we download data we'll be forced to open a new // data file for the next interval which will not be populated fully // if the maximum timestamp is not high enough. To stop processing, we // simply set the maximum timestamp to equal the current local // timestamp. if ((maximumTimestamp.compareTo(localTimestamp) > 0) && (maximumTimestamp.compareTo(currentDataState.getTimestamp()) <= 0)) { maximumTimestamp = localTimestamp; } LOG.finer("Maximum timestamp is " + maximumTimestamp); return maximumTimestamp; } private ChangeSink buildResultWriter(long sequenceNumber) { XmlChangeWriter xmlChangeWriter; ChangeSorter changeSorter; xmlChangeWriter = replicationStore.saveData(sequenceNumber); changeSorter = new ChangeSorter(new ChangeForStreamableApplierComparator()); changeSorter.setChangeSink(xmlChangeWriter); return changeSorter; } private void writeChangeset(XmlChangeReader xmlReader) { final ChangeSink localChangeSink = changeSink; xmlReader.setChangeSink(new ChangeSink() { private ChangeSink suppressedWriter = localChangeSink; @Override public void initialize(Map metaData) { // Suppress the call. } @Override public void process(ChangeContainer change) { suppressedWriter.process(change); } @Override public void complete() { // Suppress the call. } @Override public void release() { // Suppress the call. } }); xmlReader.run(); } private ReplicationFileMergerConfiguration getConfiguration() { return new ReplicationFileMergerConfiguration(new File(getWorkingDirectory(), CONFIG_FILE)); } /** * {@inheritDoc} */ @Override protected void processInitialize(Map metaData) { // Do nothing. } /** * {@inheritDoc} */ @Override protected void processInitializeState(ReplicationState initialState) { Date initialDate; Date alignedDate; long intervalLength; intervalLength = getConfiguration().getIntervalLength(); initialDate = initialState.getTimestamp(); // Align the date to an interval boundary. alignedDate = alignDateToIntervalBoundary(initialDate, intervalLength); // If the date has been moved, then advance it to the next interval. We // do this because // during replication we never claim to have covered a time period that // we haven't received // data for. We may include extra data from a previous interval. By // advancing the stated // initial timestamp to the next interval our first replication will // include some data from // the previous interval. if (alignedDate.compareTo(initialDate) < 0) { alignedDate = new Date(alignedDate.getTime() + intervalLength); } // Create an initial replication state object. currentDataState = new ReplicationState(alignedDate, 0); // Write out the initial "0" state file. replicationStore.saveState(currentDataState); } /** * {@inheritDoc} */ @Override protected void processChangeset(XmlChangeReader xmlReader, ReplicationState replicationState) { int intervalLength; ReplicationFileMergerConfiguration configuration; configuration = getConfiguration(); // Get the configured interval length. intervalLength = configuration.getIntervalLength(); // If this is the first time through, initialise a writer for the next // sequence number. if (!sinkActive) { // Increment the current sequence number. currentDataState.setSequenceNumber(currentDataState.getSequenceNumber() + 1); // Initialise an output file for the new sequence number. LOG.finer("Opening change sink for interval with sequence number " + currentDataState.getSequenceNumber()); changeSink = buildResultWriter(currentDataState.getSequenceNumber()); } if (intervalLength > 0) { // If this is the first time through, align the timestamp at the // next boundary. if (!sinkActive) { Date intervalEnd; intervalEnd = new Date(currentDataState.getTimestamp().getTime() + intervalLength); intervalEnd = alignDateToIntervalBoundary(intervalEnd, intervalLength); currentDataState.setTimestamp(intervalEnd); LOG.finer("End of current interval is " + intervalEnd); } // If the replication state has moved us past the current interval // end point we need to // open a new interval. This may occur many times if the current // replication state moves // us past several intervals. while (replicationState.getTimestamp().compareTo(currentDataState.getTimestamp()) > 0) { // If we have an open changeset writer, close it and save the // current state. LOG.finer("Closing change sink for interval with sequence number " + currentDataState.getSequenceNumber()); changeSink.complete(); changeSink.release(); replicationStore.saveState(currentDataState); // Update the state to match the next interval. currentDataState.setSequenceNumber(currentDataState.getSequenceNumber() + 1); currentDataState.setTimestamp(new Date(currentDataState.getTimestamp().getTime() + configuration.getIntervalLength())); // Begin a new interval. LOG.finer("Opening change sink for interval with sequence number " + currentDataState.getSequenceNumber()); changeSink = buildResultWriter(currentDataState.getSequenceNumber()); } } else { // There is no maximum interval set, so simply update the current // state based on the // current replication state. LOG.finer("End of current interval is " + replicationState.getTimestamp()); currentDataState.setTimestamp(replicationState.getTimestamp()); } // Write the changeset to the writer. writeChangeset(xmlReader); // We are guaranteed to have an active writer at this point. sinkActive = true; } /** * {@inheritDoc} */ @Override protected void processComplete() { if (sinkActive) { LOG.finer("Closing change sink for interval with sequence number " + currentDataState.getSequenceNumber()); changeSink.complete(); replicationStore.saveState(currentDataState); changeSink.release(); changeSink = null; sinkActive = false; } } /** * {@inheritDoc} */ @Override protected void processRelease() { if (sinkActive) { changeSink.release(); sinkActive = false; } } } ReplicationFileMergerFactory.java000066400000000000000000000025221253404521400405170ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.v0_6; import java.io.File; import org.openstreetmap.osmosis.core.pipeline.common.RunnableTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; /** * The task manager factory for a replication file merger. */ public class ReplicationFileMergerFactory extends TaskManagerFactory { private static final String ARG_WORKING_DIRECTORY = "workingDirectory"; private static final String DEFAULT_WORKING_DIRECTORY = "./"; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String workingDirectoryString; File workingDirectory; // Get the task arguments. workingDirectoryString = getStringArgument( taskConfig, ARG_WORKING_DIRECTORY, getDefaultStringArgument(taskConfig, DEFAULT_WORKING_DIRECTORY) ); // Convert argument strings to strongly typed objects. workingDirectory = new File(workingDirectoryString); return new RunnableTaskManager( taskConfig.getId(), new ReplicationFileMerger( workingDirectory ), taskConfig.getPipeArgs() ); } } ReplicationFileMergerInitializer.java000066400000000000000000000046321253404521400413770ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.v0_6; import java.io.File; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.task.common.RunnableTask; import org.openstreetmap.osmosis.core.util.FileBasedLock; import org.openstreetmap.osmosis.core.util.ResourceFileManager; /** * Initialises the working directory for the replication file merger task. */ public class ReplicationFileMergerInitializer implements RunnableTask { private static final String LOCK_FILE_NAME = "download.lock"; private static final String CONFIG_FILE_NAME = "configuration.txt"; private static final String CONFIG_RESOURCE = "impl/replicationFileMergerConfiguration.txt"; private static final String DATA_DIRECTORY = "data"; private File workingDirectory; /** * Creates a new instance. * * @param workingDirectory * The directory containing configuration and tracking files. */ public ReplicationFileMergerInitializer(File workingDirectory) { this.workingDirectory = workingDirectory; } /** * Initializes a working directory. */ private void initializeDirectory() { File configFile; File dataDirectory; ResourceFileManager resourceFileManager; // Instantiate utility objects. resourceFileManager = new ResourceFileManager(); // Build file objects from file names. configFile = new File(workingDirectory, CONFIG_FILE_NAME); // Copy the template configuration file into the working directory. if (configFile.exists()) { throw new OsmosisRuntimeException("Config file " + configFile + " already exists."); } resourceFileManager.copyResourceToFile(getClass(), CONFIG_RESOURCE, configFile); // Create the data directory. dataDirectory = new File(workingDirectory, DATA_DIRECTORY); if (dataDirectory.exists()) { throw new OsmosisRuntimeException("Data directory " + dataDirectory + " already exists."); } if (!dataDirectory.mkdir()) { throw new OsmosisRuntimeException("Unable to create data directory " + dataDirectory + "."); } } /** * {@inheritDoc} */ @Override public void run() { FileBasedLock fileLock; fileLock = new FileBasedLock(new File(workingDirectory, LOCK_FILE_NAME)); try { fileLock.lock(); initializeDirectory(); fileLock.unlock(); } finally { fileLock.release(); } } } ReplicationFileMergerInitializerFactory.java000066400000000000000000000025641253404521400427310ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.v0_6; import java.io.File; import org.openstreetmap.osmosis.core.pipeline.common.RunnableTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; /** * The task manager factory for a replication file merger initializer. */ public class ReplicationFileMergerInitializerFactory extends TaskManagerFactory { private static final String ARG_WORKING_DIRECTORY = "workingDirectory"; private static final String DEFAULT_WORKING_DIRECTORY = "./"; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String workingDirectoryString; File workingDirectory; // Get the task arguments. workingDirectoryString = getStringArgument( taskConfig, ARG_WORKING_DIRECTORY, getDefaultStringArgument(taskConfig, DEFAULT_WORKING_DIRECTORY) ); // Convert argument strings to strongly typed objects. workingDirectory = new File(workingDirectoryString); return new RunnableTaskManager( taskConfig.getId(), new ReplicationFileMergerInitializer( workingDirectory ), taskConfig.getPipeArgs() ); } } ReplicationLagReader.java000066400000000000000000000111761253404521400370010ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.v0_6; import java.io.File; import java.text.MessageFormat; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.task.common.RunnableTask; import org.openstreetmap.osmosis.core.util.FileBasedLock; import org.openstreetmap.osmosis.core.util.PropertiesPersister; import org.openstreetmap.osmosis.replication.common.ReplicationState; import org.openstreetmap.osmosis.replication.common.ServerStateReader; import org.openstreetmap.osmosis.replication.v0_6.impl.ReplicationDownloaderConfiguration; /** * Compares the timestamp of a local replication directory and the timestamp on the * HTTP server that is configured to provide the replication files. It calculates * the number of seconds the local replication directory is behind the HTTP server * and prints it to stdout. * * @author Peter Koerner */ public class ReplicationLagReader implements RunnableTask { private static final Logger LOG = Logger.getLogger(ReplicationLagReader.class.getName()); private static final String LOCK_FILE_NAME = "download.lock"; private static final String CONFIG_FILE = "configuration.txt"; private static final String LOCAL_STATE_FILE = "state.txt"; private boolean humanReadable; private File workingDirectory; private ServerStateReader serverStateReader; /** * Creates a new instance. * * @param workingDirectory * The directory containing configuration and tracking files. * @param humanReadable * Print the replication lag in a Hours, Minutes and Seconds * instead of the raw number of seconds */ public ReplicationLagReader(File workingDirectory, boolean humanReadable) { this.workingDirectory = workingDirectory; this.humanReadable = humanReadable; serverStateReader = new ServerStateReader(); } /** * Calculate the replication lag and print it to stdout */ private void getLag() { ReplicationDownloaderConfiguration configuration; ReplicationState serverState; ReplicationState localState; PropertiesPersister localStatePersistor; // Instantiate utility objects. configuration = new ReplicationDownloaderConfiguration(new File(workingDirectory, CONFIG_FILE)); // Obtain the server state. LOG.fine("Reading current server state."); serverState = serverStateReader.getServerState(configuration.getBaseUrl()); // Build the local state persister which is used for both loading and storing local state. localStatePersistor = new PropertiesPersister(new File(workingDirectory, LOCAL_STATE_FILE)); // If local state isn't available we need to fail because no lag can be calculated. if (!localStatePersistor.exists()) { throw new OsmosisRuntimeException("Can't read local state."); } // fetch the local state from the file localState = new ReplicationState(localStatePersistor.loadMap()); // extract the time of the local and the remote state files long local = localState.getTimestamp().getTime(); long server = serverState.getTimestamp().getTime(); // we assume the server being before the local state while calculating the difference long lag = (server - local) / 1000; // check if a human readable version is requested if (this.humanReadable) { if (lag > 86400) { // more than a day Object[] args = { new Long(lag / 86400), new Long((lag % 86400) / 3600) }; System.out.println( new MessageFormat("{0} day(s) and {1} hour(s)").format(args) ); } else if (lag > 3600) { // morte than an hour Object[] args = { new Long(lag / 3600), new Long((lag % 3600) / 60) }; System.out.println( new MessageFormat("{0} hour(s) and {1} minute(s)").format(args) ); } else if (lag > 60) { // more than a minute Object[] args = { new Long(lag / 60), new Long(lag % 60) }; System.out.println( new MessageFormat("{0} minute(s) and {1} second(s)").format(args) ); } else { Object[] args = { new Long(lag) }; // just some seconds System.out.println( new MessageFormat("{0} second(s)").format(args) ); } } else { // print out the raw number of seconds System.out.println(lag); } } /** * {@inheritDoc} */ @Override public void run() { FileBasedLock fileLock; fileLock = new FileBasedLock(new File(workingDirectory, LOCK_FILE_NAME)); try { fileLock.lock(); getLag(); fileLock.unlock(); } finally { fileLock.release(); } } } ReplicationLagReaderFactory.java000066400000000000000000000032221253404521400403220ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.v0_6; import java.io.File; import org.openstreetmap.osmosis.core.pipeline.common.RunnableTaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; /** * The task manager factory for a replication lag reader. * * @author Peter Koerner */ public class ReplicationLagReaderFactory extends TaskManagerFactory { private static final String ARG_HUMAN_READABLE = "humanReadable"; private static final boolean DEFAULT_HUMAN_READABLE = false; private static final String ARG_WORKING_DIRECTORY = "workingDirectory"; private static final String DEFAULT_WORKING_DIRECTORY = "./"; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String workingDirectoryString; boolean humanReadableFlag; File workingDirectory; // Get the task arguments. workingDirectoryString = getStringArgument( taskConfig, ARG_WORKING_DIRECTORY, getDefaultStringArgument(taskConfig, DEFAULT_WORKING_DIRECTORY) ); humanReadableFlag = getBooleanArgument( taskConfig, ARG_HUMAN_READABLE, DEFAULT_HUMAN_READABLE ); // Convert argument strings to strongly typed objects. workingDirectory = new File(workingDirectoryString); return new RunnableTaskManager( taskConfig.getId(), new ReplicationLagReader( workingDirectory, humanReadableFlag ), taskConfig.getPipeArgs() ); } } ReplicationStateWriter.java000066400000000000000000000072421253404521400374270ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.v0_6; import java.io.File; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.util.FileBasedLock; import org.openstreetmap.osmosis.core.util.PropertiesPersister; import org.openstreetmap.osmosis.replication.common.ReplicationState; /** * This class manages persistence of state for replication streams into a state * properties file. If used alone, it will store the state for a replication * pipeline, and will discard the output. It can be used within a larger task * performing processing on the replication data. It supports the initialize and * complete method being called multiple times to signify multiple replication * intervals being called within a single pipeline run. * * @author Brett Henderson */ public class ReplicationStateWriter implements ChangeSink { private static final Logger LOG = Logger.getLogger(ReplicationStateWriter.class.getName()); private static final String LOCK_FILE = "replicate.lock"; private static final String STATE_FILE = "state.txt"; private FileBasedLock fileLock; private boolean lockObtained; private PropertiesPersister statePersistor; private ReplicationState state; /** * Creates a new instance. * * @param workingDirectory * The directory containing configuration and tracking files. */ public ReplicationStateWriter(File workingDirectory) { // Create the lock object used to ensure only a single process attempts // to write to the data directory. fileLock = new FileBasedLock(new File(workingDirectory, LOCK_FILE)); // Create the object used to persist current state. statePersistor = new PropertiesPersister(new File(workingDirectory, STATE_FILE)); } @Override public void initialize(Map metaData) { if (lockObtained) { throw new OsmosisRuntimeException("initialize has already been called"); } // Lock the working directory. fileLock.lock(); lockObtained = true; // Get the replication state from the upstream task. if (!metaData.containsKey(ReplicationState.META_DATA_KEY)) { throw new OsmosisRuntimeException("No replication state has been provided in metadata key " + ReplicationState.META_DATA_KEY + "."); } state = (ReplicationState) metaData.get(ReplicationState.META_DATA_KEY); // Populate the state from the existing state if it exists. if (statePersistor.exists()) { state.load(statePersistor.loadMap()); // The current sequence number must now be incremented. state.setSequenceNumber(state.getSequenceNumber() + 1); if (LOG.isLoggable(Level.FINER)) { LOG.finer("Replication sequence number is " + state.getSequenceNumber() + "."); } } } @Override public void process(ChangeContainer change) { if (!lockObtained) { throw new OsmosisRuntimeException("initialize has not been called"); } if (state.getSequenceNumber() == 0) { throw new OsmosisRuntimeException("No changes can be included for replication sequence 0."); } } @Override public void complete() { if (!lockObtained) { throw new OsmosisRuntimeException("initialize has not been called"); } // Write the global state file. statePersistor.store(state.store()); state = null; // Release the lock. fileLock.unlock(); lockObtained = false; } @Override public void release() { state = null; fileLock.release(); lockObtained = false; } } ReplicationToChangeWriter.java000066400000000000000000000053611253404521400400370ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.v0_6; import java.io.File; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSinkChangeSource; import org.openstreetmap.osmosis.replication.common.ReplicationState; /** * This task allows a replication stream to be converted to a standard change * stream. It handles the state persistence required by a replication sink, and * then passes the replication data to a standard change sink destination. A * typical use case would be receiving a replication stream live from a * database, then applying those changes to another database where the change * applier task doesn't support the replication metadata extensions. * * @author Brett Henderson */ public class ReplicationToChangeWriter implements ChangeSinkChangeSource { /** * This handles and persists the replication metadata. */ private ReplicationStateWriter stateWriter; private ReplicationState state; private ChangeSink changeSink; /** * Creates a new instance. * * @param workingDirectory * The directory containing configuration and tracking files. */ public ReplicationToChangeWriter(File workingDirectory) { stateWriter = new ReplicationStateWriter(workingDirectory); } @Override public void setChangeSink(ChangeSink changeSink) { this.changeSink = changeSink; } @Override public void initialize(Map metaData) { // Initialise the replication meta data. stateWriter.initialize(metaData); // Get the replication state for this pipeline run. state = (ReplicationState) metaData.get(ReplicationState.META_DATA_KEY); // Initialise the downstream tasks passing everything except the // replication state. if (state.getSequenceNumber() > 0) { Map downstreamMetaData = new HashMap(metaData); downstreamMetaData.remove(ReplicationState.META_DATA_KEY); changeSink.initialize(downstreamMetaData); } } @Override public void process(ChangeContainer change) { // Perform replication checks. stateWriter.process(change); // Pass the change downstream. changeSink.process(change); } @Override public void complete() { // We must complete downstream before we complete the replication writer // so that we know the replication data has been committed before we // persist replication state. if (state.getSequenceNumber() > 0) { changeSink.complete(); } stateWriter.complete(); } @Override public void release() { changeSink.release(); stateWriter.release(); } } ReplicationToChangeWriterFactory.java000066400000000000000000000025271253404521400413700ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.v0_6; import java.io.File; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.ChangeSinkChangeSourceManager; /** * The task manager factory for a replication to change writer. */ public class ReplicationToChangeWriterFactory extends TaskManagerFactory { private static final String ARG_WORKING_DIRECTORY = "workingDirectory"; private static final String DEFAULT_WORKING_DIRECTORY = "./"; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String workingDirectoryString; File workingDirectory; // Get the task arguments. workingDirectoryString = getStringArgument(taskConfig, ARG_WORKING_DIRECTORY, getDefaultStringArgument(taskConfig, DEFAULT_WORKING_DIRECTORY)); // Convert argument strings to strongly typed objects. workingDirectory = new File(workingDirectoryString); return new ChangeSinkChangeSourceManager( taskConfig.getId(), new ReplicationToChangeWriter(workingDirectory), taskConfig.getPipeArgs()); } } ReplicationWriter.java000066400000000000000000000051021253404521400364170ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.v0_6; import java.io.File; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.replication.common.FileReplicationStore; import org.openstreetmap.osmosis.replication.common.ReplicationState; import org.openstreetmap.osmosis.replication.common.ReplicationStore; import org.openstreetmap.osmosis.xml.v0_6.XmlChangeWriter; /** * This class receives replication streams and writes them to replication files. * It supports the initialize and complete method being called multiple times to * signify multiple replication intervals and each will be written to a * different replication file with a unique sequence number. * * @author Brett Henderson */ public class ReplicationWriter implements ChangeSink { private ReplicationStore replicationStore; private ReplicationStateWriter stateWriter; private ReplicationState state; private XmlChangeWriter changeWriter; /** * Creates a new instance. * * @param workingDirectory * The directory containing configuration and tracking files. */ public ReplicationWriter(File workingDirectory) { replicationStore = new FileReplicationStore(workingDirectory, false); stateWriter = new ReplicationStateWriter(workingDirectory); } @Override public void initialize(Map metaData) { // Initialise the replication meta data. stateWriter.initialize(metaData); // Get the replication state for this pipeline run. state = (ReplicationState) metaData.get(ReplicationState.META_DATA_KEY); // Initialize a new change writer for the current sequence number. if (state.getSequenceNumber() > 0) { changeWriter = replicationStore.saveData(state.getSequenceNumber()); } } @Override public void process(ChangeContainer change) { changeWriter.process(change); } @Override public void complete() { if (state.getSequenceNumber() > 0) { // Complete the writing of the change file. changeWriter.complete(); changeWriter.release(); changeWriter = null; } // Write the sequenced state file. replicationStore.saveState(state); // We must only complete the state writer after we've finished writing // the replication data and sequence numbered state. stateWriter.complete(); } @Override public void release() { if (changeWriter != null) { changeWriter.release(); changeWriter = null; } stateWriter.release(); } } ReplicationWriterFactory.java000066400000000000000000000024561253404521400377600ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.v0_6; import java.io.File; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.ChangeSinkManager; /** * The task manager factory for a replication file downloader. */ public class ReplicationWriterFactory extends TaskManagerFactory { private static final String ARG_WORKING_DIRECTORY = "workingDirectory"; private static final String DEFAULT_WORKING_DIRECTORY = "./"; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String workingDirectoryString; File workingDirectory; // Get the task arguments. workingDirectoryString = getStringArgument(taskConfig, ARG_WORKING_DIRECTORY, getDefaultStringArgument(taskConfig, DEFAULT_WORKING_DIRECTORY)); // Convert argument strings to strongly typed objects. workingDirectory = new File(workingDirectoryString); return new ChangeSinkManager( taskConfig.getId(), new ReplicationWriter(workingDirectory), taskConfig.getPipeArgs()); } } osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/impl/000077500000000000000000000000001253404521400331305ustar00rootroot00000000000000ChangesetFileNameFormatter.java000066400000000000000000000031051253404521400411010ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.v0_6.impl; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import java.util.TimeZone; /** * This class will generate changeset filenames. * * @author Brett Henderson */ public class ChangesetFileNameFormatter { private DateFormat beginDateFormat; private DateFormat endDateFormat; /** * Creates a new instance. * * @param beginFileNameFormat * The date format of the beginning of the filename. * @param endFileNameFormat * The date format of the end of the filename. */ public ChangesetFileNameFormatter(String beginFileNameFormat, String endFileNameFormat) { TimeZone utcTimezone; utcTimezone = TimeZone.getTimeZone("UTC"); beginDateFormat = new SimpleDateFormat(beginFileNameFormat, Locale.US); endDateFormat = new SimpleDateFormat(endFileNameFormat, Locale.US); beginDateFormat.setTimeZone(utcTimezone); endDateFormat.setTimeZone(utcTimezone); } /** * Generates an appropriate file name based on the input dates. * * @param intervalBegin * The beginning of the time interval. * @param intervalEnd * The end of the time interval. * @return The file name. */ public String generateFileName(Date intervalBegin, Date intervalEnd) { String fileName; fileName = beginDateFormat.format(intervalBegin) + "-" + endDateFormat.format(intervalEnd) + ".osc.gz"; return fileName; } } IntervalDownloaderConfiguration.java000066400000000000000000000043571253404521400422600ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.v0_6.impl; import java.io.File; import java.util.Properties; import org.openstreetmap.osmosis.core.util.PropertiesPersister; /** * Loads and exposes the extraction configuration properties. * * @author Brett Henderson */ public class IntervalDownloaderConfiguration { private static final String KEY_BASE_URL = "baseUrl"; private static final String KEY_CHANGE_FILE_BEGIN_FORMAT = "changeFileBeginFormat"; private static final String KEY_CHANGE_FILE_END_FORMAT = "changeFileEndFormat"; private static final String KEY_INTERVAL_LENGTH = "intervalLength"; private static final String KEY_MAX_DOWNLOAD_COUNT = "maxDownloadCount"; private Properties properties; /** * Creates a new instance. * * @param configFile * The configuration file to read from. */ public IntervalDownloaderConfiguration(File configFile) { properties = new PropertiesPersister(configFile).load(); } /** * Returns the URL that change files should be downloaded from. * * @return The download URL. */ public String getBaseUrl() { String baseUrl; baseUrl = properties.getProperty(KEY_BASE_URL); if (!baseUrl.substring(baseUrl.length() - 1).equals("/")) { baseUrl += "/"; } return baseUrl; } /** * Returns the begin time portion of the changeset filename. * * @return The format. */ public String getChangeFileBeginFormat() { return properties.getProperty(KEY_CHANGE_FILE_BEGIN_FORMAT); } /** * Returns the end time portion of the changeset filename. * * @return The format. */ public String getChangeFileEndFormat() { return properties.getProperty(KEY_CHANGE_FILE_END_FORMAT); } /** * Returns the duration of each changeset interval. * * @return The interval length in milliseconds. */ public int getIntervalLength() { return Integer.parseInt(properties.getProperty(KEY_INTERVAL_LENGTH)) * 1000; } /** * Returns the maximum number of files to download in a single invocation. * * @return The maximum download count. */ public int getMaxDownloadCount() { return Integer.parseInt(properties.getProperty(KEY_MAX_DOWNLOAD_COUNT)); } } ReplicationDownloaderConfiguration.java000066400000000000000000000032411253404521400427340ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.v0_6.impl; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.util.Properties; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.util.PropertiesPersister; /** * Loads and exposes the configuration properties for downloading replication history. * * @author Brett Henderson */ public class ReplicationDownloaderConfiguration { private static final String KEY_BASE_URL = "baseUrl"; private static final String KEY_MAX_INTERVAL = "maxInterval"; private Properties properties; /** * Creates a new instance. * * @param configFile * The configuration file to read from. */ public ReplicationDownloaderConfiguration(File configFile) { properties = new PropertiesPersister(configFile).load(); } /** * Returns the URL that change files should be downloaded from. * * @return The download URL. */ public URL getBaseUrl() { String baseUrl; baseUrl = properties.getProperty(KEY_BASE_URL); if (!baseUrl.substring(baseUrl.length() - 1).equals("/")) { baseUrl += "/"; } try { return new URL(baseUrl); } catch (MalformedURLException e) { throw new OsmosisRuntimeException( "Unable to convert URL string (" + baseUrl + ") into a URL.", e); } } /** * Returns the maximum interval to be downloaded in a single invocation. * * @return The maximum download interval. */ public int getMaxInterval() { return Integer.parseInt(properties.getProperty(KEY_MAX_INTERVAL)) * 1000; } } ReplicationFileMergerConfiguration.java000066400000000000000000000017311253404521400426610ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.v0_6.impl; import java.io.File; import java.util.Properties; import org.openstreetmap.osmosis.core.util.PropertiesPersister; /** * Loads and exposes the configuration properties for replication file merging. */ public class ReplicationFileMergerConfiguration { private static final String KEY_INTERVAL_LENGTH = "intervalLength"; private Properties properties; /** * Creates a new instance. * * @param configFile * The configuration file to read from. */ public ReplicationFileMergerConfiguration(File configFile) { properties = new PropertiesPersister(configFile).load(); } /** * Returns the duration of each changeset interval. * * @return The interval length in milliseconds. */ public int getIntervalLength() { return Integer.parseInt(properties.getProperty(KEY_INTERVAL_LENGTH)) * 1000; } } osmosis-0.44.1/osmosis-replication/src/main/resources/000077500000000000000000000000001253404521400230245ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/resources/org/000077500000000000000000000000001253404521400236135ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/resources/org/openstreetmap/000077500000000000000000000000001253404521400265015ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/resources/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400301755ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/resources/org/openstreetmap/osmosis/replication/000077500000000000000000000000001253404521400325065ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/resources/org/openstreetmap/osmosis/replication/v0_6/000077500000000000000000000000001253404521400332605ustar00rootroot00000000000000000077500000000000000000000000001253404521400341425ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/resources/org/openstreetmap/osmosis/replication/v0_6/implintervalConfiguration.txt000066400000000000000000000013071253404521400412600ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/resources/org/openstreetmap/osmosis/replication/v0_6/impl# The URL of the directory containing change files. baseUrl=http://planet.openstreetmap.org/replication/hour # The length of an extraction interval in seconds (3600 = 1 hour). intervalLength=3600 # Define the changeset filename format. The format is {changeFileBeginFormat}-{changeFileEndFormat}.osc. # Be careful to pick a format that won't result in duplicate names for the specified interval size. # Change file begin format changeFileBeginFormat=yyyyMMddHH changeFileEndFormat=yyyyMMddHH # Defines the maximum number of files to download in a single invocation. # There will be approximately two threads created for every downloaded file. # Setting this to 0 disables this feature. maxDownloadCount = 20replicationDownloaderConfiguration.txt000066400000000000000000000003741253404521400437670ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/resources/org/openstreetmap/osmosis/replication/v0_6/impl# The URL of the directory containing change files. baseUrl=http://planet.openstreetmap.org/replication/minute # Defines the maximum time interval in seconds to download in a single invocation. # Setting to 0 disables this feature. maxInterval = 3600 replicationFileMergerConfiguration.txt000066400000000000000000000005221253404521400437050ustar00rootroot00000000000000osmosis-0.44.1/osmosis-replication/src/main/resources/org/openstreetmap/osmosis/replication/v0_6/impl# The URL of the directory containing change files. baseUrl=http://planet.openstreetmap.org/replication/minute # The length of an extraction interval in seconds (3600 = 1 hour). intervalLength=60 # Defines the maximum time interval in seconds to download in a single invocation. # Setting to 0 disables this feature. maxInterval = 3600 osmosis-0.44.1/osmosis-replication/src/main/resources/osmosis-plugins.conf000066400000000000000000000000751253404521400270500ustar00rootroot00000000000000org.openstreetmap.osmosis.replication.ReplicationPluginLoaderosmosis-0.44.1/osmosis-set/000077500000000000000000000000001253404521400155615ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/.checkstyle000066400000000000000000000010051253404521400177140ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/.gitignore000066400000000000000000000000531253404521400175470ustar00rootroot00000000000000.classpath .project .settings /bin /build osmosis-0.44.1/osmosis-set/build.gradle000066400000000000000000000002131253404521400200340ustar00rootroot00000000000000dependencies { compile project(':osmosis-core') testCompile project(':osmosis-testutil') testCompile project(':osmosis-xml') } osmosis-0.44.1/osmosis-set/src/000077500000000000000000000000001253404521400163505ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/main/000077500000000000000000000000001253404521400172745ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/main/java/000077500000000000000000000000001253404521400202155ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/main/java/org/000077500000000000000000000000001253404521400210045ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/main/java/org/openstreetmap/000077500000000000000000000000001253404521400236725ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/main/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400253665ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/main/java/org/openstreetmap/osmosis/set/000077500000000000000000000000001253404521400261615ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/main/java/org/openstreetmap/osmosis/set/SetPluginLoader.java000066400000000000000000000052701253404521400320710ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.plugin.PluginLoader; import org.openstreetmap.osmosis.set.v0_6.ChangeAppenderFactory; import org.openstreetmap.osmosis.set.v0_6.ChangeApplierFactory; import org.openstreetmap.osmosis.set.v0_6.ChangeDeriverFactory; import org.openstreetmap.osmosis.set.v0_6.ChangeMergerFactory; import org.openstreetmap.osmosis.set.v0_6.ChangeSimplifierFactory; import org.openstreetmap.osmosis.set.v0_6.ChangeToFullHistoryConvertorFactory; import org.openstreetmap.osmosis.set.v0_6.EntityMergerFactory; import org.openstreetmap.osmosis.set.v0_6.FlattenFilterFactory; /** * The plugin loader for the Set manipulation tasks. * * @author Brett Henderson */ public class SetPluginLoader implements PluginLoader { /** * {@inheritDoc} */ @Override public Map loadTaskFactories() { Map factoryMap; factoryMap = new HashMap(); factoryMap.put("apply-change", new ChangeApplierFactory()); factoryMap.put("ac", new ChangeApplierFactory()); factoryMap.put("derive-change", new ChangeDeriverFactory()); factoryMap.put("dc", new ChangeDeriverFactory()); factoryMap.put("flatten", new FlattenFilterFactory()); factoryMap.put("f", new FlattenFilterFactory()); factoryMap.put("merge", new EntityMergerFactory()); factoryMap.put("m", new EntityMergerFactory()); factoryMap.put("merge-change", new ChangeMergerFactory()); factoryMap.put("mc", new ChangeMergerFactory()); factoryMap.put("append-change", new ChangeAppenderFactory()); factoryMap.put("apc", new ChangeAppenderFactory()); factoryMap.put("simplify-change", new ChangeSimplifierFactory()); factoryMap.put("simc", new ChangeSimplifierFactory()); factoryMap.put("convert-change-to-full-history", new ChangeToFullHistoryConvertorFactory()); factoryMap.put("cctfh", new ChangeToFullHistoryConvertorFactory()); factoryMap.put("apply-change-0.6", new ChangeApplierFactory()); factoryMap.put("derive-change-0.6", new ChangeDeriverFactory()); factoryMap.put("flatten-0.6", new FlattenFilterFactory()); factoryMap.put("merge-0.6", new EntityMergerFactory()); factoryMap.put("merge-change-0.6", new ChangeMergerFactory()); factoryMap.put("append-change-0.6", new ChangeAppenderFactory()); factoryMap.put("simplify-change-0.6", new ChangeSimplifierFactory()); factoryMap.put("convert-change-to-full-history-0.6", new ChangeToFullHistoryConvertorFactory()); return factoryMap; } } osmosis-0.44.1/osmosis-set/src/main/java/org/openstreetmap/osmosis/set/v0_6/000077500000000000000000000000001253404521400267335ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/main/java/org/openstreetmap/osmosis/set/v0_6/BoundRemovedAction.java000066400000000000000000000023701253404521400333270ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Defines possible actions to take when a task removes * a bound entity from the output stream. */ public enum BoundRemovedAction { /** * Continue processing quietly. */ Ignore ("ignore"), /** * Continue processing but emit a warning to the log. */ Warn ("warn"), /** * Stop processing and emit an error message to the log. */ Fail ("fail"); private final String keyword; private BoundRemovedAction(String keyword) { this.keyword = keyword; } /** * Returns an action for a given string, if possible. * * @param s the string to parse * @return an action corresponding to a string, if it exists. */ public static BoundRemovedAction parse(String s) { if (s == null) { throw new OsmosisRuntimeException( "Unrecognized bound removed action value: must be one of ignore, warn, fail."); } for (BoundRemovedAction a : values()) { if (a.keyword.equals(s.toLowerCase())) { return a; } } throw new OsmosisRuntimeException( "Unrecognized bound removed action value: must be one of ignore, warn, fail."); } } osmosis-0.44.1/osmosis-set/src/main/java/org/openstreetmap/osmosis/set/v0_6/ChangeAppender.java000066400000000000000000000056661253404521400324570ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.set.v0_6.impl.DataPostboxChangeSink; import org.openstreetmap.osmosis.core.store.DataPostbox; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.MultiChangeSinkRunnableChangeSource; /** * Combines multiple change sources into a single data set. It is done by writing the contents of * each of the input sources to the sink in order. * * @author Brett Henderson */ public class ChangeAppender implements MultiChangeSinkRunnableChangeSource { private List> sources; private ChangeSink changeSink; /** * Creates a new instance. * * @param sourceCount * The number of sources to be appended. * @param inputBufferCapacity * The capacity of the buffer to use for each source, in objects. */ public ChangeAppender(int sourceCount, int inputBufferCapacity) { sources = new ArrayList>(sourceCount); for (int i = 0; i < sourceCount; i++) { sources.add(new DataPostbox(inputBufferCapacity)); } } /** * {@inheritDoc} */ @Override public ChangeSink getChangeSink(int instance) { if (instance < 0 || instance >= sources.size()) { throw new OsmosisRuntimeException("Sink instance " + instance + " is not valid."); } return new DataPostboxChangeSink(sources.get(instance)); } /** * {@inheritDoc} */ @Override public int getChangeSinkCount() { return sources.size(); } /** * {@inheritDoc} */ @Override public void setChangeSink(ChangeSink changeSink) { this.changeSink = changeSink; } /** * {@inheritDoc} */ @Override public void run() { try { Map metaData; metaData = new HashMap(); // Get the initialization data from each source in turn and merge // it. If the same data exists in multiple sources the last will // win. for (DataPostbox source : sources) { metaData.putAll(source.outputInitialize()); } changeSink.initialize(metaData); // Write the data from each source to the sink in turn. for (DataPostbox source : sources) { while (source.hasNext()) { changeSink.process(source.getNext()); } } changeSink.complete(); // Complete all input sources. for (DataPostbox source : sources) { source.outputComplete(); } } finally { changeSink.release(); // Release all input sources. for (DataPostbox source : sources) { source.outputRelease(); } } } } ChangeAppenderFactory.java000066400000000000000000000025661253404521400337240ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/main/java/org/openstreetmap/osmosis/set/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.MultiChangeSinkRunnableChangeSourceManager; /** * The task manager factory for a change appender. * * @author Brett Henderson */ public class ChangeAppenderFactory extends TaskManagerFactory { private static final String ARG_SOURCE_COUNT = "sourceCount"; private static final int DEFAULT_SOURCE_COUNT = 2; private static final String ARG_BUFFER_CAPACITY = "bufferCapacity"; private static final int DEFAULT_BUFFER_CAPACITY = 20; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { int sourceCount; sourceCount = getIntegerArgument(taskConfig, ARG_SOURCE_COUNT, DEFAULT_SOURCE_COUNT); int bufferCapacity = getIntegerArgument( taskConfig, ARG_BUFFER_CAPACITY, getDefaultIntegerArgument(taskConfig, DEFAULT_BUFFER_CAPACITY) ); return new MultiChangeSinkRunnableChangeSourceManager( taskConfig.getId(), new ChangeAppender(sourceCount, bufferCapacity), taskConfig.getPipeArgs() ); } } osmosis-0.44.1/osmosis-set/src/main/java/org/openstreetmap/osmosis/set/v0_6/ChangeApplier.java000066400000000000000000000160271253404521400323060ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.sort.v0_6.EntityByTypeThenIdComparator; import org.openstreetmap.osmosis.core.sort.v0_6.EntityContainerComparator; import org.openstreetmap.osmosis.core.sort.v0_6.SortedDeltaChangePipeValidator; import org.openstreetmap.osmosis.core.sort.v0_6.SortedEntityPipeValidator; import org.openstreetmap.osmosis.core.store.DataPostbox; import org.openstreetmap.osmosis.core.task.common.ChangeAction; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.MultiSinkMultiChangeSinkRunnableSource; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.set.v0_6.impl.DataPostboxChangeSink; import org.openstreetmap.osmosis.set.v0_6.impl.DataPostboxSink; /** * Applies a change set to an input source and produces an updated data set. * * @author Brett Henderson */ public class ChangeApplier implements MultiSinkMultiChangeSinkRunnableSource { private Sink sink; private DataPostbox basePostbox; private SortedEntityPipeValidator sortedEntityValidator; private DataPostbox changePostbox; private SortedDeltaChangePipeValidator sortedChangeValidator; /** * Creates a new instance. * * @param inputBufferCapacity * The size of the buffers to use for input sources. */ public ChangeApplier(int inputBufferCapacity) { basePostbox = new DataPostbox(inputBufferCapacity); sortedEntityValidator = new SortedEntityPipeValidator(); sortedEntityValidator.setSink(new DataPostboxSink(basePostbox)); changePostbox = new DataPostbox(inputBufferCapacity); sortedChangeValidator = new SortedDeltaChangePipeValidator(); sortedChangeValidator.setChangeSink(new DataPostboxChangeSink(changePostbox)); } /** * {@inheritDoc} */ public Sink getSink(int instance) { if (instance != 0) { throw new OsmosisRuntimeException("Sink instance " + instance + " is not valid."); } return sortedEntityValidator; } /** * This implementation always returns 1. * * @return 1 */ public int getSinkCount() { return 1; } /** * {@inheritDoc} */ public ChangeSink getChangeSink(int instance) { if (instance != 0) { throw new OsmosisRuntimeException("Change sink instance " + instance + " is not valid."); } return sortedChangeValidator; } /** * This implementation always returns 1. * * @return 1 */ public int getChangeSinkCount() { return 1; } /** * {@inheritDoc} */ public void setSink(Sink sink) { this.sink = sink; } /** * Processes an entity that exists on the base source but not the change * source. * * @param entityContainer * The entity to be processed. */ private void processBaseOnlyEntity(EntityContainer entityContainer) { // The base entity doesn't exist on the change source therefore we // simply pass it through. sink.process(entityContainer); } /** * Processes a change for an entity that exists on the change source but not * the base source. * * @param changeContainer * The change to be processed. */ private void processChangeOnlyEntity(ChangeContainer changeContainer) { // This entity doesn't exist in the "base" source therefore // we would normally expect a create. // But to cover cases where the change is being re-applied or it is a // previously deleted item which will show as a modify we need to be // lenient with error checking. // It is also possible that a delete will come through for a // previously deleted item which can be ignored. if (changeContainer.getAction().equals(ChangeAction.Create) || changeContainer.getAction().equals(ChangeAction.Modify)) { sink.process(changeContainer.getEntityContainer()); } } /** * Processes a change for an entity that exists on both the base source and * the change source. * * @param changeContainer * The change to be processed. */ private void processBothSourceEntity(EntityContainer entityContainer, ChangeContainer changeContainer) { // The same entity exists in both sources therefore we are // expecting a modify or delete. However a create is possible if the // data is being re-applied so we need to be lenient. if (changeContainer.getAction().equals(ChangeAction.Create) || changeContainer.getAction().equals(ChangeAction.Modify)) { sink.process(changeContainer.getEntityContainer()); } } /** * Processes the input sources and sends the updated data stream to the * sink. */ public void run() { try { EntityContainerComparator comparator; EntityContainer base = null; ChangeContainer change = null; Map metaData; // Create a comparator for comparing two entities by type and identifier. comparator = new EntityContainerComparator(new EntityByTypeThenIdComparator()); // Initialise the pipeline with a combination of the metadata from // both inputs. The change stream metadata will be applied second // and will override any values with the same key. metaData = new HashMap(); metaData.putAll(basePostbox.outputInitialize()); metaData.putAll(changePostbox.outputInitialize()); sink.initialize(metaData); // We continue in the comparison loop while both sources still have data. while ((base != null || basePostbox.hasNext()) && (change != null || changePostbox.hasNext())) { int comparisonResult; // Get the next input data where required. if (base == null) { base = basePostbox.getNext(); } if (change == null) { change = changePostbox.getNext(); } // Compare the two sources. comparisonResult = comparator.compare(base, change.getEntityContainer()); if (comparisonResult < 0) { processBaseOnlyEntity(base); base = null; } else if (comparisonResult > 0) { processChangeOnlyEntity(change); change = null; } else { processBothSourceEntity(base, change); base = null; change = null; } } // Any remaining "base" entities are unmodified. while (base != null || basePostbox.hasNext()) { if (base == null) { base = basePostbox.getNext(); } processBaseOnlyEntity(base); base = null; } // Process any remaining "change" entities. while (change != null || changePostbox.hasNext()) { if (change == null) { change = changePostbox.getNext(); } processChangeOnlyEntity(change); change = null; } sink.complete(); basePostbox.outputComplete(); changePostbox.outputComplete(); } finally { sink.release(); basePostbox.outputRelease(); changePostbox.outputRelease(); } } } ChangeApplierFactory.java000066400000000000000000000022111253404521400335450ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/main/java/org/openstreetmap/osmosis/set/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.MultiSinkMultiChangeSinkRunnableSourceManager; /** * The task manager factory for a change applier. * * @author Brett Henderson */ public class ChangeApplierFactory extends TaskManagerFactory { private static final String ARG_BUFFER_CAPACITY = "bufferCapacity"; private static final int DEFAULT_BUFFER_CAPACITY = 20; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { int bufferCapacity = getIntegerArgument( taskConfig, ARG_BUFFER_CAPACITY, getDefaultIntegerArgument(taskConfig, DEFAULT_BUFFER_CAPACITY) ); return new MultiSinkMultiChangeSinkRunnableSourceManager( taskConfig.getId(), new ChangeApplier(bufferCapacity), taskConfig.getPipeArgs() ); } } osmosis-0.44.1/osmosis-set/src/main/java/org/openstreetmap/osmosis/set/v0_6/ChangeDeriver.java000066400000000000000000000134641253404521400323140ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6; import java.util.Collections; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.change.v0_6.impl.TimestampSetter; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.sort.v0_6.EntityByTypeThenIdComparator; import org.openstreetmap.osmosis.core.sort.v0_6.EntityContainerComparator; import org.openstreetmap.osmosis.core.store.DataPostbox; import org.openstreetmap.osmosis.core.task.common.ChangeAction; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.MultiSinkRunnableChangeSource; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.set.v0_6.impl.DataPostboxSink; /** * Compares two different data sources and produces a set of differences. * * @author Brett Henderson */ public class ChangeDeriver implements MultiSinkRunnableChangeSource { private ChangeSink changeSink; private DataPostbox fromPostbox; private DataPostboxSink fromSink; private DataPostbox toPostbox; private DataPostboxSink toSink; /** * Creates a new instance. * * @param inputBufferCapacity * The size of the buffers to use for input sources. */ public ChangeDeriver(int inputBufferCapacity) { fromPostbox = new DataPostbox(inputBufferCapacity); fromSink = new DataPostboxSink(fromPostbox); toPostbox = new DataPostbox(inputBufferCapacity); toSink = new DataPostboxSink(toPostbox); } /** * {@inheritDoc} */ public Sink getSink(int instance) { switch (instance) { case 0: return fromSink; case 1: return toSink; default: throw new OsmosisRuntimeException("Sink instance " + instance + " is not valid."); } } /** * This implementation always returns 2. * * @return 2 */ public int getSinkCount() { return 2; } /** * {@inheritDoc} */ public void setChangeSink(ChangeSink changeSink) { this.changeSink = changeSink; } /** * Processes the input sources and sends the changes to the change sink. */ public void run() { try { EntityContainerComparator comparator; EntityContainer fromEntityContainer = null; EntityContainer toEntityContainer = null; TimestampSetter timestampSetter; // Create a comparator for comparing two entities by type and identifier. comparator = new EntityContainerComparator(new EntityByTypeThenIdComparator()); // Create an object for setting the current timestamp on entities being deleted. timestampSetter = new TimestampSetter(); // We can't get meaningful data from the initialize data on the // input streams, so pass empty meta data to the sink and discard // the input meta data. fromPostbox.outputInitialize(); toPostbox.outputInitialize(); changeSink.initialize(Collections.emptyMap()); // We continue in the comparison loop while both sources still have data. while ( (fromEntityContainer != null || fromPostbox.hasNext()) && (toEntityContainer != null || toPostbox.hasNext())) { int comparisonResult; // Get the next input data where required. if (fromEntityContainer == null) { fromEntityContainer = fromPostbox.getNext(); } if (toEntityContainer == null) { toEntityContainer = toPostbox.getNext(); } // Compare the two sources. comparisonResult = comparator.compare(fromEntityContainer, toEntityContainer); if (comparisonResult < 0) { // The from entity doesn't exist on the to source therefore // has been deleted. We don't know when the entity was // deleted so set the delete time to the current time. changeSink.process( new ChangeContainer( timestampSetter.updateTimestamp(fromEntityContainer), ChangeAction.Delete)); fromEntityContainer = null; } else if (comparisonResult > 0) { // The to entity doesn't exist on the from source therefore has // been created. changeSink.process(new ChangeContainer(toEntityContainer, ChangeAction.Create)); toEntityContainer = null; } else { // The entity exists on both sources, therefore we must // compare // the entities directly. If there is a difference, the // entity has been modified. if (!fromEntityContainer.getEntity().equals(toEntityContainer.getEntity())) { changeSink.process(new ChangeContainer(toEntityContainer, ChangeAction.Modify)); } fromEntityContainer = null; toEntityContainer = null; } } // Any remaining "from" entities are deletes. while (fromEntityContainer != null || fromPostbox.hasNext()) { if (fromEntityContainer == null) { fromEntityContainer = fromPostbox.getNext(); } // The from entity doesn't exist on the to source therefore // has been deleted. We don't know when the entity was // deleted so set the delete time to the current time. changeSink.process( new ChangeContainer( timestampSetter.updateTimestamp(fromEntityContainer), ChangeAction.Delete)); fromEntityContainer = null; } // Any remaining "to" entities are creates. while (toEntityContainer != null || toPostbox.hasNext()) { if (toEntityContainer == null) { toEntityContainer = toPostbox.getNext(); } changeSink.process(new ChangeContainer(toEntityContainer, ChangeAction.Create)); toEntityContainer = null; } changeSink.complete(); fromPostbox.outputComplete(); toPostbox.outputComplete(); } finally { changeSink.release(); fromPostbox.outputRelease(); toPostbox.outputRelease(); } } } ChangeDeriverFactory.java000066400000000000000000000021711253404521400335560ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/main/java/org/openstreetmap/osmosis/set/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.MultiSinkRunnableChangeSourceManager; /** * The task manager factory for a change deriver. * * @author Brett Henderson */ public class ChangeDeriverFactory extends TaskManagerFactory { private static final String ARG_BUFFER_CAPACITY = "bufferCapacity"; private static final int DEFAULT_BUFFER_CAPACITY = 20; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { int bufferCapacity = getIntegerArgument( taskConfig, ARG_BUFFER_CAPACITY, getDefaultIntegerArgument(taskConfig, DEFAULT_BUFFER_CAPACITY) ); return new MultiSinkRunnableChangeSourceManager( taskConfig.getId(), new ChangeDeriver(bufferCapacity), taskConfig.getPipeArgs() ); } } osmosis-0.44.1/osmosis-set/src/main/java/org/openstreetmap/osmosis/set/v0_6/ChangeMerger.java000066400000000000000000000156101253404521400321300ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6; import java.util.Collections; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.merge.common.ConflictResolutionMethod; import org.openstreetmap.osmosis.core.sort.v0_6.EntityByTypeThenIdThenVersionComparator; import org.openstreetmap.osmosis.core.sort.v0_6.EntityContainerComparator; import org.openstreetmap.osmosis.core.sort.v0_6.SortedHistoryChangePipeValidator; import org.openstreetmap.osmosis.core.store.DataPostbox; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.MultiChangeSinkRunnableChangeSource; import org.openstreetmap.osmosis.set.v0_6.impl.DataPostboxChangeSink; /** * Merges two change sources into a single data set. Conflicting elements are * resolved by using either the latest timestamp (default) or always selecting * the second source. * * @author Brett Henderson */ public class ChangeMerger implements MultiChangeSinkRunnableChangeSource { private ChangeSink changeSink; private DataPostbox postbox0; private SortedHistoryChangePipeValidator sortedChangeValidator0; private DataPostbox postbox1; private SortedHistoryChangePipeValidator sortedChangeValidator1; private ConflictResolutionMethod conflictResolutionMethod; /** * Creates a new instance. * * @param conflictResolutionMethod * The method to used to resolve conflict when two sources * contain the same entity. * @param inputBufferCapacity * The size of the buffers to use for input sources. */ public ChangeMerger(ConflictResolutionMethod conflictResolutionMethod, int inputBufferCapacity) { this.conflictResolutionMethod = conflictResolutionMethod; postbox0 = new DataPostbox(inputBufferCapacity); sortedChangeValidator0 = new SortedHistoryChangePipeValidator(); sortedChangeValidator0.setChangeSink(new DataPostboxChangeSink(postbox0)); postbox1 = new DataPostbox(inputBufferCapacity); sortedChangeValidator1 = new SortedHistoryChangePipeValidator(); sortedChangeValidator1.setChangeSink(new DataPostboxChangeSink(postbox1)); } /** * {@inheritDoc} */ public ChangeSink getChangeSink(int instance) { // Determine which postbox should be written to. switch (instance) { case 0: return sortedChangeValidator0; case 1: return sortedChangeValidator1; default: throw new OsmosisRuntimeException("Sink instance " + instance + " is not valid."); } } /** * This implementation always returns 2. * * @return 2 */ public int getChangeSinkCount() { return 2; } /** * {@inheritDoc} */ public void setChangeSink(ChangeSink changeSink) { this.changeSink = changeSink; } /** * {@inheritDoc} */ public void run() { try { EntityContainerComparator comparator; ChangeContainer changeContainer0 = null; ChangeContainer changeContainer1 = null; // Create a comparator for comparing two entities by type and identifier. comparator = new EntityContainerComparator(new EntityByTypeThenIdThenVersionComparator()); // We can't get meaningful data from the initialize data on the // input streams, so pass empty meta data to the sink and discard // the input meta data. postbox0.outputInitialize(); postbox1.outputInitialize(); changeSink.initialize(Collections.emptyMap()); // We continue in the comparison loop while both sources still have data. while ( (changeContainer0 != null || postbox0.hasNext()) && (changeContainer1 != null || postbox1.hasNext())) { long comparisonResult; // Get the next input data where required. if (changeContainer0 == null) { changeContainer0 = postbox0.getNext(); } if (changeContainer1 == null) { changeContainer1 = postbox1.getNext(); } // Compare the two entities. comparisonResult = comparator.compare(changeContainer0.getEntityContainer(), changeContainer1.getEntityContainer()); if (comparisonResult < 0) { // Entity 0 doesn't exist on the other source and can be // sent straight through. changeSink.process(changeContainer0); changeContainer0 = null; } else if (comparisonResult > 0) { // Entity 1 doesn't exist on the other source and can be // sent straight through. changeSink.process(changeContainer1); changeContainer1 = null; } else { // The entity exists on both sources so we must resolve the conflict. if (conflictResolutionMethod.equals(ConflictResolutionMethod.Timestamp)) { int timestampComparisonResult; timestampComparisonResult = changeContainer0.getEntityContainer().getEntity().getTimestamp() .compareTo(changeContainer1.getEntityContainer().getEntity().getTimestamp()); if (timestampComparisonResult < 0) { changeSink.process(changeContainer1); } else if (timestampComparisonResult > 0) { changeSink.process(changeContainer0); } else { // If both have identical timestamps, use the second source. changeSink.process(changeContainer1); } } else if (conflictResolutionMethod.equals(ConflictResolutionMethod.LatestSource)) { changeSink.process(changeContainer1); } else if (conflictResolutionMethod.equals(ConflictResolutionMethod.Version)) { int version0 = changeContainer0.getEntityContainer().getEntity().getVersion(); int version1 = changeContainer1.getEntityContainer().getEntity().getVersion(); if (version0 < version1) { changeSink.process(changeContainer1); } else if (version0 > version1) { changeSink.process(changeContainer0); } else { // If both have identical versions, use the second source. changeSink.process(changeContainer1); } } else { throw new OsmosisRuntimeException( "Conflict resolution method " + conflictResolutionMethod + " is not recognized."); } changeContainer0 = null; changeContainer1 = null; } } // Any remaining entities on either source can be sent straight through. while (changeContainer0 != null || postbox0.hasNext()) { if (changeContainer0 == null) { changeContainer0 = postbox0.getNext(); } changeSink.process(changeContainer0); changeContainer0 = null; } while (changeContainer1 != null || postbox1.hasNext()) { if (changeContainer1 == null) { changeContainer1 = postbox1.getNext(); } changeSink.process(changeContainer1); changeContainer1 = null; } changeSink.complete(); postbox0.outputComplete(); postbox1.outputComplete(); } finally { changeSink.release(); postbox0.outputRelease(); postbox1.outputRelease(); } } } osmosis-0.44.1/osmosis-set/src/main/java/org/openstreetmap/osmosis/set/v0_6/ChangeMergerFactory.java000066400000000000000000000052431253404521400334610ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.merge.common.ConflictResolutionMethod; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.MultiChangeSinkRunnableChangeSourceManager; /** * The task manager factory for a change merger. * * @author Brett Henderson */ public class ChangeMergerFactory extends TaskManagerFactory { private static final String ARG_CONFLICT_RESOLUTION_METHOD = "conflictResolutionMethod"; private static final String DEFAULT_CONFLICT_RESOLUTION_METHOD = "version"; private static final String ALTERNATIVE_CONFLICT_RESOLUTION_METHOD_1 = "timestamp"; private static final String ALTERNATIVE_CONFLICT_RESOLUTION_METHOD_2 = "lastSource"; private static final Map CONFLICT_RESOLUTION_METHOD_MAP = new HashMap(); private static final String ARG_BUFFER_CAPACITY = "bufferCapacity"; private static final int DEFAULT_BUFFER_CAPACITY = 20; static { CONFLICT_RESOLUTION_METHOD_MAP.put( DEFAULT_CONFLICT_RESOLUTION_METHOD, ConflictResolutionMethod.Version); CONFLICT_RESOLUTION_METHOD_MAP.put( ALTERNATIVE_CONFLICT_RESOLUTION_METHOD_1, ConflictResolutionMethod.Timestamp); CONFLICT_RESOLUTION_METHOD_MAP.put( ALTERNATIVE_CONFLICT_RESOLUTION_METHOD_2, ConflictResolutionMethod.LatestSource); } /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String conflictResolutionMethod; conflictResolutionMethod = getStringArgument( taskConfig, ARG_CONFLICT_RESOLUTION_METHOD, DEFAULT_CONFLICT_RESOLUTION_METHOD); if (!CONFLICT_RESOLUTION_METHOD_MAP.containsKey(conflictResolutionMethod)) { throw new OsmosisRuntimeException( "Argument " + ARG_CONFLICT_RESOLUTION_METHOD + " for task " + taskConfig.getId() + " has value \"" + conflictResolutionMethod + "\" which is unrecognised."); } int bufferCapacity = getIntegerArgument( taskConfig, ARG_BUFFER_CAPACITY, getDefaultIntegerArgument(taskConfig, DEFAULT_BUFFER_CAPACITY) ); return new MultiChangeSinkRunnableChangeSourceManager( taskConfig.getId(), new ChangeMerger(CONFLICT_RESOLUTION_METHOD_MAP.get(conflictResolutionMethod), bufferCapacity), taskConfig.getPipeArgs() ); } } osmosis-0.44.1/osmosis-set/src/main/java/org/openstreetmap/osmosis/set/v0_6/ChangeSimplifier.java000066400000000000000000000032601253404521400330100ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.set.v0_6.impl.ChangeSimplifierImpl; import org.openstreetmap.osmosis.core.sort.v0_6.SortedHistoryChangePipeValidator; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSinkChangeSource; /** * Looks at a sorted change stream and condenses multiple changes for a single entity into a single * change. * * @author Brett Henderson */ public class ChangeSimplifier implements ChangeSinkChangeSource { private SortedHistoryChangePipeValidator orderingValidator; private ChangeSimplifierImpl changeSimplifier; /** * Creates a new instance. */ public ChangeSimplifier() { orderingValidator = new SortedHistoryChangePipeValidator(); changeSimplifier = new ChangeSimplifierImpl(); orderingValidator.setChangeSink(changeSimplifier); } /** * {@inheritDoc} */ @Override public void initialize(Map metaData) { orderingValidator.initialize(metaData); } /** * {@inheritDoc} */ @Override public void process(ChangeContainer change) { orderingValidator.process(change); } /** * {@inheritDoc} */ @Override public void complete() { orderingValidator.complete(); } /** * {@inheritDoc} */ @Override public void release() { orderingValidator.release(); } /** * {@inheritDoc} */ @Override public void setChangeSink(ChangeSink changeSink) { changeSimplifier.setChangeSink(changeSink); } } ChangeSimplifierFactory.java000066400000000000000000000015031253404521400342570ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/main/java/org/openstreetmap/osmosis/set/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.ChangeSinkChangeSourceManager; /** * The task manager factory for a change simplifier. * * @author Brett Henderson */ public class ChangeSimplifierFactory extends TaskManagerFactory { /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { return new ChangeSinkChangeSourceManager( taskConfig.getId(), new ChangeSimplifier(), taskConfig.getPipeArgs() ); } } ChangeToFullHistoryConvertor.java000066400000000000000000000031751253404521400353240ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/main/java/org/openstreetmap/osmosis/set/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.task.common.ChangeAction; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSinkSource; import org.openstreetmap.osmosis.core.task.v0_6.Sink; /** * Translates a change stream into a full history stream which is a normal * entity stream with visible attributes. * * @author Brett Henderson */ public class ChangeToFullHistoryConvertor implements ChangeSinkSource { private Sink sink; /** * {@inheritDoc} */ @Override public void setSink(Sink sink) { this.sink = sink; } /** * {@inheritDoc} */ public void initialize(Map metaData) { sink.initialize(metaData); } /** * {@inheritDoc} */ @Override public void process(ChangeContainer change) { // Deleted entities are not visible, all others are. boolean visible = (ChangeAction.Delete != change.getAction()); // Set a visible meta-tag on the entity because the Osmosis data model // doesn't natively support visible. EntityContainer entityContainer = change.getEntityContainer().getWriteableInstance(); entityContainer.getEntity().getMetaTags().put("visible", visible); sink.process(entityContainer); } /** * {@inheritDoc} */ @Override public void complete() { sink.complete(); } /** * {@inheritDoc} */ @Override public void release() { sink.release(); } } ChangeToFullHistoryConvertorFactory.java000066400000000000000000000015361253404521400366530ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/main/java/org/openstreetmap/osmosis/set/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.ChangeSinkSourceManager; /** * The task manager factory for a change to full-history convertor. * * @author Brett Henderson */ public class ChangeToFullHistoryConvertorFactory extends TaskManagerFactory { /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { return new ChangeSinkSourceManager( taskConfig.getId(), new ChangeToFullHistoryConvertor(), taskConfig.getPipeArgs() ); } } osmosis-0.44.1/osmosis-set/src/main/java/org/openstreetmap/osmosis/set/v0_6/EntityMerger.java000066400000000000000000000225551253404521400322250ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6; import java.util.Collections; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; import org.openstreetmap.osmosis.core.merge.common.ConflictResolutionMethod; import org.openstreetmap.osmosis.core.sort.v0_6.EntityByTypeThenIdComparator; import org.openstreetmap.osmosis.core.sort.v0_6.EntityContainerComparator; import org.openstreetmap.osmosis.core.sort.v0_6.SortedEntityPipeValidator; import org.openstreetmap.osmosis.core.store.DataPostbox; import org.openstreetmap.osmosis.core.task.v0_6.MultiSinkRunnableSource; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.set.v0_6.impl.DataPostboxSink; /** * Merges two sources into a single data set. Conflicting elements are resolved * by using either the latest timestamp (default) or always selecting the second * source. * * @author Brett Henderson */ public class EntityMerger implements MultiSinkRunnableSource { private static final Logger LOG = Logger.getLogger(EntityMerger.class.getName()); private Sink sink; private DataPostbox postbox0; private SortedEntityPipeValidator sortedEntityValidator0; private DataPostbox postbox1; private SortedEntityPipeValidator sortedEntityValidator1; private ConflictResolutionMethod conflictResolutionMethod; private BoundRemovedAction boundRemovedAction; /** * Creates a new instance. * * @param conflictResolutionMethod * The method to used to resolve conflict when two sources * contain the same entity. * @param inputBufferCapacity * The size of the buffers to use for input sources. * @param boundRemovedAction * The action to take if the merge operation removes * a bound entity. */ public EntityMerger(ConflictResolutionMethod conflictResolutionMethod, int inputBufferCapacity, BoundRemovedAction boundRemovedAction) { this.conflictResolutionMethod = conflictResolutionMethod; postbox0 = new DataPostbox(inputBufferCapacity); sortedEntityValidator0 = new SortedEntityPipeValidator(); sortedEntityValidator0.setSink(new DataPostboxSink(postbox0)); postbox1 = new DataPostbox(inputBufferCapacity); sortedEntityValidator1 = new SortedEntityPipeValidator(); sortedEntityValidator1.setSink(new DataPostboxSink(postbox1)); } /** * {@inheritDoc} */ public Sink getSink(int instance) { // Determine which postbox should be written to. switch (instance) { case 0: return sortedEntityValidator0; case 1: return sortedEntityValidator1; default: throw new OsmosisRuntimeException("Sink instance " + instance + " is not valid."); } } /** * This implementation always returns 2. * * @return 2 */ public int getSinkCount() { return 2; } /** * {@inheritDoc} */ public void setSink(Sink sink) { this.sink = sink; } /** * {@inheritDoc} */ public void run() { try { EntityContainerComparator comparator; EntityContainer entityContainer0 = null; EntityContainer entityContainer1 = null; // Create a comparator for comparing two entities by type and identifier. comparator = new EntityContainerComparator(new EntityByTypeThenIdComparator()); // We can't get meaningful data from the initialize data on the // input streams, so pass empty meta data to the sink and discard // the input meta data. postbox0.outputInitialize(); postbox1.outputInitialize(); sink.initialize(Collections.emptyMap()); // BEGIN bound special handling // If there is a bound, it's going to be the first object // in a properly sorted stream entityContainer0 = nextOrNull(postbox0); entityContainer1 = nextOrNull(postbox1); // There's only need for special processing if there actually is some data // on both streams - no data implies no bound if (entityContainer0 != null && entityContainer1 != null) { Bound bound0 = null; Bound bound1 = null; // If there are any bounds upstream, eat them up if (entityContainer0.getEntity().getType() == EntityType.Bound) { bound0 = (Bound) entityContainer0.getEntity(); entityContainer0 = nextOrNull(postbox0); } if (entityContainer1.getEntity().getType() == EntityType.Bound) { bound1 = (Bound) entityContainer1.getEntity(); entityContainer1 = nextOrNull(postbox1); } // Only post a bound downstream if both upstream sources had a bound. // (Otherwise there's either nothing to post or the posted bound is going // to be smaller than the actual data, which is bad) if (bound0 != null && bound1 != null) { sink.process(new BoundContainer(bound0.union(bound1))); } else if ((bound0 != null && bound1 == null) || (bound0 == null && bound1 != null)) { handleBoundRemoved(bound0 == null); } } // END bound special handling // We continue in the comparison loop while both sources still have data. while ( (entityContainer0 != null || postbox0.hasNext()) && (entityContainer1 != null || postbox1.hasNext())) { long comparisonResult; // Get the next input data where required. if (entityContainer0 == null) { entityContainer0 = postbox0.getNext(); } if (entityContainer1 == null) { entityContainer1 = postbox1.getNext(); } // Compare the two entities. comparisonResult = comparator.compare(entityContainer0, entityContainer1); if (comparisonResult < 0) { // Entity 0 doesn't exist on the other source and can be // sent straight through. sink.process(entityContainer0); entityContainer0 = null; } else if (comparisonResult > 0) { // Entity 1 doesn't exist on the other source and can be // sent straight through. sink.process(entityContainer1); entityContainer1 = null; } else { // The entity exists on both sources so we must resolve the conflict. if (conflictResolutionMethod.equals(ConflictResolutionMethod.Timestamp)) { int timestampComparisonResult; timestampComparisonResult = entityContainer0.getEntity().getTimestamp() .compareTo(entityContainer1.getEntity().getTimestamp()); if (timestampComparisonResult < 0) { sink.process(entityContainer1); } else if (timestampComparisonResult > 0) { sink.process(entityContainer0); } else { // If both have identical timestamps, use the second source. sink.process(entityContainer1); } } else if (conflictResolutionMethod.equals(ConflictResolutionMethod.LatestSource)) { sink.process(entityContainer1); } else if (conflictResolutionMethod.equals(ConflictResolutionMethod.Version)) { int version0 = entityContainer0.getEntity().getVersion(); int version1 = entityContainer1.getEntity().getVersion(); if (version0 < version1) { sink.process(entityContainer1); } else if (version0 > version1) { sink.process(entityContainer0); } else { // If both have identical versions, use the second source. sink.process(entityContainer1); } } else { throw new OsmosisRuntimeException( "Conflict resolution method " + conflictResolutionMethod + " is not recognized."); } entityContainer0 = null; entityContainer1 = null; } } // Any remaining entities on either source can be sent straight through. while (entityContainer0 != null || postbox0.hasNext()) { if (entityContainer0 == null) { entityContainer0 = postbox0.getNext(); } sink.process(entityContainer0); entityContainer0 = null; } while (entityContainer1 != null || postbox1.hasNext()) { if (entityContainer1 == null) { entityContainer1 = postbox1.getNext(); } sink.process(entityContainer1); entityContainer1 = null; } sink.complete(); postbox0.outputComplete(); postbox1.outputComplete(); } finally { sink.release(); postbox0.outputRelease(); postbox1.outputRelease(); } } private void handleBoundRemoved(boolean source0BoundMissing) { if (boundRemovedAction == BoundRemovedAction.Ignore) { // Nothing to do return; } // Message for log or exception String missingSourceID, otherSourceID; if (source0BoundMissing) { missingSourceID = "0"; otherSourceID = "1"; } else { missingSourceID = "1"; otherSourceID = "0"; } String message = String.format( "Source %s of the merge task has an explicit bound set, but source %s has not. " + "Therefore the explicit bound has been removed from the merged stream.", missingSourceID, otherSourceID); // Now actually log or fail. if (boundRemovedAction == BoundRemovedAction.Warn) { LOG.warning(message); } else if (boundRemovedAction == BoundRemovedAction.Fail) { throw new OsmosisRuntimeException(message); } } private static EntityContainer nextOrNull(DataPostbox postbox) { if (postbox.hasNext()) { return postbox.getNext(); } return null; } } osmosis-0.44.1/osmosis-set/src/main/java/org/openstreetmap/osmosis/set/v0_6/EntityMergerFactory.java000066400000000000000000000057661253404521400335620ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.merge.common.ConflictResolutionMethod; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.MultiSinkRunnableSourceManager; /** * The task manager factory for an entity merger. * * @author Brett Henderson */ public class EntityMergerFactory extends TaskManagerFactory { private static final String ARG_CONFLICT_RESOLUTION_METHOD = "conflictResolutionMethod"; private static final String DEFAULT_CONFLICT_RESOLUTION_METHOD = "version"; private static final String ALTERNATIVE_CONFLICT_RESOLUTION_METHOD_1 = "timestamp"; private static final String ALTERNATIVE_CONFLICT_RESOLUTION_METHOD_2 = "lastSource"; private static final Map CONFLICT_RESOLUTION_METHOD_MAP = new HashMap(); private static final String ARG_BOUND_REMOVED_ACTION = "boundRemovedAction"; private static final String DEFAULT_BOUND_REMOVED_ACTION = "warn"; private static final String ARG_BUFFER_CAPACITY = "bufferCapacity"; private static final int DEFAULT_BUFFER_CAPACITY = 20; static { CONFLICT_RESOLUTION_METHOD_MAP.put( DEFAULT_CONFLICT_RESOLUTION_METHOD, ConflictResolutionMethod.Version); CONFLICT_RESOLUTION_METHOD_MAP.put( ALTERNATIVE_CONFLICT_RESOLUTION_METHOD_1, ConflictResolutionMethod.Timestamp); CONFLICT_RESOLUTION_METHOD_MAP.put( ALTERNATIVE_CONFLICT_RESOLUTION_METHOD_2, ConflictResolutionMethod.LatestSource); } /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String conflictResolutionMethod; conflictResolutionMethod = getStringArgument( taskConfig, ARG_CONFLICT_RESOLUTION_METHOD, DEFAULT_CONFLICT_RESOLUTION_METHOD); BoundRemovedAction boundRemovedAction; boundRemovedAction = BoundRemovedAction.parse( getStringArgument(taskConfig, ARG_BOUND_REMOVED_ACTION, DEFAULT_BOUND_REMOVED_ACTION)); int bufferCapacity = getIntegerArgument( taskConfig, ARG_BUFFER_CAPACITY, getDefaultIntegerArgument(taskConfig, DEFAULT_BUFFER_CAPACITY) ); if (!CONFLICT_RESOLUTION_METHOD_MAP.containsKey(conflictResolutionMethod)) { throw new OsmosisRuntimeException( "Argument " + ARG_CONFLICT_RESOLUTION_METHOD + " for task " + taskConfig.getId() + " has value \"" + conflictResolutionMethod + "\" which is unrecognised."); } return new MultiSinkRunnableSourceManager( taskConfig.getId(), new EntityMerger(CONFLICT_RESOLUTION_METHOD_MAP.get(conflictResolutionMethod), bufferCapacity, boundRemovedAction), taskConfig.getPipeArgs() ); } } osmosis-0.44.1/osmosis-set/src/main/java/org/openstreetmap/osmosis/set/v0_6/FlattenFilter.java000066400000000000000000000037471253404521400323540ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.sort.v0_6.SortedDuplicateEntityPipeValidator; /** * Flatten / simplify a sorted entity stream. (similar to --simplify-change) */ public class FlattenFilter extends SortedDuplicateEntityPipeValidator { private Sink sink; private Sink flattener = new Sink() { private EntityContainer previousContainer; @Override public void initialize(Map metaData) { sink.initialize(metaData); } /** * Process a node, way or relation. * * @param currentContainer * The entity container to be processed. */ @Override public void process(EntityContainer currentContainer) { if (previousContainer == null) { previousContainer = currentContainer; return; } Entity current = currentContainer.getEntity(); Entity previous = previousContainer.getEntity(); if (current.getId() != previous.getId() || !current.getType().equals(previous.getType())) { sink.process(previousContainer); previousContainer = currentContainer; return; } if (current.getVersion() > previous.getVersion()) { previousContainer = currentContainer; } } @Override public void complete() { /* * If we've stored entities temporarily, we now need to forward the * stored ones to the output. */ if (previousContainer != null) { sink.process(previousContainer); } sink.complete(); } @Override public void release() { sink.release(); } }; /** * Creates a new instance. */ public FlattenFilter() { super.setSink(flattener); } /** * {@inheritDoc} */ public void setSink(Sink sink) { this.sink = sink; } } FlattenFilterFactory.java000066400000000000000000000014151253404521400336130ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/main/java/org/openstreetmap/osmosis/set/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkSourceManager; /** * The task manager factory for a flatten/simplify filter. */ public class FlattenFilterFactory extends TaskManagerFactory { /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl( TaskConfiguration taskConfig) { return new SinkSourceManager( taskConfig.getId(), new FlattenFilter(), taskConfig.getPipeArgs() ); } } osmosis-0.44.1/osmosis-set/src/main/java/org/openstreetmap/osmosis/set/v0_6/impl/000077500000000000000000000000001253404521400276745ustar00rootroot00000000000000ChangeSimplifierImpl.java000066400000000000000000000056721253404521400345250ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/main/java/org/openstreetmap/osmosis/set/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6.impl; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.task.common.ChangeAction; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSinkChangeSource; /** * Looks at a sorted change stream and condenses multiple changes for a single entity into a single * change. * * @author Brett Henderson */ public class ChangeSimplifierImpl implements ChangeSinkChangeSource { private List currentChanges; private ChangeSink changeSink; /** * Creates a new instance. */ public ChangeSimplifierImpl() { currentChanges = new ArrayList(); } private void flushCurrentChanges() { ChangeContainer changeBegin; ChangeContainer changeEnd; ChangeAction actionBegin; ChangeAction actionEnd; ChangeAction actionResult; changeBegin = currentChanges.get(0); changeEnd = currentChanges.get(currentChanges.size() - 1); actionBegin = changeBegin.getAction(); actionEnd = changeEnd.getAction(); // If the final action is a delete we'll send a delete action regardless of whether the // first action was a create just in case the create should have been a modify. // If the first action is a create, then the result is always a create (except for delete // case above). // Everything else is treated as a modify. if (actionEnd.equals(ChangeAction.Delete)) { actionResult = ChangeAction.Delete; } else if (actionBegin.equals(ChangeAction.Create)) { actionResult = ChangeAction.Create; } else { actionResult = ChangeAction.Modify; } changeSink.process(new ChangeContainer(changeEnd.getEntityContainer(), actionResult)); currentChanges.clear(); } /** * {@inheritDoc} */ @Override public void initialize(Map metaData) { changeSink.initialize(metaData); } /** * {@inheritDoc} */ @Override public void process(ChangeContainer change) { // If the current change is for a different entity to those in our current changes list, // then we must process the current changes. if (currentChanges.size() > 0) { long currentId; currentId = currentChanges.get(0).getEntityContainer().getEntity().getId(); if (currentId != change.getEntityContainer().getEntity().getId()) { flushCurrentChanges(); } } currentChanges.add(change); } /** * {@inheritDoc} */ @Override public void complete() { if (!currentChanges.isEmpty()) { flushCurrentChanges(); } changeSink.complete(); } /** * {@inheritDoc} */ @Override public void release() { changeSink.release(); } /** * {@inheritDoc} */ @Override public void setChangeSink(ChangeSink changeSink) { this.changeSink = changeSink; } } DataPostboxChangeSink.java000066400000000000000000000023261253404521400346460ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/main/java/org/openstreetmap/osmosis/set/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6.impl; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.store.DataPostbox; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; /** * A change sink that writes all of its data to a postbox to be read by another thread. * * @author Brett Henderson */ public class DataPostboxChangeSink implements ChangeSink { private DataPostbox postbox; /** * Creates a new instance. * * @param postbox * The postbox to write all incoming data into. */ public DataPostboxChangeSink(DataPostbox postbox) { this.postbox = postbox; } /** * {@inheritDoc} */ @Override public void initialize(Map metaData) { postbox.initialize(metaData); } /** * {@inheritDoc} */ @Override public void process(ChangeContainer change) { postbox.put(change); } /** * {@inheritDoc} */ @Override public void complete() { postbox.complete(); } /** * {@inheritDoc} */ @Override public void release() { postbox.release(); } } DataPostboxSink.java000066400000000000000000000022671253404521400335440ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/main/java/org/openstreetmap/osmosis/set/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6.impl; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.store.DataPostbox; import org.openstreetmap.osmosis.core.task.v0_6.Sink; /** * A sink that writes all of its data to a postbox to be read by another thread. * * @author Brett Henderson */ public class DataPostboxSink implements Sink { private DataPostbox postbox; /** * Creates a new instance. * * @param postbox * The postbox to write all incoming data into. */ public DataPostboxSink(DataPostbox postbox) { this.postbox = postbox; } /** * {@inheritDoc} */ @Override public void initialize(Map metaData) { postbox.initialize(metaData); } /** * {@inheritDoc} */ @Override public void process(EntityContainer entity) { postbox.put(entity); } /** * {@inheritDoc} */ @Override public void complete() { postbox.complete(); } /** * {@inheritDoc} */ @Override public void release() { postbox.release(); } } osmosis-0.44.1/osmosis-set/src/main/resources/000077500000000000000000000000001253404521400213065ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/main/resources/osmosis-plugins.conf000066400000000000000000000000551253404521400253300ustar00rootroot00000000000000org.openstreetmap.osmosis.set.SetPluginLoaderosmosis-0.44.1/osmosis-set/src/test/000077500000000000000000000000001253404521400173275ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/test/java/000077500000000000000000000000001253404521400202505ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/test/java/org/000077500000000000000000000000001253404521400210375ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/test/java/org/openstreetmap/000077500000000000000000000000001253404521400237255ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/test/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400254215ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/test/java/org/openstreetmap/osmosis/set/000077500000000000000000000000001253404521400262145ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/test/java/org/openstreetmap/osmosis/set/v0_6/000077500000000000000000000000001253404521400267665ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/test/java/org/openstreetmap/osmosis/set/v0_6/ChangeAppenderTest.java000066400000000000000000000027031253404521400333370ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6; import java.io.File; import java.io.IOException; import org.junit.Test; import org.openstreetmap.osmosis.core.Osmosis; import org.openstreetmap.osmosis.testutil.AbstractDataTest; /** * Tests the change appender task. * * @author Brett Henderson */ public class ChangeAppenderTest extends AbstractDataTest { /** * Tests appending two change files into a single file. * * @throws IOException * if any file operations fail. */ @Test public void testAppend() throws IOException { File sourceFile1; File sourceFile2; File expectedOutputFile; File actualOutputFile; // Generate files. sourceFile1 = dataUtils.createDataFile("v0_6/append-change-in1.osc"); sourceFile2 = dataUtils.createDataFile("v0_6/append-change-in2.osc"); expectedOutputFile = dataUtils.createDataFile("v0_6/append-change-out.osc"); actualOutputFile = dataUtils.newFile(); // Append the two source files into the destination file. Osmosis.run( new String [] { "-q", "--read-xml-change-0.6", sourceFile2.getPath(), "--read-xml-change-0.6", sourceFile1.getPath(), "--append-change-0.6", "--write-xml-change-0.6", actualOutputFile.getPath() } ); // Validate that the output file matches the expected result. dataUtils.compareFiles(expectedOutputFile, actualOutputFile); } } osmosis-0.44.1/osmosis-set/src/test/java/org/openstreetmap/osmosis/set/v0_6/ChangeApplierTest.java000066400000000000000000000140451253404521400331770ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6; import java.io.File; import java.io.IOException; import org.junit.Test; import org.openstreetmap.osmosis.core.Osmosis; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.testutil.AbstractDataTest; /** * Test the --apply-change task. * * @author Igor Podolskiy */ public class ChangeApplierTest extends AbstractDataTest { /** * Test the application of an empty change to a non-empty stream. * * @throws Exception * if something goes wrong */ @Test public void emptyChange() throws Exception { applyChange("v0_6/apply_change/apply-change-base.osm", "v0_6/empty-change.osc", "v0_6/apply_change/apply-change-base.osm"); } /** * Test the application of a non-empty change to an empty stream. * * @throws Exception * if something goes wrong */ @Test public void emptyBase() throws Exception { applyChange("v0_6/empty-entity.osm", "v0_6/apply_change/change-delete.osc", "v0_6/empty-entity.osm"); } /** * Test the application of an empty change to an empty stream. * * @throws Exception * if something goes wrong */ @Test public void emptyBoth() throws Exception { applyChange("v0_6/empty-entity.osm", "v0_6/empty-change.osc", "v0_6/empty-entity.osm"); } /** * Test the creation of a node. * * @throws Exception * if something goes wrong */ @Test public void createNode() throws Exception { applyChange("v0_6/apply_change/apply-change-base.osm", "v0_6/apply_change/change-create.osc", "v0_6/apply_change/apply-change-create.osm"); } /** * Test the modification of a node. * * @throws Exception * if something goes wrong */ @Test public void modifyNode() throws Exception { applyChange("v0_6/apply_change/apply-change-base.osm", "v0_6/apply_change/change-modify.osc", "v0_6/apply_change/apply-change-modify.osm"); } /** * Test the deletion of a node. * * @throws Exception * if something goes wrong */ @Test public void deleteNode() throws Exception { applyChange("v0_6/apply_change/apply-change-base.osm", "v0_6/apply_change/change-delete.osc", "v0_6/apply_change/apply-change-delete.osm"); } /** * Test the creation, modification and deletion of the same entity in a single stream. * * @throws Exception * if something goes wrong */ @Test(expected = OsmosisRuntimeException.class) public void createModifyDelete() throws Exception { applyChange("v0_6/apply_change/apply-change-base.osm", "v0_6/apply_change/change-create-modify-delete.osc", "v0_6/apply_change/apply-change-base.osm"); } /** * Test the deletion of an entity that does not exist in the source stream. * * Deletion of a non-existent entity doesn't change anything. * * @throws Exception * if something goes wrong */ @Test public void deleteNonExistent() throws Exception { applyChange("v0_6/apply_change/apply-change-base.osm", "v0_6/apply_change/change-delete-nonexistent.osc", "v0_6/apply_change/apply-change-base.osm"); } /** * Test the modification of an entity that does not exist in the source stream. * * Modification of a non-existent entity has the same effect as its creation. * * @throws Exception * if something goes wrong */ @Test public void modifyNonExistent() throws Exception { applyChange("v0_6/apply_change/apply-change-base.osm", "v0_6/apply_change/change-modify-nonexistent.osc", "v0_6/apply_change/apply-change-modify-nonexistent.osm"); } /** * Test the creation of an entity that already exists in the source stream. * * Creation of an existent entity has the same effect as a modification. * * @throws Exception * if something goes wrong */ @Test public void createExistent() throws Exception { applyChange("v0_6/apply_change/apply-change-base.osm", "v0_6/apply_change/change-create-existent.osc", "v0_6/apply_change/apply-change-base.osm"); } /** * Test the case when the version in the change stream is lower than in the * source stream. * * @throws Exception * if something goes wrong */ @Test public void modifyHigherVersion() throws Exception { applyChange("v0_6/apply_change/apply-change-base-high.osm", "v0_6/apply_change/change-modify.osc", "v0_6/apply_change/apply-change-modify-higher.osm"); } /** * Test the case when the change is longer than the source stream * and consists of creates. * * @throws Exception * if something goes wrong */ @Test public void longChangeCreate() throws Exception { applyChange("v0_6/apply_change/apply-change-base-node-only.osm", "v0_6/apply_change/change-big-create.osc", "v0_6/apply_change/apply-change-big.osm"); } /** * Test the case when the change is longer than the source * stream and consists of deletes. * * @throws Exception * if something goes wrong */ @Test public void longChangeDelete() throws Exception { applyChange("v0_6/apply_change/apply-change-base-node-only.osm", "v0_6/apply_change/change-big-delete.osc", "v0_6/apply_change/apply-change-base-node-only.osm"); } private void applyChange(String sourceFileName, String changeFileName, String expectedOutputFileName) throws IOException { File sourceFile; File changeFile; File expectedOutputFile; File actualOutputFile; sourceFile = dataUtils.createDataFile(sourceFileName); changeFile = dataUtils.createDataFile(changeFileName); expectedOutputFile = dataUtils.createDataFile(expectedOutputFileName); actualOutputFile = dataUtils.newFile(); Osmosis.run( new String [] { "-q", "--read-xml-change-0.6", changeFile.getPath(), "--read-xml-0.6", sourceFile.getPath(), "--apply-change-0.6", "--write-xml-0.6", actualOutputFile.getPath() } ); dataUtils.compareFiles(expectedOutputFile, actualOutputFile); } } osmosis-0.44.1/osmosis-set/src/test/java/org/openstreetmap/osmosis/set/v0_6/ChangeDeriverTest.java000066400000000000000000000103111253404521400331730ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6; import java.io.File; import java.io.IOException; import java.util.List; import org.junit.Assert; import org.junit.Test; import org.openstreetmap.osmosis.core.Osmosis; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; import org.openstreetmap.osmosis.core.misc.v0_6.EmptyReader; import org.openstreetmap.osmosis.core.task.common.ChangeAction; import org.openstreetmap.osmosis.core.task.v0_6.RunnableSource; import org.openstreetmap.osmosis.testutil.AbstractDataTest; import org.openstreetmap.osmosis.testutil.v0_6.RunTaskUtilities; import org.openstreetmap.osmosis.testutil.v0_6.SinkChangeInspector; import org.openstreetmap.osmosis.xml.common.CompressionMethod; import org.openstreetmap.osmosis.xml.v0_6.XmlReader; /** * Tests for --derive-change task. * * @author Igor Podolskiy */ public class ChangeDeriverTest extends AbstractDataTest { /** * Empty inputs should yield empty change. * * @throws Exception if something goes wrong. */ @Test public void emptyInputs() throws Exception { deriveChange("v0_6/empty-entity.osm", "v0_6/empty-entity.osm", "v0_6/empty-change.osc"); } /** * Same inputs should yield empty change. * * @throws Exception if something goes wrong. */ @Test public void sameInputs() throws Exception { deriveChange("v0_6/derive_change/simple.osm", "v0_6/derive_change/simple.osm", "v0_6/empty-change.osc"); } /** * Deriving change with an empty left input should yield * a change with deletes only. * * @throws Exception if something goes wrong. */ @Test public void leftEmpty() throws Exception { deriveChange("v0_6/empty-entity.osm", "v0_6/derive_change/simple.osm", "v0_6/derive_change/full-create.osc"); } /** * Deriving change with an empty right input should yield * a change with creates only. * * @throws Exception if something goes wrong. */ @Test public void rightEmpty() throws Exception { // Cannot be tested with file comparison as the derived // change contains deletes which have a current timestamp // that cannot be reliably predicted. // Therefore, check all relevant attributes manually. ChangeDeriver deriver = new ChangeDeriver(1); RunnableSource left = new XmlReader(dataUtils.createDataFile( "v0_6/derive_change/simple.osm"), true, CompressionMethod.None); RunnableSource right = new EmptyReader(); SinkChangeInspector result = RunTaskUtilities.run(deriver, left, right); List changes = result.getProcessedChanges(); Assert.assertEquals(3, changes.size()); for (ChangeContainer changeContainer : changes) { Assert.assertEquals(ChangeAction.Delete, changeContainer.getAction()); } Entity e; e = changes.get(0).getEntityContainer().getEntity(); Assert.assertEquals(EntityType.Node, e.getType()); Assert.assertEquals(10, e.getId()); Assert.assertEquals(34, e.getVersion()); e = changes.get(1).getEntityContainer().getEntity(); Assert.assertEquals(EntityType.Way, e.getType()); Assert.assertEquals(100, e.getId()); Assert.assertEquals(56, e.getVersion()); e = changes.get(2).getEntityContainer().getEntity(); Assert.assertEquals(EntityType.Relation, e.getType()); Assert.assertEquals(1000, e.getId()); Assert.assertEquals(78, e.getVersion()); } private void deriveChange(String leftFileName, String rightFileName, String expectedOutputFileName) throws IOException { File leftFile; File rightFile; File expectedOutputFile; File actualOutputFile; leftFile = dataUtils.createDataFile(leftFileName); rightFile = dataUtils.createDataFile(rightFileName); expectedOutputFile = dataUtils.createDataFile(expectedOutputFileName); actualOutputFile = dataUtils.newFile(); Osmosis.run( new String [] { "-q", "--read-xml-0.6", rightFile.getPath(), "--read-xml-0.6", leftFile.getPath(), "--derive-change-0.6", "--write-xml-change-0.6", actualOutputFile.getPath() } ); dataUtils.compareFiles(expectedOutputFile, actualOutputFile); } } ChangeSimplifierTest.java000066400000000000000000000140331253404521400336240ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/test/java/org/openstreetmap/osmosis/set/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6; import java.io.File; import java.io.IOException; import java.util.Date; import java.util.HashMap; import org.junit.Assert; import org.junit.Test; import org.openstreetmap.osmosis.core.Osmosis; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.misc.v0_6.NullChangeWriter; import org.openstreetmap.osmosis.core.task.common.ChangeAction; import org.openstreetmap.osmosis.testutil.AbstractDataTest; /** * Tests the change simplifier task. */ public class ChangeSimplifierTest extends AbstractDataTest { /** * Tests that a set of changes is simplified correctly. * * @throws IOException * if any file operations fail. */ @Test public void commonCase() throws IOException { File sourceFile; File expectedOutputFile; File actualOutputFile; // Generate files. sourceFile = dataUtils.createDataFile("v0_6/simplify-change-in.osc"); expectedOutputFile = dataUtils.createDataFile("v0_6/simplify-change-out.osc"); actualOutputFile = dataUtils.newFile(); Osmosis.run( new String [] { "-q", "--read-xml-change-0.6", sourceFile.getPath(), "--simplify-change-0.6", "--write-xml-change-0.6", actualOutputFile.getPath() } ); // Validate that the output file matches the expected result. dataUtils.compareFiles(expectedOutputFile, actualOutputFile); } /** * Tests that simplifying an already simple change successfully * yields the same change. * * @throws Exception * if anything fails. */ @Test public void alreadySimple() throws Exception { File sourceFile; File expectedOutputFile; File actualOutputFile; sourceFile = dataUtils.createDataFile("v0_6/simplify-change-out.osc"); expectedOutputFile = dataUtils.createDataFile("v0_6/simplify-change-out.osc"); actualOutputFile = dataUtils.newFile(); Osmosis.run( new String [] { "-q", "--read-xml-change-0.6", sourceFile.getPath(), "--simplify-change-0.6", "--write-xml-change-0.6", actualOutputFile.getPath() } ); dataUtils.compareFiles(expectedOutputFile, actualOutputFile); } /** * Tests that simplifying an empty change successfully * yields an empty change. * * @throws Exception * if anything fails. */ @Test public void empty() throws Exception { File expectedOutputFile; File actualOutputFile; expectedOutputFile = dataUtils.createDataFile("v0_6/empty-change.osc"); actualOutputFile = dataUtils.newFile(); Osmosis.run( new String [] { "-q", "--read-empty-change-0.6", "--simplify-change-0.6", "--write-xml-change-0.6", actualOutputFile.getPath() } ); dataUtils.compareFiles(expectedOutputFile, actualOutputFile); } /** * Tests that badly ordered input (with respect to the version) is detected correctly. * * @throws Exception * if anything fails. */ @Test public void badSortOrderVersion() throws Exception { ChangeSimplifier simplifier = new ChangeSimplifier(); simplifier.setChangeSink(new NullChangeWriter()); simplifier.initialize(new HashMap()); Node node; node = new Node(new CommonEntityData(1, 2, new Date(), OsmUser.NONE, 2), 1, 1); simplifier.process(new ChangeContainer(new NodeContainer(node), ChangeAction.Modify)); try { node = new Node(new CommonEntityData(1, 1, new Date(), OsmUser.NONE, 1), 1, 1); simplifier.process(new ChangeContainer(new NodeContainer(node), ChangeAction.Modify)); } catch (OsmosisRuntimeException e) { if (e.getMessage().startsWith("Pipeline entities are not sorted")) { return; } throw e; } Assert.fail("Expected exception not thrown"); } /** * Tests that badly ordered input (with respect to the ids) is detected correctly. * * @throws Exception * if anything fails. */ @Test public void badSortOrderId() throws Exception { ChangeSimplifier simplifier = new ChangeSimplifier(); simplifier.setChangeSink(new NullChangeWriter()); simplifier.initialize(new HashMap()); Node node; node = new Node(new CommonEntityData(2, 2, new Date(), OsmUser.NONE, 2), 1, 1); simplifier.process(new ChangeContainer(new NodeContainer(node), ChangeAction.Modify)); try { node = new Node(new CommonEntityData(1, 2, new Date(), OsmUser.NONE, 1), 1, 1); simplifier.process(new ChangeContainer(new NodeContainer(node), ChangeAction.Modify)); } catch (OsmosisRuntimeException e) { if (e.getMessage().startsWith("Pipeline entities are not sorted")) { return; } throw e; } Assert.fail("Expected exception not thrown"); } /** * Tests that badly ordered input (with respect to the ids) is detected correctly. * * @throws Exception * if anything fails. */ @Test public void badSortOrderType() throws Exception { ChangeSimplifier simplifier = new ChangeSimplifier(); simplifier.setChangeSink(new NullChangeWriter()); simplifier.initialize(new HashMap()); Node node; Way way; way = new Way(new CommonEntityData(2, 2, new Date(), OsmUser.NONE, 2)); simplifier.process(new ChangeContainer(new WayContainer(way), ChangeAction.Modify)); try { node = new Node(new CommonEntityData(1, 2, new Date(), OsmUser.NONE, 1), 1, 1); simplifier.process(new ChangeContainer(new NodeContainer(node), ChangeAction.Modify)); } catch (OsmosisRuntimeException e) { if (e.getMessage().startsWith("Pipeline entities are not sorted")) { return; } throw e; } Assert.fail("Expected exception not thrown"); } } ChangeToFullHistoryConvertorTest.java000066400000000000000000000025041253404521400362120ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/test/java/org/openstreetmap/osmosis/set/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6; import java.io.File; import java.io.IOException; import org.junit.Test; import org.openstreetmap.osmosis.core.Osmosis; import org.openstreetmap.osmosis.testutil.AbstractDataTest; /** * Tests the change to full history convertor task. * * @author Brett Henderson */ public class ChangeToFullHistoryConvertorTest extends AbstractDataTest { /** * Tests appending two change files into a single file. * * @throws IOException * if any file operations fail. */ @Test public void testConvert() throws IOException { File sourceFile; File expectedOutputFile; File actualOutputFile; // Generate files. sourceFile = dataUtils.createDataFile("v0_6/change-to-full-history-in.osc"); expectedOutputFile = dataUtils.createDataFile("v0_6/change-to-full-history-out.osm"); actualOutputFile = dataUtils.newFile(); // Append the two source files into the destination file. Osmosis.run(new String[] {"-q", "--read-xml-change-0.6", sourceFile.getPath(), "--convert-change-to-full-history-0.6", "--write-xml-0.6", actualOutputFile.getPath() }); // Validate that the output file matches the expected result. dataUtils.compareFiles(expectedOutputFile, actualOutputFile); } } osmosis-0.44.1/osmosis-set/src/test/java/org/openstreetmap/osmosis/set/v0_6/EntityMergerTest.java000066400000000000000000000272461253404521400331220ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6; import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.junit.Assert; import org.junit.Test; import org.openstreetmap.osmosis.core.Osmosis; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.merge.common.ConflictResolutionMethod; import org.openstreetmap.osmosis.core.misc.v0_6.EmptyReader; import org.openstreetmap.osmosis.testutil.AbstractDataTest; import org.openstreetmap.osmosis.testutil.v0_6.RunTaskUtilities; import org.openstreetmap.osmosis.xml.common.CompressionMethod; import org.openstreetmap.osmosis.xml.v0_6.XmlReader; /** * Test the --merge task. * * @author Igor Podolskiy */ public class EntityMergerTest extends AbstractDataTest { /** * Tests empty + X == X. * * @throws Exception if something fails */ @Test public void firstEmpty() throws Exception { File sourceFile; File expectedOutputFile; File actualOutputFile; // Generate files. sourceFile = dataUtils.createDataFile("v0_6/merge/merge-in-1.osm"); expectedOutputFile = dataUtils.createDataFile("v0_6/merge/merge-in-1.osm"); actualOutputFile = dataUtils.newFile(); // Run the merge. Osmosis.run( new String [] { "-q", "--read-xml-0.6", sourceFile.getPath(), "--read-empty-0.6", "--merge", "--write-xml-0.6", actualOutputFile.getPath() } ); // Validate that the output file matches the expected result. dataUtils.compareFiles(expectedOutputFile, actualOutputFile); } /** * Tests X + empty == X. * * @throws Exception if something fails */ @Test public void secondEmpty() throws Exception { File sourceFile; File expectedOutputFile; File actualOutputFile; // Generate files. sourceFile = dataUtils.createDataFile("v0_6/merge/merge-in-1.osm"); expectedOutputFile = dataUtils.createDataFile("v0_6/merge/merge-in-1.osm"); actualOutputFile = dataUtils.newFile(); // Run the merge. Osmosis.run( new String [] { "-q", "--read-empty-0.6", "--read-xml-0.6", sourceFile.getPath(), "--merge", "--write-xml-0.6", actualOutputFile.getPath() } ); // Validate that the output file matches the expected result. dataUtils.compareFiles(expectedOutputFile, actualOutputFile); } /** * Tests X + X == X. * * @throws Exception if something fails */ @Test public void selfMerge() throws Exception { File sourceFile1; File sourceFile2; File expectedOutputFile; File actualOutputFile; // Generate files. sourceFile1 = dataUtils.createDataFile("v0_6/merge/merge-in-1.osm"); sourceFile2 = dataUtils.createDataFile("v0_6/merge/merge-in-1.osm"); expectedOutputFile = dataUtils.createDataFile("v0_6/merge/merge-in-1.osm"); actualOutputFile = dataUtils.newFile(); // Run the merge. Osmosis.run( new String [] { "-q", "--read-xml-0.6", sourceFile2.getPath(), "--read-xml-0.6", sourceFile1.getPath(), "--merge", "--write-xml-0.6", actualOutputFile.getPath() } ); // Validate that the output file matches the expected result. dataUtils.compareFiles(expectedOutputFile, actualOutputFile); } /** * Tests the timestamp conflict resolution strategy. * * @throws Exception if something fails */ @Test public void timestampConflictResolution() throws Exception { File sourceFile1; File sourceFile2; File expectedOutputFile; File actualOutputFile; // Generate files. sourceFile1 = dataUtils.createDataFile("v0_6/merge/merge-in-1.osm"); sourceFile2 = dataUtils.createDataFile("v0_6/merge/merge-in-2-timestamp.osm"); expectedOutputFile = dataUtils.createDataFile("v0_6/merge/merge-out-timestamp.osm"); actualOutputFile = dataUtils.newFile(); // Run the merge. Osmosis.run( new String [] { "-q", "--read-xml-0.6", sourceFile2.getPath(), "--read-xml-0.6", sourceFile1.getPath(), "--merge", "conflictResolutionMethod=timestamp", "--write-xml-0.6", actualOutputFile.getPath() } ); // Validate that the output file matches the expected result. dataUtils.compareFiles(expectedOutputFile, actualOutputFile); // Timestamp conflict resolution should be commutative. // Run the merge. Osmosis.run( new String [] { "-q", "--read-xml-0.6", sourceFile1.getPath(), "--read-xml-0.6", sourceFile2.getPath(), "--merge", "conflictResolutionMethod=timestamp", "--write-xml-0.6", actualOutputFile.getPath() } ); // Validate that the output file matches the expected result. dataUtils.compareFiles(expectedOutputFile, actualOutputFile); } /** * Tests the version conflict resolution strategy. * * @throws Exception if something fails */ @Test public void versionConflictResolution() throws Exception { File sourceFile1; File sourceFile2; File expectedOutputFile; File actualOutputFile; // Generate files. sourceFile1 = dataUtils.createDataFile("v0_6/merge/merge-in-1.osm"); sourceFile2 = dataUtils.createDataFile("v0_6/merge/merge-in-2-version.osm"); expectedOutputFile = dataUtils.createDataFile("v0_6/merge/merge-out-version.osm"); actualOutputFile = dataUtils.newFile(); // Run the merge. Osmosis.run( new String [] { "-q", "--read-xml-0.6", sourceFile2.getPath(), "--read-xml-0.6", sourceFile1.getPath(), "--merge", "conflictResolutionMethod=version", "--write-xml-0.6", actualOutputFile.getPath() } ); // Validate that the output file matches the expected result. dataUtils.compareFiles(expectedOutputFile, actualOutputFile); // Version conflict resolution should be commutative. // Run the merge. Osmosis.run( new String [] { "-q", "--read-xml-0.6", sourceFile1.getPath(), "--read-xml-0.6", sourceFile2.getPath(), "--merge", "conflictResolutionMethod=version", "--write-xml-0.6", actualOutputFile.getPath() } ); // Validate that the output file matches the expected result. dataUtils.compareFiles(expectedOutputFile, actualOutputFile); } /** * Tests the version conflict resolution strategy. * * @throws Exception if something fails */ @Test public void secondSourceConflictResolution() throws Exception { File sourceFile1; File sourceFile2; File expectedOutputFile; File actualOutputFile; // Generate files. sourceFile1 = dataUtils.createDataFile("v0_6/merge/merge-in-1.osm"); sourceFile2 = dataUtils.createDataFile("v0_6/merge/merge-in-2-secondSource.osm"); expectedOutputFile = dataUtils.createDataFile("v0_6/merge/merge-out-secondSource.osm"); actualOutputFile = dataUtils.newFile(); // Run the merge. Osmosis.run( new String [] { "-q", "--read-xml-0.6", sourceFile2.getPath(), "--read-xml-0.6", sourceFile1.getPath(), "--merge", "conflictResolutionMethod=lastSource", "--write-xml-0.6", actualOutputFile.getPath() } ); // Validate that the output file matches the expected result. dataUtils.compareFiles(expectedOutputFile, actualOutputFile); // Timestamp conflict resolution is NOT commutative, // but it deserves testing as well. // As the mergen-in-2 input does not contain any entities that are not // in the second source, the output should be identical to the first source. expectedOutputFile = dataUtils.createDataFile("v0_6/merge/merge-in-1.osm"); // Run the merge. Osmosis.run( new String [] { "-q", "--read-xml-0.6", sourceFile1.getPath(), "--read-xml-0.6", sourceFile2.getPath(), "--merge", "conflictResolutionMethod=lastSource", "--write-xml-0.6", actualOutputFile.getPath() } ); // Validate that the output file matches the expected result. dataUtils.compareFiles(expectedOutputFile, actualOutputFile); } /** * Tests merging two completely disjunct datasets (no conflicts). * * @throws Exception if something fails */ @Test public void disjunctDatasets() throws Exception { File sourceFile1; File sourceFile2; File expectedOutputFile; File actualOutputFile; // Generate files. sourceFile1 = dataUtils.createDataFile("v0_6/merge/merge-in-1.osm"); sourceFile2 = dataUtils.createDataFile("v0_6/merge/merge-in-2-disjunct.osm"); expectedOutputFile = dataUtils.createDataFile("v0_6/merge/merge-out-disjunct.osm"); actualOutputFile = dataUtils.newFile(); // Run the merge. Osmosis.run( new String [] { "-q", "--read-xml-0.6", sourceFile2.getPath(), "--read-xml-0.6", sourceFile1.getPath(), "--merge", "--write-xml-0.6", actualOutputFile.getPath() } ); // Validate that the output file matches the expected result. dataUtils.compareFiles(expectedOutputFile, actualOutputFile); // Merging of disjunct datasets should be commutative. // Run the merge. Osmosis.run( new String [] { "-q", "--read-xml-0.6", sourceFile1.getPath(), "--read-xml-0.6", sourceFile2.getPath(), "--merge", "conflictResolutionMethod=version", "--write-xml-0.6", actualOutputFile.getPath() } ); // Validate that the output file matches the expected result. dataUtils.compareFiles(expectedOutputFile, actualOutputFile); } /** * Tests bad sort order in an input stream (node, way, relations not in * order). * * @throws Exception * if something fails */ @Test public void badSortOrderType() throws Exception { File sourceFile = dataUtils.createDataFile("v0_6/merge/merge-in-badorder-type.osm"); mergeAndLookForException(sourceFile, "Pipeline entities are not sorted"); } /** * Tests bad sort order in an input stream (ids not sorted). * * @throws Exception * if something fails */ @Test public void badSortOrderId() throws Exception { File sourceFile = dataUtils.createDataFile("v0_6/merge/merge-in-badorder-id.osm"); mergeAndLookForException(sourceFile, "Pipeline entities are not sorted"); } /** * Runs a merge and records the exceptions that happened during the merge. * * The test is considered passed iff at least one exception was thrown and * the exception message begins with a given string. * * This method does not use command line parsing because it is impossible * to check whether the right exception has been thrown. Also, as all * exceptions are OsmosisRuntimeExceptions, we need to check the message * so the JUnit expected exception facility is no good here. * * To add insult to injury, running a merge task involves three worker threads; * the exception we expect is thrown on one of those worker threads which brings * the pipeline down. But we want to check for that one source exception * is thrown for the correct reason, otherwise the test becomes very unspecific. * */ private void mergeAndLookForException(File sourceFile, String exceptionMessagePrefix) throws Exception { final List exceptions = Collections.synchronizedList(new ArrayList()); XmlReader reader = new XmlReader(sourceFile, false, CompressionMethod.None); EntityMerger merger = new EntityMerger( ConflictResolutionMethod.LatestSource, 1, BoundRemovedAction.Ignore); RunTaskUtilities.run(merger, reader, new EmptyReader(), new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(Thread t, Throwable e) { exceptions.add(e); } }); // At least one of those exceptions should be a "Pipeline not sorted" one boolean sortExceptionFound = false; for (Throwable t : exceptions) { if (!(t instanceof OsmosisRuntimeException)) { Assert.fail("Unexpected exception thrown: " + t); } sortExceptionFound |= t.getMessage().startsWith(exceptionMessagePrefix); } if (!sortExceptionFound) { Assert.fail("Expected exception not thrown"); } } } osmosis-0.44.1/osmosis-set/src/test/java/org/openstreetmap/osmosis/set/v0_6/FlattenFilterTest.java000066400000000000000000000047511253404521400332430ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6; import java.io.File; import java.io.IOException; import org.junit.Test; import org.openstreetmap.osmosis.core.Osmosis; import org.openstreetmap.osmosis.testutil.AbstractDataTest; /** * Tests the flatten filter. * * @author Igor Podolskiy */ public class FlattenFilterTest extends AbstractDataTest { /** * Tests that a set of changes is simplified correctly. * * @throws IOException * if any file operations fail. */ @Test public void commonCase() throws IOException { File sourceFile; File expectedOutputFile; File actualOutputFile; // Generate files. sourceFile = dataUtils.createDataFile("v0_6/flatten-in.osm"); expectedOutputFile = dataUtils.createDataFile("v0_6/flatten-out.osm"); actualOutputFile = dataUtils.newFile(); Osmosis.run( new String [] { "-q", "--read-xml-0.6", sourceFile.getPath(), "--flatten-0.6", "--write-xml-0.6", actualOutputFile.getPath() } ); // Validate that the output file matches the expected result. dataUtils.compareFiles(expectedOutputFile, actualOutputFile); } /** * Tests that simplifying an already simple change successfully * yields the same change. * * @throws Exception * if anything fails. */ @Test public void alreadyFlattened() throws Exception { File sourceFile; File expectedOutputFile; File actualOutputFile; sourceFile = dataUtils.createDataFile("v0_6/flatten-out.osm"); expectedOutputFile = dataUtils.createDataFile("v0_6/flatten-out.osm"); actualOutputFile = dataUtils.newFile(); Osmosis.run( new String [] { "-q", "--read-xml-0.6", sourceFile.getPath(), "--flatten-0.6", "--write-xml-0.6", actualOutputFile.getPath() } ); dataUtils.compareFiles(expectedOutputFile, actualOutputFile); } /** * Tests that simplifying an empty change successfully * yields an empty change. * * @throws Exception * if anything fails. */ @Test public void empty() throws Exception { File expectedOutputFile; File actualOutputFile; expectedOutputFile = dataUtils.createDataFile("v0_6/empty-entity.osm"); actualOutputFile = dataUtils.newFile(); Osmosis.run( new String [] { "-q", "--read-empty-0.6", "--flatten-0.6", "--write-xml-0.6", actualOutputFile.getPath() } ); dataUtils.compareFiles(expectedOutputFile, actualOutputFile); } } osmosis-0.44.1/osmosis-set/src/test/java/org/openstreetmap/osmosis/set/v0_6/MergeBoundTest.java000066400000000000000000000174111253404521400325240ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import org.junit.Assert; import org.junit.Test; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.merge.common.ConflictResolutionMethod; import org.openstreetmap.osmosis.core.misc.v0_6.EmptyReader; import org.openstreetmap.osmosis.core.task.v0_6.RunnableSource; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.testutil.v0_6.RunTaskUtilities; import org.openstreetmap.osmosis.testutil.v0_6.SinkEntityInspector; /** * Tests bounding box processing in merge tasks. * * @author Igor Podolskiy */ public class MergeBoundTest { /** * A simple dummy ID generator for the helper source class. */ private static AtomicInteger idGenerator = new AtomicInteger(1000); /** * Tests the proper working of the merge task if neither * source has a declared bound. * * @throws Exception if something goes wrong */ @Test public void testNeitherHasBound() throws Exception { RunnableSource source0 = new BoundSource(new Bound(1, 2, 4, 3, "source0"), false); RunnableSource source1 = new BoundSource(new Bound(5, 6, 8, 7, "source1"), false); EntityMerger merger = new EntityMerger(ConflictResolutionMethod.LatestSource, 1, BoundRemovedAction.Ignore); SinkEntityInspector merged = RunTaskUtilities.run(merger, source0, source1); List mergedList = createList(merged.getProcessedEntities()); Assert.assertEquals(2, mergedList.size()); for (EntityContainer entityContainer : mergedList) { Assert.assertEquals(EntityType.Node, entityContainer.getEntity().getType()); } } /** * Tests whether merge will delete the declared bound if only source 0 * has a declared bound. * * @throws Exception if something goes wrong */ @Test public void testSource0HasBound() throws Exception { RunnableSource source0 = new BoundSource(new Bound(1, 2, 4, 3, "source0"), true); RunnableSource source1 = new BoundSource(new Bound(5, 6, 8, 7, "source1"), false); EntityMerger merger = new EntityMerger(ConflictResolutionMethod.LatestSource, 1, BoundRemovedAction.Ignore); SinkEntityInspector merged = RunTaskUtilities.run(merger, source0, source1); List mergedList = createList(merged.getProcessedEntities()); Assert.assertEquals(2, mergedList.size()); for (EntityContainer entityContainer : mergedList) { Assert.assertEquals(EntityType.Node, entityContainer.getEntity().getType()); } } /** * Tests whether merge will delete the declared bound if only source 1 * has a declared bound. * * @throws Exception if something goes wrong */ @Test public void testSource1HasBound() throws Exception { RunnableSource source0 = new BoundSource(new Bound(1, 2, 4, 3, "source0"), false); RunnableSource source1 = new BoundSource(new Bound(5, 6, 8, 7, "source1"), true); EntityMerger merger = new EntityMerger(ConflictResolutionMethod.LatestSource, 1, BoundRemovedAction.Ignore); SinkEntityInspector merged = RunTaskUtilities.run(merger, source0, source1); List mergedList = createList(merged.getProcessedEntities()); Assert.assertEquals(2, mergedList.size()); for (EntityContainer entityContainer : mergedList) { Assert.assertEquals(EntityType.Node, entityContainer.getEntity().getType()); } } /** * Test the proper computation of the union bound iff both sources * have bounds. * * @throws Exception if something goes wrong */ @Test public void testBothHaveBounds() throws Exception { Bound bound0 = new Bound(1, 2, 4, 3, "source1"); RunnableSource source0 = new BoundSource(bound0, true); Bound bound1 = new Bound(5, 6, 8, 7, "source2"); RunnableSource source1 = new BoundSource(bound1, true); EntityMerger merger = new EntityMerger(ConflictResolutionMethod.LatestSource, 1, BoundRemovedAction.Ignore); SinkEntityInspector merged = RunTaskUtilities.run(merger, source0, source1); List mergedList = createList(merged.getProcessedEntities()); Assert.assertEquals(3, mergedList.size()); Assert.assertEquals(EntityType.Bound, mergedList.get(0).getEntity().getType()); // Check the bound Bound bound01 = (Bound) mergedList.get(0).getEntity(); Assert.assertEquals(bound0.union(bound1), bound01); for (int i = 1; i < mergedList.size(); i++) { Assert.assertEquals(EntityType.Node, mergedList.get(i).getEntity().getType()); } } /** * Tests the proper working of the merge task if both sources are * empty. * * @throws Exception if something goes wrong */ @Test public void testBothEmpty() throws Exception { RunnableSource source0 = new EmptyReader(); RunnableSource source1 = new EmptyReader(); EntityMerger merger = new EntityMerger(ConflictResolutionMethod.LatestSource, 1, BoundRemovedAction.Ignore); SinkEntityInspector merged = RunTaskUtilities.run(merger, source0, source1); Assert.assertTrue("Expected empty result set but got some data", merged.getLastEntityContainer() == null); } /** * Tests the proper working of the merge task if exactly one source is * empty with respect to the declared bound. * * @throws Exception if something goes wrong */ @Test public void testOneSourceEmpty() throws Exception { RunnableSource source0 = new EmptyReader(); Bound bound1 = new Bound(5, 6, 8, 7, "source2"); RunnableSource source1 = new BoundSource(bound1, true); EntityMerger merger = new EntityMerger(ConflictResolutionMethod.LatestSource, 1, BoundRemovedAction.Ignore); SinkEntityInspector merged = RunTaskUtilities.run(merger, source0, source1); List mergedList = createList(merged.getProcessedEntities()); Assert.assertEquals(2, mergedList.size()); Assert.assertEquals(bound1, mergedList.get(0).getEntity()); Assert.assertEquals(EntityType.Node, mergedList.get(1).getEntity().getType()); } private static List createList(Iterable t) { List list = new ArrayList(); for (T elem : t) { list.add(elem); } return list; } /** * A simple source which provides a single node in the center of a given * bounding box, and optionally, a declared bounding box. */ private static class BoundSource implements RunnableSource { private Sink sink; private Bound bound; private boolean publishBound; public BoundSource(Bound bound, boolean publishBound) { if (bound == null) { throw new IllegalArgumentException("bound must not be null"); } this.publishBound = publishBound; this.bound = bound; } @Override public void setSink(Sink sink) { this.sink = sink; } @Override public void run() { try { sink.initialize(Collections.emptyMap()); if (publishBound) { sink.process(new BoundContainer(bound)); } sink.process(new NodeContainer(createNode())); sink.complete(); } finally { sink.release(); } } private Node createNode() { double lon = (bound.getRight() - bound.getLeft()) / 2; double lat = (bound.getTop() - bound.getBottom()) / 2; return new Node( new CommonEntityData(idGenerator.incrementAndGet(), 1, new Date(), OsmUser.NONE, 1), lat, lon); } } } osmosis-0.44.1/osmosis-set/src/test/resources/000077500000000000000000000000001253404521400213415ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/test/resources/data/000077500000000000000000000000001253404521400222525ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/test/resources/data/template/000077500000000000000000000000001253404521400240655ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/000077500000000000000000000000001253404521400246375ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/append-change-in1.osc000066400000000000000000000023421253404521400305250ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/append-change-in2.osc000066400000000000000000000023131253404521400305240ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/append-change-out.osc000066400000000000000000000044521253404521400306510ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/apply_change/000077500000000000000000000000001253404521400272715ustar00rootroot00000000000000apply-change-base-high.osm000066400000000000000000000011651253404521400341320ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/apply_change apply-change-base-node-only.osm000066400000000000000000000003621253404521400351150ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/apply_change osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/apply_change/apply-change-base.osm000066400000000000000000000011541253404521400332720ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/apply_change/apply-change-big.osm000066400000000000000000000021431253404521400331200ustar00rootroot00000000000000 apply-change-create.osm000066400000000000000000000013761253404521400335520ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/apply_change apply-change-delete.osm000066400000000000000000000007321253404521400335440ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/apply_change apply-change-modify-higher.osm000066400000000000000000000011621253404521400350330ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/apply_change apply-change-modify-nonexistent.osm000066400000000000000000000013761253404521400361520ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/apply_change apply-change-modify.osm000066400000000000000000000011541253404521400335700ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/apply_change osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/apply_change/change-big-create.osc000066400000000000000000000020271253404521400332250ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/apply_change/change-big-delete.osc000066400000000000000000000020271253404521400332240ustar00rootroot00000000000000 change-create-existent.osc000066400000000000000000000004321253404521400342460ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/apply_change change-create-modify-delete.osc000066400000000000000000000011701253404521400351320ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/apply_change osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/apply_change/change-create.osc000066400000000000000000000004321253404521400324640ustar00rootroot00000000000000 change-delete-nonexistent.osc000066400000000000000000000003711253404521400347620ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/apply_change osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/apply_change/change-delete.osc000066400000000000000000000003661253404521400324710ustar00rootroot00000000000000 change-modify-nonexistent.osc000066400000000000000000000004321253404521400350050ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/apply_change osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/apply_change/change-modify.osc000066400000000000000000000004321253404521400325100ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/change-to-full-history-in.osc000066400000000000000000000034351253404521400322620ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/change-to-full-history-out.osm000066400000000000000000000034161253404521400324740ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/derive_change/000077500000000000000000000000001253404521400274225ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/derive_change/full-create.osc000066400000000000000000000012601253404521400323320ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/derive_change/simple.osm000066400000000000000000000011651253404521400314360ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/empty-change.osc000066400000000000000000000001541253404521400277260ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/empty-entity.osm000066400000000000000000000001401253404521400300220ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/flatten-in.osm000066400000000000000000000032041253404521400274170ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/flatten-out.osm000066400000000000000000000011541253404521400276220ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/merge/000077500000000000000000000000001253404521400257365ustar00rootroot00000000000000osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/merge/merge-in-1.osm000066400000000000000000000011541253404521400303200ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/merge/merge-in-2-disjunct.osm000066400000000000000000000011541253404521400321420ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/merge/merge-in-2-secondSource.osm000066400000000000000000000007221253404521400327530ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/merge/merge-in-2-timestamp.osm000066400000000000000000000007221253404521400323220ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/merge/merge-in-2-version.osm000066400000000000000000000007221253404521400320040ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/merge/merge-in-badorder-id.osm000066400000000000000000000016201253404521400323320ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/merge/merge-in-badorder-type.osm000066400000000000000000000011541253404521400327210ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/merge/merge-out-disjunct.osm000066400000000000000000000021701253404521400322030ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/merge/merge-out-secondSource.osm000066400000000000000000000012741253404521400330200ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/merge/merge-out-timestamp.osm000066400000000000000000000012251253404521400323630ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/merge/merge-out-version.osm000066400000000000000000000012231253404521400320430ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/simplify-change-in.osc000066400000000000000000000065231253404521400310360ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-set/src/test/resources/data/template/v0_6/simplify-change-out.osc000066400000000000000000000031161253404521400312320ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-tagfilter/000077500000000000000000000000001253404521400167475ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/.checkstyle000066400000000000000000000010051253404521400211020ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-tagfilter/.gitignore000066400000000000000000000000531253404521400207350ustar00rootroot00000000000000.classpath .project .settings /bin /build osmosis-0.44.1/osmosis-tagfilter/build.gradle000066400000000000000000000002131253404521400212220ustar00rootroot00000000000000dependencies { compile project(':osmosis-core') testCompile project(':osmosis-testutil') testCompile project(':osmosis-xml') } osmosis-0.44.1/osmosis-tagfilter/src/000077500000000000000000000000001253404521400175365ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/main/000077500000000000000000000000001253404521400204625ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/main/java/000077500000000000000000000000001253404521400214035ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/main/java/org/000077500000000000000000000000001253404521400221725ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/main/java/org/openstreetmap/000077500000000000000000000000001253404521400250605ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/main/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400265545ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/main/java/org/openstreetmap/osmosis/tagfilter/000077500000000000000000000000001253404521400305355ustar00rootroot00000000000000TagFilterPluginLoader.java000066400000000000000000000050251253404521400355120ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/main/java/org/openstreetmap/osmosis/tagfilter// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagfilter; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.tagfilter.v0_6.NodeKeyFilterFactory; import org.openstreetmap.osmosis.tagfilter.v0_6.NodeKeyValueFilterFactory; import org.openstreetmap.osmosis.tagfilter.v0_6.TagFilterFactory; import org.openstreetmap.osmosis.tagfilter.v0_6.TagRemoverFactory; import org.openstreetmap.osmosis.tagfilter.v0_6.UsedNodeFilterFactory; import org.openstreetmap.osmosis.tagfilter.v0_6.UsedWayFilterFactory; import org.openstreetmap.osmosis.tagfilter.v0_6.WayKeyFilterFactory; import org.openstreetmap.osmosis.tagfilter.v0_6.WayKeyValueFilterFactory; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.plugin.PluginLoader; /** * The plugin loader for the Set manipulation tasks. * * @author Brett Henderson */ public class TagFilterPluginLoader implements PluginLoader { /** * {@inheritDoc} */ @Override public Map loadTaskFactories() { Map factoryMap; factoryMap = new HashMap(); factoryMap.put("used-node", new UsedNodeFilterFactory()); factoryMap.put("un", new UsedNodeFilterFactory()); factoryMap.put("used-way", new UsedWayFilterFactory()); factoryMap.put("uw", new UsedWayFilterFactory()); factoryMap.put("tag-filter", new TagFilterFactory()); factoryMap.put("tf", new TagFilterFactory()); factoryMap.put("node-key", new NodeKeyFilterFactory()); factoryMap.put("nk", new NodeKeyFilterFactory()); factoryMap.put("node-key-value", new NodeKeyValueFilterFactory()); factoryMap.put("nkv", new NodeKeyValueFilterFactory()); factoryMap.put("way-key", new WayKeyFilterFactory()); factoryMap.put("wk", new WayKeyFilterFactory()); factoryMap.put("way-key-value", new WayKeyValueFilterFactory()); factoryMap.put("wkv", new WayKeyValueFilterFactory()); factoryMap.put("used-node-0.6", new UsedNodeFilterFactory()); factoryMap.put("used-way-0.6", new UsedWayFilterFactory()); factoryMap.put("tag-filter-0.6", new TagFilterFactory()); factoryMap.put("node-key-0.6", new NodeKeyFilterFactory()); factoryMap.put("node-key-value-0.6", new NodeKeyValueFilterFactory()); factoryMap.put("way-key-0.6", new WayKeyFilterFactory()); factoryMap.put("way-key-value-0.6", new WayKeyValueFilterFactory()); factoryMap.put("remove-tags-0.6", new TagRemoverFactory()); return factoryMap; } } osmosis-0.44.1/osmosis-tagfilter/src/main/java/org/openstreetmap/osmosis/tagfilter/common/000077500000000000000000000000001253404521400320255ustar00rootroot00000000000000KeyValueFileReader.java000066400000000000000000000037221253404521400362650ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/main/java/org/openstreetmap/osmosis/tagfilter/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagfilter.common; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.LinkedList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; /** * Reads the content of a file containing "key.value" tags. * *

* The content of the file contains one key.value pair per line. Example:
* * * railway.tram * railway.tram_stop * * * @author Raluca Martinescu */ public class KeyValueFileReader { /** * Our logger for debug and error -output. */ private static final Logger LOG = Logger.getLogger(KeyValueFileReader.class.getName()); /** * Where we read from. */ private BufferedReader reader; /** * Creates a new instance. * * @param keyValueFile * The file to read key.value tags from. * @throws FileNotFoundException * in case the specified file does not exist */ public KeyValueFileReader(final File keyValueFile) throws FileNotFoundException { this.reader = new BufferedReader(new FileReader(keyValueFile)); } /** * Reads the file and returns an array of key.value tags. * * @return an array of key.value tags * @throws IOException * in case the file could not be read */ public String[] loadKeyValues() throws IOException { List result = new LinkedList(); try { String line; while ((line = reader.readLine()) != null) { result.add(line); } } finally { cleanup(); } return result.toArray(new String[0]); } /** * Releases any resources remaining open. */ private void cleanup() { if (reader != null) { try { reader.close(); } catch (Exception e) { LOG.log(Level.SEVERE, "Unable to close file reader.", e); } finally { reader = null; } } } } osmosis-0.44.1/osmosis-tagfilter/src/main/java/org/openstreetmap/osmosis/tagfilter/v0_6/000077500000000000000000000000001253404521400313075ustar00rootroot00000000000000NodeKeyFilter.java000066400000000000000000000051711253404521400346030ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/main/java/org/openstreetmap/osmosis/tagfilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagfilter.v0_6; import java.util.HashSet; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityProcessor; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.task.v0_6.SinkSource; /** * A class filtering everything but allowed nodes. * * @author Aurelien Jacobs */ public class NodeKeyFilter implements SinkSource, EntityProcessor { private Sink sink; private HashSet allowedKeys; /** * Creates a new instance. * * @param keyList * Comma-separated list of allowed key, * e.g. "place,amenity" */ public NodeKeyFilter(String keyList) { allowedKeys = new HashSet(); String[] keys = keyList.split(","); for (int i = 0; i < keys.length; i++) { allowedKeys.add(keys[i]); } } /** * {@inheritDoc} */ public void initialize(Map metaData) { sink.initialize(metaData); } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { // Ask the entity container to invoke the appropriate processing method // for the entity type. entityContainer.process(this); } /** * {@inheritDoc} */ public void process(BoundContainer boundContainer) { // By default, pass it on unchanged sink.process(boundContainer); } /** * {@inheritDoc} */ public void process(NodeContainer container) { Node node = container.getEntity(); boolean matchesFilter = false; for (Tag tag : node.getTags()) { if (allowedKeys.contains(tag.getKey())) { matchesFilter = true; break; } } if (matchesFilter) { sink.process(container); } } /** * {@inheritDoc} */ public void process(WayContainer container) { // Do nothing. } /** * {@inheritDoc} */ public void process(RelationContainer container) { // Do nothing. } /** * {@inheritDoc} */ public void complete() { sink.complete(); } /** * {@inheritDoc} */ public void release() { sink.release(); } /** * {@inheritDoc} */ public void setSink(Sink sink) { this.sink = sink; } } NodeKeyFilterFactory.java000066400000000000000000000017031253404521400361300ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/main/java/org/openstreetmap/osmosis/tagfilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagfilter.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkSourceManager; /** * Extends the basic task manager factory functionality with used-node filter task * specific common methods. * * @author Brett Henderson * @author Christoph Sommer */ public class NodeKeyFilterFactory extends TaskManagerFactory { /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String keyList = getStringArgument(taskConfig, "keyList"); return new SinkSourceManager( taskConfig.getId(), new NodeKeyFilter(keyList), taskConfig.getPipeArgs() ); } } NodeKeyValueFilter.java000066400000000000000000000074041253404521400356010ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/main/java/org/openstreetmap/osmosis/tagfilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagfilter.v0_6; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.HashSet; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityProcessor; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.task.v0_6.SinkSource; import org.openstreetmap.osmosis.tagfilter.common.KeyValueFileReader; /** * A class filtering everything but allowed nodes. * * @author Aurelien Jacobs */ public class NodeKeyValueFilter implements SinkSource, EntityProcessor { private Sink sink; private HashSet allowedKeyValues; /** * Creates a new instance. * * @param keyValueList * Comma-separated list of allowed key-value combinations, * e.g. "place.city,place.town" */ public NodeKeyValueFilter(String keyValueList) { allowedKeyValues = new HashSet(); String[] keyValues = keyValueList.split(","); for (int i = 0; i < keyValues.length; i++) { allowedKeyValues.add(keyValues[i]); } } /** * Creates a new instance. * * @param keyValueListFile * File containing one key-value combination per line */ public NodeKeyValueFilter(File keyValueListFile) { String[] keyValues; try { KeyValueFileReader reader = new KeyValueFileReader(keyValueListFile); keyValues = reader.loadKeyValues(); } catch (FileNotFoundException ex) { throw new OsmosisRuntimeException("Unable to find key.value file " + keyValueListFile.getAbsolutePath() + ".", ex); } catch (IOException ex) { throw new OsmosisRuntimeException("Unable to read from key.value file " + keyValueListFile.getAbsolutePath() + ".", ex); } allowedKeyValues = new HashSet(); for (int i = 0; i < keyValues.length; i++) { allowedKeyValues.add(keyValues[i]); } } /** * {@inheritDoc} */ public void initialize(Map metaData) { sink.initialize(metaData); } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { // Ask the entity container to invoke the appropriate processing method // for the entity type. entityContainer.process(this); } /** * {@inheritDoc} */ public void process(BoundContainer boundContainer) { // By default, pass it on unchanged sink.process(boundContainer); } /** * {@inheritDoc} */ public void process(NodeContainer container) { Node node = container.getEntity(); boolean matchesFilter = false; for (Tag tag : node.getTags()) { String keyValue = tag.getKey() + "." + tag.getValue(); if (allowedKeyValues.contains(keyValue)) { matchesFilter = true; break; } } if (matchesFilter) { sink.process(container); } } /** * {@inheritDoc} */ public void process(WayContainer container) { // Do nothing. } /** * {@inheritDoc} */ public void process(RelationContainer container) { // Do nothing. } /** * {@inheritDoc} */ public void complete() { sink.complete(); } /** * {@inheritDoc} */ public void release() { sink.release(); } /** * {@inheritDoc} */ public void setSink(Sink sink) { this.sink = sink; } } NodeKeyValueFilterFactory.java000066400000000000000000000027221253404521400371270ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/main/java/org/openstreetmap/osmosis/tagfilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagfilter.v0_6; import java.io.File; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkSourceManager; /** * Extends the basic task manager factory functionality with used-node filter task * specific common methods. * * @author Brett Henderson * @author Christoph Sommer */ public class NodeKeyValueFilterFactory extends TaskManagerFactory { private static final String ARG_KEY_VALUE_LIST = "keyValueList"; private static final String ARG_KEY_VALUE_LIST_FILE = "keyValueListFile"; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { NodeKeyValueFilter nodeKeyValueFilter; if (doesArgumentExist(taskConfig, ARG_KEY_VALUE_LIST)) { String keyValueList = getStringArgument(taskConfig, ARG_KEY_VALUE_LIST); nodeKeyValueFilter = new NodeKeyValueFilter(keyValueList); } else { String keyValueListFile = getStringArgument(taskConfig, ARG_KEY_VALUE_LIST_FILE); nodeKeyValueFilter = new NodeKeyValueFilter(new File(keyValueListFile)); } return new SinkSourceManager( taskConfig.getId(), nodeKeyValueFilter, taskConfig.getPipeArgs() ); } } TagFilter.java000066400000000000000000000125271253404521400337630ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/main/java/org/openstreetmap/osmosis/tagfilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagfilter.v0_6; import java.util.Set; import java.util.Map; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.task.v0_6.SinkSource; /** * A simple class to filter node, way, and relation entities by their tag keys and/or values. * * @author Andrew Byrd */ public class TagFilter implements SinkSource { private Sink sink; private Set tagKeys; private Map> tagKeyValues; private Class filterClass; private boolean reject; private boolean matchesEverything; private static final Logger LOG = Logger.getLogger(TagFilter.class.getName()); /** * Creates a new instance. * * @param filterMode * A 2-field dash-separated string specifying: * 1. Whether the filter accepts or rejects entities * 2. The entity type upon which it operates * * @param tagKeys * A Set of tag key Strings. The filter will match these tags irrespective of tag values. * * @param tagKeyValues * A map of tag key Strings to Sets of tag key values. These key-value pairs are checked * against each entity's tags to determine whether or not it matches the filter. */ public TagFilter(String filterMode, Set tagKeys, Map> tagKeyValues) { String[] filterModeSplit = filterMode.toLowerCase().split("-"); if (filterModeSplit.length != 2) { throw new OsmosisRuntimeException( "The TagFilter task's default parameter must consist of an action and an entity type separated by '-'."); } String action = filterModeSplit[0]; if (action.equals("accept")) { reject = false; } else if (action.equals("reject")) { reject = true; } else { throw new OsmosisRuntimeException( "The TagFilter action must be either 'accept' or 'reject'. '" + action + "' is not a supported mode."); } String entity = filterModeSplit[1]; if (entity.endsWith("s")) { entity = entity.substring(0, entity.length() - 1); } if (entity.equals("node")) { filterClass = NodeContainer.class; } else if (entity.equals("way")) { filterClass = WayContainer.class; } else if (entity.equals("relation")) { filterClass = RelationContainer.class; } else { throw new OsmosisRuntimeException( "The TagFilter entity type must be one of 'node', 'way', or 'relation'. '" + entity + "' is not a supported entity type."); } matchesEverything = (tagKeys.size() == 0 && tagKeyValues.size() == 0); this.tagKeys = tagKeys; this.tagKeyValues = tagKeyValues; String logString = "New TagFilter "; if (reject) { logString += "rejects "; } else { logString += "accepts "; } logString += filterClass; if (matchesEverything) { logString += " (no tag-based filtering)."; } else { logString += " having tag keys " + tagKeys + " or tag key-value pairs " + tagKeyValues + "."; } LOG.finer(logString); } /** * Checks whether the Entity in a container has tags that match this filter. * * @param container * The container holding the entity whose tags shall be examined. */ private boolean matches(EntityContainer container) { boolean matched = false; for (Tag tag : container.getEntity().getTags()) { String key = tag.getKey(); if (tagKeys.contains(key)) { matched = true; break; } Set values = tagKeyValues.get(key); if ((values != null) && values.contains(tag.getValue())) { matched = true; break; } } return matched; } /** * {@inheritDoc} */ public void initialize(Map metaData) { sink.initialize(metaData); } /** * {@inheritDoc} */ public void process(EntityContainer container) { if (filterClass.isInstance(container)) { if (reject ^ (matchesEverything || matches(container))) { sink.process(container); } } else { sink.process(container); } } /** * {@inheritDoc} */ public void complete() { sink.complete(); } /** * {@inheritDoc} */ public void release() { sink.release(); } /** * {@inheritDoc} */ public void setSink(Sink sink) { this.sink = sink; } } TagFilterFactory.java000066400000000000000000000054301253404521400353060ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/main/java/org/openstreetmap/osmosis/tagfilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagfilter.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkSourceManager; import java.util.Map; import java.util.Set; import java.util.HashMap; import java.util.HashSet; /** * Extends the basic task manager factory functionality with TagFilter task * specific common methods. * * @author Andrew Byrd */ public class TagFilterFactory extends TaskManagerFactory { /** * Decodes escaped wildcard, separator, equals, and space characters. * * @param s * the String to decode. */ private String unEscape(String s) { StringBuilder sb = new StringBuilder(); boolean escaped = false; for (char c : s.toCharArray()) { if (escaped) { switch (c) { case '%': sb.append('%'); break; case 'a': sb.append('*'); break; case 'c': sb.append(','); break; case 'e': sb.append('='); break; case 's': sb.append(' '); break; default : break; } escaped = false; } else { if (c == '%') { escaped = true; } else { sb.append(c); } } } return sb.toString(); } /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { // Iterate over keyword arguments and fetch them through the appropriate TaskManagerFactory utility method // to avoid 'Argument was not recognized' exceptions from Osmosis Set keys = new HashSet(); Map> keyValues = new HashMap>(); for (String key : taskConfig.getConfigArgs().keySet()) { String value = getStringArgument(taskConfig, key); if (value.equals("*")) { keys.add(unEscape(key)); } else { Set values = new HashSet(); for (String v : value.split(",")) { values.add(unEscape(v)); } keyValues.put(unEscape(key), values); } } return new SinkSourceManager( taskConfig.getId(), new TagFilter(getDefaultStringArgument(taskConfig, ""), keys, keyValues), taskConfig.getPipeArgs() ); } } TagRemover.java000066400000000000000000000045421253404521400341530ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/main/java/org/openstreetmap/osmosis/tagfilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagfilter.v0_6; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.task.v0_6.SinkSource; /** * Filters a set of tags from all entities. This allows unwanted tags to be * removed from the data. * * @author Jochen Topf * @author Brett Henderson */ public class TagRemover implements SinkSource { private Sink sink; private HashSet keysToDrop; private String[] keyPrefixesToDrop; /** * Creates a new instance. * * @param keyList * Comma separated list of keys of tags to be removed. * @param keyPrefixList * Comma separated list of key prefixes of tags to be removed. */ public TagRemover(String keyList, String keyPrefixList) { keysToDrop = new HashSet(); String[] keys = keyList.split(","); for (int i = 0; i < keys.length; i++) { keysToDrop.add(keys[i]); } keyPrefixesToDrop = keyPrefixList.split(","); if (keyPrefixesToDrop[0] == "") { keyPrefixesToDrop = new String[] {}; } } /** * {@inheritDoc} */ public void setSink(Sink sink) { this.sink = sink; } /** * {@inheritDoc} */ public void initialize(Map metaData) { sink.initialize(metaData); } /** * {@inheritDoc} */ @Override public void process(EntityContainer entityContainer) { EntityContainer writeableContainer; Entity entity; writeableContainer = entityContainer.getWriteableInstance(); entity = writeableContainer.getEntity(); for (Iterator i = entity.getTags().iterator(); i.hasNext();) { Tag tag; tag = i.next(); if (keysToDrop.contains(tag.getKey())) { i.remove(); } else { for (String prefix : keyPrefixesToDrop) { if (tag.getKey().startsWith(prefix)) { i.remove(); break; } } } } sink.process(writeableContainer); } /** * {@inheritDoc} */ public void complete() { sink.complete(); } /** * {@inheritDoc} */ public void release() { sink.release(); } } TagRemoverFactory.java000066400000000000000000000023151253404521400354770ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/main/java/org/openstreetmap/osmosis/tagfilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagfilter.v0_6; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkSourceManager; /** * Extends the basic task manager factory functionality with drop tags task * specific common methods. * * @author Jochen Topf */ public class TagRemoverFactory extends TaskManagerFactory { /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String keys; String keyPrefixes; try { keys = getStringArgument(taskConfig, "keys"); } catch (OsmosisRuntimeException e) { keys = ""; } try { keyPrefixes = getStringArgument(taskConfig, "keyPrefixes"); } catch (OsmosisRuntimeException e) { keyPrefixes = ""; } return new SinkSourceManager( taskConfig.getId(), new TagRemover(keys, keyPrefixes), taskConfig.getPipeArgs() ); } } UsedNodeFilter.java000066400000000000000000000121221253404521400347450ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/main/java/org/openstreetmap/osmosis/tagfilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagfilter.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityProcessor; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.openstreetmap.osmosis.core.filter.common.IdTracker; import org.openstreetmap.osmosis.core.filter.common.IdTrackerFactory; import org.openstreetmap.osmosis.core.filter.common.IdTrackerType; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.store.SimpleObjectStore; import org.openstreetmap.osmosis.core.store.SingleClassObjectSerializationFactory; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.task.v0_6.SinkSource; /** * Restricts output of nodes to those that are used in ways and relations. * * @author Brett Henderson * @author Karl Newman * @author Christoph Sommer * @author Bartosz Fabianowski */ public class UsedNodeFilter implements SinkSource, EntityProcessor { private Sink sink; private SimpleObjectStore allNodes; private SimpleObjectStore allWays; private SimpleObjectStore allRelations; private IdTracker requiredNodes; /** * Creates a new instance. * * @param idTrackerType * Defines the id tracker implementation to use. */ public UsedNodeFilter(IdTrackerType idTrackerType) { allNodes = new SimpleObjectStore( new SingleClassObjectSerializationFactory(NodeContainer.class), "afnd", true); allWays = new SimpleObjectStore( new SingleClassObjectSerializationFactory(WayContainer.class), "afwy", true); allRelations = new SimpleObjectStore( new SingleClassObjectSerializationFactory(RelationContainer.class), "afrl", true); requiredNodes = IdTrackerFactory.createInstance(idTrackerType); } /** * {@inheritDoc} */ public void initialize(Map metaData) { sink.initialize(metaData); } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { // Ask the entity container to invoke the appropriate processing method // for the entity type. entityContainer.process(this); } /** * {@inheritDoc} */ public void process(BoundContainer boundContainer) { // By default, pass it on unchanged sink.process(boundContainer); } /** * {@inheritDoc} */ public void process(NodeContainer container) { allNodes.add(container); } /** * {@inheritDoc} */ public void process(WayContainer container) { Way way; // mark all nodes as required way = container.getEntity(); for (WayNode nodeReference : way.getWayNodes()) { long nodeId = nodeReference.getNodeId(); requiredNodes.set(nodeId); } allWays.add(container); } /** * {@inheritDoc} */ public void process(RelationContainer container) { Relation relation; // mark all nodes as required relation = container.getEntity(); for (RelationMember memberReference : relation.getMembers()) { if (memberReference.getMemberType() == EntityType.Node) { long nodeId = memberReference.getMemberId(); requiredNodes.set(nodeId); } } allRelations.add(container); } /** * {@inheritDoc} */ public void complete() { // send on all required nodes ReleasableIterator nodeIterator = allNodes.iterate(); while (nodeIterator.hasNext()) { NodeContainer nodeContainer = nodeIterator.next(); long nodeId = nodeContainer.getEntity().getId(); if (!requiredNodes.get(nodeId)) { continue; } sink.process(nodeContainer); } nodeIterator.release(); nodeIterator = null; // send on all ways ReleasableIterator wayIterator = allWays.iterate(); while (wayIterator.hasNext()) { sink.process(wayIterator.next()); } wayIterator.release(); wayIterator = null; // send on all relations ReleasableIterator relationIterator = allRelations.iterate(); while (relationIterator.hasNext()) { sink.process(relationIterator.next()); } relationIterator.release(); relationIterator = null; // done sink.complete(); } /** * {@inheritDoc} */ public void release() { if (allNodes != null) { allNodes.release(); } if (allWays != null) { allWays.release(); } if (allRelations != null) { allRelations.release(); } sink.release(); } /** * {@inheritDoc} */ public void setSink(Sink sink) { this.sink = sink; } } UsedNodeFilterFactory.java000066400000000000000000000027571253404521400363120ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/main/java/org/openstreetmap/osmosis/tagfilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagfilter.v0_6; import org.openstreetmap.osmosis.core.filter.common.IdTrackerType; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkSourceManager; /** * Extends the basic task manager factory functionality with used-node filter task * specific common methods. * * @author Brett Henderson * @author Christoph Sommer */ public class UsedNodeFilterFactory extends TaskManagerFactory { private static final IdTrackerType DEFAULT_ID_TRACKER_TYPE = IdTrackerType.Dynamic; /** * Utility method that returns the IdTrackerType to use for a given taskConfig. * * @param taskConfig * Contains all information required to instantiate and configure * the task. * @return The entity identifier tracker type. */ protected IdTrackerType getIdTrackerType( TaskConfiguration taskConfig) { return DEFAULT_ID_TRACKER_TYPE; } /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { IdTrackerType idTrackerType = getIdTrackerType(taskConfig); return new SinkSourceManager( taskConfig.getId(), new UsedNodeFilter(idTrackerType), taskConfig.getPipeArgs() ); } } UsedWayFilter.java000066400000000000000000000114041253404521400346220ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/main/java/org/openstreetmap/osmosis/tagfilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagfilter.v0_6; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityProcessor; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.core.filter.common.IdTracker; import org.openstreetmap.osmosis.core.filter.common.IdTrackerFactory; import org.openstreetmap.osmosis.core.filter.common.IdTrackerType; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.store.SimpleObjectStore; import org.openstreetmap.osmosis.core.store.SingleClassObjectSerializationFactory; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.task.v0_6.SinkSource; /** * Restricts output of ways to those that are used in relations. * * @author Brett Henderson * @author Karl Newman * @author Christoph Sommer * @author Bartosz Fabianowski */ public class UsedWayFilter implements SinkSource, EntityProcessor { private Sink sink; private SimpleObjectStore allNodes; private SimpleObjectStore allWays; private SimpleObjectStore allRelations; private IdTracker requiredWays; /** * Creates a new instance. * * @param idTrackerType * Defines the id tracker implementation to use. */ public UsedWayFilter(IdTrackerType idTrackerType) { allNodes = new SimpleObjectStore( new SingleClassObjectSerializationFactory(NodeContainer.class), "afnd", true); allWays = new SimpleObjectStore( new SingleClassObjectSerializationFactory(WayContainer.class), "afwy", true); allRelations = new SimpleObjectStore( new SingleClassObjectSerializationFactory(RelationContainer.class), "afrl", true); requiredWays = IdTrackerFactory.createInstance(idTrackerType); } /** * {@inheritDoc} */ public void initialize(Map metaData) { sink.initialize(metaData); } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { // Ask the entity container to invoke the appropriate processing method // for the entity type. entityContainer.process(this); } /** * {@inheritDoc} */ public void process(BoundContainer boundContainer) { // By default, pass it on unchanged sink.process(boundContainer); } /** * {@inheritDoc} */ public void process(NodeContainer container) { allNodes.add(container); } /** * {@inheritDoc} */ public void process(WayContainer container) { allWays.add(container); } /** * {@inheritDoc} */ public void process(RelationContainer container) { Relation relation; // mark all nodes as required relation = container.getEntity(); for (RelationMember memberReference : relation.getMembers()) { if (memberReference.getMemberType() == EntityType.Way) { long wayId = memberReference.getMemberId(); requiredWays.set(wayId); } } allRelations.add(container); } /** * {@inheritDoc} */ public void complete() { // send on all nodes ReleasableIterator nodeIterator = allNodes.iterate(); while (nodeIterator.hasNext()) { sink.process(nodeIterator.next()); } nodeIterator.release(); nodeIterator = null; // send on all required ways ReleasableIterator wayIterator = allWays.iterate(); while (wayIterator.hasNext()) { WayContainer wayContainer = wayIterator.next(); long wayId = wayContainer.getEntity().getId(); if (!requiredWays.get(wayId)) { continue; } sink.process(wayContainer); } wayIterator.release(); wayIterator = null; // send on all relations ReleasableIterator relationIterator = allRelations.iterate(); while (relationIterator.hasNext()) { sink.process(relationIterator.next()); } relationIterator.release(); relationIterator = null; // done sink.complete(); } /** * {@inheritDoc} */ public void release() { if (allNodes != null) { allNodes.release(); } if (allWays != null) { allWays.release(); } if (allRelations != null) { allRelations.release(); } sink.release(); } /** * {@inheritDoc} */ public void setSink(Sink sink) { this.sink = sink; } } UsedWayFilterFactory.java000066400000000000000000000030071253404521400361520ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/main/java/org/openstreetmap/osmosis/tagfilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagfilter.v0_6; import org.openstreetmap.osmosis.core.filter.common.IdTrackerType; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkSourceManager; /** * Extends the basic task manager factory functionality with used-way filter task * specific common methods. * * @author Brett Henderson * @author Christoph Sommer * @author Bartosz Fabianowski */ public class UsedWayFilterFactory extends TaskManagerFactory { private static final IdTrackerType DEFAULT_ID_TRACKER_TYPE = IdTrackerType.Dynamic; /** * Utility method that returns the IdTrackerType to use for a given taskConfig. * * @param taskConfig * Contains all information required to instantiate and configure * the task. * @return The entity identifier tracker type. */ protected IdTrackerType getIdTrackerType( TaskConfiguration taskConfig) { return DEFAULT_ID_TRACKER_TYPE; } /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { IdTrackerType idTrackerType = getIdTrackerType(taskConfig); return new SinkSourceManager( taskConfig.getId(), new UsedWayFilter(idTrackerType), taskConfig.getPipeArgs() ); } } WayKeyFilter.java000066400000000000000000000053551253404521400344620ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/main/java/org/openstreetmap/osmosis/tagfilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagfilter.v0_6; import java.util.HashSet; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityProcessor; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.task.v0_6.SinkSource; /** * A simple class to filter way entities by their tag keys. * Based on work by Brett Henderson, Karl Newman, Christoph Sommer, Aurelien Jacobs * * @author Andrew Byrd */ public class WayKeyFilter implements SinkSource, EntityProcessor { private Sink sink; private HashSet allowedKeys; /** * Creates a new instance. * * @param keyList * Comma-separated list of allowed keys, * e.g. "highway,place" */ public WayKeyFilter(String keyList) { allowedKeys = new HashSet(); String[] keys = keyList.split(","); for (int i = 0; i < keys.length; i++) { allowedKeys.add(keys[i]); } } /** * {@inheritDoc} */ public void initialize(Map metaData) { sink.initialize(metaData); } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { // Ask the entity container to invoke the appropriate processing method // for the entity type. entityContainer.process(this); } /** * {@inheritDoc} */ public void process(BoundContainer boundContainer) { // By default, pass it on unchanged sink.process(boundContainer); } /** * {@inheritDoc} */ public void process(NodeContainer container) { sink.process(container); } /** * {@inheritDoc} */ public void process(WayContainer container) { Way way = container.getEntity(); boolean matchesFilter = false; for (Tag tag : way.getTags()) { if (allowedKeys.contains(tag.getKey())) { matchesFilter = true; break; } } if (matchesFilter) { sink.process(container); } } /** * {@inheritDoc} */ public void process(RelationContainer container) { sink.process(container); } /** * {@inheritDoc} */ public void complete() { sink.complete(); } /** * {@inheritDoc} */ public void release() { sink.release(); } /** * {@inheritDoc} */ public void setSink(Sink sink) { this.sink = sink; } } WayKeyFilterFactory.java000066400000000000000000000017011253404521400360010ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/main/java/org/openstreetmap/osmosis/tagfilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagfilter.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkSourceManager; /** * Extends the basic task manager factory functionality with used-node filter task * specific common methods. * * @author Brett Henderson * @author Christoph Sommer */ public class WayKeyFilterFactory extends TaskManagerFactory { /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String keyList = getStringArgument(taskConfig, "keyList"); return new SinkSourceManager( taskConfig.getId(), new WayKeyFilter(keyList), taskConfig.getPipeArgs() ); } } WayKeyValueFilter.java000066400000000000000000000075471253404521400354640ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/main/java/org/openstreetmap/osmosis/tagfilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagfilter.v0_6; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.HashSet; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityProcessor; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.task.v0_6.SinkSource; import org.openstreetmap.osmosis.tagfilter.common.KeyValueFileReader; /** * A simple class to filter way entities by their tags. * * @author Brett Henderson * @author Karl Newman * @author Christoph Sommer */ public class WayKeyValueFilter implements SinkSource, EntityProcessor { private Sink sink; private HashSet allowedKeyValues; /** * Creates a new instance. * * @param keyValueList * Comma-separated list of allowed key-value combinations, * e.g. "highway.motorway,highway.motorway_link" */ public WayKeyValueFilter(String keyValueList) { allowedKeyValues = new HashSet(); String[] keyValues = keyValueList.split(","); for (int i = 0; i < keyValues.length; i++) { allowedKeyValues.add(keyValues[i]); } } /** * Creates a new instance. * * @param keyValueListFile * File containing one key-value combination per line */ public WayKeyValueFilter(File keyValueListFile) { String[] keyValues; try { KeyValueFileReader reader = new KeyValueFileReader(keyValueListFile); keyValues = reader.loadKeyValues(); } catch (FileNotFoundException ex) { throw new OsmosisRuntimeException("Unable to find key.value file " + keyValueListFile.getAbsolutePath() + ".", ex); } catch (IOException ex) { throw new OsmosisRuntimeException("Unable to read from key.value file " + keyValueListFile.getAbsolutePath() + ".", ex); } allowedKeyValues = new HashSet(); for (int i = 0; i < keyValues.length; i++) { allowedKeyValues.add(keyValues[i]); } } /** * {@inheritDoc} */ public void initialize(Map metaData) { sink.initialize(metaData); } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { // Ask the entity container to invoke the appropriate processing method // for the entity type. entityContainer.process(this); } /** * {@inheritDoc} */ public void process(BoundContainer boundContainer) { // By default, pass it on unchanged sink.process(boundContainer); } /** * {@inheritDoc} */ public void process(NodeContainer container) { sink.process(container); } /** * {@inheritDoc} */ public void process(WayContainer container) { Way way = container.getEntity(); boolean matchesFilter = false; for (Tag tag : way.getTags()) { String keyValue = tag.getKey() + "." + tag.getValue(); if (allowedKeyValues.contains(keyValue)) { matchesFilter = true; break; } } if (matchesFilter) { sink.process(container); } } /** * {@inheritDoc} */ public void process(RelationContainer container) { sink.process(container); } /** * {@inheritDoc} */ public void complete() { sink.complete(); } /** * {@inheritDoc} */ public void release() { sink.release(); } /** * {@inheritDoc} */ public void setSink(Sink sink) { this.sink = sink; } } WayKeyValueFilterFactory.java000066400000000000000000000033311253404521400367770ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/main/java/org/openstreetmap/osmosis/tagfilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagfilter.v0_6; import java.io.File; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkSourceManager; /** * Extends the basic task manager factory functionality with used-node filter task * specific common methods. * * @author Brett Henderson * @author Christoph Sommer */ public class WayKeyValueFilterFactory extends TaskManagerFactory { private static final String ARG_KEY_VALUE_LIST = "keyValueList"; private static final String ARG_KEY_VALUE_LIST_FILE = "keyValueListFile"; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { WayKeyValueFilter wayKeyValueFilter; if (doesArgumentExist(taskConfig, ARG_KEY_VALUE_LIST)) { String keyValueList = getStringArgument(taskConfig, ARG_KEY_VALUE_LIST); wayKeyValueFilter = new WayKeyValueFilter(keyValueList); } else if (doesArgumentExist(taskConfig, ARG_KEY_VALUE_LIST_FILE)) { String keyValueListFile = getStringArgument(taskConfig, ARG_KEY_VALUE_LIST_FILE); wayKeyValueFilter = new WayKeyValueFilter(new File(keyValueListFile)); } else { String keyValueList = getDefaultStringArgument(taskConfig, "highway.motorway,highway.motorway_link,highway.trunk,highway.trunk_link"); wayKeyValueFilter = new WayKeyValueFilter(keyValueList); } return new SinkSourceManager( taskConfig.getId(), wayKeyValueFilter, taskConfig.getPipeArgs() ); } } osmosis-0.44.1/osmosis-tagfilter/src/main/resources/000077500000000000000000000000001253404521400224745ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/main/resources/osmosis-plugins.conf000066400000000000000000000000711253404521400265140ustar00rootroot00000000000000org.openstreetmap.osmosis.tagfilter.TagFilterPluginLoaderosmosis-0.44.1/osmosis-tagfilter/src/test/000077500000000000000000000000001253404521400205155ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/test/java/000077500000000000000000000000001253404521400214365ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/test/java/org/000077500000000000000000000000001253404521400222255ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/test/java/org/openstreetmap/000077500000000000000000000000001253404521400251135ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/test/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400266075ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/test/java/org/openstreetmap/osmosis/tagfilter/000077500000000000000000000000001253404521400305705ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/test/java/org/openstreetmap/osmosis/tagfilter/common/000077500000000000000000000000001253404521400320605ustar00rootroot00000000000000KeyValueFileReaderTest.java000066400000000000000000000025531253404521400371610ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/test/java/org/openstreetmap/osmosis/tagfilter/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagfilter.common; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import org.junit.Assert; import org.junit.Test; import org.openstreetmap.osmosis.testutil.AbstractDataTest; /** * Tests for the KeyValueFileReader class. * * @author Raluca Martinescu */ public class KeyValueFileReaderTest extends AbstractDataTest { /** * Tests that in case the file does not exist, the KeyValueFileReader * constructor throws an exception. * * @throws FileNotFoundException * when the test class encounters the non-existent file. */ @Test(expected = FileNotFoundException.class) public final void testFileNotFound() throws FileNotFoundException { File file = new File("non_existing_file.txt"); new KeyValueFileReader(file); } /** * Tests the reading of key-value pairs from the file. * * @throws IOException * if the allowed-key-values file cannot be found. */ @Test public final void testLoadKeyValues() throws IOException { File file = dataUtils.createDataFile("v0_6/allowed-key-values.txt"); String[] expected = {"box_type.lamp_box", "box_type.wall"}; String[] actual = new KeyValueFileReader(file).loadKeyValues(); Assert.assertArrayEquals(expected, actual); } } osmosis-0.44.1/osmosis-tagfilter/src/test/java/org/openstreetmap/osmosis/tagfilter/v0_6/000077500000000000000000000000001253404521400313425ustar00rootroot00000000000000NodeKeyValueFilterTest.java000066400000000000000000000035561253404521400365000ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/test/java/org/openstreetmap/osmosis/tagfilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagfilter.v0_6; import java.io.File; import java.io.IOException; import org.junit.Test; import org.openstreetmap.osmosis.core.Osmosis; import org.openstreetmap.osmosis.testutil.AbstractDataTest; /** * Tests for the NodeKeyValueFilter class. * * @author Raluca Martinescu */ public class NodeKeyValueFilterTest extends AbstractDataTest { /** * Tests the node key-value filter when allowed value pairs are read from * comma separated list of values. * * @throws IOException * if file manipulation fails. */ @Test public final void testNodeKeyValueFilterFromList() throws IOException { testNodeKeyValueFilter("keyValueList=box_type.lamp_box,box_type.wall"); } /** * Tests the node key-value filter when allowed value pairs are read from * file. * * @throws IOException * if file manipulation fails. */ @Test public final void testNodeKeyValueFilterFromFile() throws IOException { File allowedPairs = dataUtils.createDataFile("v0_6/allowed-key-values.txt"); testNodeKeyValueFilter("keyValueListFile=" + allowedPairs.getPath()); } private void testNodeKeyValueFilter(String keyValueListOption) throws IOException { File inputFile = dataUtils.createDataFile("v0_6/node-key-value-filter-snapshot.osm"); File expectedResultFile = dataUtils.createDataFile("v0_6/node-key-value-filter-expected.osm"); File outputFile = dataUtils.newFile(); // filter by key-value pairs Osmosis.run( new String [] { "-q", "--read-xml-0.6", inputFile.getPath(), "--node-key-value", keyValueListOption, "--write-xml-0.6", outputFile.getPath() } ); // Validate that the output file matches the expected file dataUtils.compareFiles(expectedResultFile, outputFile); } } TagFilterTest.java000066400000000000000000000131351253404521400346520ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/test/java/org/openstreetmap/osmosis/tagfilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagfilter.v0_6; import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.openstreetmap.osmosis.testutil.v0_6.SinkEntityInspector; /** * Tests the TagFilter implementation. * * @author Andrew Byrd * Based on tests written by Karl Newman */ public class TagFilterTest { private SinkEntityInspector entityInspector; private TagFilter tagFilter; private Node amenityNode; private NodeContainer amenityNodeContainer; private Node taglessNode; private NodeContainer taglessNodeContainer; private Way motorwayWay; private WayContainer motorwayWayContainer; private Way residentialWay; private WayContainer residentialWayContainer; private Relation testRelation; private RelationContainer testRelationContainer; /** * Performs pre-test activities. */ @Before public void setUp() { OsmUser user; List tags; user = new OsmUser(12, "OsmosisTest"); tags = Arrays.asList(new Tag("amenity", "bank"), new Tag("Akey", "Avalue")); amenityNode = new Node(new CommonEntityData(1101, 0, new Date(), user, 0, tags), 1, 2); amenityNodeContainer = new NodeContainer(amenityNode); tags = new ArrayList(); taglessNode = new Node(new CommonEntityData(1102, 0, new Date(), user, 0, tags), 3, 4); taglessNodeContainer = new NodeContainer(taglessNode); tags = Arrays.asList(new Tag("highway", "motorway"), new Tag("Bkey", "Bvalue")); motorwayWay = new Way(new CommonEntityData(2201, 0, new Date(), user, 0, tags), new ArrayList()); motorwayWayContainer = new WayContainer(motorwayWay); tags = Arrays.asList(new Tag("highway", "residential"), new Tag("Ckey", "Cvalue")); residentialWay = new Way(new CommonEntityData(2202, 0, new Date(), user, 0, tags), new ArrayList()); residentialWayContainer = new WayContainer(residentialWay); tags = Arrays.asList(new Tag("Dkey", "Dvalue")); testRelation = new Relation(new CommonEntityData(3301, 0, new Date(), user, 0, tags), new ArrayList()); testRelationContainer = new RelationContainer(testRelation); } /** * Performs post-test activities. */ @After public void tearDown() { // nothing to do here. } /** * Test passing a node which matches the filter. */ @Test public final void testAcceptNode() { Set keys = new HashSet(Arrays.asList("amenity")); Map> keyValues = new HashMap>(); keyValues.put("key", new HashSet(Arrays.asList("valone", "valtwo"))); tagFilter = new TagFilter("accept-nodes", keys, keyValues); entityInspector = new SinkEntityInspector(); tagFilter.setSink(entityInspector); tagFilter.process(amenityNodeContainer); tagFilter.process(taglessNodeContainer); tagFilter.process(residentialWayContainer); tagFilter.complete(); List expectedResult = Arrays.asList(amenityNodeContainer, residentialWayContainer); assertTrue(entityInspector.getProcessedEntities().equals(expectedResult)); tagFilter.release(); } /** * Test rejecting a way which matches the filter. */ @Test public final void testRejectWay() { Set keys = new HashSet(); Map> keyValues = new HashMap>(); keyValues.put("highway", new HashSet(Arrays.asList("motorway", "motorway_link"))); tagFilter = new TagFilter("reject-ways", keys, keyValues); entityInspector = new SinkEntityInspector(); tagFilter.setSink(entityInspector); tagFilter.process(amenityNodeContainer); tagFilter.process(residentialWayContainer); tagFilter.process(motorwayWayContainer); tagFilter.complete(); List expectedResult = Arrays.asList(amenityNodeContainer, residentialWayContainer); assertTrue(entityInspector.getProcessedEntities().equals(expectedResult)); tagFilter.release(); } /** * Test rejecting a relation without tag-based filtering. */ @Test public final void testRejectRelation() { Set keys = new HashSet(); Map> keyValues = new HashMap>(); tagFilter = new TagFilter("reject-relations", keys, keyValues); entityInspector = new SinkEntityInspector(); tagFilter.setSink(entityInspector); tagFilter.process(amenityNodeContainer); tagFilter.process(residentialWayContainer); tagFilter.process(testRelationContainer); tagFilter.complete(); List expectedResult = Arrays.asList(amenityNodeContainer, residentialWayContainer); assertTrue(entityInspector.getProcessedEntities().equals(expectedResult)); tagFilter.release(); } } TagRemoverTest.java000066400000000000000000000040241253404521400350410ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/test/java/org/openstreetmap/osmosis/tagfilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagfilter.v0_6; import java.io.File; import java.io.IOException; import org.junit.Test; import org.openstreetmap.osmosis.core.Osmosis; import org.openstreetmap.osmosis.testutil.AbstractDataTest; /** * Tests for the tag remover task. * * @author Brett Henderson */ public class TagRemoverTest extends AbstractDataTest { /** * Tests tag removal functionality using full key names. * * @throws IOException * if file manipulation fails. */ @Test public void testKey() throws IOException { File inputFile; File outputFile; File expectedResultFile; inputFile = dataUtils.createDataFile("v0_6/tag-remove-snapshot.osm"); expectedResultFile = dataUtils.createDataFile("v0_6/tag-remove-expected.osm"); outputFile = dataUtils.newFile(); // Remove all created_by tags. Osmosis.run( new String [] { "-q", "--read-xml-0.6", inputFile.getPath(), "--remove-tags-0.6", "keys=created_by", "--write-xml-0.6", outputFile.getPath() } ); // Validate that the output file matches the input file. dataUtils.compareFiles(expectedResultFile, outputFile); } /** * Tests tag removal functionality using full key names. * * @throws IOException * if file manipulation fails. */ @Test public void testKeyPrefix() throws IOException { File inputFile; File outputFile; File expectedResultFile; inputFile = dataUtils.createDataFile("v0_6/tag-remove-snapshot.osm"); expectedResultFile = dataUtils.createDataFile("v0_6/tag-remove-expected.osm"); outputFile = dataUtils.newFile(); // Remove all created_by tags. Osmosis.run( new String [] { "-q", "--read-xml-0.6", inputFile.getPath(), "--remove-tags-0.6", "keyPrefixes=crea", "--write-xml-0.6", outputFile.getPath() } ); // Validate that the output file matches the input file. dataUtils.compareFiles(expectedResultFile, outputFile); } } WayKeyValueFilterTest.java000066400000000000000000000035371253404521400363520ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/test/java/org/openstreetmap/osmosis/tagfilter/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagfilter.v0_6; import java.io.File; import java.io.IOException; import org.junit.Test; import org.openstreetmap.osmosis.core.Osmosis; import org.openstreetmap.osmosis.testutil.AbstractDataTest; /** * Tests for the WayKeyValueFilter class. * * @author Raluca Martinescu */ public class WayKeyValueFilterTest extends AbstractDataTest { /** * Tests the way key-value filter when allowed value pairs are read from * comma separated list of values. * * @throws IOException * if file manipulation fails. */ @Test public final void testWayKeyValueFilterFromList() throws IOException { testWayKeyValueFilter("keyValueList=box_type.lamp_box,box_type.wall"); } /** * Tests the way key-value filter when allowed value pairs are read from * file. * * @throws IOException * if file manipulation fails. */ @Test public final void testWayKeyValueFilterFromFile() throws IOException { File allowedPairs = dataUtils.createDataFile("v0_6/allowed-key-values.txt"); testWayKeyValueFilter("keyValueListFile=" + allowedPairs.getPath()); } private void testWayKeyValueFilter(String keyValueListOption) throws IOException { File inputFile = dataUtils.createDataFile("v0_6/way-key-value-filter-snapshot.osm"); File expectedResultFile = dataUtils.createDataFile("v0_6/way-key-value-filter-expected.osm"); File outputFile = dataUtils.newFile(); // filter by key-value pairs Osmosis.run( new String [] { "-q", "--read-xml-0.6", inputFile.getPath(), "--way-key-value", keyValueListOption, "--write-xml-0.6", outputFile.getPath() } ); // Validate that the output file matches the expected file dataUtils.compareFiles(expectedResultFile, outputFile); } } osmosis-0.44.1/osmosis-tagfilter/src/test/resources/000077500000000000000000000000001253404521400225275ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/test/resources/data/000077500000000000000000000000001253404521400234405ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/test/resources/data/template/000077500000000000000000000000001253404521400252535ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/test/resources/data/template/v0_6/000077500000000000000000000000001253404521400260255ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/test/resources/data/template/v0_6/allowed-key-values.txt000066400000000000000000000000371253404521400323000ustar00rootroot00000000000000box_type.lamp_box box_type.wallnode-key-value-filter-expected.osm000066400000000000000000000016141253404521400343770ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/test/resources/data/template/v0_6 node-key-value-filter-snapshot.osm000066400000000000000000000043741253404521400344430ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/test/resources/data/template/v0_6 osmosis-0.44.1/osmosis-tagfilter/src/test/resources/data/template/v0_6/tag-remove-expected.osm000066400000000000000000000030331253404521400324110ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-tagfilter/src/test/resources/data/template/v0_6/tag-remove-snapshot.osm000066400000000000000000000033711253404521400324540ustar00rootroot00000000000000 way-key-value-filter-expected.osm000066400000000000000000000026741253404521400342610ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/test/resources/data/template/v0_6 way-key-value-filter-snapshot.osm000066400000000000000000000034651253404521400343160ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagfilter/src/test/resources/data/template/v0_6 osmosis-0.44.1/osmosis-tagtransform/000077500000000000000000000000001253404521400174755ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/.checkstyle000066400000000000000000000010051253404521400216300ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-tagtransform/.gitignore000066400000000000000000000000531253404521400214630ustar00rootroot00000000000000.classpath .project .settings /bin /build osmosis-0.44.1/osmosis-tagtransform/build.gradle000066400000000000000000000005151253404521400217550ustar00rootroot00000000000000dependencies { compile project(':osmosis-core') compile project(':osmosis-xml') testCompile project(':osmosis-testutil') } /* * Disable checkstyle. * The tag transform plugin used to exist outside the main source tree and as a result * doesn't comply with Osmosis coding standards. */ checkstyleMain.enabled = false osmosis-0.44.1/osmosis-tagtransform/src/000077500000000000000000000000001253404521400202645ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/000077500000000000000000000000001253404521400212105ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/000077500000000000000000000000001253404521400221315ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/000077500000000000000000000000001253404521400227205ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/000077500000000000000000000000001253404521400256065ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400273025ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform/000077500000000000000000000000001253404521400320115ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform/Match.java000066400000000000000000000004531253404521400337120ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagtransform; public interface Match { String getMatchID(); String getKey(int group); String getValue(int group); int getKeyGroupCount(); int getValueGroupCount(); } Matcher.java000066400000000000000000000005601253404521400341610ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagtransform; import java.util.Collection; import java.util.Map; public interface Matcher { Collection match(Map tags, TTEntityType type, String uname, int uid); void outputStats(StringBuilder output, String indent); } osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform/Output.java000066400000000000000000000004731253404521400341600ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagtransform; import java.util.Collection; import java.util.Map; public interface Output { void apply(Map originalTags, Map tags, Collection matches); } StatsSaveException.java000066400000000000000000000005561253404521400363770ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagtransform; import java.io.IOException; public class StatsSaveException extends RuntimeException { private static final long serialVersionUID = 1L; public StatsSaveException(String message, IOException cause) { super(message, cause); } } TTEntityType.java000066400000000000000000000007751253404521400351740ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagtransform; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; public enum TTEntityType { NODE, WAY, RELATION, BOUND; public static TTEntityType fromEntityType06(EntityType entityType) { switch (entityType) { case Node: return NODE; case Way: return WAY; case Relation: return RELATION; case Bound: return BOUND; default: return null; } } } TransformPlugin.java000066400000000000000000000023561253404521400357350ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagtransform; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.plugin.PluginLoader; import org.openstreetmap.osmosis.tagtransform.v0_6.TransformChangeTaskFactory; import org.openstreetmap.osmosis.tagtransform.v0_6.TransformTaskFactory; public class TransformPlugin implements PluginLoader { @Override public Map loadTaskFactories() { TransformTaskFactory transformFactory = new org.openstreetmap.osmosis.tagtransform.v0_6.TransformTaskFactory(); TransformChangeTaskFactory changeTransformFactory = new org.openstreetmap.osmosis.tagtransform.v0_6.TransformChangeTaskFactory(); Map tasks = new HashMap(); tasks.put("tag-transform-0.6", transformFactory); tasks.put("tag-transform", transformFactory); tasks.put("tt", transformFactory); tasks.put("tag-transform-change-0.6", changeTransformFactory); tasks.put("tag-transform-change", changeTransformFactory); tasks.put("ttc", changeTransformFactory); return tasks; } } Translation.java000066400000000000000000000006721253404521400351000ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagtransform; import java.util.Collection; import java.util.Map; public interface Translation { Collection match(Map tags, TTEntityType entityType, String uname, int uid); boolean isDropOnMatch(); Collection getOutputs(); void outputStats(StringBuilder output, String indent); } osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform/impl/000077500000000000000000000000001253404521400327525ustar00rootroot00000000000000AndMatcher.java000066400000000000000000000033061253404521400355460ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagtransform.impl; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import org.openstreetmap.osmosis.tagtransform.Match; import org.openstreetmap.osmosis.tagtransform.Matcher; import org.openstreetmap.osmosis.tagtransform.TTEntityType; public class AndMatcher implements Matcher { private Collection matchers; private long matchHits = 0; private TTEntityType type; private String uname; private int uid; public AndMatcher(Collection matchers, TTEntityType type, String uname, int uid) { this.matchers = matchers; this.type = type; this.uname = uname; this.uid = uid; } @Override public Collection match(Map tags, TTEntityType entityType, String entityUname, int entityUid) { if (this.type != null && this.type != entityType) { return null; } if (this.uname != null && !this.uname.equals(entityUname)) { return null; } if (this.uid != 0 && this.uid != entityUid) { return null; } List allMatches = new ArrayList(); for (Matcher matcher : matchers) { Collection matches = matcher.match(tags, entityType, entityUname, entityUid); if (matches == null || matches.isEmpty()) { return null; } allMatches.addAll(matches); } matchHits++; return allMatches; } @Override public void outputStats(StringBuilder output, String indent) { output.append(indent); output.append("And: "); output.append(matchHits); output.append('\n'); for (Matcher matcher : matchers) { matcher.outputStats(output, indent + " "); } } } CopyAll.java000066400000000000000000000010011253404521400350710ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagtransform.impl; import java.util.Collection; import java.util.Map; import org.openstreetmap.osmosis.tagtransform.Match; import org.openstreetmap.osmosis.tagtransform.Output; public class CopyAll implements Output { @Override public void apply(Map originalTags, Map tags, Collection matches) { // copy all tags tags.putAll(originalTags); } } CopyMatched.java000066400000000000000000000011651253404521400357410ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagtransform.impl; import java.util.Collection; import java.util.Map; import org.openstreetmap.osmosis.tagtransform.Match; import org.openstreetmap.osmosis.tagtransform.Output; public class CopyMatched implements Output { @Override public void apply(Map originalTags, Map tags, Collection matches) { // put any matches directly for (Match match : matches) { if (match.getKeyGroupCount() > 0) { tags.put(match.getKey(0), match.getValue(0)); } } } } CopyUnmatched.java000066400000000000000000000014121253404521400362770ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagtransform.impl; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.tagtransform.Match; import org.openstreetmap.osmosis.tagtransform.Output; public class CopyUnmatched implements Output { @Override public void apply(Map originalTags, Map tags, Collection matches) { // copy the original, then remove the matches Map toCopy = new HashMap(originalTags); for (Match match : matches) { if (match.getKeyGroupCount() > 0) { toCopy.remove(match.getKey(0)); } } // apply the copy tags.putAll(toCopy); } } MatchResultMatch.java000066400000000000000000000016471253404521400367560ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagtransform.impl; import java.util.regex.MatchResult; import org.openstreetmap.osmosis.tagtransform.Match; public class MatchResultMatch implements Match { private MatchResult keyRes; private MatchResult valueRes; private String matchID; public MatchResultMatch(String matchID, MatchResult keyRes, MatchResult valueRes) { this.matchID = matchID; this.keyRes = keyRes; this.valueRes = valueRes; } @Override public String getKey(int group) { return keyRes.group(group); } @Override public int getKeyGroupCount() { return keyRes.groupCount() + 1; } @Override public String getMatchID() { return matchID; } @Override public String getValue(int group) { return valueRes.group(group); } @Override public int getValueGroupCount() { return valueRes.groupCount() + 1; } } NoTagMatcher.java000066400000000000000000000036571253404521400360650ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagtransform.impl; import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.Map.Entry; import java.util.regex.Pattern; import org.openstreetmap.osmosis.tagtransform.Match; import org.openstreetmap.osmosis.tagtransform.Matcher; import org.openstreetmap.osmosis.tagtransform.TTEntityType; public class NoTagMatcher implements Matcher { private Pattern keyPattern; private Pattern valuePattern; private long matchHits; public NoTagMatcher(String keyPattern, String valuePattern) { this.keyPattern = Pattern.compile(keyPattern); this.valuePattern = Pattern.compile(valuePattern); } @Override public Collection match(Map tags, TTEntityType type, String uname, int uid) { // loop through the tags to find matches for (Entry tag : tags.entrySet()) { java.util.regex.Matcher keyMatch = keyPattern.matcher(tag.getKey()); java.util.regex.Matcher valueMatch = valuePattern.matcher(tag.getValue()); if (keyMatch.matches() && valueMatch.matches()) { return null; } } matchHits += 1; return Collections.singleton(NULL_MATCH); } @Override public void outputStats(StringBuilder output, String indent) { output.append(indent); output.append("NoTag["); output.append(keyPattern.pattern()); output.append(","); output.append(valuePattern.pattern()); output.append("]: "); output.append(matchHits); output.append('\n'); } private static final Match NULL_MATCH = new Match() { @Override public int getValueGroupCount() { return 0; } @Override public String getValue(int group) { return null; } @Override public String getMatchID() { return null; } @Override public int getKeyGroupCount() { return 0; } @Override public String getKey(int group) { return null; } }; } OrMatcher.java000066400000000000000000000033031253404521400354210ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagtransform.impl; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import org.openstreetmap.osmosis.tagtransform.Match; import org.openstreetmap.osmosis.tagtransform.Matcher; import org.openstreetmap.osmosis.tagtransform.TTEntityType; public class OrMatcher implements Matcher { private Collection matchers; private long matchHits = 0; private TTEntityType type; private String uname; private int uid; public OrMatcher(Collection matchers, TTEntityType type, String uname, int uid) { this.matchers = matchers; this.type = type; this.uname = uname; this.uid = uid; } @Override public Collection match(Map tags, TTEntityType entityType, String entityUname, int entityUid) { if (this.type != null && this.type != entityType) { return null; } if (this.uname != null && !this.uname.equals(entityUname)) { return null; } if (this.uid != 0 && this.uid != entityUid) { return null; } List allMatches = new ArrayList(); for (Matcher matcher : matchers) { Collection matches = matcher.match(tags, entityType, entityUname, entityUid); if (matches != null) { allMatches.addAll(matches); } } if (!allMatches.isEmpty()) { matchHits++; } return allMatches; } @Override public void outputStats(StringBuilder output, String indent) { output.append(indent); output.append("Or: "); output.append(matchHits); output.append('\n'); for (Matcher matcher : matchers) { matcher.outputStats(output, indent + " "); } } } TagMatcher.java000066400000000000000000000036531253404521400355640ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagtransform.impl; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.regex.MatchResult; import java.util.regex.Pattern; import org.openstreetmap.osmosis.tagtransform.Match; import org.openstreetmap.osmosis.tagtransform.Matcher; import org.openstreetmap.osmosis.tagtransform.TTEntityType; public class TagMatcher implements Matcher { private String matchID; private Pattern keyPattern; private Pattern valuePattern; private long matchHits = 0; public TagMatcher(String matchID, String keyPattern, String valuePattern) { this.matchID = matchID; this.keyPattern = Pattern.compile(keyPattern); this.valuePattern = Pattern.compile(valuePattern); } @Override public Collection match(Map tags, TTEntityType type, String uname, int uid) { List matches = new ArrayList(); // loop through the tags to find matches for (Entry tag : tags.entrySet()) { java.util.regex.Matcher keyMatch = keyPattern.matcher(tag.getKey()); java.util.regex.Matcher valueMatch = valuePattern.matcher(tag.getValue()); if (keyMatch.matches() && valueMatch.matches()) { MatchResult keyRes = keyMatch.toMatchResult(); MatchResult valueRes = valueMatch.toMatchResult(); matches.add(new MatchResultMatch(matchID, keyRes, valueRes)); } } matchHits += matches.size(); return matches; } @Override public void outputStats(StringBuilder output, String indent) { output.append(indent); output.append("Tag["); if (matchID != null) { output.append(matchID); output.append(","); } output.append(keyPattern.pattern()); output.append(","); output.append(valuePattern.pattern()); output.append("]: "); output.append(matchHits); output.append('\n'); } } TagOutput.java000066400000000000000000000034211253404521400354720ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagtransform.impl; import java.text.MessageFormat; import java.util.Collection; import java.util.Map; import org.openstreetmap.osmosis.tagtransform.Match; import org.openstreetmap.osmosis.tagtransform.Output; public class TagOutput implements Output { private MessageFormat keyFormat; private MessageFormat valueFormat; private String fromMatch; public TagOutput(String key, String value, String fromMatch) { keyFormat = new MessageFormat(santitise(key)); valueFormat = new MessageFormat(santitise(value)); if ((fromMatch != null && fromMatch.length() > 0)) { this.fromMatch = fromMatch; } } private String santitise(String str) { if (str == null || str.length() == 0) { return "{0}"; } return str; } @Override public void apply(Map originalTags, Map tags, Collection matches) { // if we have a fromMatch field we apply our format to // each and every matching match if (fromMatch != null) { for (Match match : matches) { String matchID = match.getMatchID(); if (matchID != null && matchID.equals(fromMatch)) { // process key args String[] args = new String[match.getKeyGroupCount()]; for (int i = 0; i < args.length; i++) { args[i] = match.getKey(i); } String key = keyFormat.format(args); // process value args args = new String[match.getValueGroupCount()]; for (int i = 0; i < args.length; i++) { args[i] = match.getValue(i); } String value = valueFormat.format(args); // put the tag tags.put(key, value); } } } else { // simple case tags.put(keyFormat.format(null), valueFormat.format(null)); } } } TransformHelper.java000066400000000000000000000112151253404521400366510ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagtransform.impl; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.domain.common.TimestampFormat; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.task.common.Task; import org.openstreetmap.osmosis.core.task.v0_6.Initializable; import org.openstreetmap.osmosis.tagtransform.Match; import org.openstreetmap.osmosis.tagtransform.Output; import org.openstreetmap.osmosis.tagtransform.StatsSaveException; import org.openstreetmap.osmosis.tagtransform.TTEntityType; import org.openstreetmap.osmosis.tagtransform.Translation; import org.openstreetmap.osmosis.xml.common.XmlTimestampFormat; /** * Class is intended to provide utility place for tag transform functionality. * See {@link org.openstreetmap.osmosis.tagtransform.v0_6.TransformTask * TransformTask} for example implementation. * * @author apopov * * @param * is a sink type. */ public abstract class TransformHelper implements Initializable { protected Logger logger = Logger.getLogger(this.getClass().getName()); protected T sink; protected String statsFile; protected String configFile; protected List translations; protected static TimestampFormat timestampFormat = new XmlTimestampFormat(); public TransformHelper(String configFile, String statsFile) { logger.log(Level.FINE, "Transform configured with " + configFile + " and " + statsFile); translations = new TransformLoader().load(configFile); this.statsFile = statsFile; this.configFile = configFile; } @Override public void initialize(Map metaData) { sink.initialize(metaData); } public void setSink(T sink) { this.sink = sink; } @Override public void complete() { if (statsFile != null && !statsFile.isEmpty()) { StringBuilder builder = new StringBuilder(); builder.append(configFile); builder.append("\n\n"); for (Translation t : translations) { t.outputStats(builder, ""); } Writer writer = null; try { writer = new FileWriter(new File(statsFile)); writer.write(builder.toString()); } catch (IOException e) { throw new StatsSaveException("Failed to save stats: " + e.getLocalizedMessage(), e); } finally { if (writer != null) { try { writer.close(); } catch (IOException e) { logger.log(Level.WARNING, "Unable to close stats file " + statsFile + ".", e); } } } } sink.complete(); } @Override public void release() { sink.release(); } /** * Transforms entity container according to configFile. * * @param entityContainer * The entity to be processed. * @return transformed (if needed) entityContainer */ protected EntityContainer processEntityContainer(EntityContainer entityContainer) { // Entities may have been made read-only at some point in the pipeline. // We want a writeable instance so that we can update the tags. EntityContainer writeableEntityContainer = entityContainer.getWriteableInstance(); Entity entity = entityContainer.getEntity(); Collection entityTags = entity.getTags(); EntityType entityType = entity.getType(); // Store the tags in a map keyed by tag key. Map tagMap = new HashMap(); for (Tag tag : entity.getTags()) { tagMap.put(tag.getKey(), tag.getValue()); } // Apply tag transformations. for (Translation translation : translations) { Collection matches = translation.match(tagMap, TTEntityType.fromEntityType06(entityType), entity .getUser().getName(), entity.getUser().getId()); if (matches == null || matches.isEmpty()) { continue; } if (translation.isDropOnMatch()) { return null; } Map newTags = new HashMap(); for (Output output : translation.getOutputs()) { output.apply(tagMap, newTags, matches); } tagMap = newTags; } // Replace the entity tags with the transformed values. entityTags.clear(); for (Entry tag : tagMap.entrySet()) { entityTags.add(new Tag(tag.getKey(), tag.getValue())); } return writeableEntityContainer; } } TransformLoadException.java000066400000000000000000000005351253404521400401730ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagtransform.impl; public class TransformLoadException extends RuntimeException { private static final long serialVersionUID = 1L; public TransformLoadException(String message, Exception cause) { super(message, cause); } } TransformLoader.java000066400000000000000000000121721253404521400366430ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagtransform.impl; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.openstreetmap.osmosis.tagtransform.Matcher; import org.openstreetmap.osmosis.tagtransform.Output; import org.openstreetmap.osmosis.tagtransform.TTEntityType; import org.openstreetmap.osmosis.tagtransform.Translation; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; public class TransformLoader { private static final Logger LOG = Logger.getLogger(TransformLoader.class.getName()); public List load(String configFile) { List translations = new ArrayList(); File file = new File(configFile); try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(file); NodeList translationElements = doc.getDocumentElement().getElementsByTagName("translation"); for (int i = 0; i < translationElements.getLength(); i++) { Translation t = parseTranslation((Element) translationElements.item(i)); if (t != null) { translations.add(t); } } } catch (Exception e) { throw new TransformLoadException("Failed to load transform", e); } return translations; } private Translation parseTranslation(Element element) { String name = ""; String description = ""; Matcher matcher = null; Matcher finder = null; List output = new ArrayList(); NodeList children = element.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { if (!(children.item(i) instanceof Element)) { continue; } Element child = (Element) children.item(i); String nodeName = child.getNodeName(); if (nodeName.equals("name")) { name = child.getTextContent(); } else if (nodeName.equals("description")) { description = child.getTextContent(); } else if (nodeName.equals("match")) { matcher = parseMatcher(child); } else if (nodeName.equals("find")) { finder = parseMatcher(child); } else if (nodeName.equals("output")) { NodeList outputs = child.getChildNodes(); for (int j = 0; j < outputs.getLength(); j++) { if (!(outputs.item(j) instanceof Element)) { continue; } Output o = parseOutput((Element) outputs.item(j)); if (o != null) { output.add(o); } } } } if (matcher != null) { LOG.info("New translation: " + name); return new TranslationImpl(name, description, matcher, finder, output); } else { return null; } } private Output parseOutput(Element child) { String name = child.getNodeName(); if (name.equals("copy-all")) { return new CopyAll(); } else if (name.equals("copy-unmatched")) { return new CopyUnmatched(); } else if (name.equals("copy-matched")) { return new CopyMatched(); } else if (name.equals("tag")) { String k = child.getAttribute("k"); String v = child.getAttribute("v"); String m = child.getAttribute("from_match"); return new TagOutput(k, v, m); } return null; } private Matcher parseMatcher(Element matcher) { String name = matcher.getNodeName(); if (name.equals("match") || name.equals("find")) { NodeList children = matcher.getChildNodes(); List matchers = new ArrayList(); String uname = null; int uid = 0; for (int i = 0; i < children.getLength(); i++) { if (!(children.item(i) instanceof Element)) { continue; } Element child = (Element) children.item(i); Matcher m = parseMatcher(child); if (m != null) { matchers.add(m); } } TTEntityType type = getType(matcher.getAttribute("type")); if (matcher.getAttribute("user") != "") { uname = matcher.getAttribute("user"); } if (matcher.getAttribute("uid") != "") { uid = Integer.parseInt(matcher.getAttribute("uid")); } String mode; if (name.equals("find")) { mode = "or"; } else { mode = matcher.getAttribute("mode"); } if (mode == null || mode.equals("") || mode.equals("and")) { return new AndMatcher(matchers, type, uname, uid); } else if (mode.equals("or")) { return new OrMatcher(matchers, type, uname, uid); } } else if (name.equals("tag")) { String k = matcher.getAttribute("k"); String v = matcher.getAttribute("v"); String id = matcher.getAttribute("match_id"); return new TagMatcher(id, k, v); } else if (name.equals("notag")) { String k = matcher.getAttribute("k"); String v = matcher.getAttribute("v"); return new NoTagMatcher(k, v); } return null; } private TTEntityType getType(String type) { if (type == null || type.isEmpty() || type.equals("all")) { return null; } if (type.equals("node")) { return TTEntityType.NODE; } if (type.equals("way")) { return TTEntityType.WAY; } if (type.equals("relation")) { return TTEntityType.RELATION; } if (type.equals("bound")) { return TTEntityType.BOUND; } return null; } } TranslationImpl.java000066400000000000000000000043441253404521400366630ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagtransform.impl; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import org.openstreetmap.osmosis.tagtransform.Match; import org.openstreetmap.osmosis.tagtransform.Matcher; import org.openstreetmap.osmosis.tagtransform.Output; import org.openstreetmap.osmosis.tagtransform.TTEntityType; import org.openstreetmap.osmosis.tagtransform.Translation; public class TranslationImpl implements Translation { private String name; private String description; private Matcher matcher; private List output; private Matcher finder; public TranslationImpl(String name, String description, Matcher matcher, Matcher finder, List output) { this.name = name; this.description = description; this.matcher = matcher; this.finder = finder; this.output = output; } @Override public Collection getOutputs() { return output; } @Override public boolean isDropOnMatch() { return output.isEmpty(); } @Override public Collection match(Map tags, TTEntityType type, String uname, int uid) { Collection matches = matcher.match(tags, type, uname, uid); if (matches != null && !matches.isEmpty()) { Collection finds; if (finder == null) { finds = null; } else { finds = finder.match(tags, type, uname, uid); } if (finds != null && !finds.isEmpty()) { if (matches instanceof ArrayList) { matches.addAll(finds); } else { List allMatches = new ArrayList(); allMatches.addAll(matches); allMatches.addAll(finds); return allMatches; } } return matches; } return null; } @Override public void outputStats(StringBuilder statsOutput, String indent) { statsOutput.append(indent); statsOutput.append(name); statsOutput.append(":"); statsOutput.append('\n'); if (description != null && !description.isEmpty()) { statsOutput.append(description); statsOutput.append('\n'); } matcher.outputStats(statsOutput, indent + " "); if (finder != null) { finder.outputStats(statsOutput, " + "); } statsOutput.append('\n'); } } osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform/v0_6/000077500000000000000000000000001253404521400325635ustar00rootroot00000000000000TransformChangeTask.java000066400000000000000000000023301253404521400372510ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagtransform.v0_6; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.task.common.ChangeAction; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSinkChangeSource; import org.openstreetmap.osmosis.tagtransform.impl.TransformHelper; public class TransformChangeTask extends TransformHelper implements ChangeSinkChangeSource { public TransformChangeTask(String configFile, String statsFile) { super(configFile, statsFile); } @Override public void process(ChangeContainer changeContainer) { if (!ChangeAction.Delete.equals(changeContainer.getAction())) { EntityContainer output = super.processEntityContainer(changeContainer.getEntityContainer()); if (output != null) { sink.process(new ChangeContainer(output, changeContainer.getAction())); } } else { sink.process(changeContainer); } } @Override public void setChangeSink(ChangeSink changeSink) { this.setSink(changeSink); } } TransformChangeTaskFactory.java000066400000000000000000000016411253404521400406050ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagtransform.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.ChangeSinkChangeSourceManager; public class TransformChangeTaskFactory extends TaskManagerFactory { @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String configFile = getStringArgument(taskConfig, "file", getDefaultStringArgument(taskConfig, "transform.xml")); String statsFile = getStringArgument(taskConfig, "stats", null); return new ChangeSinkChangeSourceManager(taskConfig.getId(), new TransformChangeTask(configFile, statsFile), taskConfig.getPipeArgs()); } } TransformTask.java000066400000000000000000000013751253404521400361530ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagtransform.v0_6; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.task.v0_6.SinkSource; import org.openstreetmap.osmosis.tagtransform.impl.TransformHelper; public class TransformTask extends TransformHelper implements SinkSource { public TransformTask(String configFile, String statsFile) { super(configFile, statsFile); } @Override public void process(EntityContainer entityContainer) { EntityContainer output = processEntityContainer(entityContainer); if (output != null) { sink.process(output); } } } TransformTaskFactory.java000066400000000000000000000016011253404521400374730ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/java/org/openstreetmap/osmosis/tagtransform/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagtransform.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkSourceManager; public class TransformTaskFactory extends TaskManagerFactory { @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String configFile = getStringArgument(taskConfig, "file", getDefaultStringArgument(taskConfig, "transform.xml")); String statsFile = getStringArgument(taskConfig, "stats", null); return new SinkSourceManager(taskConfig.getId(), new TransformTask(configFile, statsFile), taskConfig.getPipeArgs()); } } osmosis-0.44.1/osmosis-tagtransform/src/main/resources/000077500000000000000000000000001253404521400232225ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/main/resources/osmosis-plugins.conf000066400000000000000000000000661253404521400272460ustar00rootroot00000000000000org.openstreetmap.osmosis.tagtransform.TransformPluginosmosis-0.44.1/osmosis-tagtransform/src/test/000077500000000000000000000000001253404521400212435ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/test/java/000077500000000000000000000000001253404521400221645ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/test/java/org/000077500000000000000000000000001253404521400227535ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/test/java/org/openstreetmap/000077500000000000000000000000001253404521400256415ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/test/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400273355ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/test/java/org/openstreetmap/osmosis/tagtransform/000077500000000000000000000000001253404521400320445ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/test/java/org/openstreetmap/osmosis/tagtransform/v0_6/000077500000000000000000000000001253404521400326165ustar00rootroot00000000000000TagTransformTest.java000066400000000000000000000026431253404521400366560ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/test/java/org/openstreetmap/osmosis/tagtransform/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.tagtransform.v0_6; import java.io.File; import java.io.IOException; import org.junit.Test; import org.openstreetmap.osmosis.core.Osmosis; import org.openstreetmap.osmosis.testutil.AbstractDataTest; /** * Tests the tag transform functionality. * * @author Brett Henderson */ public class TagTransformTest extends AbstractDataTest { /** * Tests transforming all tags in a single OSM file. * * @throws IOException * if any file operations fail. */ @Test public void testTransform() throws IOException { File sourceFile; File translationFile; File expectedOutputFile; File actualOutputFile; // Generate files. sourceFile = dataUtils.createDataFile("v0_6/test-in.osm"); translationFile = dataUtils.createDataFile("v0_6/translation.xml"); expectedOutputFile = dataUtils.createDataFile("v0_6/test-out.osm"); actualOutputFile = dataUtils.newFile(); // Append the two source files into the destination file. Osmosis.run( new String[] { "-q", "--read-xml-0.6", sourceFile.getPath(), "--tag-transform-0.6", "file=" + translationFile, "--tag-sort-0.6", "--write-xml-0.6", actualOutputFile.getPath() } ); // Validate that the output file matches the expected result. dataUtils.compareFiles(expectedOutputFile, actualOutputFile); } } osmosis-0.44.1/osmosis-tagtransform/src/test/resources/000077500000000000000000000000001253404521400232555ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/test/resources/data/000077500000000000000000000000001253404521400241665ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/test/resources/data/template/000077500000000000000000000000001253404521400260015ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/test/resources/data/template/v0_6/000077500000000000000000000000001253404521400265535ustar00rootroot00000000000000osmosis-0.44.1/osmosis-tagtransform/src/test/resources/data/template/v0_6/test-in.osm000066400000000000000000000040531253404521400306600ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-tagtransform/src/test/resources/data/template/v0_6/test-out.osm000066400000000000000000000041231253404521400310570ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-tagtransform/src/test/resources/data/template/v0_6/translation.xml000066400000000000000000000122571253404521400316420ustar00rootroot00000000000000 Strip unused Simplify True Simplifies the different variations of true/false, yes/no. Simplify Access Simplifies the access restrictions to yes/no. Bike->Toucan Convert bike crossings Paths->track Paths/footways->cycleway Convert paths to cycleways -- these have precedence in this result Paths->footway NCN Find all the way ncn variations and tag consistently RCN Find all the way rcn variations and tag consistently LCN Find all the way lcn variations and tag consistently Arbitrary Piste Remapping Just test some of the advanced features by remapping the piste:* style tags osmosis-0.44.1/osmosis-testutil/000077500000000000000000000000001253404521400166435ustar00rootroot00000000000000osmosis-0.44.1/osmosis-testutil/.checkstyle000066400000000000000000000010051253404521400207760ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-testutil/.gitignore000066400000000000000000000000531253404521400206310ustar00rootroot00000000000000.classpath .project .settings /bin /build osmosis-0.44.1/osmosis-testutil/build.gradle000066400000000000000000000002011253404521400211130ustar00rootroot00000000000000dependencies { compile project(':osmosis-core') compile group: 'junit', name: 'junit', version: dependencyVersionJunit } osmosis-0.44.1/osmosis-testutil/src/000077500000000000000000000000001253404521400174325ustar00rootroot00000000000000osmosis-0.44.1/osmosis-testutil/src/main/000077500000000000000000000000001253404521400203565ustar00rootroot00000000000000osmosis-0.44.1/osmosis-testutil/src/main/java/000077500000000000000000000000001253404521400212775ustar00rootroot00000000000000osmosis-0.44.1/osmosis-testutil/src/main/java/org/000077500000000000000000000000001253404521400220665ustar00rootroot00000000000000osmosis-0.44.1/osmosis-testutil/src/main/java/org/openstreetmap/000077500000000000000000000000001253404521400247545ustar00rootroot00000000000000osmosis-0.44.1/osmosis-testutil/src/main/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400264505ustar00rootroot00000000000000osmosis-0.44.1/osmosis-testutil/src/main/java/org/openstreetmap/osmosis/testutil/000077500000000000000000000000001253404521400303255ustar00rootroot00000000000000AbstractDataTest.java000066400000000000000000000007141253404521400343100ustar00rootroot00000000000000osmosis-0.44.1/osmosis-testutil/src/main/java/org/openstreetmap/osmosis/testutil// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.testutil; import org.junit.Rule; /** * Convenience base class providing facilities for test data creation and * lifecycle management. * * @author Brett Henderson */ public class AbstractDataTest { /** * Manages creation and lifecycle of test data files. */ @Rule public TestDataUtilities dataUtils = new TestDataUtilities(); } TestDataUtilities.java000066400000000000000000000131041253404521400345150ustar00rootroot00000000000000osmosis-0.44.1/osmosis-testutil/src/main/java/org/openstreetmap/osmosis/testutil// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.testutil; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.nio.charset.Charset; import java.util.zip.GZIPOutputStream; import org.junit.Assert; import org.junit.rules.TemporaryFolder; import org.openstreetmap.osmosis.core.OsmosisConstants; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Provides re-usable functionality for utilising data files within junit tests. * * @author Brett Henderson */ public class TestDataUtilities extends TemporaryFolder { private static final Charset UTF8 = Charset.forName("UTF-8"); /** * Obtains the data file with the specified name. The name is a path * relative to the data input directory. The returned file will have any * occurrences of %VERSION% replaced with the current version. * * @param dataFileName * The name of the data file to be loaded. * @return The file object pointing to the data file. */ public File createDataFile(String dataFileName) { try { BufferedReader dataReader; BufferedWriter dataWriter; File tmpFile; String line; // Open the data template file. dataReader = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream( "/data/template/" + dataFileName), UTF8)); // Create a temporary file and open it. tmpFile = newFile(); dataWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(tmpFile), UTF8)); // Copy all data into the temp file replacing the version string. while ((line = dataReader.readLine()) != null) { line = line.replace("%VERSION%", OsmosisConstants.VERSION); dataWriter.write(line); dataWriter.newLine(); } dataReader.close(); dataWriter.close(); return tmpFile; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to build test data file " + dataFileName, e); } } /** * Obtains the data file with the specified name. The name is a path * relative to the data input directory. * * @param systemPropertyName * The system property to use for getting the file name. If this * doesn't exist, the dataFileName is used instead. * @param dataFileName * The name of the data file to be loaded. * @return The file object pointing to the data file. */ public File createDataFile(String systemPropertyName, String dataFileName) { String fileName; // Get the filename from the system property if it exists. fileName = System.getProperty(systemPropertyName); if (fileName != null) { return new File(fileName); } // No system property is available so use the provided file name. return createDataFile(dataFileName); } private void copyFiles(File from, File to) throws IOException { byte[] buffer; int bytesRead; BufferedInputStream isFrom; BufferedOutputStream osTo; buffer = new byte[4096]; isFrom = new BufferedInputStream(new FileInputStream(from)); osTo = new BufferedOutputStream(new FileOutputStream(to)); while ((bytesRead = isFrom.read(buffer)) >= 0) { osTo.write(buffer, 0, bytesRead); } isFrom.close(); osTo.close(); } private void handleInequalFiles(File file1, File file2, long failureoffset) throws IOException { File file1Copy; File file2Copy; // We must create copies of the files because the originals will be // cleaned up at the completion of the test. file1Copy = File.createTempFile("junit", null); file2Copy = File.createTempFile("junit", null); copyFiles(file1, file1Copy); copyFiles(file2, file2Copy); Assert.fail("File " + file1Copy + " and file " + file2Copy + " are not equal at file offset " + failureoffset + "."); } /** * Validates the contents of two files for equality. * * @param file1 * The first file. * @param file2 * The second file. * @throws IOException * if an exception occurs. */ public void compareFiles(File file1, File file2) throws IOException { BufferedInputStream inStream1; BufferedInputStream inStream2; int byte1; int byte2; long offset; inStream1 = new BufferedInputStream(new FileInputStream(file1)); inStream2 = new BufferedInputStream(new FileInputStream(file2)); offset = 0; do { byte1 = inStream1.read(); byte2 = inStream2.read(); if (byte1 != byte2) { handleInequalFiles(file1, file2, offset); } offset++; } while (byte1 >= 0); inStream2.close(); inStream1.close(); } /** * Compresses the contents of a file into a new compressed file. * * @param inputFile * The uncompressed input file. * @param outputFile * The compressed output file to generate. * @throws IOException * if an exception occurs. */ public void compressFile(File inputFile, File outputFile) throws IOException { BufferedInputStream inStream; BufferedOutputStream outStream; byte[] buffer; int bytesRead; inStream = new BufferedInputStream(new FileInputStream(inputFile)); outStream = new BufferedOutputStream(new GZIPOutputStream(new FileOutputStream(outputFile))); buffer = new byte[4096]; do { bytesRead = inStream.read(buffer); if (bytesRead > 0) { outStream.write(buffer, 0, bytesRead); } } while (bytesRead >= 0); outStream.close(); inStream.close(); } } osmosis-0.44.1/osmosis-testutil/src/main/java/org/openstreetmap/osmosis/testutil/v0_6/000077500000000000000000000000001253404521400310775ustar00rootroot00000000000000RunTaskUtilities.java000066400000000000000000000100001253404521400351350ustar00rootroot00000000000000osmosis-0.44.1/osmosis-testutil/src/main/java/org/openstreetmap/osmosis/testutil/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.testutil.v0_6; import org.openstreetmap.osmosis.core.task.v0_6.MultiSinkRunnableChangeSource; import org.openstreetmap.osmosis.core.task.v0_6.MultiSinkRunnableSource; import org.openstreetmap.osmosis.core.task.v0_6.RunnableSource; /** * Utility methods for running complicated tasks like MultiSinks. * * @author Igor Podolskiy */ public final class RunTaskUtilities { private RunTaskUtilities() { } /** * Helper method to execute a two-sink entity source. * * @param multiSink the multi-sink source to run. * @param source1 the first source to feed to the sink. * @param source2 the second source to feed to the sink. * @return the sink entity inspector containing the result. * @throws Exception if something goes wrong. */ public static SinkEntityInspector run(MultiSinkRunnableSource multiSink, RunnableSource source1, RunnableSource source2) throws Exception { return run(multiSink, source1, source2, null); } /** * Helper method to execute a two-sink entity source. * * @param multiSink the multi-sink source to run. * @param source1 the first source to feed to the sink. * @param source2 the second source to feed to the sink. * @param exceptionHandler the exception handler to attach to threads. * @return the sink entity inspector containing the result. * @throws Exception if something goes wrong. */ public static SinkEntityInspector run(MultiSinkRunnableSource multiSink, RunnableSource source1, RunnableSource source2, Thread.UncaughtExceptionHandler exceptionHandler) throws Exception { SinkEntityInspector inspector = new SinkEntityInspector(); source1.setSink(multiSink.getSink(0)); source2.setSink(multiSink.getSink(1)); multiSink.setSink(inspector); runCore(multiSink, source1, source2, exceptionHandler); return inspector; } /** * Helper method to execute a two-sink change source. * * @param multiSink the twp-sink change source to run. * @param source1 the first source to feed to the sink. * @param source2 the second source to feed to the sink. * @return the sink change inspector containing the result. * @throws Exception if something goes wrong. */ public static SinkChangeInspector run(MultiSinkRunnableChangeSource multiSink, RunnableSource source1, RunnableSource source2) throws Exception { return run(multiSink, source1, source2, null); } /** * Helper method to execute a two-sink change source. * * @param multiSink the twp-sink change source to run. * @param source1 the first source to feed to the sink. * @param source2 the second source to feed to the sink. * @param exceptionHandler the exception handler to attach to threads. * @return the sink change inspector containing the result. * @throws Exception if something goes wrong. */ public static SinkChangeInspector run(MultiSinkRunnableChangeSource multiSink, RunnableSource source1, RunnableSource source2, Thread.UncaughtExceptionHandler exceptionHandler) throws Exception { SinkChangeInspector inspector = new SinkChangeInspector(); source1.setSink(multiSink.getSink(0)); source2.setSink(multiSink.getSink(1)); multiSink.setChangeSink(inspector); runCore(multiSink, source1, source2, exceptionHandler); return inspector; } private static void runCore(Runnable multiSink, Runnable source1, Runnable source2, Thread.UncaughtExceptionHandler exceptionHandler) throws InterruptedException { Thread sourceThread1 = new Thread(source1); Thread sourceThread2 = new Thread(source2); Thread sinkThread = new Thread(multiSink); if (exceptionHandler != null) { sourceThread1.setUncaughtExceptionHandler(exceptionHandler); sourceThread2.setUncaughtExceptionHandler(exceptionHandler); sinkThread.setUncaughtExceptionHandler(exceptionHandler); } sinkThread.start(); sourceThread1.start(); sourceThread2.start(); sinkThread.join(); sourceThread1.join(); sourceThread2.join(); } } SinkChangeInspector.java000066400000000000000000000031141253404521400355630ustar00rootroot00000000000000osmosis-0.44.1/osmosis-testutil/src/main/java/org/openstreetmap/osmosis/testutil/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.testutil.v0_6; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; /** * Mock object for inspecting the resulting changes after passing through a pipeline task. * * @author Igor Podolskiy */ public class SinkChangeInspector implements ChangeSink { private List receivedChanges; /** * Creates a new instance. */ public SinkChangeInspector() { receivedChanges = new ArrayList(); } @Override public void initialize(Map metaData) { // Nothing to do here } @Override public void complete() { // Nothing to do here } @Override public void release() { // Nothing to do here } @Override public void process(ChangeContainer change) { receivedChanges.add(change); } /** * Returns the list of the processed changes. * * @return the list of the processed changes, never null. */ public List getProcessedChanges() { return receivedChanges; } /** * Returns the last processed change container, or null if no changes have * been processed. * * @return the last processed change container, or null if no changes have * been processed. */ public ChangeContainer getLastChangeContainer() { if (receivedChanges.isEmpty()) { return null; } return receivedChanges.get(receivedChanges.size() - 1); } } SinkEntityInspector.java000066400000000000000000000034631253404521400356610ustar00rootroot00000000000000osmosis-0.44.1/osmosis-testutil/src/main/java/org/openstreetmap/osmosis/testutil/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.testutil.v0_6; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.task.v0_6.Sink; /** * Mock object for inspecting the resulting entities after passing through a pipeline task. * * @author Karl Newman */ public class SinkEntityInspector implements Sink { private List processedEntities; /** * Creates a new instance. */ public SinkEntityInspector() { processedEntities = new LinkedList(); } /** * {@inheritDoc} */ public void initialize(Map metaData) { // Nothing to do here } /** * {@inheritDoc} */ @Override public void complete() { // Nothing to do here } /** * Catch all passed entities and save them for later inspection. * * @param entityContainer * The entity to be processed. */ @Override public void process(EntityContainer entityContainer) { processedEntities.add(entityContainer); } /** * {@inheritDoc} */ @Override public void release() { // Nothing to do here } /** * Shortcut method if you only care about the most recent EntityContainer. * * @return the lastEntityContainer */ public EntityContainer getLastEntityContainer() { if (processedEntities.isEmpty()) { return null; } else { return processedEntities.get(processedEntities.size() - 1); } } /** * Retrieve an Iterable of all the processed EntityContainers. * * @return the processedEntities */ public Iterable getProcessedEntities() { return Collections.unmodifiableList(processedEntities); } } osmosis-0.44.1/osmosis-xml/000077500000000000000000000000001253404521400155665ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/.checkstyle000066400000000000000000000010051253404521400177210ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-xml/.gitignore000066400000000000000000000000531253404521400175540ustar00rootroot00000000000000.classpath .project .settings /bin /build osmosis-0.44.1/osmosis-xml/build.gradle000066400000000000000000000003051253404521400200430ustar00rootroot00000000000000dependencies { compile project(':osmosis-core') compile group: 'commons-codec', name: 'commons-codec', version: dependencyVersionCommonsCodec testCompile project(':osmosis-testutil') } osmosis-0.44.1/osmosis-xml/src/000077500000000000000000000000001253404521400163555ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/000077500000000000000000000000001253404521400173015ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/000077500000000000000000000000001253404521400202225ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/000077500000000000000000000000001253404521400210115ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/000077500000000000000000000000001253404521400236775ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400253735ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/000077500000000000000000000000001253404521400261735ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/XmlPluginLoader.java000066400000000000000000000042651253404521400321130ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.plugin.PluginLoader; import org.openstreetmap.osmosis.xml.v0_6.FastXmlReaderFactory; import org.openstreetmap.osmosis.xml.v0_6.XmlChangeReaderFactory; import org.openstreetmap.osmosis.xml.v0_6.XmlChangeUploaderFactory; import org.openstreetmap.osmosis.xml.v0_6.XmlChangeWriterFactory; import org.openstreetmap.osmosis.xml.v0_6.XmlDownloaderFactory; import org.openstreetmap.osmosis.xml.v0_6.XmlReaderFactory; import org.openstreetmap.osmosis.xml.v0_6.XmlWriterFactory; /** * The plugin loader for the XML tasks. * * @author Brett Henderson */ public class XmlPluginLoader implements PluginLoader { /** * {@inheritDoc} */ @Override public Map loadTaskFactories() { Map factoryMap; factoryMap = new HashMap(); factoryMap.put("read-xml", new XmlReaderFactory()); factoryMap.put("fast-read-xml", new FastXmlReaderFactory()); factoryMap.put("rx", new XmlReaderFactory()); factoryMap.put("read-xml-change", new XmlChangeReaderFactory()); factoryMap.put("upload-xml-change", new XmlChangeUploaderFactory()); factoryMap.put("rxc", new XmlChangeReaderFactory()); factoryMap.put("write-xml", new XmlWriterFactory()); factoryMap.put("wx", new XmlWriterFactory()); factoryMap.put("write-xml-change", new XmlChangeWriterFactory()); factoryMap.put("wxc", new XmlChangeWriterFactory()); factoryMap.put("read-api", new XmlDownloaderFactory()); factoryMap.put("ra", new XmlDownloaderFactory()); factoryMap.put("read-xml-0.6", new XmlReaderFactory()); factoryMap.put("fast-read-xml-0.6", new FastXmlReaderFactory()); factoryMap.put("read-xml-change-0.6", new XmlChangeReaderFactory()); factoryMap.put("write-xml-0.6", new XmlWriterFactory()); factoryMap.put("write-xml-change-0.6", new XmlChangeWriterFactory()); factoryMap.put("read-api-0.6", new XmlDownloaderFactory()); return factoryMap; } } osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/common/000077500000000000000000000000001253404521400274635ustar00rootroot00000000000000BaseElementProcessor.java000066400000000000000000000054201253404521400343340ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.common; import java.util.Calendar; import org.openstreetmap.osmosis.core.domain.common.SimpleTimestampContainer; import org.openstreetmap.osmosis.core.domain.common.TimestampContainer; import org.openstreetmap.osmosis.core.domain.common.TimestampFormat; import org.openstreetmap.osmosis.core.domain.common.UnparsedTimestampContainer; /** * Provides common functionality shared by element processor implementations. * * @author Brett Henderson */ public abstract class BaseElementProcessor implements ElementProcessor { private BaseElementProcessor parentProcessor; private ElementProcessor dummyChildProcessor; private TimestampFormat timestampFormat; private TimestampContainer dummyTimestampContainer; private boolean enableDateParsing; /** * Creates a new instance. * * @param parentProcessor * The parent of this element processor. * @param enableDateParsing * If true, dates will be parsed from xml data, else the current * date will be used thus saving parsing time. */ protected BaseElementProcessor(BaseElementProcessor parentProcessor, boolean enableDateParsing) { this.parentProcessor = parentProcessor; this.enableDateParsing = enableDateParsing; if (enableDateParsing) { timestampFormat = new XmlTimestampFormat(); } else { Calendar calendar; calendar = Calendar.getInstance(); calendar.set(Calendar.MILLISECOND, 0); dummyTimestampContainer = new SimpleTimestampContainer(calendar.getTime()); } } /** * This implementation returns a dummy element processor as the child which * ignores all nested xml elements. Sub-classes wishing to handle child * elements must override this method and delegate to this method for xml * elements they don't care about. * * @param uri * The element uri. * @param localName * The element localName. * @param qName * The element qName. * @return A dummy element processor. */ public ElementProcessor getChild(String uri, String localName, String qName) { if (dummyChildProcessor == null) { dummyChildProcessor = new DummyElementProcessor(this); } return dummyChildProcessor; } /** * {@inheritDoc} */ public ElementProcessor getParent() { return parentProcessor; } /** * Parses a date using the standard osm date format. * * @param data * The date string to be parsed. * @return The parsed date (if dateparsing is enabled). */ protected TimestampContainer createTimestampContainer(String data) { if (enableDateParsing) { return new UnparsedTimestampContainer(timestampFormat, data); } else { return dummyTimestampContainer; } } } osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/common/BaseXmlWriter.java000066400000000000000000000122051253404521400330560ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.common; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * An OSM data sink for storing all data to an xml file. * * @author Brett Henderson */ public abstract class BaseXmlWriter { private static Logger log = Logger.getLogger(BaseXmlWriter.class.getName()); private boolean closeRequired; private boolean writerProvided; private File file; private boolean initialized; private BufferedWriter writer; private CompressionMethod compressionMethod; /** * Creates a new instance to write to the provided writer. * * @param writer The writer to receive data. This writer will not be closed on completion. */ public BaseXmlWriter(BufferedWriter writer) { this.writer = writer; writerProvided = true; closeRequired = false; } /** * Creates a new instance to write to the specified file. * * @param file * The file to write. * @param compressionMethod * Specifies the compression method to employ. */ public BaseXmlWriter(File file, CompressionMethod compressionMethod) { this.file = file; this.compressionMethod = compressionMethod; writerProvided = false; closeRequired = true; } /** * Sets the writer on the element writer used for this implementation. * * @param resultWriter * The writer receiving xml data. */ protected abstract void setWriterOnElementWriter(BufferedWriter resultWriter); /** * Calls the begin method of the element writer used for this implementation. */ protected abstract void beginElementWriter(); /** * Calls the end method of the element writer used for this implementation. */ protected abstract void endElementWriter(); /** * Writes data to the output file. * * @param data * The data to be written. */ private void write(String data) { try { writer.write(data); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write data.", e); } } /** * Writes a new line in the output file. */ private void writeNewLine() { try { writer.newLine(); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write data.", e); } } /** * Initialize the object. * * @param metaData * Meta data applicable to this pipeline invocation. */ public void initialize(Map metaData) { // Do nothing. } /** * Initialises the output file for writing. This must be called by * sub-classes before any writing is performed. This method may be called * multiple times without adverse affect allowing sub-classes to invoke it * every time they perform processing. */ protected void initialize() { if (!initialized) { if (!writerProvided) { OutputStream outStream = null; try { OutputStreamWriter outStreamWriter; // make "-" an alias for /dev/stdout if (file.getName().equals("-")) { outStream = System.out; // We don't want to close stdout because we'll need to // re-use it if we receive multiple streams. closeRequired = false; } else { outStream = new FileOutputStream(file); } outStream = new CompressionActivator(compressionMethod).createCompressionOutputStream(outStream); outStreamWriter = new OutputStreamWriter(outStream, "UTF-8"); writer = new BufferedWriter(outStreamWriter); outStream = null; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to open file for writing.", e); } finally { if (outStream != null) { try { outStream.close(); } catch (Exception e) { log.log(Level.SEVERE, "Unable to close output stream.", e); } outStream = null; } } } setWriterOnElementWriter(writer); initialized = true; write(""); writeNewLine(); beginElementWriter(); } } /** * Flushes all changes to file. */ public void complete() { // We need to call this here so that we create empty files if no records // are available. initialize(); endElementWriter(); try { if (closeRequired) { writer.close(); writer = null; } else if (!writerProvided) { writer.flush(); } initialized = false; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to complete writing to the xml stream.", e); } } /** * Cleans up any open file handles. */ public void release() { try { if (closeRequired) { try { try { if (writer != null) { writer.close(); } } catch (IOException e) { log.log(Level.SEVERE, "Unable to close writer.", e); } } finally { writer = null; } } } finally { initialized = false; } } } CompressionActivator.java000066400000000000000000000065061253404521400344340ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.common; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.zip.GZIPOutputStream; import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream; import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.util.MultiMemberGZIPInputStream; /** * A utility class for layering compression streams on top of underlying byte * streams based upon a specified compression algorithm. * * @author Brett Henderson */ public class CompressionActivator { private CompressionMethod compressionMethod; /** * Creates a new instance. * * @param compressionMethod * The compression method to employ. */ public CompressionActivator(CompressionMethod compressionMethod) { this.compressionMethod = compressionMethod; } /** * Wraps a compression stream around the destination stream based upon the * requested compression method. If this method returns successfully, the * input destination stream does not require closing after use because it * will be closed when the returned output stream is closed. * * @param destinationStream * The destination stream for receiving compressed data. * @return A stream for writing compressed data to the destination stream. */ public OutputStream createCompressionOutputStream(OutputStream destinationStream) { try { if (CompressionMethod.None.equals(compressionMethod)) { return destinationStream; } if (CompressionMethod.GZip.equals(compressionMethod)) { return new GZIPOutputStream(destinationStream); } if (CompressionMethod.BZip2.equals(compressionMethod)) { return new BZip2CompressorOutputStream(destinationStream); } throw new OsmosisRuntimeException("Compression method " + compressionMethod + " is not recognized."); } catch (IOException e) { throw new OsmosisRuntimeException( "Unable to instantiate a " + compressionMethod + " compression stream.", e); } } /** * Wraps a compression stream around the source stream based upon the * requested compression method. If this method returns successfully, the * input source stream does not require closing after use because it will be * closed when the returned input stream is closed. * * @param sourceStream * The source stream for providing compressed data. * @return A stream for writing compressed data to the destination stream. */ public InputStream createCompressionInputStream(InputStream sourceStream) { try { if (CompressionMethod.None.equals(compressionMethod)) { return sourceStream; } if (CompressionMethod.GZip.equals(compressionMethod)) { return new MultiMemberGZIPInputStream(sourceStream); } if (CompressionMethod.BZip2.equals(compressionMethod)) { return new BZip2CompressorInputStream(sourceStream); } throw new OsmosisRuntimeException("Compression method " + compressionMethod + " is not recognized."); } catch (IOException e) { throw new OsmosisRuntimeException( "Unable to instantiate a " + compressionMethod + " compression stream.", e); } } } osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/common/CompressionMethod.java000066400000000000000000000007371253404521400337770ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.common; /** * Defines the various compression methods supported by xml tasks. * * @author Brett Henderson */ public enum CompressionMethod { /** * Specifies that no compression be performed. */ None, /** * Specifies that GZip compression should be used. */ GZip, /** * Specifies that BZip2 compression should be used. */ BZip2 } CompressionMethodDeriver.java000066400000000000000000000017701253404521400352370ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.common; /** * A utility class for deriving the appropriate compression method based on the * file extension. * * @author Brett Henderson */ public class CompressionMethodDeriver { private static final CompressionMethod DEFAULT_COMPRESSION_METHOD = CompressionMethod.None; private static final String FILE_SUFFIX_GZIP = ".gz"; private static final String FILE_SUFFIX_BZIP2 = ".bz2"; /** * Determines the appropriate compression method for a file based upon the * file extension. * * @param fileName * The name of the file. * @return The compression method. */ public CompressionMethod deriveCompressionMethod(String fileName) { if (fileName.endsWith(FILE_SUFFIX_GZIP)) { return CompressionMethod.GZip; } else if (fileName.endsWith(FILE_SUFFIX_BZIP2)) { return CompressionMethod.BZip2; } else { return DEFAULT_COMPRESSION_METHOD; } } } DummyElementProcessor.java000066400000000000000000000040151253404521400345540ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.common; import org.xml.sax.Attributes; /** * Provides a no-op implementation of an element processor. This implementation * is provided to allow nested elements to be ignored if they are not required. * * @author Brett Henderson */ public class DummyElementProcessor extends BaseElementProcessor { private int nestedElementCount; /** * Creates a new instance. * * @param parentProcessor * The parent of this element processor. */ public DummyElementProcessor(BaseElementProcessor parentProcessor) { super(parentProcessor, false); } /** * This implementation does not do any processing. * * @param attributes * The attributes of the new element. */ public void begin(Attributes attributes) { // Nothing to do because we're not processing this element. } /** * This implementation returns itself and increments an internal counter. * The corresponding getParent method decrements the counter and when it * reaches zero returns the true parent of this instance. * * @param uri * The element uri. * @param localName * The element localName. * @param qName * The element qName. * @return This instance. */ @Override public ElementProcessor getChild(String uri, String localName, String qName) { nestedElementCount++; return this; } /** * This implementation decrements an internal counter, if the counter * reaches zero the true parent is returned, else this instance is returned. * * @return The element processor for the parent of the current element. */ @Override public ElementProcessor getParent() { if (nestedElementCount > 0) { nestedElementCount--; return this; } else { return super.getParent(); } } /** * This implementation does not do any processing. */ public void end() { // Nothing to do because we're not processing this element. } } osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/common/ElementProcessor.java000066400000000000000000000024471253404521400336260ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.common; import org.xml.sax.Attributes; /** * An element processor provides a handler for processing a specific xml element * within a document. It provides a state pattern approach to processing nested * xml structures. * * @author Brett Henderson */ public interface ElementProcessor { /** * Initialises the element processor with attributes for a new element to be * processed. * * @param attributes * The attributes of the new element. */ void begin(Attributes attributes); /** * Retrieves the appropriate child element processor for the newly * encountered nested element. * * @param uri * The element uri. * @param localName * The element localName. * @param qName * The element qName. * @return The appropriate element processor for the nested element. */ ElementProcessor getChild(String uri, String localName, String qName); /** * Returns the parent element processor. * * @return The parent element processor. */ ElementProcessor getParent(); /** * Finalises processing for the element processor, this is called when the * end of an element is reached. */ void end(); } osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/common/ElementWriter.java000066400000000000000000000150231253404521400331150ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.common; import java.io.IOException; import java.io.Writer; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.domain.common.TimestampFormat; /** * Provides common functionality for all classes writing elements to xml. * * @author Brett Henderson */ public class ElementWriter { /** * The number of spaces to indent per indent level. */ private static final int INDENT_SPACES_PER_LEVEL = 2; /** * Defines the characters that must be replaced by * an encoded string when writing to XML. */ private static final Map XML_ENCODING; static { // Define all the characters and their encodings. XML_ENCODING = new HashMap(); // Non-xml compatible control characters will not be written // with the exception of tab, carriage return and line feed. for (int i = 0; i <= 0x1F; i++) { if (i != 0x9 && i != 0xA && i != 0xD) { XML_ENCODING.put(new Character((char) i), ""); } } XML_ENCODING.put(new Character((char) 0x7F), ""); XML_ENCODING.put(new Character('<'), "<"); XML_ENCODING.put(new Character('>'), ">"); XML_ENCODING.put(new Character('"'), """); XML_ENCODING.put(new Character('\''), "'"); XML_ENCODING.put(new Character('&'), "&"); XML_ENCODING.put(new Character('\n'), " "); XML_ENCODING.put(new Character('\r'), " "); XML_ENCODING.put(new Character('\t'), " "); } /** * The output destination for writing all xml. */ private Writer myWriter; /** * The name of the element to be written. */ private final String myElementName; /** * The indent level of the element. */ private final int myIndentLevel; private final TimestampFormat myTimestampFormat; /** * Line separator string. This is the value of the line.separator * property at the moment that the stream was created. */ private String myLineSeparator; /** * Creates a new instance. * * @param anElementName The name of the element to be written. * @param anIndentionLevel The indent level of the element. */ protected ElementWriter(final String anElementName, final int anIndentionLevel) { this.myElementName = anElementName; this.myIndentLevel = anIndentionLevel; myTimestampFormat = new XmlTimestampFormat(); this.myLineSeparator = System.getProperty("line.separator"); } /** * Sets the writer used as the xml output destination. * * @param aWriter The writer. */ public void setWriter(final Writer aWriter) { if (aWriter == null) { throw new IllegalArgumentException("null writer given"); } this.myWriter = aWriter; } /** * Writes a series of spaces to indent the current line. * * @throws IOException if an error occurs. */ private void writeIndent() throws IOException { int indentSpaceCount; indentSpaceCount = myIndentLevel * INDENT_SPACES_PER_LEVEL; for (int i = 0; i < indentSpaceCount; i++) { myWriter.append(' '); } } /** * A utility method for encoding data in XML format. * * @param data The data to be formatted. * @return The formatted data. This may be the input * string if no changes are required. */ private String escapeData(final String data) { StringBuilder buffer = null; for (int i = 0; i < data.length(); ++i) { char currentChar = data.charAt(i); String replacement = XML_ENCODING.get(new Character(currentChar)); if (replacement != null) { if (buffer == null) { buffer = new StringBuilder(data.substring(0, i)); } buffer.append(replacement); } else if (buffer != null) { buffer.append(currentChar); } } if (buffer == null) { return data; } else { return buffer.toString(); } } /** * Returns a timestamp format suitable for xml files. * * @return The timestamp format. */ protected TimestampFormat getTimestampFormat() { return myTimestampFormat; } /** * Writes an element opening line without the final * closing portion of the tag. */ protected void beginOpenElement() { try { writeIndent(); myWriter.append('<'); myWriter.append(this.myElementName); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write data.", e); } } /** * Writes out the opening tag of the element. * * @param closeElement If true, the element will be closed * immediately and written as a single * tag in the output xml file. */ protected void endOpenElement(final boolean closeElement) { try { if (closeElement) { myWriter.append('/'); } myWriter.append('>'); myWriter.append(this.myLineSeparator); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write data.", e); } } /** * Adds an attribute to the element. * * @param name The name of the attribute. * @param value The value of the attribute. */ protected void addAttribute(final String name, final String value) { try { myWriter.append(' '); myWriter.append(name); myWriter.append("=\""); myWriter.append(escapeData(value)); myWriter.append('"'); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write data.", e); } } /** * Writes the closing tag of the element. */ protected void closeElement() { try { writeIndent(); myWriter.append("'); myWriter.append(this.myLineSeparator); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to write data.", e); } } } XmlTaskManagerFactory.java000066400000000000000000000046501253404521400344620ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.common; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; /** * Extends the basic task manager factory functionality with xml task specific common methods. * * @author Brett Henderson */ public abstract class XmlTaskManagerFactory extends TaskManagerFactory { private static final String ARG_COMPRESSION_METHOD = "compressionMethod"; private static final String ARG_ENCODING_HACK = "encodingHack"; private static final boolean DEFAULT_ENCODING_HACK = false; /** * Utility method for retrieving a CompressionMethod argument value from a * Map of task arguments. * * @param taskConfig * Contains all information required to instantiate and configure * the task. * @param fileName * The file name used to determine the default compression * method. * @return The value of the argument. */ protected CompressionMethod getCompressionMethodArgument( TaskConfiguration taskConfig, String fileName) { CompressionMethod result; String rawValue = getStringArgument(taskConfig, ARG_COMPRESSION_METHOD, "auto").toLowerCase(); if ("none".equals(rawValue)) { result = CompressionMethod.None; } else if ("gzip".equals(rawValue)) { result = CompressionMethod.GZip; } else if ("bzip2".equals(rawValue)) { result = CompressionMethod.BZip2; } else if ("auto".equals(rawValue)) { result = new CompressionMethodDeriver().deriveCompressionMethod(fileName); } else { throw new OsmosisRuntimeException( "Argument " + ARG_COMPRESSION_METHOD + " for task " + taskConfig.getId() + " must be one of none, gzip, bzip2 or auto."); } return result; } /** * Utility method for retrieving the argument specifying whether to enable * the production file encoding hack to work around a bug in the current * production configuration. * * @param taskConfig * Contains all information required to instantiate and configure * the task. * @return The value of the argument. */ protected boolean getProdEncodingHackArgument( TaskConfiguration taskConfig) { return getBooleanArgument(taskConfig, ARG_ENCODING_HACK, DEFAULT_ENCODING_HACK); } } XmlTimestampFormat.java000066400000000000000000000026551253404521400340540ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/common// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.common; import java.util.Date; import org.openstreetmap.osmosis.core.domain.common.TimestampFormat; import org.openstreetmap.osmosis.core.time.DateFormatter; import org.openstreetmap.osmosis.core.time.DateParser; /** * A timestamp format implementation for dates read and stored from osm xml * files. * * @author Brett Henderson */ public class XmlTimestampFormat extends TimestampFormat { private ThreadLocal dateFormatterStore; private ThreadLocal dateParserStore; /** * Creates a new instance. */ public XmlTimestampFormat() { dateFormatterStore = new ThreadLocal(); dateParserStore = new ThreadLocal(); } /** * {@inheritDoc} */ @Override public String formatTimestamp(Date timestamp) { DateFormatter dateFormatter; dateFormatter = dateFormatterStore.get(); if (dateFormatter == null) { dateFormatter = new DateFormatter(); dateFormatterStore.set(dateFormatter); } return dateFormatter.format(timestamp); } /** * {@inheritDoc} */ @Override public Date parseTimestamp(String timestamp) { DateParser dateParser; dateParser = dateParserStore.get(); if (dateParser == null) { dateParser = new DateParser(); dateParserStore.set(dateParser); } return dateParser.parse(timestamp); } } osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/000077500000000000000000000000001253404521400267455ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/FastXmlReader.java000066400000000000000000000063531253404521400323200ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Collections; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamReader; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.task.v0_6.RunnableSource; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.xml.common.CompressionActivator; import org.openstreetmap.osmosis.xml.common.CompressionMethod; import org.openstreetmap.osmosis.xml.v0_6.impl.FastXmlParser; /** * An OSM data source reading from an xml file. The entire contents of the file * are read. * * @author Jiri Clement * @author Brett Henderson */ public class FastXmlReader implements RunnableSource { private static Logger log = Logger.getLogger(FastXmlReader.class.getName()); private Sink sink; private final File file; private final boolean enableDateParsing; private final CompressionMethod compressionMethod; /** * Creates a new instance. * * @param file * The file to read. * @param enableDateParsing * If true, dates will be parsed from xml data, else the current * date will be used thus saving parsing time. * @param compressionMethod * Specifies the compression method to employ. */ public FastXmlReader(File file, boolean enableDateParsing, CompressionMethod compressionMethod) { this.file = file; this.enableDateParsing = enableDateParsing; this.compressionMethod = compressionMethod; } /** * {@inheritDoc} */ public void setSink(Sink sink) { this.sink = sink; } /** * Reads all data from the file and send it to the sink. */ public void run() { InputStream inputStream = null; FastXmlParser parser = null; try { sink.initialize(Collections.emptyMap()); // make "-" an alias for /dev/stdin if (file.getName().equals("-")) { inputStream = System.in; } else { inputStream = new FileInputStream(file); } inputStream = new CompressionActivator(compressionMethod). createCompressionInputStream(inputStream); XMLInputFactory factory = XMLInputFactory.newInstance(); factory.setProperty(XMLInputFactory.IS_COALESCING, false); factory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, false); factory.setProperty(XMLInputFactory.IS_VALIDATING, false); XMLStreamReader xpp = factory.createXMLStreamReader(inputStream); parser = new FastXmlParser(sink, xpp, enableDateParsing); parser.readOsm(); sink.complete(); } catch (Exception e) { throw new OsmosisRuntimeException("Unable to read XML file " + file + ".", e); } finally { sink.release(); if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { log.log(Level.SEVERE, "Unable to close input stream.", e); } inputStream = null; } } } } FastXmlReaderFactory.java000066400000000000000000000034231253404521400335640ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6; import java.io.File; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.v0_6.RunnableSourceManager; import org.openstreetmap.osmosis.xml.common.CompressionMethod; import org.openstreetmap.osmosis.xml.common.XmlTaskManagerFactory; /** * The task manager factory for an xml reader. * * @author Brett Henderson */ public class FastXmlReaderFactory extends XmlTaskManagerFactory { private static final String ARG_FILE_NAME = "file"; private static final String DEFAULT_FILE_NAME = "dump.osm"; private static final String ARG_ENABLE_DATE_PARSING = "enableDateParsing"; private static final boolean DEFAULT_ENABLE_DATE_PARSING = true; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String fileName; File file; boolean enableDateParsing; CompressionMethod compressionMethod; FastXmlReader task; // Get the task arguments. fileName = getStringArgument( taskConfig, ARG_FILE_NAME, getDefaultStringArgument(taskConfig, DEFAULT_FILE_NAME) ); enableDateParsing = getBooleanArgument(taskConfig, ARG_ENABLE_DATE_PARSING, DEFAULT_ENABLE_DATE_PARSING); compressionMethod = getCompressionMethodArgument(taskConfig, fileName); // Create a file object from the file name provided. file = new File(fileName); // Build the task object. task = new FastXmlReader(file, enableDateParsing, compressionMethod); return new RunnableSourceManager(taskConfig.getId(), task, taskConfig.getPipeArgs()); } } osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/XmlChangeReader.java000066400000000000000000000074201253404521400326040ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Collections; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.RunnableChangeSource; import org.openstreetmap.osmosis.xml.common.CompressionActivator; import org.openstreetmap.osmosis.xml.common.CompressionMethod; import org.openstreetmap.osmosis.xml.v0_6.impl.OsmChangeHandler; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; /** * A change source reading from an xml file. The entire contents of the file * are read. * * @author Brett Henderson */ public class XmlChangeReader implements RunnableChangeSource { private static Logger log = Logger.getLogger(XmlReader.class.getName()); private ChangeSink changeSink; private File file; private boolean enableDateParsing; private CompressionMethod compressionMethod; /** * Creates a new instance. * * @param file * The file to read. * @param enableDateParsing * If true, dates will be parsed from xml data, else the current * date will be used thus saving parsing time. * @param compressionMethod * Specifies the compression method to employ. */ public XmlChangeReader(File file, boolean enableDateParsing, CompressionMethod compressionMethod) { this.file = file; this.enableDateParsing = enableDateParsing; this.compressionMethod = compressionMethod; } /** * {@inheritDoc} */ public void setChangeSink(ChangeSink changeSink) { this.changeSink = changeSink; } /** * Creates a new SAX parser. * * @return The newly created SAX parser. */ private SAXParser createParser() { try { return SAXParserFactory.newInstance().newSAXParser(); } catch (ParserConfigurationException e) { throw new OsmosisRuntimeException("Unable to create SAX Parser.", e); } catch (SAXException e) { throw new OsmosisRuntimeException("Unable to create SAX Parser.", e); } } /** * Reads all data from the file and send it to the sink. */ public void run() { InputStream inputStream = null; try { SAXParser parser; changeSink.initialize(Collections.emptyMap()); // make "-" an alias for /dev/stdin if (file.getName().equals("-")) { inputStream = System.in; } else { inputStream = new FileInputStream(file); } inputStream = new CompressionActivator(compressionMethod). createCompressionInputStream(inputStream); parser = createParser(); parser.parse(inputStream, new OsmChangeHandler(changeSink, enableDateParsing)); changeSink.complete(); } catch (SAXParseException e) { throw new OsmosisRuntimeException( "Unable to parse xml file " + file + ". publicId=(" + e.getPublicId() + "), systemId=(" + e.getSystemId() + "), lineNumber=" + e.getLineNumber() + ", columnNumber=" + e.getColumnNumber() + ".", e); } catch (SAXException e) { throw new OsmosisRuntimeException("Unable to parse XML.", e); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to read XML file " + file + ".", e); } finally { changeSink.release(); if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { log.log(Level.SEVERE, "Unable to close input stream.", e); } inputStream = null; } } } } XmlChangeReaderFactory.java000066400000000000000000000034121253404521400340520ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6; import java.io.File; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.v0_6.RunnableChangeSourceManager; import org.openstreetmap.osmosis.xml.common.CompressionMethod; import org.openstreetmap.osmosis.xml.common.XmlTaskManagerFactory; /** * The task manager factory for an xml change reader. * * @author Brett Henderson */ public class XmlChangeReaderFactory extends XmlTaskManagerFactory { private static final String ARG_FILE_NAME = "file"; private static final String DEFAULT_FILE_NAME = "change.osc"; private static final String ARG_ENABLE_DATE_PARSING = "enableDateParsing"; private static final boolean DEFAULT_ENABLE_DATE_PARSING = true; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String fileName; File file; boolean enableDateParsing; CompressionMethod compressionMethod; XmlChangeReader task; // Get the task arguments. fileName = getStringArgument( taskConfig, ARG_FILE_NAME, getDefaultStringArgument(taskConfig, DEFAULT_FILE_NAME) ); enableDateParsing = getBooleanArgument(taskConfig, ARG_ENABLE_DATE_PARSING, DEFAULT_ENABLE_DATE_PARSING); compressionMethod = getCompressionMethodArgument(taskConfig, fileName); // Create a file object from the file name provided. file = new File(fileName); // Build the task object. task = new XmlChangeReader(file, enableDateParsing, compressionMethod); return new RunnableChangeSourceManager(taskConfig.getId(), task, taskConfig.getPipeArgs()); } } osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/XmlChangeUploader.java000066400000000000000000000260261253404521400331600ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.StringWriter; import java.net.HttpURLConnection; import java.net.URL; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.codec.binary.Base64; import org.openstreetmap.osmosis.core.OsmosisConstants; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.xml.v0_6.impl.OsmChangeWriter; /** * An OSM change sink for uploading all data to an OpenStreetMap server. * * @author Marcus Wolschon Marcus@Wolscon.biz */ public class XmlChangeUploader implements ChangeSink { /** * Our logger for debug and error -output. */ private static final Logger LOG = Logger.getLogger( XmlChangeUploader.class.getName()); /** * Default-value for {@link DownloadingDataSet#APIBASEURSETTING}. */ private static final String DEFAULTAPIBASEURL = "http://api.openstreetmap.org/api/0.6"; /** * The baseURL defaults to the value of DEFAULTAPIBASEURL. */ private String myBaseURL; /** * the user-name to use. */ private String myUserName; /** * the password to use. */ private String myPassword; /** * Comment to add to the Changeset. */ private String myComment; /** * Used to generate the XML-content of an osc-file. */ private OsmChangeWriter myChangeWriter; /** * The ID of the changeset we opened on the server. */ private int myChangesetNumber = -1; /** * We cache the changeset here to replace the * changeset-id later. */ private StringWriter myChangesetBuffer = new StringWriter(); /** * Creates a new instance. * The baseURL defaults to the production API. * @param aBaseURL may be null * @param aUserName the user-name to use * @param aPassword the password to use * @param aComment the comment to set in the changeset */ public XmlChangeUploader(final String aBaseURL, final String aUserName, final String aPassword, final String aComment) { if (aBaseURL == null) { this.myBaseURL = DEFAULTAPIBASEURL; } else { this.myBaseURL = aBaseURL; } if (aUserName == null) { throw new IllegalArgumentException("null username given"); } this.myUserName = aUserName; if (aPassword == null) { throw new IllegalArgumentException("null password given"); } this.myPassword = aPassword; if (aComment == null) { this.myComment = ""; } else { this.myComment = aComment; } this.myPassword = aPassword; this.myChangeWriter = new OsmChangeWriter("osmChange", 0); } /** * Open the changeset if it is not yet open. * @throws IOException if we cannot contact the server. */ protected final void initialize() throws IOException { if (myChangesetNumber == -1) { URL url = new URL(this.myBaseURL + "/changeset/create"); System.err.println("DEBUG: URL= " + url.toString()); HttpURLConnection httpCon = (HttpURLConnection) url.openConnection(); httpCon.setRequestProperty("User-Agent", "Osmosis/" + OsmosisConstants.VERSION); // we do not use Authenticator.setDefault() // here to stay thread-safe. httpCon.setRequestProperty("Authorization", "Basic " + Base64.encodeBase64String( (this.myUserName + ":" + this.myPassword).getBytes("UTF8"))); httpCon.setDoOutput(true); httpCon.setRequestMethod("PUT"); OutputStreamWriter out = new OutputStreamWriter( httpCon.getOutputStream()); out.write("\n" + "\t\n"); out.write("\t\t\n"); out.write("\t\t\n"); out.write("\t\n"); out.close(); int responseCode = httpCon.getResponseCode(); if (responseCode != HttpURLConnection.HTTP_OK) { InputStreamReader reader = new InputStreamReader( httpCon.getInputStream()); LOG.severe(readAll(reader).toString()); throw new IllegalStateException("Http-Status-code is not" + " 200 OK but " + responseCode + " \"" + httpCon.getResponseMessage() + "\" Error=" + httpCon.getHeaderField("Error")); } Reader in = new InputStreamReader(httpCon.getInputStream()); char[] buffer = new char[Byte.MAX_VALUE]; int len = in.read(buffer); int changeset = Integer.parseInt(new String(buffer, 0, len)); LOG.info("opened changeset with ID: " + changeset); this.myChangesetNumber = changeset; this.myChangeWriter.setWriter(this.myChangesetBuffer); this.myChangeWriter.begin(); } } /** * {@inheritDoc} */ public void initialize(Map metaData) { // Do nothing. } /** * {@inheritDoc} */ public final void process(final ChangeContainer changeContainer) { try { initialize(); myChangeWriter.process(changeContainer); } catch (IOException e) { throw new OsmosisRuntimeException( "Cannot open changeset on server", e); } } /** * close the changeset on the server. */ public final void complete() { try { myChangeWriter.end(); LOG.fine("complete() called"); uploadChangeBuffer(); closeChangeset(); } catch (Exception e) { throw new OsmosisRuntimeException( "cannot upload or close changeset.", e); } } /** * Upload the buffered changes to the server, * replacing the changeset-number. * @throws IOException if we cannot contact the server */ private void uploadChangeBuffer() throws IOException { URL url = new URL(this.myBaseURL + "/changeset/" + this.myChangesetNumber + "/upload"); HttpURLConnection httpCon = (HttpURLConnection) url.openConnection(); httpCon.setDoOutput(true); // we do not use Authenticator.setDefault() here to stay thread-safe. httpCon.setRequestProperty("Authorization", "Basic " + Base64.encodeBase64String( (this.myUserName + ":" + this.myPassword).getBytes("UTF8"))); OutputStream out = httpCon.getOutputStream(); OutputStreamWriter writer = new OutputStreamWriter(out, "UTF8"); writer.flush(); String changeSet = this.myChangesetBuffer.getBuffer().toString(); System.out.println("changeset we got uploading:\n" + changeSet); String modified = changeSet.replaceAll("changeset=\"[0-9]*\"", "changeset=\"" + this.myChangesetNumber + "\""); System.out.println("changeset we are uploading:\n" + modified); writer.write(modified); writer.close(); int responseCode = httpCon.getResponseCode(); LOG.fine("response-code to changeset: " + responseCode); if (responseCode != HttpURLConnection.HTTP_OK) { // InputStreamReader reader = new InputStreamReader( // httpCon.getInputStream()); // LOG.severe("response:\n" + readAll(reader).toString()); throw new IllegalStateException("Http-Status-code is not" + " 200 OK but " + responseCode + " \"" + httpCon.getResponseMessage() + "\" Error=" + httpCon.getHeaderField("Error")); } } /** * Close the changeset on the server, * commiting the change. * @throws IOException if we cannot contact the server */ private void closeChangeset() throws IOException { URL url = new URL(this.myBaseURL + "/changeset/" + this.myChangesetNumber + "/close"); System.err.println("DEBUG: URL= " + url.toString()); HttpURLConnection httpCon = (HttpURLConnection) url.openConnection(); httpCon.setDoOutput(true); httpCon.setRequestMethod("PUT"); // we do not use Authenticator.setDefault() here to stay thread-safe. httpCon.setRequestProperty("Authorization", "Basic " + Base64.encodeBase64String( (this.myUserName + ":" + this.myPassword).getBytes("UTF8"))); httpCon.setRequestProperty( "Content-Type", "application/x-www-form-urlencoded"); httpCon.connect(); int responseCode = httpCon.getResponseCode(); LOG.info("response-code to closing of changeset: " + responseCode); this.myChangesetNumber = -1; if (responseCode != HttpURLConnection.HTTP_OK) { // InputStreamReader reader = new InputStreamReader( // httpCon.getInputStream()); // LOG.severe(readAll(reader).toString()); throw new IllegalStateException("Http-Status-code is not" + " 200 OK but " + responseCode + " \"" + httpCon.getResponseMessage() + "\" Error=" + httpCon.getHeaderField("Error")); } } /** * Read this reader into a String. * @param aReader where to read from * @return the content * @throws IOException if we cannot read */ private StringBuilder readAll(final Reader aReader) throws IOException { char[] buffer = new char[Byte.MAX_VALUE]; int reat = -1; StringBuilder sb = new StringBuilder(); while ((reat = aReader.read(buffer)) >= 0) { sb.append(buffer, 0, reat); } aReader.close(); return sb; } /** * {@inheritDoc} */ @Override public final void release() { if (this.myChangesetNumber != -1) { try { LOG.fine("release() called"); closeChangeset(); } catch (Exception e) { LOG.log(Level.SEVERE, "Cannot close changeset.", e); } } } } XmlChangeUploaderFactory.java000066400000000000000000000040141253404521400344220ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.v0_6.ChangeSinkManager; import org.openstreetmap.osmosis.xml.common.XmlTaskManagerFactory; /** * The task manager factory for an {@link XmlChangeUploader}. * * @author Marcus Wolschon MArcus@Wolschon.biz */ public class XmlChangeUploaderFactory extends XmlTaskManagerFactory { /** * Argument-name for the username. */ private static final String ARG_USER_NAME = "user"; /** * Argument-name for the password. */ private static final String ARG_PASSWORD = "password"; /** * Argument-name for the baseurl. */ private static final String ARG_BASEURL = "server"; /** * Argument-name for the comment for the changeset. */ private static final String ARG_COMMENT = "comment"; /** * {@inheritDoc} */ @Override protected final TaskManager createTaskManagerImpl( final TaskConfiguration taskConfig) { // Get the task arguments. String userName = getStringArgument( taskConfig, ARG_USER_NAME ); String password = getStringArgument( taskConfig, ARG_PASSWORD ); String baseURL = getStringArgument( taskConfig, ARG_BASEURL, null ); String comment = getStringArgument( taskConfig, ARG_COMMENT, "" ); // Build the task object. XmlChangeUploader task = new XmlChangeUploader( baseURL, userName, password, comment); return new ChangeSinkManager(taskConfig.getId(), task, taskConfig.getPipeArgs()); } } osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/XmlChangeWriter.java000066400000000000000000000034561253404521400326630ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6; import java.io.BufferedWriter; import java.io.File; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.xml.common.BaseXmlWriter; import org.openstreetmap.osmosis.xml.common.CompressionMethod; import org.openstreetmap.osmosis.xml.v0_6.impl.OsmChangeWriter; /** * An OSM change sink for storing all data to an xml file. * * @author Brett Henderson */ public class XmlChangeWriter extends BaseXmlWriter implements ChangeSink { private OsmChangeWriter osmChangeWriter; /** * Creates a new instance. * * @param writer * The writer to send all data to. */ public XmlChangeWriter(BufferedWriter writer) { super(writer); osmChangeWriter = new OsmChangeWriter("osmChange", 0); } /** * Creates a new instance. * * @param file * The file to write. * @param compressionMethod * Specifies the compression method to employ. */ public XmlChangeWriter(File file, CompressionMethod compressionMethod) { super(file, compressionMethod); osmChangeWriter = new OsmChangeWriter("osmChange", 0); } /** * {@inheritDoc} */ public void process(ChangeContainer changeContainer) { initialize(); osmChangeWriter.process(changeContainer); } /** * {@inheritDoc} */ @Override protected void beginElementWriter() { osmChangeWriter.begin(); } /** * {@inheritDoc} */ @Override protected void endElementWriter() { osmChangeWriter.end(); } /** * {@inheritDoc} */ @Override protected void setWriterOnElementWriter(BufferedWriter writer) { osmChangeWriter.setWriter(writer); } } XmlChangeWriterFactory.java000066400000000000000000000027221253404521400341270ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6; import java.io.File; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.v0_6.ChangeSinkManager; import org.openstreetmap.osmosis.xml.common.CompressionMethod; import org.openstreetmap.osmosis.xml.common.XmlTaskManagerFactory; /** * The task manager factory for an xml change writer. * * @author Brett Henderson */ public class XmlChangeWriterFactory extends XmlTaskManagerFactory { private static final String ARG_FILE_NAME = "file"; private static final String DEFAULT_FILE_NAME = "change.osc"; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String fileName; File file; CompressionMethod compressionMethod; XmlChangeWriter task; // Get the task arguments. fileName = getStringArgument( taskConfig, ARG_FILE_NAME, getDefaultStringArgument(taskConfig, DEFAULT_FILE_NAME) ); compressionMethod = getCompressionMethodArgument(taskConfig, fileName); // Create a file object from the file name provided. file = new File(fileName); // Build the task object. task = new XmlChangeWriter(file, compressionMethod); return new ChangeSinkManager(taskConfig.getId(), task, taskConfig.getPipeArgs()); } } osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/XmlDownloader.java000066400000000000000000000204751253404521400323770ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.Collections; import java.util.logging.Level; import java.util.logging.Logger; import java.util.zip.Inflater; import java.util.zip.InflaterInputStream; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.OsmosisConstants; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.core.task.v0_6.RunnableSource; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.core.util.MultiMemberGZIPInputStream; import org.openstreetmap.osmosis.xml.v0_6.impl.OsmHandler; import org.openstreetmap.osmosis.xml.v0_6.impl.XmlConstants; /** * An OSM data source reading from an osm-xml file from the * OpenStreetMap-server. * * @author Marcus Wolschon */ public class XmlDownloader implements RunnableSource { /** * The http-response-code for OK. */ private static final int RESPONSECODE_OK = 200; /** * My logger for debug- and error-output. */ private static Logger log = Logger.getLogger(XmlDownloader.class.getName()); /** * The timeout we use for the HttpURLConnection. */ private static final int TIMEOUT = 15000; /** * Where to deliver the loaded data. */ private Sink mySink; /** * Left longitude of the bounding box. */ private double myLeft; /** * Right longitude of the bounding box. */ private double myRight; /** * Top latitude of the bounding box. */ private double myTop; /** * Bottom latitude of the bounding box. */ private double myBottom; /** * The base url of the server. * Defaults to. "http://www.openstreetmap.org/api/0.5". */ private String myBaseUrl = XmlConstants.DEFAULT_URL; /** * The http connection used to retrieve data. */ private HttpURLConnection myActiveConnection; /** * The stream providing response data. */ private InputStream responseStream; /** * Creates a new instance with the specified geographical coordinates. * * @param left * The longitude marking the left edge of the bounding box. * @param right * The longitude marking the right edge of the bounding box. * @param top * The latitude marking the top edge of the bounding box. * @param bottom * The latitude marking the bottom edge of the bounding box. * @param baseUrl * (optional) The base url of the server (eg. * http://www.openstreetmap.org/api/0.5). */ public XmlDownloader(final double left, final double right, final double top, final double bottom, final String baseUrl) { this.myLeft = Math.min(left, right); this.myRight = Math.max(left, right); this.myTop = Math.max(top, bottom); this.myBottom = Math.min(top, bottom); if (baseUrl != null) { this.myBaseUrl = baseUrl; } } /** * {@inheritDoc} */ public void setSink(final Sink aSink) { this.mySink = aSink; } /** * Cleans up any resources remaining after completion. */ private void cleanup() { if (myActiveConnection != null) { try { myActiveConnection.disconnect(); } catch (Exception e) { log.log(Level.SEVERE, "Unable to disconnect.", e); } myActiveConnection = null; } if (responseStream != null) { try { responseStream.close(); } catch (IOException e) { log.log(Level.SEVERE, "Unable to close response stream.", e); } responseStream = null; } } /** * Creates a new SAX parser. * * @return The newly created SAX parser. */ private SAXParser createParser() { try { return SAXParserFactory.newInstance().newSAXParser(); } catch (ParserConfigurationException e) { throw new OsmosisRuntimeException("Unable to create SAX Parser.", e); } catch (SAXException e) { throw new OsmosisRuntimeException("Unable to create SAX Parser.", e); } } /** * Reads all data from the server and send it to the {@link Sink}. */ public void run() { try { mySink.initialize(Collections.emptyMap()); SAXParser parser = createParser(); InputStream inputStream = getInputStream(myBaseUrl + "/map?bbox=" + myLeft + "," + myBottom + "," + myRight + "," + myTop); // First send the Bound down the pipeline mySink.process(new BoundContainer(new Bound(myRight, myLeft, myTop, myBottom, myBaseUrl))); try { parser.parse(inputStream, new OsmHandler(mySink, true)); } finally { inputStream.close(); inputStream = null; } mySink.complete(); } catch (SAXParseException e) { throw new OsmosisRuntimeException( "Unable to parse xml" + ". publicId=(" + e.getPublicId() + "), systemId=(" + e.getSystemId() + "), lineNumber=" + e.getLineNumber() + ", columnNumber=" + e.getColumnNumber() + ".", e); } catch (SAXException e) { throw new OsmosisRuntimeException("Unable to parse XML.", e); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to read XML.", e); } finally { mySink.release(); cleanup(); } } /** * Open a connection to the given url and return a reader on the input * stream from that connection. * * @param pUrlStr * The exact url to connect to. * @return An reader reading the input stream (servers answer) or * null. * @throws IOException * on io-errors */ private InputStream getInputStream(final String pUrlStr) throws IOException { URL url; int responseCode; String encoding; url = new URL(pUrlStr); myActiveConnection = (HttpURLConnection) url.openConnection(); myActiveConnection.setRequestProperty("User-Agent", "Osmosis/" + OsmosisConstants.VERSION); myActiveConnection.setRequestProperty("Accept-Encoding", "gzip, deflate"); responseCode = myActiveConnection.getResponseCode(); if (responseCode != RESPONSECODE_OK) { String message; String apiErrorMessage; apiErrorMessage = myActiveConnection.getHeaderField("Error"); if (apiErrorMessage != null) { message = "Received API HTTP response code " + responseCode + " with message \"" + apiErrorMessage + "\" for URL \"" + pUrlStr + "\"."; } else { message = "Received API HTTP response code " + responseCode + " for URL \"" + pUrlStr + "\"."; } throw new OsmosisRuntimeException(message); } myActiveConnection.setConnectTimeout(TIMEOUT); encoding = myActiveConnection.getContentEncoding(); responseStream = myActiveConnection.getInputStream(); if (encoding != null && encoding.equalsIgnoreCase("gzip")) { responseStream = new MultiMemberGZIPInputStream(responseStream); } else if (encoding != null && encoding.equalsIgnoreCase("deflate")) { responseStream = new InflaterInputStream(responseStream, new Inflater(true)); } return responseStream; } } XmlDownloaderFactory.java000066400000000000000000000036571253404521400336530ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory; import org.openstreetmap.osmosis.core.pipeline.v0_6.RunnableSourceManager; import org.openstreetmap.osmosis.xml.v0_6.impl.XmlConstants; /** * The task manager factory for an xml reader * that downloads the map instead of reading it from * a file.. * * @author Marcus Wolschon */ public class XmlDownloaderFactory extends TaskManagerFactory { private static final String ARG_LEFT = "left"; private static final String ARG_RIGHT = "right"; private static final String ARG_TOP = "top"; private static final String ARG_BOTTOM = "bottom"; private static final String ARG_URL = "url"; private static final double DEFAULT_LEFT = -180; private static final double DEFAULT_RIGHT = 180; private static final double DEFAULT_TOP = 90; private static final double DEFAULT_BOTTOM = -90; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { double left; double right; double top; double bottom; String url; // Get the task arguments. left = getDoubleArgument(taskConfig, ARG_LEFT, DEFAULT_LEFT); right = getDoubleArgument(taskConfig, ARG_RIGHT, DEFAULT_RIGHT); top = getDoubleArgument(taskConfig, ARG_TOP, DEFAULT_TOP); bottom = getDoubleArgument(taskConfig, ARG_BOTTOM, DEFAULT_BOTTOM); url = getStringArgument(taskConfig, ARG_URL, XmlConstants.DEFAULT_URL); // Create and return the task and associated manager. return new RunnableSourceManager( taskConfig.getId(), new XmlDownloader(left, right, top, bottom, url), taskConfig.getPipeArgs() ); } } osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/XmlReader.java000066400000000000000000000072541253404521400315030ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Collections; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.task.v0_6.RunnableSource; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.xml.common.CompressionActivator; import org.openstreetmap.osmosis.xml.common.CompressionMethod; import org.openstreetmap.osmosis.xml.v0_6.impl.OsmHandler; /** * An OSM data source reading from an xml file. The entire contents of the file * are read. * * @author Brett Henderson */ public class XmlReader implements RunnableSource { private static Logger log = Logger.getLogger(XmlReader.class.getName()); private Sink sink; private File file; private boolean enableDateParsing; private CompressionMethod compressionMethod; /** * Creates a new instance. * * @param file * The file to read. * @param enableDateParsing * If true, dates will be parsed from xml data, else the current * date will be used thus saving parsing time. * @param compressionMethod * Specifies the compression method to employ. */ public XmlReader(File file, boolean enableDateParsing, CompressionMethod compressionMethod) { this.file = file; this.enableDateParsing = enableDateParsing; this.compressionMethod = compressionMethod; } /** * {@inheritDoc} */ public void setSink(Sink sink) { this.sink = sink; } /** * Creates a new SAX parser. * * @return The newly created SAX parser. */ private SAXParser createParser() { try { return SAXParserFactory.newInstance().newSAXParser(); } catch (ParserConfigurationException e) { throw new OsmosisRuntimeException("Unable to create SAX Parser.", e); } catch (SAXException e) { throw new OsmosisRuntimeException("Unable to create SAX Parser.", e); } } /** * Reads all data from the file and send it to the sink. */ public void run() { InputStream inputStream = null; try { SAXParser parser; sink.initialize(Collections.emptyMap()); // make "-" an alias for /dev/stdin if (file.getName().equals("-")) { inputStream = System.in; } else { inputStream = new FileInputStream(file); } inputStream = new CompressionActivator(compressionMethod). createCompressionInputStream(inputStream); parser = createParser(); parser.parse(inputStream, new OsmHandler(sink, enableDateParsing)); sink.complete(); } catch (SAXParseException e) { throw new OsmosisRuntimeException( "Unable to parse xml file " + file + ". publicId=(" + e.getPublicId() + "), systemId=(" + e.getSystemId() + "), lineNumber=" + e.getLineNumber() + ", columnNumber=" + e.getColumnNumber() + ".", e); } catch (SAXException e) { throw new OsmosisRuntimeException("Unable to parse XML.", e); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to read XML file " + file + ".", e); } finally { sink.release(); if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { log.log(Level.SEVERE, "Unable to close input stream.", e); } inputStream = null; } } } } osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/XmlReaderFactory.java000066400000000000000000000033441253404521400330270ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6; import java.io.File; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.v0_6.RunnableSourceManager; import org.openstreetmap.osmosis.xml.common.CompressionMethod; import org.openstreetmap.osmosis.xml.common.XmlTaskManagerFactory; /** * The task manager factory for an xml reader. * * @author Brett Henderson */ public class XmlReaderFactory extends XmlTaskManagerFactory { private static final String ARG_FILE_NAME = "file"; private static final String DEFAULT_FILE_NAME = "dump.osm"; private static final String ARG_ENABLE_DATE_PARSING = "enableDateParsing"; private static final boolean DEFAULT_ENABLE_DATE_PARSING = true; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String fileName; File file; boolean enableDateParsing; CompressionMethod compressionMethod; XmlReader task; // Get the task arguments. fileName = getStringArgument( taskConfig, ARG_FILE_NAME, getDefaultStringArgument(taskConfig, DEFAULT_FILE_NAME) ); enableDateParsing = getBooleanArgument(taskConfig, ARG_ENABLE_DATE_PARSING, DEFAULT_ENABLE_DATE_PARSING); compressionMethod = getCompressionMethodArgument(taskConfig, fileName); // Create a file object from the file name provided. file = new File(fileName); // Build the task object. task = new XmlReader(file, enableDateParsing, compressionMethod); return new RunnableSourceManager(taskConfig.getId(), task, taskConfig.getPipeArgs()); } } osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/XmlWriter.java000066400000000000000000000043441253404521400315520ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6; import java.io.BufferedWriter; import java.io.File; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.xml.common.BaseXmlWriter; import org.openstreetmap.osmosis.xml.common.CompressionMethod; import org.openstreetmap.osmosis.xml.v0_6.impl.OsmWriter; /** * An OSM data sink for storing all data to an xml file. * * @author Brett Henderson */ public class XmlWriter extends BaseXmlWriter implements Sink { private OsmWriter osmWriter; /** * Creates a new instance. * * @param writer * The writer to send all data to. */ public XmlWriter(BufferedWriter writer) { super(writer); osmWriter = new OsmWriter("osm", 0, true, false); } /** * Creates a new instance. * * @param file * The file to write. * @param compressionMethod * Specifies the compression method to employ. */ public XmlWriter(File file, CompressionMethod compressionMethod) { super(file, compressionMethod); osmWriter = new OsmWriter("osm", 0, true, false); } /** * Creates a new instance. * * @param file * The file to write. * @param compressionMethod * Specifies the compression method to employ. * @param legacyBound * If true, write the legacy {@literal } element * instead of the correct {@literal } one. */ public XmlWriter(File file, CompressionMethod compressionMethod, boolean legacyBound) { super(file, compressionMethod); osmWriter = new OsmWriter("osm", 0, true, legacyBound); } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { initialize(); osmWriter.process(entityContainer); } /** * {@inheritDoc} */ @Override protected void beginElementWriter() { osmWriter.begin(); } /** * {@inheritDoc} */ @Override protected void endElementWriter() { osmWriter.end(); } /** * {@inheritDoc} */ @Override protected void setWriterOnElementWriter(BufferedWriter writer) { osmWriter.setWriter(writer); } } osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/XmlWriterFactory.java000066400000000000000000000032231253404521400330750ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6; import java.io.File; import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration; import org.openstreetmap.osmosis.core.pipeline.common.TaskManager; import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkManager; import org.openstreetmap.osmosis.xml.common.CompressionMethod; import org.openstreetmap.osmosis.xml.common.XmlTaskManagerFactory; /** * The task manager factory for an xml writer. * * @author Brett Henderson */ public class XmlWriterFactory extends XmlTaskManagerFactory { private static final String ARG_FILE_NAME = "file"; private static final String DEFAULT_FILE_NAME = "dump.osm"; private static final String ARG_LEGACY_BOUND = "useLegacyBound"; private static final boolean DEFAULT_LEGACY_BOUND = false; /** * {@inheritDoc} */ @Override protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) { String fileName; File file; XmlWriter task; CompressionMethod compressionMethod; // Get the task arguments. fileName = getStringArgument( taskConfig, ARG_FILE_NAME, getDefaultStringArgument(taskConfig, DEFAULT_FILE_NAME) ); compressionMethod = getCompressionMethodArgument(taskConfig, fileName); // Create a file object from the file name provided. file = new File(fileName); boolean legacyBound = getBooleanArgument(taskConfig, ARG_LEGACY_BOUND, DEFAULT_LEGACY_BOUND); // Build the task object. task = new XmlWriter(file, compressionMethod, legacyBound); return new SinkManager(taskConfig.getId(), task, taskConfig.getPipeArgs()); } } osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl/000077500000000000000000000000001253404521400277065ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl/BoundWriter.java000066400000000000000000000045201253404521400330160ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import java.util.Locale; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.xml.common.ElementWriter; /** * @author KNewman * @author Igor Podolskiy * */ public class BoundWriter extends ElementWriter { private boolean legacyBound; /** * Creates a new instance. * * @param elementName * The name of the element to be written. * @param indentLevel * The indent level of the element. * @param legacyBound * If true, write the legacy {@literal } element * instead of the correct {@literal } one. */ public BoundWriter(String elementName, int indentLevel, boolean legacyBound) { super(elementName, indentLevel); this.legacyBound = legacyBound; } /** * Writes the bound. * * @param bound * The bound to be processed. */ public void process(Bound bound) { if (legacyBound) { processLegacy(bound); } else { processRegular(bound); } } private void processRegular(Bound bound) { String format = "%.5f"; beginOpenElement(); addAttribute(XmlConstants.ATTRIBUTE_NAME_MINLON, String.format(Locale.US, format, bound.getLeft())); addAttribute(XmlConstants.ATTRIBUTE_NAME_MINLAT, String.format(Locale.US, format, bound.getBottom())); addAttribute(XmlConstants.ATTRIBUTE_NAME_MAXLON, String.format(Locale.US, format, bound.getRight())); addAttribute(XmlConstants.ATTRIBUTE_NAME_MAXLAT, String.format(Locale.US, format, bound.getTop())); if (bound.getOrigin() != null) { addAttribute("origin", bound.getOrigin()); } endOpenElement(true); } private void processLegacy(Bound bound) { // Only add the Bound if the origin string isn't empty if (!"".equals(bound.getOrigin())) { beginOpenElement(); // Write with the US locale (to force . instead of , as the decimal // separator) // Use only 5 decimal places (~1.2 meter resolution should be // sufficient for Bound) addAttribute("box", String.format( Locale.US, "%.5f,%.5f,%.5f,%.5f", bound.getBottom(), bound.getLeft(), bound.getTop(), bound.getRight())); addAttribute("origin", bound.getOrigin()); endOpenElement(true); } } } BoundsElementProcessor.java000066400000000000000000000052721253404521400351440ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import org.xml.sax.Attributes; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.xml.common.BaseElementProcessor; /** * Provides an element processor implementation for a node. * * @author Karl Newman * @author Igor Podolskiy */ public class BoundsElementProcessor extends SourceElementProcessor { private Bound bound; private String defaultOrigin; /** * Creates a new instance. * * @param parentProcessor * The parent of this element processor. * @param sink * The sink for receiving processed data. * @param enableDateParsing * If true, dates will be parsed from xml data, else the current date will be used * thus saving parsing time. * @param defaultOrigin * The origin to set on the bound entity if there is no explicit origin defined. */ public BoundsElementProcessor(BaseElementProcessor parentProcessor, Sink sink, boolean enableDateParsing, String defaultOrigin) { super(parentProcessor, sink, enableDateParsing); this.defaultOrigin = defaultOrigin; } /** * {@inheritDoc} */ @Override public void begin(Attributes attributes) { double bottom = getRequiredDoubleValue(attributes, XmlConstants.ATTRIBUTE_NAME_MINLAT); double left = getRequiredDoubleValue(attributes, XmlConstants.ATTRIBUTE_NAME_MINLON); double top = getRequiredDoubleValue(attributes, XmlConstants.ATTRIBUTE_NAME_MAXLAT); double right = getRequiredDoubleValue(attributes, XmlConstants.ATTRIBUTE_NAME_MAXLON); String origin = attributes.getValue(XmlConstants.ATTRIBUTE_NAME_ORIGIN); if (origin == null) { origin = defaultOrigin; } bound = new Bound(right, left, top, bottom, origin); } private double getRequiredDoubleValue(Attributes attributes, String attributeName) { String valueString = attributes.getValue(attributeName); if (valueString == null) { throw new OsmosisRuntimeException(String.format( "Required attribute %s of the bounds element is missing", attributeName)); } try { return Double.parseDouble(valueString); } catch (NumberFormatException e) { throw new OsmosisRuntimeException( String.format("Cannot parse the %s attribute of the bounds element", attributeName), e); } } /** * {@inheritDoc} */ @Override public void end() { getSink().process(new BoundContainer(bound)); bound = null; } } ChangeSourceElementProcessor.java000066400000000000000000000106401253404521400362530ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import java.util.Map; import org.xml.sax.Attributes; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.task.common.ChangeAction; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.xml.common.BaseElementProcessor; import org.openstreetmap.osmosis.xml.common.ElementProcessor; /** * Provides an element processor implementation for an osm change element. * * @author Brett Henderson */ public class ChangeSourceElementProcessor extends BaseElementProcessor { private static final String ELEMENT_NAME_CREATE = "create"; private static final String ELEMENT_NAME_MODIFY = "modify"; private static final String ELEMENT_NAME_DELETE = "delete"; private static final String ATTRIBUTE_NAME_VERSION = "version"; private OsmElementProcessor createElementProcessor; private OsmElementProcessor modifyElementProcessor; private OsmElementProcessor deleteElementProcessor; /** * Creates a new instance. * * @param parentProcessor * The parent of this element processor. * @param changeSink * The changeSink for receiving processed data. * @param enableDateParsing * If true, dates will be parsed from xml data, else the current * date will be used thus saving parsing time. */ public ChangeSourceElementProcessor( BaseElementProcessor parentProcessor, ChangeSink changeSink, boolean enableDateParsing) { super(parentProcessor, enableDateParsing); createElementProcessor = new OsmElementProcessor( this, new ChangeSinkAdapter(changeSink, ChangeAction.Create), enableDateParsing, false, true); modifyElementProcessor = new OsmElementProcessor( this, new ChangeSinkAdapter(changeSink, ChangeAction.Modify), enableDateParsing, false, true); deleteElementProcessor = new OsmElementProcessor( this, new ChangeSinkAdapter(changeSink, ChangeAction.Delete), enableDateParsing, false, false); } /** * {@inheritDoc} */ public void begin(Attributes attributes) { String fileVersion; fileVersion = attributes.getValue(ATTRIBUTE_NAME_VERSION); if (!XmlConstants.OSM_VERSION.equals(fileVersion)) { System.err.println( "Warning, expected version " + XmlConstants.OSM_VERSION + " but received " + fileVersion + "." ); } } /** * Retrieves the appropriate child element processor for the newly * encountered nested element. * * @param uri * The element uri. * @param localName * The element localName. * @param qName * The element qName. * @return The appropriate element processor for the nested element. */ @Override public ElementProcessor getChild(String uri, String localName, String qName) { if (ELEMENT_NAME_CREATE.equals(qName)) { return createElementProcessor; } else if (ELEMENT_NAME_MODIFY.equals(qName)) { return modifyElementProcessor; } else if (ELEMENT_NAME_DELETE.equals(qName)) { return deleteElementProcessor; } return super.getChild(uri, localName, qName); } /** * {@inheritDoc} */ public void end() { // This class produces no data and therefore doesn't need to do anything // when the end of the element is reached. } private static class ChangeSinkAdapter implements Sink { private ChangeSink changeSink; private ChangeAction action; /** * Creates a new instance. * * @param changeSink * The changeSink for receiving processed data. * @param action * The action to apply to all data received. */ public ChangeSinkAdapter(ChangeSink changeSink, ChangeAction action) { this.changeSink = changeSink; this.action = action; } /** * {@inheritDoc} */ public void initialize(Map metaData) { changeSink.initialize(metaData); } /** * {@inheritDoc} */ public void process(EntityContainer entityContainer) { changeSink.process(new ChangeContainer(entityContainer, action)); } /** * {@inheritDoc} */ public void complete() { changeSink.complete(); } /** * {@inheritDoc} */ public void release() { changeSink.release(); } } } EntityElementProcessor.java000066400000000000000000000041511253404521400351610ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.xml.common.BaseElementProcessor; /** * Provides common element processor functionality for all entity processors. * * @author Brett Henderson */ public abstract class EntityElementProcessor extends SourceElementProcessor { /** * Creates a new instance. * * @param parentProcessor * The parent of this element processor. * @param sink * The sink for receiving processed data. * @param enableDateParsing * If true, dates will be parsed from xml data, else the current * date will be used thus saving parsing time. */ public EntityElementProcessor(BaseElementProcessor parentProcessor, Sink sink, boolean enableDateParsing) { super(parentProcessor, sink, enableDateParsing); } /** * Creates a user instance appropriate to the arguments. This includes * identifying the case where no user is available. * * @param rawUserId * The value of the user id attribute. * @param rawUserName * The value of the user name attribute. * @return The appropriate user instance. */ protected OsmUser buildUser(String rawUserId, String rawUserName) { if (rawUserId != null) { int userId; String userName; userId = Integer.parseInt(rawUserId); if (rawUserName == null) { userName = ""; } else { userName = rawUserName; } return new OsmUser(userId, userName); } else { return OsmUser.NONE; } } /** * Parses a changeset id based on the provided attribute value. If no attribute is available it * will be defaulted to 0. * * @param rawChangesetId * The raw changeset id attribute value. * @return The parsed changeset id. */ protected long buildChangesetId(String rawChangesetId) { if (rawChangesetId != null) { return Long.parseLong(rawChangesetId); } else { return 0; } } } osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl/EntityWriter.java000066400000000000000000000033401253404521400332220ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import java.util.Map.Entry; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.xml.common.ElementWriter; /** * Provides common functionality for all classes writing OSM entities to xml. * * @author Brett Henderson */ public class EntityWriter extends ElementWriter { /** * Creates a new instance. * * @param elementName * The name of the element to be written. * @param indentionLevel * The indent level of the element. */ protected EntityWriter(String elementName, int indentionLevel) { super(elementName, indentionLevel); } /** * Add common entity attributes. * * @param entity * The entity being written. */ protected void addCommonAttributes(Entity entity) { addAttribute("id", Long.toString(entity.getId())); addAttribute("version", Integer.toString(entity.getVersion())); addAttribute("timestamp", entity.getFormattedTimestamp(getTimestampFormat())); OsmUser user = entity.getUser(); if (!user.equals(OsmUser.NONE)) { addAttribute("uid", Integer.toString(user.getId())); addAttribute("user", user.getName()); } if (entity.getChangesetId() != 0) { addAttribute("changeset", Long.toString(entity.getChangesetId())); } } /** * Add metatag attributes. * * @param entity * The entity being written. */ protected void addMetatags(Entity entity) { for (Entry metaTag : entity.getMetaTags().entrySet()) { addAttribute(metaTag.getKey(), metaTag.getValue().toString()); } } } osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl/FastXmlParser.java000066400000000000000000000335371253404521400333170ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import java.util.Calendar; import java.util.logging.Logger; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.domain.common.SimpleTimestampContainer; import org.openstreetmap.osmosis.core.domain.common.TimestampContainer; import org.openstreetmap.osmosis.core.domain.common.TimestampFormat; import org.openstreetmap.osmosis.core.domain.common.UnparsedTimestampContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.xml.common.XmlTimestampFormat; /** * Reads the contents of an osm file using a Stax parser. * * @author Jiri Klement * @author Brett Henderson * @author Igor Podolskiy */ public class FastXmlParser { private static final String ELEMENT_NAME_BOUND = "bound"; private static final String ELEMENT_NAME_NODE = "node"; private static final String ELEMENT_NAME_WAY = "way"; private static final String ELEMENT_NAME_RELATION = "relation"; private static final String ELEMENT_NAME_TAG = "tag"; private static final String ELEMENT_NAME_NODE_REFERENCE = "nd"; private static final String ELEMENT_NAME_MEMBER = "member"; private static final String ATTRIBUTE_NAME_ID = "id"; private static final String ATTRIBUTE_NAME_VERSION = "version"; private static final String ATTRIBUTE_NAME_GENERATOR = "generator"; private static final String ATTRIBUTE_NAME_TIMESTAMP = "timestamp"; private static final String ATTRIBUTE_NAME_USER_ID = "uid"; private static final String ATTRIBUTE_NAME_USER = "user"; private static final String ATTRIBUTE_NAME_CHANGESET_ID = "changeset"; private static final String ATTRIBUTE_NAME_LATITUDE = "lat"; private static final String ATTRIBUTE_NAME_LONGITUDE = "lon"; private static final String ATTRIBUTE_NAME_KEY = "k"; private static final String ATTRIBUTE_NAME_VALUE = "v"; private static final String ATTRIBUTE_NAME_REF = "ref"; private static final String ATTRIBUTE_NAME_TYPE = "type"; private static final String ATTRIBUTE_NAME_ROLE = "role"; private static final String ATTRIBUTE_NAME_BOX = "box"; private static final String ATTRIBUTE_NAME_ORIGIN = "origin"; private static final Logger LOG = Logger.getLogger(FastXmlParser.class.getName()); private static final Object ELEMENT_NAME_BOUNDS = "bounds"; /** * Creates a new instance. * * @param sink * The sink receiving all output data. * @param reader * The input xml reader. * @param enableDateParsing * If true, parsing of dates in the xml will be enabled, * otherwise the current system time will be used. */ public FastXmlParser(Sink sink, XMLStreamReader reader, boolean enableDateParsing) { this.sink = sink; this.enableDateParsing = enableDateParsing; this.reader = reader; if (enableDateParsing) { timestampFormat = new XmlTimestampFormat(); } else { Calendar calendar; calendar = Calendar.getInstance(); calendar.set(Calendar.MILLISECOND, 0); dummyTimestampContainer = new SimpleTimestampContainer(calendar.getTime()); } memberTypeParser = new MemberTypeParser(); } private final XMLStreamReader reader; private final Sink sink; private final boolean enableDateParsing; private final MemberTypeParser memberTypeParser; private TimestampFormat timestampFormat; private TimestampContainer dummyTimestampContainer; private TimestampContainer parseTimestamp(String data) { if (enableDateParsing) { return new UnparsedTimestampContainer(timestampFormat, data); } else { return dummyTimestampContainer; } } private void readUnknownElement() throws XMLStreamException { int level = 0; do { if (reader.getEventType() == XMLStreamConstants.START_ELEMENT) { level++; } else if (reader.getEventType() == XMLStreamConstants.END_ELEMENT) { level--; } reader.nextTag(); } while (level > 0); } /** * Creates a user instance based on the current entity attributes. This includes identifying the * case where no user is available. * * @return The appropriate user instance. */ private OsmUser readUser() { String rawUserId; String rawUserName; rawUserId = reader.getAttributeValue(null, ATTRIBUTE_NAME_USER_ID); rawUserName = reader.getAttributeValue(null, ATTRIBUTE_NAME_USER); if (rawUserId != null) { int userId; String userName; userId = Integer.parseInt(rawUserId); if (rawUserName == null) { userName = ""; } else { userName = rawUserName; } return new OsmUser(userId, userName); } else { return OsmUser.NONE; } } /** * Parses a changeset id from the current entity. * * @return The changeset id as a long. 0 is returned if no attribute is available. */ private long readChangesetId() { String changesetIdAttribute; changesetIdAttribute = reader.getAttributeValue(null, ATTRIBUTE_NAME_CHANGESET_ID); if (changesetIdAttribute != null) { return Long.parseLong(changesetIdAttribute); } else { return 0; } } private Bound readBound() throws Exception { String boxString; String origin; String[] boundStrings; Double right; Double left; Double top; Double bottom; boxString = reader.getAttributeValue(null, ATTRIBUTE_NAME_BOX); if (boxString == null) { throw new OsmosisRuntimeException("Missing required box attribute of bound element"); } boundStrings = boxString.split(","); if (boundStrings.length != 4) { throw new OsmosisRuntimeException("Badly formed box attribute of bound element"); } try { bottom = Double.parseDouble(boundStrings[0]); left = Double.parseDouble(boundStrings[1]); top = Double.parseDouble(boundStrings[2]); right = Double.parseDouble(boundStrings[3]); } catch (NumberFormatException e) { throw new OsmosisRuntimeException("Can't parse box attribute of bound element", e); } origin = reader.getAttributeValue(null, ATTRIBUTE_NAME_ORIGIN); if (origin == null || origin.equals("")) { throw new OsmosisRuntimeException("Origin attribute of bound element is empty or missing."); } Bound bound = new Bound(right, left, top, bottom, origin); reader.nextTag(); reader.nextTag(); return bound; } private Bound readBounds(String defaultOrigin) throws Exception { double bottom = getRequiredDoubleValue(XmlConstants.ATTRIBUTE_NAME_MINLAT); double left = getRequiredDoubleValue(XmlConstants.ATTRIBUTE_NAME_MINLON); double top = getRequiredDoubleValue(XmlConstants.ATTRIBUTE_NAME_MAXLAT); double right = getRequiredDoubleValue(XmlConstants.ATTRIBUTE_NAME_MAXLON); String origin = reader.getAttributeValue(null, ATTRIBUTE_NAME_ORIGIN); if (origin == null) { origin = defaultOrigin; } reader.nextTag(); reader.nextTag(); return new Bound(right, left, top, bottom, origin); } private double getRequiredDoubleValue(String attributeName) { String valueString = reader.getAttributeValue(null, attributeName); if (valueString == null) { throw new OsmosisRuntimeException(String.format( "Required attribute %s of the bounds element is missing", attributeName)); } try { return Double.parseDouble(valueString); } catch (NumberFormatException e) { throw new OsmosisRuntimeException( String.format("Cannot parse the %s attribute of the bounds element", attributeName), e); } } private Tag readTag() throws Exception { Tag tag = new Tag(reader.getAttributeValue(null, ATTRIBUTE_NAME_KEY), reader.getAttributeValue(null, ATTRIBUTE_NAME_VALUE)); reader.nextTag(); reader.nextTag(); return tag; } private Node readNode() throws Exception { long id; int version; TimestampContainer timestamp; OsmUser user; long changesetId; double latitude; double longitude; Node node; id = Long.parseLong(reader.getAttributeValue(null, ATTRIBUTE_NAME_ID)); version = Integer.parseInt(reader.getAttributeValue(null, ATTRIBUTE_NAME_VERSION)); timestamp = parseTimestamp(reader.getAttributeValue(null, ATTRIBUTE_NAME_TIMESTAMP)); changesetId = Long.parseLong(reader.getAttributeValue(null, ATTRIBUTE_NAME_CHANGESET_ID)); user = readUser(); changesetId = readChangesetId(); latitude = Double.parseDouble(reader.getAttributeValue(null, ATTRIBUTE_NAME_LATITUDE)); longitude = Double.parseDouble(reader.getAttributeValue(null, ATTRIBUTE_NAME_LONGITUDE)); node = new Node(new CommonEntityData(id, version, timestamp, user, changesetId), latitude, longitude); reader.nextTag(); while (reader.getEventType() == XMLStreamConstants.START_ELEMENT) { if (reader.getLocalName().equals(ELEMENT_NAME_TAG)) { node.getTags().add(readTag()); } else { readUnknownElement(); } } reader.nextTag(); return node; } private WayNode readWayNode() throws Exception { WayNode node = new WayNode( Long.parseLong(reader.getAttributeValue(null, ATTRIBUTE_NAME_REF))); reader.nextTag(); reader.nextTag(); return node; } private Way readWay() throws Exception { long id; int version; TimestampContainer timestamp; OsmUser user; long changesetId; Way way; id = Long.parseLong(reader.getAttributeValue(null, ATTRIBUTE_NAME_ID)); version = Integer.parseInt(reader.getAttributeValue(null, ATTRIBUTE_NAME_VERSION)); timestamp = parseTimestamp(reader.getAttributeValue(null, ATTRIBUTE_NAME_TIMESTAMP)); user = readUser(); changesetId = readChangesetId(); way = new Way(new CommonEntityData(id, version, timestamp, user, changesetId)); reader.nextTag(); while (reader.getEventType() == XMLStreamConstants.START_ELEMENT) { if (reader.getLocalName().equals(ELEMENT_NAME_TAG)) { way.getTags().add(readTag()); } else if (reader.getLocalName().equals(ELEMENT_NAME_NODE_REFERENCE)) { way.getWayNodes().add(readWayNode()); } else { readUnknownElement(); } } reader.nextTag(); return way; } private RelationMember readRelationMember() throws Exception { long id; EntityType type; String role; id = Long.parseLong(reader.getAttributeValue(null, ATTRIBUTE_NAME_REF)); type = memberTypeParser.parse(reader.getAttributeValue(null, ATTRIBUTE_NAME_TYPE)); role = reader.getAttributeValue(null, ATTRIBUTE_NAME_ROLE); RelationMember relationMember = new RelationMember(id, type, role); reader.nextTag(); reader.nextTag(); return relationMember; } private Relation readRelation() throws Exception { long id; int version; TimestampContainer timestamp; OsmUser user; long changesetId; Relation relation; id = Long.parseLong(reader.getAttributeValue(null, ATTRIBUTE_NAME_ID)); version = Integer.parseInt(reader.getAttributeValue(null, ATTRIBUTE_NAME_VERSION)); timestamp = parseTimestamp(reader.getAttributeValue(null, ATTRIBUTE_NAME_TIMESTAMP)); user = readUser(); changesetId = readChangesetId(); relation = new Relation(new CommonEntityData(id, version, timestamp, user, changesetId)); reader.nextTag(); while (reader.getEventType() == XMLStreamConstants.START_ELEMENT) { if (reader.getLocalName().equals(ELEMENT_NAME_TAG)) { relation.getTags().add(readTag()); } else if (reader.getLocalName().equals(ELEMENT_NAME_MEMBER)) { relation.getMembers().add(readRelationMember()); } else { readUnknownElement(); } } reader.nextTag(); return relation; } /** * Parses the xml and sends all data to the sink. */ public void readOsm() { try { String generator = null; if (reader.nextTag() == XMLStreamConstants.START_ELEMENT && reader.getLocalName().equals("osm")) { String fileVersion; fileVersion = reader.getAttributeValue(null, ATTRIBUTE_NAME_VERSION); if (!XmlConstants.OSM_VERSION.equals(fileVersion)) { LOG.warning( "Expected version " + XmlConstants.OSM_VERSION + " but received " + fileVersion + "." ); } generator = reader.getAttributeValue(null, ATTRIBUTE_NAME_GENERATOR); reader.nextTag(); if (reader.getEventType() == XMLStreamConstants.START_ELEMENT && reader.getLocalName().equals(ELEMENT_NAME_BOUND)) { LOG.fine("Legacy element encountered."); sink.process(new BoundContainer(readBound())); } if (reader.getEventType() == XMLStreamConstants.START_ELEMENT && reader.getLocalName().equals(ELEMENT_NAME_BOUNDS)) { sink.process(new BoundContainer(readBounds(generator))); } while (reader.getEventType() == XMLStreamConstants.START_ELEMENT) { // Node, way, relation if (reader.getLocalName().equals(ELEMENT_NAME_NODE)) { sink.process(new NodeContainer(readNode())); } else if (reader.getLocalName().equals(ELEMENT_NAME_WAY)) { sink.process(new WayContainer(readWay())); } else if (reader.getLocalName().equals(ELEMENT_NAME_RELATION)) { sink.process(new RelationContainer(readRelation())); } else { readUnknownElement(); } } } else { throw new XMLStreamException(); } } catch (Exception e) { throw new OsmosisRuntimeException(e); } } } LegacyBoundElementProcessor.java000066400000000000000000000050521253404521400361020ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import org.xml.sax.Attributes; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.xml.common.BaseElementProcessor; /** * Provides an element processor implementation for a node. * * @author Karl Newman */ public class LegacyBoundElementProcessor extends SourceElementProcessor { private static final String ATTRIBUTE_NAME_BOX = "box"; private static final String ATTRIBUTE_NAME_ORIGIN = "origin"; private Bound bound; /** * Creates a new instance. * * @param parentProcessor * The parent of this element processor. * @param sink * The sink for receiving processed data. * @param enableDateParsing * If true, dates will be parsed from xml data, else the current date will be used * thus saving parsing time. */ public LegacyBoundElementProcessor(BaseElementProcessor parentProcessor, Sink sink, boolean enableDateParsing) { super(parentProcessor, sink, enableDateParsing); } /** * {@inheritDoc} */ @Override public void begin(Attributes attributes) { String boxString; String origin; String[] boundStrings; Double right; Double left; Double top; Double bottom; boxString = attributes.getValue(ATTRIBUTE_NAME_BOX); if (boxString == null) { throw new OsmosisRuntimeException("Missing required box attribute of bound element"); } boundStrings = boxString.split(","); if (boundStrings.length != 4) { throw new OsmosisRuntimeException("Badly formed box attribute of bound element"); } try { bottom = Double.parseDouble(boundStrings[0]); left = Double.parseDouble(boundStrings[1]); top = Double.parseDouble(boundStrings[2]); right = Double.parseDouble(boundStrings[3]); } catch (NumberFormatException e) { throw new OsmosisRuntimeException("Can't parse box attribute of bound element", e); } origin = attributes.getValue(ATTRIBUTE_NAME_ORIGIN); if (origin == null || origin.equals("")) { throw new OsmosisRuntimeException("Origin attribute of bound element is empty or missing."); } bound = new Bound(right, left, top, bottom, origin); } /** * {@inheritDoc} */ @Override public void end() { getSink().process(new BoundContainer(bound)); bound = null; } } MemberTypeParser.java000066400000000000000000000023031253404521400337160ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; /** * Parses the xml representation of a relation member type into an entity type * object. * * @author Brett Henderson */ public class MemberTypeParser { private static final Map MEMBER_TYPE_MAP = new HashMap(); static { MEMBER_TYPE_MAP.put("node", EntityType.Node); MEMBER_TYPE_MAP.put("way", EntityType.Way); MEMBER_TYPE_MAP.put("relation", EntityType.Relation); } /** * Parses the database representation of a relation member type into an * entity type object. * * @param memberType * The database value of member type. * @return A strongly typed entity type. */ public EntityType parse(String memberType) { if (MEMBER_TYPE_MAP.containsKey(memberType)) { return MEMBER_TYPE_MAP.get(memberType); } else { throw new OsmosisRuntimeException("The member type " + memberType + " is not recognised."); } } } MemberTypeRenderer.java000066400000000000000000000021471253404521400342360ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; /** * Renders a member type object into its xml representation. * * @author Brett Henderson */ public class MemberTypeRenderer { private static final Map MEMBER_TYPE_MAP = new HashMap(); static { MEMBER_TYPE_MAP.put(EntityType.Node, "node"); MEMBER_TYPE_MAP.put(EntityType.Way, "way"); MEMBER_TYPE_MAP.put(EntityType.Relation, "relation"); } /** * Renders a member type into its xml representation. * * @param memberType * The member type. * @return A rendered member type. */ public String render(EntityType memberType) { if (MEMBER_TYPE_MAP.containsKey(memberType)) { return MEMBER_TYPE_MAP.get(memberType); } else { throw new OsmosisRuntimeException("The member type " + memberType + " is not recognised."); } } } NodeElementProcessor.java000066400000000000000000000131751253404521400346000ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import org.xml.sax.Attributes; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.domain.common.TimestampContainer; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.xml.common.BaseElementProcessor; import org.openstreetmap.osmosis.xml.common.ElementProcessor; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Provides an element processor implementation for a node. * * @author Brett Henderson */ public class NodeElementProcessor extends EntityElementProcessor implements TagListener { private static final String ELEMENT_NAME_TAG = "tag"; private static final String ATTRIBUTE_NAME_ID = "id"; private static final String ATTRIBUTE_NAME_TIMESTAMP = "timestamp"; private static final String ATTRIBUTE_NAME_USER = "user"; private static final String ATTRIBUTE_NAME_USERID = "uid"; private static final String ATTRIBUTE_NAME_CHANGESET_ID = "changeset"; private static final String ATTRIBUTE_NAME_VERSION = "version"; private static final String ATTRIBUTE_NAME_LATITUDE = "lat"; private static final String ATTRIBUTE_NAME_LONGITUDE = "lon"; private TagElementProcessor tagElementProcessor; private Node node; private boolean coordinatesRequired; /** * Creates a new instance. * * @param parentProcessor * The parent of this element processor. * @param sink * The sink for receiving processed data. * @param enableDateParsing * If true, dates will be parsed from xml data, else the current * date will be used thus saving parsing time. */ public NodeElementProcessor(BaseElementProcessor parentProcessor, Sink sink, boolean enableDateParsing) { this(parentProcessor, sink, enableDateParsing, true); } /** * Creates a new instance. * * @param parentProcessor * The parent of this element processor. * @param sink * The sink for receiving processed data. * @param enableDateParsing * If true, dates will be parsed from xml data, else the current * date will be used thus saving parsing time. * @param coordinatesRequired * If true, nodes without lat and lon attributes set will cause an exception. */ public NodeElementProcessor(BaseElementProcessor parentProcessor, Sink sink, boolean enableDateParsing, boolean coordinatesRequired) { super(parentProcessor, sink, enableDateParsing); this.coordinatesRequired = coordinatesRequired; tagElementProcessor = new TagElementProcessor(this, this); } /** * {@inheritDoc} */ public void begin(Attributes attributes) { long id; String sversion; int version; TimestampContainer timestampContainer; String rawUserId; String rawUserName; OsmUser user; long changesetId; double latitude; double longitude; id = Long.parseLong(attributes.getValue(ATTRIBUTE_NAME_ID)); sversion = attributes.getValue(ATTRIBUTE_NAME_VERSION); if (sversion == null) { throw new OsmosisRuntimeException("Node " + id + " does not have a version attribute as OSM 0.6 are required to have. Is this a 0.5 file?"); } else { version = Integer.parseInt(sversion); } timestampContainer = createTimestampContainer(attributes.getValue(ATTRIBUTE_NAME_TIMESTAMP)); rawUserId = attributes.getValue(ATTRIBUTE_NAME_USERID); rawUserName = attributes.getValue(ATTRIBUTE_NAME_USER); changesetId = buildChangesetId(attributes.getValue(ATTRIBUTE_NAME_CHANGESET_ID)); latitude = getLatLonDouble(attributes, ATTRIBUTE_NAME_LATITUDE, id); longitude = getLatLonDouble(attributes, ATTRIBUTE_NAME_LONGITUDE, id); user = buildUser(rawUserId, rawUserName); node = new Node(new CommonEntityData(id, version, timestampContainer, user, changesetId), latitude, longitude); } /** * Retrieves the appropriate child element processor for the newly * encountered nested element. * * @param uri * The element uri. * @param localName * The element localName. * @param qName * The element qName. * @return The appropriate element processor for the nested element. */ @Override public ElementProcessor getChild(String uri, String localName, String qName) { if (ELEMENT_NAME_TAG.equals(qName)) { return tagElementProcessor; } return super.getChild(uri, localName, qName); } /** * {@inheritDoc} */ public void end() { getSink().process(new NodeContainer(node)); } /** * This is called by child element processors when a tag object is * encountered. * * @param tag * The tag to be processed. */ public void processTag(Tag tag) { node.getTags().add(tag); } private double getLatLonDouble(Attributes attributes, String attributeName, long id) { String value = attributes.getValue(attributeName); if (value == null) { if (coordinatesRequired) { throw new OsmosisRuntimeException(String.format( "Node %s does not have its %s attribute set; this attribute is required in current context.", id, attributeName)); } else { return Double.NaN; } } try { return Double.parseDouble(value); } catch (NumberFormatException ex) { throw new OsmosisRuntimeException(String.format( "Node %s: cannot parse the %s attribute as a numeric value", id, attributeName)); } } } osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl/NodeWriter.java000066400000000000000000000040131253404521400326310ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import java.io.Writer; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.NumberFormat; import java.util.Collection; import java.util.Locale; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; /** * Renders a node as xml. * * @author Brett Henderson */ public class NodeWriter extends EntityWriter { /** * Write the tags of a node. */ private TagWriter tagWriter; private NumberFormat numberFormat; /** * Creates a new instance. * * @param elementName * The name of the element to be written. * @param indentLevel * The indent level of the element. */ public NodeWriter(String elementName, int indentLevel) { super(elementName, indentLevel); tagWriter = new TagWriter("tag", indentLevel + 1); // Only write the first 7 decimal places. // Write in US locale so that a '.' is used as the decimal separator. numberFormat = new DecimalFormat( "0.#######;-0.#######", new DecimalFormatSymbols(Locale.US) ); } /** * Writes the node. * * @param node * The node to be processed. */ public void process(Node node) { Collection tags; beginOpenElement(); addCommonAttributes(node); if (!Double.isNaN(node.getLatitude())) { addAttribute("lat", numberFormat.format(node.getLatitude())); } if (!Double.isNaN(node.getLongitude())) { addAttribute("lon", numberFormat.format(node.getLongitude())); } addMetatags(node); tags = node.getTags(); if (tags.size() > 0) { endOpenElement(false); for (Tag tag : tags) { tagWriter.process(tag); } closeElement(); } else { endOpenElement(true); } } /** * {@inheritDoc} */ @Override public void setWriter(final Writer writer) { super.setWriter(writer); tagWriter.setWriter(writer); } } OsmChangeHandler.java000066400000000000000000000062701253404521400336410ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.xml.common.ElementProcessor; import org.xml.sax.Attributes; import org.xml.sax.helpers.DefaultHandler; /** * This class is a SAX default handler for processing OSM Change XML files. It * utilises a tree of element processors to extract the data from the xml * structure. * * @author Brett Henderson */ public class OsmChangeHandler extends DefaultHandler { private static final String ELEMENT_NAME_OSM_CHANGE = "osmChange"; /** * The root element processor used to process the osm change element. */ private ElementProcessor changeSourceElementProcessor; /** * The currently active element processor. This is updated whenever new xml * elements are entered or exited. */ private ElementProcessor elementProcessor; /** * @param changeSink * The changeSink to write data to. * @param enableDateParsing * If true, dates will be parsed from xml data, else the current * date will be used thus saving parsing time. */ public OsmChangeHandler(ChangeSink changeSink, boolean enableDateParsing) { changeSourceElementProcessor = new ChangeSourceElementProcessor(null, changeSink, enableDateParsing); } /** * Begins processing of a new element. * * @param uri * The uri. * @param localName * The localName. * @param qName * The qName. * @param attributes * The attributes. */ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) { // Get the appropriate element processor for the element. if (elementProcessor != null) { // We already have an active element processor, therefore use the // active element processor to retrieve the appropriate child // element processor. elementProcessor = elementProcessor.getChild(uri, localName, qName); } else if (ELEMENT_NAME_OSM_CHANGE.equals(qName)) { // There is no active element processor which means we have // encountered the root osm element. elementProcessor = changeSourceElementProcessor; } else { // There is no active element processor which means that this is a // root element. The root element in this case does not match the // expected name. throw new OsmosisRuntimeException("This does not appear to be an OSM Change XML file."); } // Initialise the element processor with the attributes of the new element. elementProcessor.begin(attributes); } /** * Ends processing of the current element. * * @param uri * The uri. * @param localName * The localName. * @param qName * The qName. */ @Override public void endElement(String uri, String localName, String qName) { // Tell the currently active element processor to complete its processing. elementProcessor.end(); // Set the active element processor to the parent of the existing processor. elementProcessor = elementProcessor.getParent(); } } OsmChangeWriter.java000066400000000000000000000075211253404521400335400ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import java.io.Writer; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.OsmosisConstants; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.task.common.ChangeAction; import org.openstreetmap.osmosis.xml.common.ElementWriter; /** * Renders OSM changes as xml. * * @author Brett Henderson */ public class OsmChangeWriter extends ElementWriter { /** * The OsmWriter to use for created elements. */ private OsmWriter osmCreateWriter; /** * The OsmWriter to use for modified elements. */ private OsmWriter osmModifyWriter; /** * The OsmWriter to use for deleted elements. */ private OsmWriter osmDeleteWriter; /** * @see #updateActiveOsmWriter(ChangeAction) */ private OsmWriter activeOsmWriter; /** * The last action (add, modify, delete) * that we processed. */ private ChangeAction lastAction; /** * Creates a new instance that * starts with an <osmChange> -element * at indent-level 0. */ public OsmChangeWriter() { this("osmChange", 0); } /** * Creates a new instance. * * @param elementName * The name of the element to be written. * @param indentLevel * The indent level of the element. */ public OsmChangeWriter(final String elementName, final int indentLevel) { super(elementName, indentLevel); osmCreateWriter = new OsmWriter("create", indentLevel + 1, false, false); osmModifyWriter = new OsmWriter("modify", indentLevel + 1, false, false); osmDeleteWriter = new OsmWriter("delete", indentLevel + 1, false, false); activeOsmWriter = null; lastAction = null; } /** * {@inheritDoc} */ @Override public void setWriter(final Writer aWriter) { super.setWriter(aWriter); this.osmCreateWriter.setWriter(aWriter); this.osmModifyWriter.setWriter(aWriter); this.osmDeleteWriter.setWriter(aWriter); } /** * Begins an <osmchange>-element. */ public void begin() { beginOpenElement(); addAttribute("version", XmlConstants.OSM_VERSION); addAttribute("generator", "Osmosis " + OsmosisConstants.VERSION); endOpenElement(false); } /** * Ends an <osmchange>-element. */ public void end() { if (activeOsmWriter != null) { activeOsmWriter.end(); activeOsmWriter = null; } lastAction = null; closeElement(); } /** * Returns the appropriate osm writer for the particular change type. * * @param action * The change action to be performed. * @return The osm writer for the change type. */ private OsmWriter getWriterForAction(final ChangeAction action) { if (action.equals(ChangeAction.Create)) { return osmCreateWriter; } else if (action.equals(ChangeAction.Modify)) { return osmModifyWriter; } else if (action.equals(ChangeAction.Delete)) { return osmDeleteWriter; } else { throw new OsmosisRuntimeException("The change action " + action + " is not recognised."); } } /** * Switch to another type of change. * @param action the action to apply to the next elements. */ private void updateActiveOsmWriter(final ChangeAction action) { if (action != lastAction) { if (activeOsmWriter != null) { activeOsmWriter.end(); } activeOsmWriter = getWriterForAction(action); activeOsmWriter.begin(); lastAction = action; } } /** * Writes the change in the container. * * @param changeContainer * The container holding the change. */ public void process(final ChangeContainer changeContainer) { updateActiveOsmWriter(changeContainer.getAction()); activeOsmWriter.process(changeContainer.getEntityContainer()); } } OsmElementProcessor.java000066400000000000000000000122471253404521400344500ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import java.util.logging.Logger; import org.xml.sax.Attributes; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.xml.common.BaseElementProcessor; import org.openstreetmap.osmosis.xml.common.ElementProcessor; /** * Provides an element processor implementation for an osm element. * * @author Brett Henderson */ public class OsmElementProcessor extends SourceElementProcessor { private static final Logger LOG = Logger.getLogger(OsmElementProcessor.class.getName()); private static final String ELEMENT_NAME_BOUND_LEGACY = "bound"; private static final String ELEMENT_NAME_BOUNDS = "bounds"; private static final String ELEMENT_NAME_NODE = "node"; private static final String ELEMENT_NAME_WAY = "way"; private static final String ELEMENT_NAME_RELATION = "relation"; private static final String ATTRIBUTE_NAME_VERSION = "version"; private static final String ATTRIBUTE_NAME_GENERATOR = "generator"; private NodeElementProcessor nodeElementProcessor; private WayElementProcessor wayElementProcessor; private RelationElementProcessor relationElementProcessor; private boolean foundBound = false; private boolean foundEntities = false; private boolean validateVersion; private String generator; /** * Creates a new instance (coordinates are required). * * @param parentProcessor * The parent of this element processor. * @param sink * The sink for receiving processed data. * @param enableDateParsing * If true, dates will be parsed from xml data, else the current * date will be used thus saving parsing time. * @param validateVersion If true, a version attribute will be checked and validated. */ public OsmElementProcessor( BaseElementProcessor parentProcessor, Sink sink, boolean enableDateParsing, boolean validateVersion) { this(parentProcessor, sink, enableDateParsing, validateVersion, true); } /** * Creates a new instance. * * @param parentProcessor * The parent of this element processor. * @param sink * The sink for receiving processed data. * @param enableDateParsing * If true, dates will be parsed from xml data, else the current * date will be used thus saving parsing time. * @param validateVersion If true, a version attribute will be checked and validated. * @param coordinatesRequired * If true, nodes without lat and lon attributes set will cause an exception. */ public OsmElementProcessor( BaseElementProcessor parentProcessor, Sink sink, boolean enableDateParsing, boolean validateVersion, boolean coordinatesRequired) { super(parentProcessor, sink, enableDateParsing); this.validateVersion = validateVersion; nodeElementProcessor = new NodeElementProcessor(this, getSink(), enableDateParsing, coordinatesRequired); wayElementProcessor = new WayElementProcessor(this, getSink(), enableDateParsing); relationElementProcessor = new RelationElementProcessor(this, getSink(), enableDateParsing); } /** * {@inheritDoc} */ public void begin(Attributes attributes) { if (validateVersion) { String fileVersion; fileVersion = attributes.getValue(ATTRIBUTE_NAME_VERSION); if (!XmlConstants.OSM_VERSION.equals(fileVersion)) { LOG.warning( "Expected version " + XmlConstants.OSM_VERSION + " but received " + fileVersion + "." ); } } generator = attributes.getValue(ATTRIBUTE_NAME_GENERATOR); } /** * Retrieves the appropriate child element processor for the newly * encountered nested element. * * @param uri * The element uri. * @param localName * The element localName. * @param qName * The element qName. * @return The appropriate element processor for the nested element. */ @Override public ElementProcessor getChild(String uri, String localName, String qName) { if (ELEMENT_NAME_BOUNDS.equals(qName) || ELEMENT_NAME_BOUND_LEGACY.equals(qName)) { if (foundEntities) { throw new OsmosisRuntimeException("Bound element must come before any entities."); } if (foundBound) { throw new OsmosisRuntimeException("Only one bound element allowed."); } foundBound = true; if (ELEMENT_NAME_BOUND_LEGACY.equals(qName)) { LOG.fine("Legacy element encountered."); return new LegacyBoundElementProcessor(this, getSink(), true); } else { return new BoundsElementProcessor(this, getSink(), true, generator); } } else if (ELEMENT_NAME_NODE.equals(qName)) { foundEntities = true; return nodeElementProcessor; } else if (ELEMENT_NAME_WAY.equals(qName)) { foundEntities = true; return wayElementProcessor; } else if (ELEMENT_NAME_RELATION.equals(qName)) { foundEntities = true; return relationElementProcessor; } return super.getChild(uri, localName, qName); } /** * {@inheritDoc} */ public void end() { // This class produces no data and therefore doesn't need to do anything // when the end of the element is reached. } } osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl/OsmHandler.java000066400000000000000000000106221253404521400326060ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.xml.common.ElementProcessor; import org.xml.sax.Attributes; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.helpers.DefaultHandler; /** * This class is a SAX default handler for processing OSM XML files. It utilises * a tree of element processors to extract the data from the xml structure. * * @author Brett Henderson */ public class OsmHandler extends DefaultHandler { private static final Logger LOG = Logger.getLogger(OsmHandler.class.getName()); private static final String ELEMENT_NAME_OSM = "osm"; /** * The root element processor used to process the osm element. */ private ElementProcessor osmElementProcessor; /** * The currently active element processor. This is updated whenever new xml * elements are entered or exited. */ private ElementProcessor elementProcessor; /** * Provides location information about the current position in the file * which is useful for reporting errors. */ private Locator documentLocator; /** * Creates a new instance. * * @param osmSink * The new osmSink to write data to. * @param enableDateParsing * If true, dates will be parsed from xml data, else the current * date will be used thus saving parsing time. */ public OsmHandler(Sink osmSink, boolean enableDateParsing) { osmElementProcessor = new OsmElementProcessor(null, osmSink, enableDateParsing, true); } /** * Begins processing of a new element. * * @param uri * The uri. * @param localName * The localName. * @param qName * The qName. * @param attributes * The attributes. */ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) { // Get the appropriate element processor for the element. if (elementProcessor != null) { // We already have an active element processor, therefore use the // active element processor to retrieve the appropriate child // element processor. elementProcessor = elementProcessor.getChild(uri, localName, qName); } else if (ELEMENT_NAME_OSM.equals(qName)) { // There is no active element processor which means we have // encountered the root osm element. elementProcessor = osmElementProcessor; } else { // There is no active element processor which means that this is a // root element. The root element in this case does not match the // expected name. throw new OsmosisRuntimeException("This does not appear to be an OSM XML file."); } // Initialise the element processor with the attributes of the new element. elementProcessor.begin(attributes); } /** * Ends processing of the current element. * * @param uri * The uri. * @param localName * The localName. * @param qName * The qName. */ @Override public void endElement(String uri, String localName, String qName) { // Tell the currently active element processor to complete its processing. elementProcessor.end(); // Set the active element processor to the parent of the existing processor. elementProcessor = elementProcessor.getParent(); } /** * Sets the document locator which is used to report the position in the * file when errors occur. * * @param documentLocator * The document locator. */ @Override public void setDocumentLocator(Locator documentLocator) { this.documentLocator = documentLocator; } /** * Called by the SAX parser when an error occurs. Used by this class to * report the current position in the file. * * @param e * The exception that occurred. * @throws SAXException * if the error reporting throws an exception. */ @Override public void error(SAXParseException e) throws SAXException { LOG.severe( "Unable to parse xml file. publicId=(" + documentLocator.getPublicId() + "), systemId=(" + documentLocator.getSystemId() + "), lineNumber=" + documentLocator.getLineNumber() + ", columnNumber=" + documentLocator.getColumnNumber() + "."); super.error(e); } } osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl/OsmWriter.java000066400000000000000000000121211253404521400325010ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import java.io.Writer; import org.openstreetmap.osmosis.core.OsmosisConstants; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityProcessor; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.xml.common.ElementWriter; /** * Renders OSM data types as xml. * * @author Brett Henderson */ public class OsmWriter extends ElementWriter { private SubElementWriter subElementWriter; private boolean renderAttributes; /** * Creates a new instance. * * @param elementName * The name of the element to be written. * @param indentLevel * The indent level of the element. * @param renderAttributes * Specifies whether attributes of the top level element should * be rendered. This would typically be set to false if this * element is embedded within a higher level element (eg. * changesets) * @param legacyBound * If true, write the legacy {@literal } element * instead of the correct {@literal } one. * */ public OsmWriter(String elementName, int indentLevel, boolean renderAttributes, boolean legacyBound) { super(elementName, indentLevel); this.renderAttributes = renderAttributes; // Create the sub-element writer which calls the appropriate element // writer based on data type. subElementWriter = new SubElementWriter(indentLevel + 1, legacyBound); } /** * Begins an element. */ public void begin() { beginOpenElement(); if (renderAttributes) { addAttribute("version", XmlConstants.OSM_VERSION); addAttribute("generator", "Osmosis " + OsmosisConstants.VERSION); } endOpenElement(false); } /** * Ends an element. */ public void end() { closeElement(); } /** * Writes the element in the container. * * @param entityContainer * The container holding the entity. */ public void process(EntityContainer entityContainer) { entityContainer.process(subElementWriter); } /** * {@inheritDoc} */ @Override public void setWriter(final Writer writer) { super.setWriter(writer); // Tell the sub element writer that a new writer is available. This will // cause the underlying entity writing classes to be updated. subElementWriter.updateWriter(writer); } /** * Directs data to the appropriate underlying element writer. * * @author Brett Henderson */ private static class SubElementWriter implements EntityProcessor { private NodeWriter nodeWriter; private WayWriter wayWriter; private RelationWriter relationWriter; private BoundWriter boundWriter; private boolean boundWritten = false; // can't write a Bound twice private boolean entitiesWritten = false; // can't write a Bound after any Entities /** * Creates a new instance. * * @param indentLevel * The indent level of the sub-elements. */ public SubElementWriter(int indentLevel, boolean legacyBound) { nodeWriter = new NodeWriter("node", indentLevel); wayWriter = new WayWriter("way", indentLevel); relationWriter = new RelationWriter("relation", indentLevel); if (legacyBound) { boundWriter = new BoundWriter("bound", indentLevel, legacyBound); } else { boundWriter = new BoundWriter("bounds", indentLevel, legacyBound); } } /** * Updates the underlying writer. * * @param writer * The writer to be used for all output xml. */ public void updateWriter(final Writer writer) { nodeWriter.setWriter(writer); wayWriter.setWriter(writer); relationWriter.setWriter(writer); boundWriter.setWriter(writer); // reset the flags indicating which data has been written boundWritten = false; entitiesWritten = false; } /** * {@inheritDoc} */ public void process(NodeContainer node) { nodeWriter.process(node.getEntity()); entitiesWritten = true; } /** * {@inheritDoc} */ public void process(WayContainer way) { wayWriter.process(way.getEntity()); entitiesWritten = true; } /** * {@inheritDoc} */ public void process(RelationContainer relation) { relationWriter.process(relation.getEntity()); entitiesWritten = true; } /** * {@inheritDoc} */ public void process(BoundContainer bound) { if (boundWritten) { throw new OsmosisRuntimeException("Bound element already written and only one allowed."); } if (entitiesWritten) { throw new OsmosisRuntimeException("Can't write bound element after other entities."); } boundWriter.process(bound.getEntity()); boundWritten = true; } } } RelationElementProcessor.java000066400000000000000000000112151253404521400354610ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.domain.common.TimestampContainer; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.xml.common.BaseElementProcessor; import org.openstreetmap.osmosis.xml.common.ElementProcessor; import org.xml.sax.Attributes; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Provides an element processor implementation for a relation. * * @author Brett Henderson */ public class RelationElementProcessor extends EntityElementProcessor implements TagListener, RelationMemberListener { private static final String ELEMENT_NAME_TAG = "tag"; private static final String ELEMENT_NAME_MEMBER = "member"; private static final String ATTRIBUTE_NAME_ID = "id"; private static final String ATTRIBUTE_NAME_TIMESTAMP = "timestamp"; private static final String ATTRIBUTE_NAME_USER = "user"; private static final String ATTRIBUTE_NAME_USERID = "uid"; private static final String ATTRIBUTE_NAME_CHANGESET_ID = "changeset"; private static final String ATTRIBUTE_NAME_VERSION = "version"; private TagElementProcessor tagElementProcessor; private RelationMemberElementProcessor relationMemberElementProcessor; private Relation relation; /** * Creates a new instance. * * @param parentProcessor * The parent of this element processor. * @param sink * The sink for receiving processed data. * @param enableDateParsing * If true, dates will be parsed from xml data, else the current * date will be used thus saving parsing time. */ public RelationElementProcessor(BaseElementProcessor parentProcessor, Sink sink, boolean enableDateParsing) { super(parentProcessor, sink, enableDateParsing); tagElementProcessor = new TagElementProcessor(this, this); relationMemberElementProcessor = new RelationMemberElementProcessor(this, this); } /** * {@inheritDoc} */ public void begin(Attributes attributes) { long id; String sversion; int version; TimestampContainer timestampContainer; String rawUserId; String rawUserName; OsmUser user; long changesetId; id = Long.parseLong(attributes.getValue(ATTRIBUTE_NAME_ID)); sversion = attributes.getValue(ATTRIBUTE_NAME_VERSION); if (sversion == null) { throw new OsmosisRuntimeException("Relation " + id + " does not have a version attribute as OSM 0.6 are required to have. Is this a 0.5 file?"); } else { version = Integer.parseInt(sversion); } timestampContainer = createTimestampContainer(attributes.getValue(ATTRIBUTE_NAME_TIMESTAMP)); rawUserId = attributes.getValue(ATTRIBUTE_NAME_USERID); rawUserName = attributes.getValue(ATTRIBUTE_NAME_USER); changesetId = buildChangesetId(attributes.getValue(ATTRIBUTE_NAME_CHANGESET_ID)); user = buildUser(rawUserId, rawUserName); relation = new Relation(new CommonEntityData(id, version, timestampContainer, user, changesetId)); } /** * Retrieves the appropriate child element processor for the newly * encountered nested element. * * @param uri * The element uri. * @param localName * The element localName. * @param qName * The element qName. * @return The appropriate element processor for the nested element. */ @Override public ElementProcessor getChild(String uri, String localName, String qName) { if (ELEMENT_NAME_MEMBER.equals(qName)) { return relationMemberElementProcessor; } else if (ELEMENT_NAME_TAG.equals(qName)) { return tagElementProcessor; } return super.getChild(uri, localName, qName); } /** * {@inheritDoc} */ public void end() { getSink().process(new RelationContainer(relation)); } /** * This is called by child element processors when a tag object is * encountered. * * @param tag * The tag to be processed. */ public void processTag(Tag tag) { relation.getTags().add(tag); } /** * This is called by child element processors when a way node object is * encountered. * * @param relationMember * The wayNode to be processed. */ public void processRelationMember(RelationMember relationMember) { relation.getMembers().add(relationMember); } } RelationMemberElementProcessor.java000066400000000000000000000036341253404521400366170ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import org.xml.sax.Attributes; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.xml.common.BaseElementProcessor; /** * Provides an element processor implementation for a relation member. * * @author Brett Henderson */ public class RelationMemberElementProcessor extends BaseElementProcessor { private static final String ATTRIBUTE_NAME_ID = "ref"; private static final String ATTRIBUTE_NAME_TYPE = "type"; private static final String ATTRIBUTE_NAME_ROLE = "role"; private RelationMemberListener relationMemberListener; private RelationMember relationMember; private MemberTypeParser memberTypeParser; /** * Creates a new instance. * * @param parentProcessor * The parent element processor. * @param relationMemberListener * The relation member listener for receiving created tags. */ public RelationMemberElementProcessor( BaseElementProcessor parentProcessor, RelationMemberListener relationMemberListener) { super(parentProcessor, true); this.relationMemberListener = relationMemberListener; memberTypeParser = new MemberTypeParser(); } /** * {@inheritDoc} */ public void begin(Attributes attributes) { long id; EntityType type; String role; id = Long.parseLong(attributes.getValue(ATTRIBUTE_NAME_ID)); type = memberTypeParser.parse(attributes.getValue(ATTRIBUTE_NAME_TYPE)); role = attributes.getValue(ATTRIBUTE_NAME_ROLE); if (role == null) { role = ""; // this may actually happen } relationMember = new RelationMember(id, type, role); } /** * {@inheritDoc} */ public void end() { relationMemberListener.processRelationMember(relationMember); relationMember = null; } } RelationMemberListener.java000066400000000000000000000010121253404521400350770ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; /** * Provides the definition of a class receiving relation members. * * @author Brett Henderson */ public interface RelationMemberListener { /** * Processes the relation member. * * @param relationMember * The relation member. */ void processRelationMember(RelationMember relationMember); } RelationMemberWriter.java000066400000000000000000000023251253404521400345760ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.xml.common.ElementWriter; /** * Renders a relation member as xml. * * @author Brett Henderson */ public class RelationMemberWriter extends ElementWriter { private MemberTypeRenderer memberTypeRenderer; /** * Creates a new instance. * * @param elementName * The name of the element to be written. * @param indentLevel * The indent level of the element. */ public RelationMemberWriter(String elementName, int indentLevel) { super(elementName, indentLevel); memberTypeRenderer = new MemberTypeRenderer(); } /** * Writes the way node. * * @param relationMember * The wayNode to be processed. */ public void processRelationMember(RelationMember relationMember) { beginOpenElement(); addAttribute("type", memberTypeRenderer.render(relationMember.getMemberType())); addAttribute("ref", Long.toString(relationMember.getMemberId())); addAttribute("role", relationMember.getMemberRole()); endOpenElement(true); } } osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl/RelationWriter.java000066400000000000000000000040231253404521400335220ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import java.io.Writer; import java.util.Collection; import java.util.List; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; /** * Renders a relation as xml. * * @author Brett Henderson */ public class RelationWriter extends EntityWriter { /** * Write the ordered list of members of a relation. */ private RelationMemberWriter relationMemberWriter; /** * Write the tags of a relation. */ private TagWriter tagWriter; /** * Creates a new instance. * * @param elementName * The name of the element to be written. * @param indentLevel * The indent level of the element. */ public RelationWriter(String elementName, int indentLevel) { super(elementName, indentLevel); tagWriter = new TagWriter("tag", indentLevel + 1); relationMemberWriter = new RelationMemberWriter("member", indentLevel + 1); } /** * Writes the relation. * * @param relation * The relation to be processed. */ public void process(Relation relation) { List relationMembers; Collection tags; beginOpenElement(); addCommonAttributes(relation); addMetatags(relation); relationMembers = relation.getMembers(); tags = relation.getTags(); if (relationMembers.size() > 0 || tags.size() > 0) { endOpenElement(false); for (RelationMember relationMember : relationMembers) { relationMemberWriter.processRelationMember(relationMember); } for (Tag tag : tags) { tagWriter.process(tag); } closeElement(); } else { endOpenElement(true); } } /** * {@inheritDoc} */ @Override public void setWriter(final Writer writer) { super.setWriter(writer); relationMemberWriter.setWriter(writer); tagWriter.setWriter(writer); } } SourceElementProcessor.java000066400000000000000000000020731253404521400351460ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.xml.common.BaseElementProcessor; /** * Provides common behaviour across all source element processors. * * @author Brett Henderson */ public abstract class SourceElementProcessor extends BaseElementProcessor { private Sink sink; /** * Creates a new instance. * * @param parentProcessor * The parent of this element processor. * @param sink * The sink for receiving processed data. * @param enableDateParsing * If true, dates will be parsed from xml data, else the current * date will be used thus saving parsing time. */ public SourceElementProcessor(BaseElementProcessor parentProcessor, Sink sink, boolean enableDateParsing) { super(parentProcessor, enableDateParsing); this.sink = sink; } /** * @return The sink. */ protected Sink getSink() { return sink; } } TagElementProcessor.java000066400000000000000000000024641253404521400344250ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import org.xml.sax.Attributes; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.xml.common.BaseElementProcessor; /** * Provides an element processor implementation for a tag. * * @author Brett Henderson */ public class TagElementProcessor extends BaseElementProcessor { private static final String ATTRIBUTE_NAME_KEY = "k"; private static final String ATTRIBUTE_NAME_VALUE = "v"; private TagListener tagListener; private Tag tag; /** * Creates a new instance. * * @param parentProcessor * The parent element processor. * @param tagListener * The tag listener for receiving created tags. */ public TagElementProcessor(BaseElementProcessor parentProcessor, TagListener tagListener) { super(parentProcessor, true); this.tagListener = tagListener; } /** * {@inheritDoc} */ public void begin(Attributes attributes) { String key; String value; key = attributes.getValue(ATTRIBUTE_NAME_KEY); value = attributes.getValue(ATTRIBUTE_NAME_VALUE); tag = new Tag(key, value); } /** * {@inheritDoc} */ public void end() { tagListener.processTag(tag); tag = null; } } osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl/TagListener.java000066400000000000000000000006461253404521400330000ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; /** * Provides the definition of a class receiving tags. * * @author Brett Henderson */ public interface TagListener { /** * Processes the tag. * * @param tag * The tag. */ void processTag(Tag tag); } osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl/TagWriter.java000066400000000000000000000016011253404521400324570ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.xml.common.ElementWriter; /** * Renders a tag as xml. * * @author Brett Henderson */ public class TagWriter extends ElementWriter { /** * Creates a new instance. * * @param elementName * The name of the element to be written. * @param indentLevel * The indent level of the element. */ public TagWriter(String elementName, int indentLevel) { super(elementName, indentLevel); } /** * Writes the tag. * * @param tag * The tag to be processed. */ public void process(Tag tag) { beginOpenElement(); addAttribute("k", tag.getKey()); addAttribute("v", tag.getValue()); endOpenElement(true); } } WayElementProcessor.java000066400000000000000000000107541253404521400344530ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.domain.common.TimestampContainer; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.xml.common.BaseElementProcessor; import org.openstreetmap.osmosis.xml.common.ElementProcessor; import org.xml.sax.Attributes; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Provides an element processor implementation for a way. * * @author Brett Henderson */ public class WayElementProcessor extends EntityElementProcessor implements TagListener, WayNodeListener { private static final String ELEMENT_NAME_TAG = "tag"; private static final String ELEMENT_NAME_NODE = "nd"; private static final String ATTRIBUTE_NAME_ID = "id"; private static final String ATTRIBUTE_NAME_TIMESTAMP = "timestamp"; private static final String ATTRIBUTE_NAME_USER = "user"; private static final String ATTRIBUTE_NAME_USERID = "uid"; private static final String ATTRIBUTE_NAME_CHANGESET_ID = "changeset"; private static final String ATTRIBUTE_NAME_VERSION = "version"; private TagElementProcessor tagElementProcessor; private WayNodeElementProcessor wayNodeElementProcessor; private Way way; /** * Creates a new instance. * * @param parentProcessor * The parent of this element processor. * @param sink * The sink for receiving processed data. * @param enableDateParsing * If true, dates will be parsed from xml data, else the current * date will be used thus saving parsing time. */ public WayElementProcessor(BaseElementProcessor parentProcessor, Sink sink, boolean enableDateParsing) { super(parentProcessor, sink, enableDateParsing); tagElementProcessor = new TagElementProcessor(this, this); wayNodeElementProcessor = new WayNodeElementProcessor(this, this); } /** * {@inheritDoc} */ public void begin(Attributes attributes) { long id; String sversion; int version; TimestampContainer timestampContainer; String rawUserId; String rawUserName; OsmUser user; long changesetId; id = Long.parseLong(attributes.getValue(ATTRIBUTE_NAME_ID)); sversion = attributes.getValue(ATTRIBUTE_NAME_VERSION); if (sversion == null) { throw new OsmosisRuntimeException("Way " + id + " does not have a version attribute as OSM 0.6 are required to have. Is this a 0.5 file?"); } else { version = Integer.parseInt(sversion); } timestampContainer = createTimestampContainer(attributes.getValue(ATTRIBUTE_NAME_TIMESTAMP)); rawUserId = attributes.getValue(ATTRIBUTE_NAME_USERID); rawUserName = attributes.getValue(ATTRIBUTE_NAME_USER); changesetId = buildChangesetId(attributes.getValue(ATTRIBUTE_NAME_CHANGESET_ID)); user = buildUser(rawUserId, rawUserName); way = new Way(new CommonEntityData(id, version, timestampContainer, user, changesetId)); } /** * Retrieves the appropriate child element processor for the newly * encountered nested element. * * @param uri * The element uri. * @param localName * The element localName. * @param qName * The element qName. * @return The appropriate element processor for the nested element. */ @Override public ElementProcessor getChild(String uri, String localName, String qName) { if (ELEMENT_NAME_NODE.equals(qName)) { return wayNodeElementProcessor; } else if (ELEMENT_NAME_TAG.equals(qName)) { return tagElementProcessor; } return super.getChild(uri, localName, qName); } /** * {@inheritDoc} */ public void end() { getSink().process(new WayContainer(way)); } /** * This is called by child element processors when a tag object is * encountered. * * @param tag * The tag to be processed. */ public void processTag(Tag tag) { way.getTags().add(tag); } /** * This is called by child element processors when a way node object is * encountered. * * @param wayNode * The wayNode to be processed. */ public void processWayNode(WayNode wayNode) { way.getWayNodes().add(wayNode); } } WayNodeElementProcessor.java000066400000000000000000000024141253404521400352530ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import org.xml.sax.Attributes; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.openstreetmap.osmosis.xml.common.BaseElementProcessor; /** * Provides an element processor implementation for a way node. * * @author Brett Henderson */ public class WayNodeElementProcessor extends BaseElementProcessor { private static final String ATTRIBUTE_NAME_ID = "ref"; private WayNodeListener wayNodeListener; private WayNode wayNode; /** * Creates a new instance. * * @param parentProcessor * The parent element processor. * @param wayNodeListener * The way node listener for receiving created tags. */ public WayNodeElementProcessor(BaseElementProcessor parentProcessor, WayNodeListener wayNodeListener) { super(parentProcessor, true); this.wayNodeListener = wayNodeListener; } /** * {@inheritDoc} */ public void begin(Attributes attributes) { long id; id = Long.parseLong(attributes.getValue(ATTRIBUTE_NAME_ID)); wayNode = new WayNode(id); } /** * {@inheritDoc} */ public void end() { wayNodeListener.processWayNode(wayNode); wayNode = null; } } WayNodeListener.java000066400000000000000000000007131253404521400335470ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; /** * Provides the definition of a class receiving way nodes. * * @author Brett Henderson */ public interface WayNodeListener { /** * Processes the way node. * * @param wayNode * The way node. */ void processWayNode(WayNode wayNode); } osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl/WayNodeWriter.java000066400000000000000000000016411253404521400333160ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.openstreetmap.osmosis.xml.common.ElementWriter; /** * Renders a way node as xml. * * @author Brett Henderson */ public class WayNodeWriter extends ElementWriter { /** * Creates a new instance. * * @param elementName * The name of the element to be written. * @param indentLevel * The indent level of the element. */ public WayNodeWriter(String elementName, int indentLevel) { super(elementName, indentLevel); } /** * Writes the way node. * * @param wayNode * The wayNode to be processed. */ public void processWayNode(WayNode wayNode) { beginOpenElement(); addAttribute("ref", Long.toString(wayNode.getNodeId())); endOpenElement(true); } } osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl/WayWriter.java000066400000000000000000000035351253404521400325140ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import java.io.Writer; import java.util.Collection; import java.util.List; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; /** * Renders a way as xml. * * @author Brett Henderson */ public class WayWriter extends EntityWriter { /** * Write the ordered list of node-references of a way. */ private WayNodeWriter wayNodeWriter; /** * Write the tags of a way. */ private TagWriter tagWriter; /** * Creates a new instance. * * @param elementName * The name of the element to be written. * @param indentLevel * The indent level of the element. */ public WayWriter(String elementName, int indentLevel) { super(elementName, indentLevel); tagWriter = new TagWriter("tag", indentLevel + 1); wayNodeWriter = new WayNodeWriter("nd", indentLevel + 1); } /** * Writes the way. * * @param way * The way to be processed. */ public void process(Way way) { List wayNodes; Collection tags; beginOpenElement(); addCommonAttributes(way); addMetatags(way); wayNodes = way.getWayNodes(); tags = way.getTags(); if (wayNodes.size() > 0 || tags.size() > 0) { endOpenElement(false); for (WayNode wayNode : wayNodes) { wayNodeWriter.processWayNode(wayNode); } for (Tag tag : tags) { tagWriter.process(tag); } closeElement(); } else { endOpenElement(true); } } /** * {@inheritDoc} */ @Override public void setWriter(final Writer writer) { super.setWriter(writer); wayNodeWriter.setWriter(writer); tagWriter.setWriter(writer); } } osmosis-0.44.1/osmosis-xml/src/main/java/org/openstreetmap/osmosis/xml/v0_6/impl/XmlConstants.java000066400000000000000000000022431253404521400332070ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; /** * Defines some common constants shared between various xml processing classes. * * @author Brett Henderson */ public final class XmlConstants { /** * The origin attribute. */ public static final String ATTRIBUTE_NAME_ORIGIN = "origin"; /** * The minlat attribute. */ public static final String ATTRIBUTE_NAME_MINLAT = "minlat"; /** * The maxlat attribute. */ public static final String ATTRIBUTE_NAME_MAXLAT = "maxlat"; /** * The minlon attribute. */ public static final String ATTRIBUTE_NAME_MINLON = "minlon"; /** * The maxlon attribute. */ public static final String ATTRIBUTE_NAME_MAXLON = "maxlon"; /** * This class cannot be instantiated. */ private XmlConstants() { } /** * Defines the version number to be stored in osm xml files. This number * will also be applied to osmChange files. */ public static final String OSM_VERSION = "0.6"; /** * The default URL for the production API. */ public static final String DEFAULT_URL = "http://www.openstreetmap.org/api/0.6"; } osmosis-0.44.1/osmosis-xml/src/main/resources/000077500000000000000000000000001253404521400213135ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/main/resources/osmosis-plugins.conf000066400000000000000000000000551253404521400253350ustar00rootroot00000000000000org.openstreetmap.osmosis.xml.XmlPluginLoaderosmosis-0.44.1/osmosis-xml/src/test/000077500000000000000000000000001253404521400173345ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/test/java/000077500000000000000000000000001253404521400202555ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/test/java/org/000077500000000000000000000000001253404521400210445ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/test/java/org/openstreetmap/000077500000000000000000000000001253404521400237325ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/test/java/org/openstreetmap/osmosis/000077500000000000000000000000001253404521400254265ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/test/java/org/openstreetmap/osmosis/xml/000077500000000000000000000000001253404521400262265ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/test/java/org/openstreetmap/osmosis/xml/common/000077500000000000000000000000001253404521400275165ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/test/java/org/openstreetmap/osmosis/xml/common/ElementWriterTest.java000066400000000000000000000024631253404521400340140ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.common; import java.io.BufferedWriter; import java.io.IOException; import java.io.StringWriter; import org.junit.Assert; import org.junit.Test; /** * Tests the element writer. */ public class ElementWriterTest { /** * Tests the element writer. * * @throws IOException * if an IO error occurs. */ @Test public void testBasic() throws IOException { MyElementWriter elementWriter; StringWriter stringWriter; BufferedWriter bufferedWriter; stringWriter = new StringWriter(); bufferedWriter = new BufferedWriter(stringWriter); elementWriter = new MyElementWriter(); elementWriter.setWriter(bufferedWriter); elementWriter.buildContent(); bufferedWriter.close(); Assert.assertEquals( "Generated xml is incorrect.", " " + System.getProperty("line.separator"), stringWriter.toString()); } private static class MyElementWriter extends ElementWriter { public MyElementWriter() { super("testElement", 1); } public void buildContent() { beginOpenElement(); addAttribute("myAttribute", "ValueBegin" + (char) 0x02 + "ValueEnd"); endOpenElement(true); } } } osmosis-0.44.1/osmosis-xml/src/test/java/org/openstreetmap/osmosis/xml/v0_6/000077500000000000000000000000001253404521400270005ustar00rootroot00000000000000XmlChangeReaderWriterTest.java000066400000000000000000000053441253404521400346200ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/test/java/org/openstreetmap/osmosis/xml/v0_6// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6; import java.io.File; import java.io.IOException; import org.junit.Test; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.misc.v0_6.NullChangeWriter; import org.openstreetmap.osmosis.testutil.AbstractDataTest; import org.openstreetmap.osmosis.xml.common.CompressionMethod; /** * A simple test verifying the operation of the xml change reader and change * writer tasks. * * @author Brett Henderson */ public class XmlChangeReaderWriterTest extends AbstractDataTest { /** * A basic test reading and writing an osm file testing both reader and * writer tasks. * * @throws IOException * if any file operations fail. */ @Test public void testSimple() throws IOException { XmlChangeReader xmlReader; XmlChangeWriter xmlWriter; File inputFile; File outputFile; inputFile = dataUtils.createDataFile("v0_6/xml-task-tests-v0_6.osc"); outputFile = dataUtils.newFile(); // Create and connect the xml tasks. xmlReader = new XmlChangeReader(inputFile, true, CompressionMethod.None); xmlWriter = new XmlChangeWriter(outputFile, CompressionMethod.None); xmlReader.setChangeSink(xmlWriter); // Process the xml. xmlReader.run(); // Validate that the output file matches the input file. dataUtils.compareFiles(inputFile, outputFile); } /** * Tests acceptance of nodes in a delete change with lat/lon attribute not set. * * @throws Exception if something goes wrong. */ @Test public void testDeleteLatLonNotSet() throws Exception { XmlChangeReader xmlReader; XmlChangeWriter xmlWriter; File inputFile; File outputFile; inputFile = dataUtils.createDataFile("v0_6/xml-delete-no-coordinates.osc"); outputFile = dataUtils.newFile(); // Create and connect the xml tasks. xmlReader = new XmlChangeReader(inputFile, true, CompressionMethod.None); xmlWriter = new XmlChangeWriter(outputFile, CompressionMethod.None); xmlReader.setChangeSink(xmlWriter); // Process the xml. xmlReader.run(); // Validate that the output file matches the input file. dataUtils.compareFiles(inputFile, outputFile); } /** * Tests non-acceptance of nodes in a non-delete change with lat/lon attribute not set. * * @throws Exception if something goes wrong. */ @Test(expected = OsmosisRuntimeException.class) public void testNonDeleteLatLonNotSet() throws Exception { File inputFile = dataUtils.createDataFile("v0_6/xml-create-no-coordinates.osc"); XmlChangeReader reader = new XmlChangeReader(inputFile, false, CompressionMethod.None); reader.setChangeSink(new NullChangeWriter()); reader.run(); } } osmosis-0.44.1/osmosis-xml/src/test/java/org/openstreetmap/osmosis/xml/v0_6/XmlReaderWriterTest.java000066400000000000000000000041021253404521400335600ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6; import java.io.File; import java.io.IOException; import org.junit.Test; import org.openstreetmap.osmosis.core.Osmosis; import org.openstreetmap.osmosis.testutil.AbstractDataTest; /** * A simple test verifying the operation of the xml reader and writer tasks. * * @author Brett Henderson */ public class XmlReaderWriterTest extends AbstractDataTest { /** * A basic test reading and writing an osm file testing both reader and * writer tasks. * * @throws IOException * if any file operations fail. */ @Test public void testSimple() throws IOException { File inputFile; File outputFile; // Generate input files. inputFile = dataUtils.createDataFile("v0_6/xml-task-tests-v0_6.osm"); outputFile = dataUtils.newFile(); // Run the pipeline. Osmosis.run( new String [] { "-q", "--read-xml-0.6", inputFile.getPath(), "--write-xml-0.6", outputFile.getPath() } ); // Validate that the output file matches the input file. dataUtils.compareFiles(inputFile, outputFile); } /** * A basic test reading and writing an osm file testing both reader and * writer tasks. * * @throws IOException * if any file operations fail. */ @Test public void testSimpleCompressed() throws IOException { File uncompressedFile; File workingFolder; File inputFile; File outputFile; // Generate input files. uncompressedFile = dataUtils.createDataFile("v0_6/xml-task-tests-v0_6.osm"); workingFolder = dataUtils.newFolder(); inputFile = new File(workingFolder, "testin.osm.gz"); outputFile = new File(workingFolder, "testout.osm.gz"); dataUtils.compressFile(uncompressedFile, inputFile); // Run the pipeline. Osmosis.run( new String [] { "-q", "--read-xml-0.6", inputFile.getPath(), "--write-xml-0.6", outputFile.getPath() } ); // Validate that the output file matches the input file. dataUtils.compareFiles(inputFile, outputFile); } } osmosis-0.44.1/osmosis-xml/src/test/java/org/openstreetmap/osmosis/xml/v0_6/impl/000077500000000000000000000000001253404521400277415ustar00rootroot00000000000000BoundWriterTest.java000066400000000000000000000044301253404521400336320ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/test/java/org/openstreetmap/osmosis/xml/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.BufferedWriter; import java.io.IOException; import java.io.StringWriter; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; /** * Tests the Bound class implementation. */ public class BoundWriterTest { private StringWriter testWriter; private BufferedWriter testBufferedWriter; /** * Performs pre-test activities. */ @Before public void setUp() { testWriter = new StringWriter(); testBufferedWriter = new BufferedWriter(testWriter); } /** * Performs post-test activities. * * @throws IOException * if stream cleanup fails. */ @After public void tearDown() throws IOException { testBufferedWriter.close(); testWriter.close(); } /** * Test writing out a normal Bound element. */ @Test public final void testProcess1() { BoundWriter bw = new BoundWriter("bound", 2, true); bw.setWriter(testBufferedWriter); bw.process(new Bound(20.123456, -21.987654, 22.555555, -23.234567, "originstring")); try { testBufferedWriter.flush(); } catch (IOException e) { e.printStackTrace(); fail("IOException"); } // If this test fails, it could be because the regex has broken. There are a number of // variations which are valid XML which this regex won't catch. It might need any number of // \\s* to account for variable whitespace. String regexMatch = "^\\s*\\s*$"; assertTrue(testWriter.toString().matches(regexMatch)); } /** * Test non-writing of a Bound element with an empty origin string. */ @Test public final void testProcess2() { BoundWriter bw = new BoundWriter("bound", 2, true); bw.setWriter(testBufferedWriter); bw.process(new Bound(20.123456, -21.987654, 22.555555, -23.234567, "")); try { testBufferedWriter.flush(); } catch (IOException e) { e.printStackTrace(); fail("IOException"); } assertTrue(testWriter.toString().equals("")); // not written; empty string } } osmosis-0.44.1/osmosis-xml/src/test/java/org/openstreetmap/osmosis/xml/v0_6/impl/NodeWriterTest.java000066400000000000000000000123371253404521400335340ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.BufferedWriter; import java.io.IOException; import java.io.StringWriter; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; /** * Tests the XML node writer implementation. */ public class NodeWriterTest { private StringWriter testWriter; private BufferedWriter testBufferedWriter; private NodeWriter testNodeWriter; private Date timestamp; // If any tests fail, it could be because the regexes have broken. There are a number of // variations which are valid XML which the regexes won't catch. They might need any number of // \\s* to account for variable whitespace, or the order of attributes may have shifted. private final String nodeOpeningMatch = "^\\s*\\s*"; private final String nodeTagMatch = "\\s*\\s*"; private final String nodeClosingMatch = "\\s*\\s*$"; /** * Performs pre-test activities. */ @Before public void setUp() { testWriter = new StringWriter(); testBufferedWriter = new BufferedWriter(testWriter); testNodeWriter = new NodeWriter("node", 2); testNodeWriter.setWriter(testBufferedWriter); Calendar calendar; calendar = Calendar.getInstance(); calendar.set(Calendar.ZONE_OFFSET, 0); calendar.set(Calendar.DST_OFFSET, 0); calendar.set(Calendar.YEAR, 2013); calendar.set(Calendar.MONTH, Calendar.OCTOBER); calendar.set(Calendar.DAY_OF_MONTH, 7); calendar.set(Calendar.HOUR_OF_DAY, 10); calendar.set(Calendar.MINUTE, 24); calendar.set(Calendar.SECOND, 31); calendar.set(Calendar.MILLISECOND, 0); timestamp = calendar.getTime(); } /** * Performs post-test activities. * * @throws IOException * if stream cleanup fails. */ @After public void tearDown() throws IOException { testBufferedWriter.close(); testWriter.close(); } /** * Test writing out a normal Node element. */ @Test public final void testProcessNormalNode() { Node node = new Node( new CommonEntityData(1234, 2, timestamp, new OsmUser(23, "someuser"), 0), 20.12345678, -21.98765432); node.getTags().add(new Tag("nodekey", "nodevalue")); testNodeWriter.process(node); try { testBufferedWriter.flush(); } catch (IOException e) { e.printStackTrace(); fail("IOException"); } String [] strArray = testWriter.toString().split("\\n", 3); assertTrue("Node opening element does not match.", strArray[0].matches(nodeOpeningMatch)); assertTrue("Node tag does not match.", strArray[1].matches(nodeTagMatch)); assertTrue("Node closing element does not match.", strArray[2].matches(nodeClosingMatch)); } /** * Test writing out a Node element with no tags. */ @Test public final void testProcessNodeNoTags() { testNodeWriter.process( new Node( new CommonEntityData( 1234, 2, timestamp, new OsmUser(23, "someuser"), 0, new ArrayList()), 20.12345678, -21.98765432)); try { testBufferedWriter.flush(); } catch (IOException e) { e.printStackTrace(); fail("IOException"); } String regexMatch = "^\\s*\\s*$"; assertTrue(testWriter.toString().matches(regexMatch)); } /** * Test writing of a Node element with no user. */ @Test public final void testProcessNodeWithNoUser() { Node node = new Node(new CommonEntityData(1234, 2, timestamp, OsmUser.NONE, 0), 20.12345678, -21.98765432); node.getTags().add(new Tag("nodekey", "nodevalue")); testNodeWriter.process(node); try { testBufferedWriter.flush(); } catch (IOException e) { e.printStackTrace(); fail("IOException"); } String nodeOpeningNoUserMatch = "^\\s*\\s*"; String [] strArray = testWriter.toString().split("\\n", 3); assertTrue("Node opening element does not match.", strArray[0].matches(nodeOpeningNoUserMatch)); assertTrue("Node tag does not match.", strArray[1].matches(nodeTagMatch)); assertTrue("Node closing element does not match.", strArray[2].matches(nodeClosingMatch)); } } osmosis-0.44.1/osmosis-xml/src/test/java/org/openstreetmap/osmosis/xml/v0_6/impl/OsmHandlerTest.java000066400000000000000000000207061253404521400335050ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.junit.Before; import org.junit.Test; import org.xml.sax.SAXException; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.testutil.v0_6.SinkEntityInspector; /** * Not sure how to go about unit testing this. The individual parser classes seem to require a lot * of infrastructure, so this test will just set up the full parser to parse an XML string and check * the produced entities. * * @author Karl Newman * */ public class OsmHandlerTest { private SAXParser parser; private SinkEntityInspector entityInspector; private static final String OSM_PREFIX = "\n"; private static final String OSM_SUFFIX = ""; /** * Performs pre-test activities. */ @Before public void setUp() { entityInspector = new SinkEntityInspector(); try { parser = SAXParserFactory.newInstance().newSAXParser(); } catch (ParserConfigurationException e) { throw new OsmosisRuntimeException("Unable to create SAX Parser.", e); } catch (SAXException e) { throw new OsmosisRuntimeException("Unable to create SAX Parser.", e); } } private void parseString(String input) { InputStream inputStream = null; try { inputStream = new ByteArrayInputStream(input.getBytes("UTF-8")); parser.parse(inputStream, new OsmHandler(entityInspector, true)); } catch (UnsupportedEncodingException e) { throw new OsmosisRuntimeException("String encoding exception", e); } catch (SAXException e) { throw new OsmosisRuntimeException("Parse exception", e); } catch (IOException e) { throw new OsmosisRuntimeException("IOException", e); } finally { try { if (inputStream != null) { inputStream.close(); } } catch (IOException e) { throw new OsmosisRuntimeException("IOException", e); } finally { inputStream = null; } } } /** * Tests that an empty xml document can be parsed successfully. */ @Test public final void testEmptyDocument() { parseString(OSM_PREFIX + OSM_SUFFIX); assertNull(entityInspector.getLastEntityContainer()); } /** * Test a normal, well-formed bound element. */ @Test public final void testBoundElement1() { parseString(OSM_PREFIX + "" + OSM_SUFFIX); Bound b = (Bound) entityInspector.getLastEntityContainer().getEntity(); assertTrue(Double.compare(b.getRight(), 45.67891) == 0 && Double.compare(b.getLeft(), -23.45678) == 0 && Double.compare(b.getTop(), 34.56789) == 0 && Double.compare(b.getBottom(), -12.34567) == 0); assertTrue(b.getOrigin().equals("someorigin")); } /** * Test a malformed box attribute for a bound element. */ @Test(expected = OsmosisRuntimeException.class) public final void testBoundElement2() { parseString(OSM_PREFIX + "" + OSM_SUFFIX); fail("Expected to throw an exception"); } /** * Test a missing box attribute of a bound element. */ @Test(expected = OsmosisRuntimeException.class) public final void testBoundElement3() { parseString(OSM_PREFIX + "" + OSM_SUFFIX); fail("Expected to throw an exception"); } /** * Test a number parse error for a box attribute of a bound element. */ @Test(expected = OsmosisRuntimeException.class) public final void testBoundElement4() { parseString(OSM_PREFIX + "" + OSM_SUFFIX); fail("Expected to throw an exception"); } /** * Test a missing origin attribute of a bound element. */ @Test(expected = OsmosisRuntimeException.class) public final void testBoundElement5() { parseString(OSM_PREFIX + "" + OSM_SUFFIX); fail("Expected to throw an exception"); } /** * Test an empty origin attribute of a bound element. */ @Test(expected = OsmosisRuntimeException.class) public final void testBoundElement6() { parseString(OSM_PREFIX + "" + OSM_SUFFIX); fail("Expected to throw an exception"); } /** * Test a repeated bound element. */ @Test(expected = OsmosisRuntimeException.class) public final void testBoundElement7() { parseString(OSM_PREFIX + "" + "" + OSM_SUFFIX); fail("Expected to throw an exception"); } /** * Test a bound element occurring after a node element. */ @Test(expected = OsmosisRuntimeException.class) public final void testBoundElement8() { parseString(OSM_PREFIX + "" + "" + OSM_SUFFIX); fail("Expected to throw an exception"); } /** * Test a bound element occurring after a way element. */ @Test(expected = OsmosisRuntimeException.class) public final void testBoundElement9() { parseString(OSM_PREFIX + "" + "" + "" + "" + "" + OSM_SUFFIX); fail("Expected to throw an exception"); } /** * Test a bound element occurring after a relation element. */ @Test(expected = OsmosisRuntimeException.class) public final void testBoundElement10() { parseString(OSM_PREFIX + "" + "" + "" + "" + "" + OSM_SUFFIX); fail("Expected to throw an exception"); } /** * Test the parsing of a bound element as returned by the OSM API * without an origin. */ @Test public void testBoundsNoOrigin() { parseString(OSM_PREFIX + "" + OSM_SUFFIX); Bound b = (Bound) entityInspector.getLastEntityContainer().getEntity(); assertEquals(-1.234, b.getLeft(), 1E-6); assertEquals(-1.234, b.getBottom(), 1E-6); assertEquals(1.234, b.getRight(), 1E-6); assertEquals(1.234, b.getTop(), 1E-6); assertNull(b.getOrigin()); } /** * Test the parsing of a bound element as returned by the OSM API * with an origin. */ @Test public void testBoundsWithOrigin() { parseString(OSM_PREFIX + "" + OSM_SUFFIX); Bound b = (Bound) entityInspector.getLastEntityContainer().getEntity(); assertEquals("someorigin", b.getOrigin()); } /** * Test the inheritance of generator to the origin. */ @Test public void testBoundsOriginInheritance() { parseString("" + "" + "" + ""); Bound b = (Bound) entityInspector.getLastEntityContainer().getEntity(); assertEquals("somegenerator", b.getOrigin()); } } osmosis-0.44.1/osmosis-xml/src/test/java/org/openstreetmap/osmosis/xml/v0_6/impl/OsmWriterTest.java000066400000000000000000000124601253404521400334020ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import static org.junit.Assert.fail; import java.io.BufferedWriter; import java.io.IOException; import java.io.StringWriter; import java.util.ArrayList; import java.util.Date; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; /** * Tests the XML osm element writer implementation. */ public class OsmWriterTest { private StringWriter testWriter; private BufferedWriter testBufferedWriter; private OsmWriter testOsmWriter; /** * Performs pre-test activities. */ @Before public void setUp() { testWriter = new StringWriter(); testBufferedWriter = new BufferedWriter(testWriter); testOsmWriter = new OsmWriter("osm", 0, true, true); testOsmWriter.setWriter(testBufferedWriter); } /** * Performs post-test activities. * * @throws IOException * if IO stream cleanup fails. */ @After public void tearDown() throws IOException { testBufferedWriter.close(); testWriter.close(); testOsmWriter = null; } /** * Test processing a single Bound entity. */ @Test public final void testProcess1() { testOsmWriter.process(new BoundContainer(new Bound("source"))); // Nothing to assert; just expect no exception } /** * Test processing a repeated Bound entity. */ @Test(expected = OsmosisRuntimeException.class) public final void testProcess2() { testOsmWriter.process(new BoundContainer(new Bound("source"))); testOsmWriter.process(new BoundContainer(new Bound("source2"))); fail("Expected to throw an exception."); } /** * Test processing a Node entity. */ @Test public final void testProcess3() { testOsmWriter.process( new NodeContainer( new Node( new CommonEntityData( 1234, 0, new Date(), new OsmUser(12, "OsmosisTest"), 0, new ArrayList()), 20, 20))); // Nothing to assert; just expect no exception } /** * Test processing a Bound after a Node. */ @Test(expected = OsmosisRuntimeException.class) public final void testProcess4() { testOsmWriter.process(new NodeContainer( new Node( new CommonEntityData(1234, 0, new Date(), new OsmUser(12, "OsmosisTest"), 0, new ArrayList()), 20, 20))); testOsmWriter.process(new BoundContainer(new Bound("source"))); fail("Expected to throw an exception."); } /** * Test processing a Way. */ @Test public final void testProcess6() { Way testWay; testWay = new Way(new CommonEntityData(3456, 0, new Date(), new OsmUser(12, "OsmosisTest"), 0)); testWay.getWayNodes().add(new WayNode(1234)); testWay.getWayNodes().add(new WayNode(1235)); testWay.getTags().add(new Tag("test_key1", "test_value1")); testOsmWriter.process(new WayContainer(testWay)); // Nothing to assert; just expect no exception } /** * Test processing a Bound after a Way. */ @Test(expected = OsmosisRuntimeException.class) public final void testProcess7() { Way testWay; testWay = new Way(new CommonEntityData(3456, 0, new Date(), new OsmUser(12, "OsmosisTest"), 0)); testWay.getWayNodes().add(new WayNode(1234)); testWay.getWayNodes().add(new WayNode(1235)); testWay.getTags().add(new Tag("test_key1", "test_value1")); testOsmWriter.process(new WayContainer(testWay)); testOsmWriter.process(new BoundContainer(new Bound("source"))); } /** * Test processing a Relation. */ @Test public final void testProcess8() { Relation testRelation; testRelation = new Relation(new CommonEntityData(3456, 0, new Date(), new OsmUser(12, "OsmosisTest"), 0)); testRelation.getMembers().add(new RelationMember(1234, EntityType.Node, "role1")); testRelation.getTags().add(new Tag("test_key1", "test_value1")); testOsmWriter.process(new RelationContainer(testRelation)); // Nothing to assert; just expect no exception } /** * Test processing a Bound after a Relation. */ @Test(expected = OsmosisRuntimeException.class) public final void testProcess9() { Relation testRelation; testRelation = new Relation(new CommonEntityData(3456, 0, new Date(), new OsmUser(12, "OsmosisTest"), 0)); testRelation.getMembers().add(new RelationMember(1234, EntityType.Node, "role1")); testRelation.getTags().add(new Tag("test_key1", "test_value1")); testOsmWriter.process(new RelationContainer(testRelation)); testOsmWriter.process(new BoundContainer(new Bound("source"))); } } RelationWriterTest.java000066400000000000000000000153651253404521400343510ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/test/java/org/openstreetmap/osmosis/xml/v0_6/impl// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.BufferedWriter; import java.io.IOException; import java.io.StringWriter; import java.util.Calendar; import java.util.Date; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.EntityType; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; /** * Tests the XML relation writer implementation. */ public class RelationWriterTest { private StringWriter testWriter; private BufferedWriter testBufferedWriter; private RelationWriter testRelationWriter; private Date timestamp; // If any tests fail, it could be because the regexes have broken. There are a number of // variations which are valid XML which the regexes won't catch. They might need any number of // \\s* to account for variable whitespace, or the order of attributes may have shifted. private final String relationOpeningMatch = "^\\s*\\s*"; private final String nodeMemberMatch = "\\s*\\s*"; private final String wayMemberMatch = "\\s*\\s*"; private final String relationMemberMatch = "\\s*\\s*"; private final String relationTagMatch = "\\s*\\s*"; private final String relationClosingMatch = "\\s*\\s*$"; /** * Performs pre-test activities. */ @Before public void setUp() { testWriter = new StringWriter(); testBufferedWriter = new BufferedWriter(testWriter); testRelationWriter = new RelationWriter("relation", 2); testRelationWriter.setWriter(testBufferedWriter); Calendar calendar; calendar = Calendar.getInstance(); calendar.set(Calendar.ZONE_OFFSET, 0); calendar.set(Calendar.DST_OFFSET, 0); calendar.set(Calendar.YEAR, 2013); calendar.set(Calendar.MONTH, Calendar.OCTOBER); calendar.set(Calendar.DAY_OF_MONTH, 7); calendar.set(Calendar.HOUR_OF_DAY, 10); calendar.set(Calendar.MINUTE, 24); calendar.set(Calendar.SECOND, 31); calendar.set(Calendar.MILLISECOND, 0); timestamp = calendar.getTime(); } /** * Performs post-test activities. * * @throws IOException * if stream cleanup fails. */ @After public void tearDown() throws IOException { testBufferedWriter.close(); testWriter.close(); } /** * Test writing out a normal Relation element. */ @Test public final void testProcessNormalRelation() { Relation relation = new Relation(new CommonEntityData(1234, 2, timestamp, new OsmUser(23, "someuser"), 0)); relation.getMembers().add(new RelationMember(2345, EntityType.Node, "noderole")); relation.getMembers().add(new RelationMember(3456, EntityType.Way, "wayrole")); relation.getMembers().add(new RelationMember(4567, EntityType.Relation, "relationrole")); relation.getTags().add(new Tag("relationkey", "relationvalue")); testRelationWriter.process(relation); try { testBufferedWriter.flush(); } catch (IOException e) { e.printStackTrace(); fail("IOException"); } String [] strArray = testWriter.toString().split("\\n", 6); assertTrue("Relation opening element does not match.", strArray[0].matches(relationOpeningMatch)); assertTrue("Relation member node does not match.", strArray[1].matches(nodeMemberMatch)); assertTrue("Relation member way does not match.", strArray[2].matches(wayMemberMatch)); assertTrue("Relation member relation does not match.", strArray[3].matches(relationMemberMatch)); assertTrue("Relation tag does not match.", strArray[4].matches(relationTagMatch)); assertTrue("Relation closing element does not match.", strArray[5].matches(relationClosingMatch)); } /** * Test writing of a Relation element with no user. */ @Test public final void testProcessRelationWithNoUser() { Relation relation = new Relation(new CommonEntityData(1234, 2, timestamp, OsmUser.NONE, 0)); relation.getMembers().add(new RelationMember(2345, EntityType.Node, "noderole")); relation.getMembers().add(new RelationMember(3456, EntityType.Way, "wayrole")); relation.getMembers().add(new RelationMember(4567, EntityType.Relation, "relationrole")); relation.getTags().add(new Tag("relationkey", "relationvalue")); testRelationWriter.process(relation); try { testBufferedWriter.flush(); } catch (IOException e) { e.printStackTrace(); fail("IOException"); } String relationOpeningNoUserMatch = "^\\s*\\s*"; String [] strArray = testWriter.toString().split("\\n", 6); assertTrue(strArray[0].matches(relationOpeningNoUserMatch)); assertTrue(strArray[1].matches(nodeMemberMatch)); assertTrue(strArray[2].matches(wayMemberMatch)); assertTrue(strArray[3].matches(relationMemberMatch)); assertTrue(strArray[4].matches(relationTagMatch)); assertTrue(strArray[5].matches(relationClosingMatch)); } /** * Test writing out a Relation element with no tags. */ @Test public final void testProcessRelationNoTags() { Relation relation = new Relation(new CommonEntityData(1234, 2, timestamp, new OsmUser(23, "someuser"), 0)); relation.getMembers().add(new RelationMember(2345, EntityType.Node, "noderole")); relation.getMembers().add(new RelationMember(3456, EntityType.Way, "wayrole")); relation.getMembers().add(new RelationMember(4567, EntityType.Relation, "relationrole")); testRelationWriter.process(relation); try { testBufferedWriter.flush(); } catch (IOException e) { e.printStackTrace(); fail("IOException"); } String [] strArray = testWriter.toString().split("\\n", 5); assertTrue(strArray[0].matches(relationOpeningMatch)); assertTrue(strArray[1].matches(nodeMemberMatch)); assertTrue(strArray[2].matches(wayMemberMatch)); assertTrue(strArray[3].matches(relationMemberMatch)); assertTrue(strArray[4].matches(relationClosingMatch)); } } osmosis-0.44.1/osmosis-xml/src/test/java/org/openstreetmap/osmosis/xml/v0_6/impl/WayWriterTest.java000066400000000000000000000132071253404521400334040ustar00rootroot00000000000000// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.BufferedWriter; import java.io.IOException; import java.io.StringWriter; import java.util.Calendar; import java.util.Date; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; /** * Tests the XML way writer implementation. */ public class WayWriterTest { private StringWriter testWriter; private BufferedWriter testBufferedWriter; private WayWriter testWayWriter; private Date timestamp; // If any tests fail, it could be because the regexes have broken. There are a number of // variations which are valid XML which the regexes won't catch. They might need any number of // \\s* to account for variable whitespace, or the order of attributes may have shifted. private final String wayOpeningMatch = "^\\s*\\s*"; private final String wayNode1Match = "\\s*\\s*"; private final String wayNode2Match = "\\s*\\s*"; private final String wayTagMatch = "\\s*\\s*"; private final String wayClosingMatch = "\\s*\\s*$"; /** * Performs pre-test activities. */ @Before public void setUp() { testWriter = new StringWriter(); testBufferedWriter = new BufferedWriter(testWriter); testWayWriter = new WayWriter("way", 2); testWayWriter.setWriter(testBufferedWriter); Calendar calendar; calendar = Calendar.getInstance(); calendar.set(Calendar.ZONE_OFFSET, 0); calendar.set(Calendar.DST_OFFSET, 0); calendar.set(Calendar.YEAR, 2013); calendar.set(Calendar.MONTH, Calendar.OCTOBER); calendar.set(Calendar.DAY_OF_MONTH, 7); calendar.set(Calendar.HOUR_OF_DAY, 10); calendar.set(Calendar.MINUTE, 24); calendar.set(Calendar.SECOND, 31); calendar.set(Calendar.MILLISECOND, 0); timestamp = calendar.getTime(); } /** * Performs post-test activities. * * @throws IOException * if stream cleanup fails. */ @After public void tearDown() throws IOException { testBufferedWriter.close(); testWriter.close(); } /** * Test writing out a normal Way element. */ @Test public final void testProcessNormalWay() { Way way = new Way(new CommonEntityData(1234, 2, timestamp, new OsmUser(23, "someuser"), 0)); way.getWayNodes().add(new WayNode(1235)); way.getWayNodes().add(new WayNode(1236)); way.getTags().add(new Tag("waykey", "wayvalue")); testWayWriter.process(way); try { testBufferedWriter.flush(); } catch (IOException e) { e.printStackTrace(); fail("IOException"); } String [] strArray = testWriter.toString().split("\\n", 5); assertTrue("Way opening element does not match.", strArray[0].matches(wayOpeningMatch)); assertTrue("Way node 1 does not match.", strArray[1].matches(wayNode1Match)); assertTrue("Way node 2 does not match.", strArray[2].matches(wayNode2Match)); assertTrue("Way tag does not match.", strArray[3].matches(wayTagMatch)); assertTrue("Way closing element does not match.", strArray[4].matches(wayClosingMatch)); } /** * Test writing of a Way element with no user. */ @Test public final void testProcessWayWithNoUser() { Way way = new Way(new CommonEntityData(1234, 2, timestamp, OsmUser.NONE, 0)); way.getWayNodes().add(new WayNode(1235)); way.getWayNodes().add(new WayNode(1236)); way.getTags().add(new Tag("waykey", "wayvalue")); testWayWriter.process(way); try { testBufferedWriter.flush(); } catch (IOException e) { e.printStackTrace(); fail("IOException"); } String wayOpeningNoUserMatch = "^\\s*\\s*"; String [] strArray = testWriter.toString().split("\\n", 5); assertTrue("Way opening element does not match.", strArray[0].matches(wayOpeningNoUserMatch)); assertTrue("Way node 1 does not match.", strArray[1].matches(wayNode1Match)); assertTrue("Way node 2 does not match.", strArray[2].matches(wayNode2Match)); assertTrue("Way tag does not match.", strArray[3].matches(wayTagMatch)); assertTrue("Way closing element does not match.", strArray[4].matches(wayClosingMatch)); } /** * Test writing out a Way element with no tags. */ @Test public final void testProcessWayNoTags() { Way way = new Way(new CommonEntityData(1234, 2, timestamp, new OsmUser(23, "someuser"), 0)); way.getWayNodes().add(new WayNode(1235)); way.getWayNodes().add(new WayNode(1236)); testWayWriter.process(way); try { testBufferedWriter.flush(); } catch (IOException e) { e.printStackTrace(); fail("IOException"); } String [] strArray = testWriter.toString().split("\\n", 4); assertTrue("Way opening element does not match.", strArray[0].matches(wayOpeningMatch)); assertTrue("Way node 1 does not match.", strArray[1].matches(wayNode1Match)); assertTrue("Way node 2 does not match.", strArray[2].matches(wayNode2Match)); assertTrue("Way closing element does not match.", strArray[3].matches(wayClosingMatch)); } } osmosis-0.44.1/osmosis-xml/src/test/resources/000077500000000000000000000000001253404521400213465ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/test/resources/data/000077500000000000000000000000001253404521400222575ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/test/resources/data/template/000077500000000000000000000000001253404521400240725ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/test/resources/data/template/v0_6/000077500000000000000000000000001253404521400246445ustar00rootroot00000000000000osmosis-0.44.1/osmosis-xml/src/test/resources/data/template/v0_6/xml-create-no-coordinates.osc000066400000000000000000000003321253404521400323330ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-xml/src/test/resources/data/template/v0_6/xml-task-tests-v0_6.osc000066400000000000000000000123421253404521400310240ustar00rootroot00000000000000 osmosis-0.44.1/osmosis-xml/src/test/resources/data/template/v0_6/xml-task-tests-v0_6.osm000066400000000000000000000033071253404521400310370ustar00rootroot00000000000000 osmosis-0.44.1/package/000077500000000000000000000000001253404521400146675ustar00rootroot00000000000000osmosis-0.44.1/package/.gitignore000066400000000000000000000000401253404521400166510ustar00rootroot00000000000000.project .settings /build /lib osmosis-0.44.1/package/bin/000077500000000000000000000000001253404521400154375ustar00rootroot00000000000000osmosis-0.44.1/package/bin/osmosis000077500000000000000000000063311253404521400170640ustar00rootroot00000000000000#!/bin/sh # Config files can define several variables used throughout this script. # JAVACMD - The java command to launch osmosis. # JAVACMD_OPTIONS - The options to append to the java command, typically used to modify jvm settings such as max memory. # OSMOSIS_OPTIONS - The options to apply to all osmosis invocations, typically used to add plugins or make quiet operation the default. if [ -f /etc/osmosis ] ; then . /etc/osmosis fi if [ -f "$HOME/.osmosis" ] ; then . "$HOME/.osmosis" fi if [ -z "$JAVACMD" ] ; then # No JAVACMD provided in osmosis config files, therefore default to java JAVACMD=java fi ## resolve links - $0 may be a link to application PRG="$0" # if started without absolute path, but from PATH environment if [ ! -s "$PRG" ] ; then PRG=`which $PRG` fi # need this for relative symlinks while [ -h "$PRG" ] ; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG="`dirname "$PRG"`/$link" fi done if [ "x$1x" = "xx" ] || echo "$@" | grep -q -e '--help' ; then cat < \(.*\)$'` if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG="`dirname "$PRG"`/$link" fi done # make it fully qualified saveddir=`pwd` MYAPP_HOME=`dirname "$PRG"`/.. MYAPP_HOME=`cd "$MYAPP_HOME" && pwd` cd "$saveddir" # Build up the classpath of required jar files. MYAPP_CLASSPATH=$MYAPP_HOME/osmosis.jar:$OSMOSIS_CLASSPATH for FILE in `ls $MYAPP_HOME/lib/default/`; do MYAPP_CLASSPATH=$MYAPP_CLASSPATH:$MYAPP_HOME/lib/default/$FILE done MAINCLASS=org.openstreetmap.osmosis.extract.apidb.v0_6.OsmosisExtractApiDb EXEC="$JAVACMD $JAVACMD_OPTIONS -cp $MYAPP_CLASSPATH $MAINCLASS $@" exec $EXEC osmosis-0.44.1/package/bin/osmosis-extract-mysql-0.6000077500000000000000000000025601253404521400222000ustar00rootroot00000000000000#!/bin/sh # Config files can define several variables used throughout this script. # JAVACMD - The java command to launch osmosis. # JAVACMD_OPTIONS - The options to append to the java command, typically used to modify jvm settings such as max memory. if [ -f /etc/osmosis ] ; then . /etc/osmosis fi if [ -f "$HOME/.osmosis" ] ; then . "$HOME/.osmosis" fi if [ -z "$JAVACMD" ] ; then # No JAVACMD provided in osmosis config files, therefore default to java JAVACMD=java fi ## resolve links - $0 may be a link to application PRG="$0" # if started without absolute path, but from PATH environment if [ ! -s "$PRG" ] ; then PRG=`which $PRG` fi # need this for relative symlinks while [ -h "$PRG" ] ; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG="`dirname "$PRG"`/$link" fi done # make it fully qualified saveddir=`pwd` MYAPP_HOME=`dirname "$PRG"`/.. MYAPP_HOME=`cd "$MYAPP_HOME" && pwd` cd "$saveddir" # Build up the classpath of required jar files. MYAPP_CLASSPATH=$MYAPP_HOME/osmosis.jar:$OSMOSIS_CLASSPATH for FILE in `ls $MYAPP_HOME/lib/default/`; do MYAPP_CLASSPATH=$MYAPP_CLASSPATH:$MYAPP_HOME/lib/default/$FILE done MAINCLASS=org.openstreetmap.osmosis.extract.mysql.v0_6.OsmosisExtractMysql EXEC="$JAVACMD $JAVACMD_OPTIONS -cp $MYAPP_CLASSPATH $MAINCLASS $@" exec $EXEC osmosis-0.44.1/package/bin/osmosis.bat000066400000000000000000000030771253404521400176320ustar00rootroot00000000000000@ECHO OFF REM This is an equivalent Windows batch file to complement the unix shell script REM Corresponding lines from the shell script are printed before the matching batch file commands REM # Config files can define several variables used throughout this script. REM # JAVACMD - The java command to launch osmosis. REM # JAVACMD_OPTIONS - The options to append to the java command, typically used to modify jvm settings such as max memory. REM # OSMOSIS_OPTIONS - The options to apply to all osmosis invocations, typically used to add plugins or make quiet operation the default. REM if [ -f /etc/osmosis ] ; then REM . /etc/osmosis REM fi IF EXIST "%ALLUSERSPROFILE%\osmosis.bat" CALL "%ALLUSERSPROFILE%\osmosis.bat" REM if [ -f "$HOME/.osmosis" ] ; then REM . "$HOME/.osmosis" REM fi IF EXIST "%USERPROFILE%\osmosis.bat" CALL "%USERPROFILE%\osmosis.bat" REM if [ -z "$JAVACMD" ] ; then REM # No JAVACMD provided in osmosis config files, therefore default to java REM JAVACMD=java REM fi IF "%JAVACMD%"=="" set JAVACMD=java REM Set "SAVEDIR" to the current directory set SAVEDIR=%CD% set MYAPP_HOME=%~dp0.. REM Now make the MYAPP_HOME path absolute cd /D %MYAPP_HOME% set MYAPP_HOME=%CD% REM Change back to the original directory cd /D %SAVEDIR% set MAINCLASS=org.codehaus.classworlds.Launcher set PLEXUS_CP=%MYAPP_HOME%\lib\default\plexus-classworlds-2.4.jar SET EXEC="%JAVACMD%" %JAVACMD_OPTIONS% -cp "%PLEXUS_CP%" -Dapp.home="%MYAPP_HOME%" -Dclassworlds.conf="%MYAPP_HOME%\config\plexus.conf" %MAINCLASS% %OSMOSIS_OPTIONS% %* %EXEC% osmosis-0.44.1/package/build.gradle000066400000000000000000000036331253404521400171530ustar00rootroot00000000000000configurations { runtime archives } dependencies { runtime project(':osmosis-apidb') runtime project(':osmosis-areafilter') runtime project(':osmosis-core') runtime project(':osmosis-dataset') runtime project(':osmosis-extract') runtime project(':osmosis-pbf') runtime project(':osmosis-pbf2') runtime project(':osmosis-pgsimple') runtime project(':osmosis-pgsnapshot') runtime project(':osmosis-replication') runtime project(':osmosis-replication-http') runtime project(':osmosis-set') runtime project(':osmosis-tagfilter') runtime project(':osmosis-tagtransform') runtime project(':osmosis-xml') runtime group: 'org.codehaus.plexus', name: 'plexus-classworlds', version: dependencyVersionClassworlds } task syncLibs(type: Sync) { into "lib/default" from configurations.runtime } def artefactPrefix = 'osmosis-' + version task distZip(type: Zip) { description = 'Builds a zip file containing a self-contained distribution of the application.' archiveName = artefactPrefix + '.zip' destinationDir = new File(projectDir, 'build/distribution') from('.') { exclude 'build*' exclude 'ivy.xml' exclude '.*' } } distZip.dependsOn syncLibs task distTgz(type: Tar) { description = 'Builds a tgz file containing a self-contained distribution of the application.' archiveName = artefactPrefix + '.tgz' destinationDir = new File(projectDir, 'build/distribution') compression = Compression.GZIP from('.') { exclude 'build*' exclude 'ivy.xml' exclude '.*' } } distTgz.dependsOn syncLibs task assemble { description = 'Generates a working application directory structure.' } assemble.dependsOn distZip, distTgz task build { description = 'Assembles and tests this project.' } build.dependsOn assemble task clean(type: Delete) { delete 'build' } artifacts { archives distZip, distTgz } osmosis-0.44.1/package/changes.txt000066400000000000000000000620201253404521400170400ustar00rootroot000000000000000.44 Improve default settings and performance of pgsnapshot load scripts. Fix remaining 64-bit id tracking problems. Increase maximum way node count from 16-bit to 32-bit int. Full null pointer exception in --merge-replication-files. Fix javadoc errors on JDK 1.8. Support spaces in installation path on Windows. Set User-Agent header on all HTTP requests. Support importing negative ids to apidb. Fix one-off error in current way/relation loading. Fix query for retrieving way nodes and relation members in pgsnapshot module. Prevent reading duplicate way nodes in pgsnapshot module. Fix deprecation warnings caused by upgrading to newer dependencies. Upgrade to protobuf 2.6.0. Fix replicate_osm_file.sh to return the correct exit status, not always -1. Add scripts to build a docker image for testing database tasks. Update build to download Gradle via https. Fix broken console logging in replication lag reader causing a crash. Update default replication URLs to match current planet server layout. Add IntelliJ IDE support. 0.43.1 Fix the version number displayed on startup to be up to date. Remove RELEASE suffix from version number of release builds. 0.43 Update command line help to point to the correct wiki location. Remove idTrackerType arguments to filtering tasks, only the Dynamic option is now available. Fix the --write-apidb task to use 64-bit ids. Upgrade to version 1.4 of the Gradle build tool. Enhance the build scripts to support publishing to Sonatype OSS Repository and Maven Central. Rename all projects to use an "osmosis-" prefix. Included a copy of the PBF OSM Binary project in the source tree, and eliminated the pre-compiled osmbin.jar. Remove pbfmarshall project due to the same functionality being provided by the osm-binary project. Removed the internal Ivy repository due to all dependencies now being available on Maven Central. Rename --read-empty short name --re to --rem to avoid clash with --report-entity. Rename --read-empty-change short name --rec to --remc for consistency with --read-empty. 0.42 Fix PostgreSQL timestamp bugs in apidb replication logic. Fix replication file merging boundary corrections. Occurs when catching up after outages. Replication logic correctly honours the max timestamp parameter. Prevent replication file downloader from reading beyond maximum available replication interval. Prevent replication file downloader from stalling if interval is too long. Improve error reporting when an unknown global option is specified. Disable automatic state.txt creation for --read-replication-interval. Add --tag-transform plugin and task. Reduce number of file handles consumed by file-based sorting. Make the default id tracker Dynamic for --used-node and --used-way. Use Gradle for the automated build scripts instead of Ant/Ivy. Fix PostgreSQL ident authentication. Remove obsolete debian build scripts. Eliminate use of deprecated Spring SimpleJdbcTemplate. Improve handling of invalid geometries in --pgsql-xxx tasks. Default keepInvalidWays option on --pgsql-xxx tasks to true. Enable keepInvalidWays functionality for --pgsql-xxx replication. Fix pgsnapshot COPY load script to use ST_ prefix for all PostGIS functions. 0.41 All entities can now pass metadata through the pipeline. XML tasks can add these as additional attributes on output. Added --convert-change-to-full-history task. Added "initialize" support to all tasks to allow pre-processing setup to occur. Added a number of unit tests to increase test coverage, and reduced use of duplicated support classes. Added support for the XML bounds element, but still support old bound element. Added configurable log message prefix to the output of --log-progress-* tasks. Added completion step timings for --log-progress-* tasks. Added continuous replication looping support to apidb replication functionality. Added --write-replication task. Enhanced --replicate-apidb to send output through the pipeline to tasks like --write-replication instead of being an all-in-one task. Added --send-replication-sequence task which notifies listeners when new replication data has been written. Added --send-replication-data task which provides streaming replication data to listeners. Added --receive-replication task which consumes data sent by --serve-replication-data. Added --replication-to-change task which converts a replication pipeline stream to a normal change stream. Added keyValueListFile option to --node-key-value and --way-key-value tasks. Added JaCoCo code coverage tool to the build process. Updated ant scripts to use build, checkstyle, test and all targets across all projects. Update pgsnapshot and pgsimple tasks to no longer use PostGIS deprecated function names. Added --read-pbf-fast PBF reader which utilises multi-threading to improve performance. Enhanced XML tasks to handle missing lat/lon attributes on deleted entities. 0.40.1 Fix the classworlds version in the Windows launcher. 0.40 Fixed base64 encoding of user credentials sent by --upload-xml-change. Added support for merging Bound objects. Modified entity object creation to require use of CommonEntityData to simplify constructors. Added metatag facility to all entities to allow custom data to be passed through the pipeline. Added read timeout to replication retrieval code to prevent it blocking forever. Improved JPF loading code to avoid NullPointerException if encountering malformed plugins. Added ability to set input buffer size for all tasks using an input buffer. Relaxed Bound argument validation to allow points on all edges of the map to be included in bounding boxes. Modified PostGIS function calls to be PostGIS 2.0 compatible. Updated build scripts to support GIT. Do not emit bound entities when reading PBF files with no bbox information set. Add --compute-bounding-box and --set-bounding-box tasks for manipulating Bound entities. Added total object count display to --report-entity task. Updated all jar dependencies with exception of Xerces to latest versions. Modified project layouts to match Maven standard layout. Enhanced tests to dynamically generate test data instead of relying on ant-based data generation. Updated apidb tasks to support new rails3-based apidb schema (rename of id columns). Fixed name of --log-progress-change-0.6 task. Was registered as --log-change-progress-0.6. Modified Ivy to symlink to jar files on supported platforms rather copy jars into projects. 0.39 Added the pgsimp tasks which are the old 0.36 version pgsql tasks supporting the old style separate tags tables. Added a new "cascadingRelations" flag to --bb and --bp which is less costly than "completeRelations" and makes sure that parent relations are emitted when a child relation of theirs is emitted even if that child happens to come after the parent in the stream. The list of relations on output may appear in a different order than on input. Fixed connection failure error handling in pgsql tasks to display the correct error message instead of a NullPointerException. Fixed serialisation logic to correctly identify and use the OsmUser.NONE singleton object. Fixed checkstyle errors in the PBF code. Renamed the PBF project to "pbf" instead of "binary". Improved performance in the DataPostbox class used for inter-thread messaging. Fixed PBF code to allow an empty file to be written. Updated PBF library dependency from version 1.0 to 1.1. Updated default PBF filename from dump.osmbin to dump.osm.pbf. Fixed PBF code to write a header block even if no bound entity exists. Added java code for PostgreSQL HStore support instead of only including a pre-compiled jar. Added a new "auto" option for the compressionMethod argument of XML tasks. Fixed the windows launch batch script to support installation to a different drive than the drive of the working directory. Fixed the UNIX launch shell script to support spaces in argument values. Enhanced --used-node to include nodes referenced by ways and relations, instead of just ways. Enhanced serialisation logic to support negative version numbers. Note this increases the space used by serialisation slightly. Added a --used-way task. 0.38 Updated internal storage to use long instead of int identifiers to remove 2^31 node id limit. Updated apidb support to the latest schema 20100910084426. Fixed the --write-pbf short option --wb to point to the writer implementation instead of the reader. Added additional quoting to commands in the osmosis.bat launcher to fix issues with spaces in the installation path. Modified plugin loader code to support multiple osmosis-plugins.conf files to allow each plugin to provide its own. 0.37 Updated the pgsql schema (now version 6) to move all tags into hstore columns, add a ways.nodes column and CLUSTER the nodes and ways tables. Significant performance increases. Fixed a bug in --bounding-box and --bounding-polygon preventing use of clipIncompleteEntities after a --tee task. Added --read-pbf and --write-pbf tasks supporting the new Google Protocol Buffer based binary data format. Added a new --flatten task for removing multiple versions of single entities from an entity stream. Fixed bugs in the --bounding-box and --bounding-polygon idTrackerType=Dynamic option. Enhanced the apidb replication read queries by adding temp table primary keys to fix performance regressions with PostgreSQL 8.4. 0.36 Removed 0.5 support. Added the --fast-write-pgsql task which uses PostgreSQL COPY commands to insert data. Added the CompactTempFile node location store type which allows efficient pgsql geometry building for small data sets. All write-pgsql tasks now default to the CompactTempFile node location type store instead of in memory. Fixed regression in tar builds to make the launch scripts executable again. Updated the pgsql schema (now version 5) to add a primary key to the relation_members table to allow more efficient updates. Updated apidb support to the latest schema 20100513171259. Updated pgsql dataset bounding box queries to force more efficient query plans by disabling inefficient join types. Added a new dynamic idTrackerType implementation selected by default to the area filtering tasks to simplify usage. Added the --read-replication-lag task which indicates how far behind the server a local replication is. 0.35 Registered --fast-read-xml as a task instead of requiring --fast-read-xml-0.6 to be specified. Fixed the completeRelations option on the --bounding-box and --bounding-polygon tasks to work as expected and documented. Updated the --fast-read-xml task to ignore changeset elements. Various enhancements to the Ivy processing including publishing of all artefacts. Fixed apidb tasks to correctly select the MySQL drivers instead of always using PostgreSQL drivers. Fixed the osmosis.bat launcher to handle spaces in the installation path. 0.34 Fixed the --sort and --sort-change tasks to use 0.6 task implementations instead of the older 0.5 implementations. Fixed the archive distributions to include the config/plexus.conf file, and include the launcher scripts in the tar version. Various cleanups of archive distributions to remove unnecessary files and minimise size. 0.33 Use Plexus Classworlds to simplify launcher scripts. Switch from org.apache.tools.bzip2 to commons-compress (this project is still alive). Updated the --apply-change task to detect full history diffs and abort. Enabled cascading deletes in the --truncate-apidb task to minimise foreign key violations on new schema updates. Updated all PostgreSQL database tasks to support IDENT authentication. Removed local postgis distribution since it is available on repo1.maven.org now. 0.32 Change to Public Domain licence. Re-factored all entity classes to use a CommonEntityData class to avoid duplication of code and simplify code re-use. Significant re-factoring of many apidb tasks to use Spring JDBC Template functionality. Added a --replicate-apidb task for extracting replication files based on PostgreSQL transaction ids. Fixed PostgreSQL apidb COPY files to include changeset id. Fixed the Windows launcher batch file to contain all libraries. Added a --read-replication-interval task. Updated XML writing tasks to ignore UTF-8 characters not supported by XML. Included new Xerces XML library to provide proper support for UTF-16 surrogate pairs. Added a --merge-replication-files task. Added a --way-key task. Added a --simplify-change task. Added pom.xml for maven artifacts 0.31 Added a --remove-tags task. Added JPF plugin support. Updated the build scripts to use Ivy dependency management. Added mutable entity support. Added writeable dataset support. Added apidb tasks that support both mysql and postgresql api databases. Added a new --append-change task for combining full history changesets. 0.30 Added 0.6 support. Enhanced the pgsql tasks and schema to support an optional "action" table. Enhanced the pgsql schema to introduce a stored procedure called during every changeset application. Enhanced the pgsql schema to include optional bbox and linestring columns on the way table. Added ability to specify slipping map zoom and coordinates as arguments to the bounding box filter. Added an "inMemoryBbox" to the pgsql writer task allowing it to calculate bounding boxes using a memory mapped file. Added an automatic VACUUM ANALYZE of the database for pgsql writer and truncation tasks. Added migration tasks --migrate and --migrate-change allowing 0.5 data to be converted to 0.6 format. Added forceUtf8 and profileSql options to all MySQL tasks. Added a --tag-sort task allowing tags within entities to be sorted alphabetically (0.6 only). Enhanced the buffer tasks to chunk objects passed (chunks are 1/4 of max buffer size) to minimise thread synchronisation (0.6 only). Dropped the default buffer size from 100 to 20 which provides slightly improved performance in most cases (0.6 only). Added the ability to generate full history changesets, as opposed to changesets with a single change per entity (0.6 only). Added a new allowIncorrectSchemaVersion option to most database tasks. Added new clipIncompleteEntities option to area filter tasks. It defaults to false which changes existing behaviour. 0.29 Fixed the --write-pgsql-simple-dump task to properly escape '\' characters. Updated the pgsql simple tasks to use an SRID of 4326. Updated build script to include a tar file distribution preserving launch script execute permissions. Enhanced the Entity class to allow dates to be represented as strings to avoid parsing overhead. Updated xml tasks to utilise this feature. Updated the pgsql simple tasks to use the new database schema which is more similar to the one used in the central MySQL Removed the old postgresql tasks. Removed "simple" from the names of the simple pgsql tasks. Added plugin support allowing new tasks in external jar files to be registered with osmosis. Added command line checks to ensure all task and option arguments are recognised, any misspelt arguments will now raise an error. Removed all static methods from the task registrar and task manager factory classes to avoid global data and simplify testing. Added the --node-key and --node-key-value tasks. 0.28 Added a maximum file download count feature to the change downloader to limit processing overhead when synchronising long time intervals. Fixed a major error in the TaskRegistrar from 0.27 where multiple tasks had the same name preventing osmosis from launching. 0.27 Added change downloader tasks providing the basis for automatic synchronisation of data sets. 0.26 Removed the bdb dataset implementation. Fixed an incorrect constant bug in the mysql tile calculator causing incorrect tile values to be generated. 0.25 Added a new osmosis-extract-mysql application for extracting regular changesets from mysql. Removed use of String.isEmpty to minimise Java5 incompatibility. Modified the default pipe connectivity functionality to use stack-based connectivity instead of queue-based connectivity. Added a populateCurrentTables option to the --write-mysql-change task to match the --write-mysql task. Added validation code to the merge tasks to verify that input data is sorted. Enhanced serialisation code to eliminate class identification information in the stream where single data types are being stored. Fixed a bug in the ListIdTracker class where unsorted ids were not being sorted correctly. Command line applications now returns status codes, 0 for success, non-zero for failure. Fixed the --read-api short name to be --ra instead of --wa. Updated store implementations to use buffered io providing significant performance improvements. Added a new osmosis-test-users-for-utf8 application for verifying the data integrity of the production user table. Added "bound" support to the pipeline. Added "-" alias for stdin/stdout to file reading/writing tasks for Cygwin & Windows Added a new dataset task --write-bdb for writing to a Berkeley DB implementation of a dataset. Added a new dataset task --read-bdb for reading from a Berkeley DB implementation of a dataset. Added a new dataset task --write-customdb for writing to a custom implementation of a dataset. Added a new dataset task --read-customdb for reading from a custom implementation of a dataset. Added a new dataset task --write-pgsql-simple for writing to a PostgreSQL implementation of a dataset. Added a new dataset task --write-pgsql-simple-dump for writing "COPY" load files for a PostgreSQL implementation of a dataset. Added a new dataset task --truncate-pgsql-simple for truncating all PostgreSQL dataset tables. Added a new dataset task --read-pgsql-simple for reading from a PostgreSQL implementation of a dataset. Added a new dataset task --dataset-bounding-box for extracting a bounding box from a dataset. Added a new dataset task --dataset-dump for dumping the entire contents of a dataset. Added new --used-node and --way-key-value tasks for filtering ways and their associated nodes with specific tags. 0.24 Fixed a bug in the XML node writing code where it would write a ',' character instead of '.' as the decimal separator in some locales. 0.23 Added support for a custom decoder when writing xml files to workaround the current production utf8 double encoding issue. Added short task names to shorten command line (eg. --write-xml becomes --wx). Fixed a node changeset bug where nodes created at the end of the interval were being excluded from the query. Added support for default task arguments requiring no name and added them for commonly used tasks requiring a single argument. 0.22 Updated mysql writing tasks to check if a timestamp is set and raise a meaningful error indicating where the error occurred. Modified mysql tasks to use the default character encoding for database connections to avoid suspected double encoding with the production database. Fixed the Entity serialisation to cater for null user ids and timestamps. Removed all 0.4 tasks. Added a new IdList id tracker implementation to be used internally by area filtering tasks to reduce memory usage on small'ish areas. Old BitSet implementation is still selectable if large bounding boxes are required. Added automatic compression method detection for all xml file tasks to avoid need to use compressionMethod argument. 0.21 Introduced a custom serialisation mechanism to improve compressed temporary file performance by approximately 5 times. Added a new RandomAccessObjectStore class which can be used as the basis for smarter tasks requiring access to data multiple times. Added completeWays and completeRelations arguments to the area filtering tasks to provide more control over the filtering process. Added new --tee and --tee-change tasks for sending data to multiple output destinations. 0.20 Fixed the integrity reporter task so that it writes new lines after each record. Relaxed validation checks in the --apply-change task so that it can apply changes to planets already containing data without aborting. 0.19 Added a new --integrity-reporter task to detect referential integrity issues between entity types. Updated the default file names for report tasks. Added a new --log-progress task to provide progress information to the jdk log during processing. Added a new --log-change-progress task to provide change progress information to the jdk log during processing. Fixed a number of bugs in the area extraction tasks. Updated area extraction tasks to support negative identifiers used on files that are ready for upload. Fixed bug in the ChangeWriter where the node insert SQL commands were missing tile parameters. 0.18 Improved error messages when errors are returned from the api. Added support for new shorter date format excluding millisecond information. Updated mysql writing code to support the new 0.5 schema version and fixed bugs in node insertion sql. Added support for quiet and verbose command line options. Modified command line arguments to default to using 0.5 tasks. 0.17 Added schema version checking to all MySQL tasks. Updated xml reading tasks to provide line number information when parse errors occur. Modified xml writing tasks to include the osmosis version number in the generator attribute. Updated mysql tasks to support the new tile indexing and fixed precision lat/lon. 0.16 Fixed a major bug in UTF-8 handling when writing xml files. All files were being written in the default character set. 0.15 Added full 0.5 support. Updated 0.4 code to the 005 schema. 0.14 Fixed a bug in the area filtering tasks where the original way was being passed to the destination instead of the modified way with only the available segments populated. Fixed a bug in the way comparison code where changes in the ordering of segments wouldn't be picked up. Fixed a bug in date parsing where the month was always being parsed a month in advance. Added the ability to load database login credentials from a properties file. Modified xml file writing to use 2 space indenting instead of 4. 0.13 Modified the --bounding-polygon task so it can read files containing blank lines. Added the ability to dump mysql "current" tables. Modified xml output to only write latitude and longitude to 7 decimal places. 0.12 Added a --read-api task for retrieving data from the central server. Added "user" support to the core data types, and all relevant tasks except database writing tasks. Added a --bounding-polygon task for filtering data by an area. Added a --report task which will produce user statistics for a data set. 0.11 Modified mysql snapshot task to read entire contents of table and process data in code in attempt to improve dump times. Added gzip and bzip2 support to xml tasks. Modified all database snapshot tasks to include entities with a timestamp equalling the snapshot time. Modified all database changeset tasks to not include the begin time and to include the end time. 0.10 Added JOSM-like date handling as a fallback if the standard xml date format isn't found. Added a custom date parser for the special case of GMT times which this tool always produces (approx 10x speedup over JOSM code and 100x speedup over standard JDK for GMT dates). 0.9 Fixed the name of the main class attribute in the jar manifest. Fixed a potential bug in the change application code where a validation step may have erroneously thrown errors. Added merge tasks to combine multiple entity or change files together. 0.8 Modified node and segment readers to avoid returning duplicate records where multiple records with identical timestamps exist. Moved main osmosis code into a "core" sub-package allowing new tools to be added. Fixed timeouts in mysql dumping of ways by using temporary files for query results. Refactored all temporary file handling to use common persistent iterator functionality. Fixed some classes not marked as Serializable. Updated change application to use less strict validation to handle "re-creates" of entities. Updated xml writing tasks to always write in UTC format. 0.7 Made a number of changes to the mysql dump task to improve performance and reduce the likelihood of timeouts. 0.6 Modified ChangeDeriver task to set the timestamp of deleted records to the current time. Fixed all uses of java.sql.Timestamp to be converted to java.util.Date explicitly instead of utilising inheritance. Fixed bug in change writer where timestamps weren't being written for segments. Added UserIdManager functionality which creates a system "Osmosis" user in the database to assign all changes to. 0.5 Modified command line date format to avoid use of spaces. 0.4 Modified mysql dump task to produce consistent snapshots. Added the ability to skip "current" tables when importing to mysql. Optimised mysql change reading queries. 0.3 Added mysql table truncator task. Updated segment xml processing code to handle timestamps. Made xml date processing during xml reading optional to improve performance. Added buffer tasks to allow pipeline processing to be split across multiple threads. Change reading and writing from a mysql database is now working, at least for simple test cases. 0.2 Added Main-Class feature to the jar manifest simplifying program launch. Added a shell launch script to simplify running on unix/linux. Added a readme with basic installation instructions. Added xml date parsing support. Fixed database dump code to read the "current" tables. Added a task for reading changes from a database. Added a task for writing changes to a database. Added a task for truncating database tables. Improved mysql import performance by disabling indexes and locking tables. 0.1 Initial version. osmosis-0.44.1/package/config/000077500000000000000000000000001253404521400161345ustar00rootroot00000000000000osmosis-0.44.1/package/config/plexus.conf000066400000000000000000000002141253404521400203200ustar00rootroot00000000000000main is org.openstreetmap.osmosis.core.Osmosis from osmosis.core [osmosis.core] load ${app.home}/lib/default/*.jar load ${app.home}/config osmosis-0.44.1/package/copying.txt000066400000000000000000000013601253404521400171000ustar00rootroot00000000000000Osmosis consists of all files in this archive with the exception of the third party libraries in the lib sub-directory, and the osmosis-osm-binary library which is a re-packaged version of a third-party library. Osmosis is placed into the public domain and where this is not legally possible everybody is granted a perpetual, irrevocable license to use this work for any purpose whatsoever. DISCLAIMERS By making Osmosis publicly available, it is hoped that users will find the software useful. However: * Osmosis comes without any warranty, to the extent permitted by applicable law. * Unless required by applicable law, no liability will be accepted by the authors and distributors of this software for any damages caused as a result of its use. osmosis-0.44.1/package/readme.txt000066400000000000000000000032011253404521400166610ustar00rootroot00000000000000INSTALLATION Unzip the distribution in the location of your choice. On unix/linux systems, make the bin/osmosis script executable (ie. chmod u+x osmosis). If desired, create a symbolic link to the osmosis script somewhere on your path (eg. ln -s appdir/bin/osmosis ~/bin/osmosis). CONFIGURATION Common command line options can be specified in configuration files. On Linux, the file can reside in the following locations with later files overriding earlier files: /etc/osmosis $HOME/.osmosis On Windows, the file can reside in the following locations with later files overriding earlier files: %ALLUSERSPROFILE%\osmosis.bat %USERPROFILE%\osmosis.bat The following variables can be defined in these files: JAVACMD - The java command to be invoked. Default is "java". JAVACMD_OPTIONS - The java jvm options to apply (eg. -Xmx512M). OSMOSIS_OPTIONS - The osmosis options to apply (eg. -q or -plugin MyPluginLoaderClass). COMPILATION To perform a complete osmosis rebuild, the following command may be run from the osmosis root directory. ant all The "all" ant target performs all steps including creation of new distribution files, checkstyle analysis and unit tests. Sometimes old files can be left hanging around causing problems. It may be necessary to run the following command to clean up any old files. ant clean If you wish to rebuild all artefacts without running unit tests, the following command may be used. ant publish HELP Osmosis documentation is available at: http://wiki.openstreetmap.org/index.php/Osmosis Please ask any questions, report any issues, or suggest enhancements using the Open Street Map talk or development mailing lists. osmosis-0.44.1/package/script/000077500000000000000000000000001253404521400161735ustar00rootroot00000000000000osmosis-0.44.1/package/script/contrib/000077500000000000000000000000001253404521400176335ustar00rootroot00000000000000osmosis-0.44.1/package/script/contrib/CreateGeometryForWays.sql000066400000000000000000000047141253404521400246140ustar00rootroot00000000000000------------------------------------------------------------------------------- -- The following script creates a new table for the pgsql simple schema for -- storing full way geometries. -- -- Author: Ralf ------------------------------------------------------------------------------- -- drop table if it exists DROP TABLE IF EXISTS way_geometry; -- create table CREATE TABLE way_geometry( way_id bigint NOT NULL ); -- add PostGIS geometry column SELECT AddGeometryColumn('', 'way_geometry', 'geom', 4326, 'GEOMETRY', 2); ------------------------------------------------------------------------------- -- the following might go into the POST_LOAD_SQL-array in the class "PostgreSqlWriter"?? ------------------------------------------------------------------------------- -- add a linestring for every way (create a polyline) INSERT INTO way_geometry select id, ( select ST_LineFromMultiPoint( Collect(nodes.geom) ) from nodes left join way_nodes on nodes.id=way_nodes.node_id where way_nodes.way_id=ways.id ) FROM ways; -- after creating a line for every way (polyline), we want closed ways to be stored as polygones. -- So we need to delete the previously created polylines for these ways first. DELETE FROM way_geometry WHERE way_id IN ( SELECT ways.id FROM ways WHERE ST_IsClosed( (SELECT ST_LineFromMultiPoint( Collect(n.geom) ) FROM nodes n LEFT JOIN way_nodes wn ON n.id=wn.node_id WHERE ways.id=wn.way_id) ) AND ST_NumPoints( (SELECT ST_LineFromMultiPoint( Collect(n.geom) ) FROM nodes n LEFT JOIN way_nodes wn ON n.id=wn.node_id WHERE ways.id=wn.way_id) ) >= 3 ) ; -- now we need to add the polyline geometry for every closed way INSERT INTO way_geometry SELECT ways.id, ( SELECT ST_MakePolygon( ST_LineFromMultiPoint(Collect(nodes.geom)) ) FROM nodes LEFT JOIN way_nodes ON nodes.id=way_nodes.node_id WHERE way_nodes.way_id=ways.id ) FROM ways WHERE ST_IsClosed( (SELECT ST_LineFromMultiPoint( Collect(n.geom) ) FROM nodes n LEFT JOIN way_nodes wn ON n.id=wn.node_id WHERE ways.id=wn.way_id) ) AND ST_NumPoints( (SELECT ST_LineFromMultiPoint( Collect(n.geom) ) FROM nodes n LEFT JOIN way_nodes wn ON n.id=wn.node_id WHERE ways.id=wn.way_id) ) >= 3 ; ------------------------------------------------------------------------------- -- create index on way_geometry CREATE INDEX idx_way_geometry_way_id ON way_geometry USING btree (way_id); CREATE INDEX idx_way_geometry_geom ON way_geometry USING gist (geom); osmosis-0.44.1/package/script/contrib/apidb_0.6.sql000066400000000000000000003221661253404521400220300ustar00rootroot00000000000000-- -- PostgreSQL database dump -- SET statement_timeout = 0; SET client_encoding = 'UTF8'; SET standard_conforming_strings = off; SET check_function_bodies = false; SET client_min_messages = warning; SET escape_string_warning = off; -- -- Name: plpgsql; Type: PROCEDURAL LANGUAGE; Schema: -; Owner: - -- CREATE OR REPLACE PROCEDURAL LANGUAGE plpgsql; SET search_path = public, pg_catalog; -- -- Name: gbtreekey16; Type: SHELL TYPE; Schema: public; Owner: - -- CREATE TYPE gbtreekey16; -- -- Name: gbtreekey16_in(cstring); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbtreekey16_in(cstring) RETURNS gbtreekey16 LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbtreekey_in'; -- -- Name: gbtreekey16_out(gbtreekey16); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbtreekey16_out(gbtreekey16) RETURNS cstring LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbtreekey_out'; -- -- Name: gbtreekey16; Type: TYPE; Schema: public; Owner: - -- CREATE TYPE gbtreekey16 ( INTERNALLENGTH = 16, INPUT = gbtreekey16_in, OUTPUT = gbtreekey16_out, ALIGNMENT = int4, STORAGE = plain ); -- -- Name: gbtreekey32; Type: SHELL TYPE; Schema: public; Owner: - -- CREATE TYPE gbtreekey32; -- -- Name: gbtreekey32_in(cstring); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbtreekey32_in(cstring) RETURNS gbtreekey32 LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbtreekey_in'; -- -- Name: gbtreekey32_out(gbtreekey32); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbtreekey32_out(gbtreekey32) RETURNS cstring LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbtreekey_out'; -- -- Name: gbtreekey32; Type: TYPE; Schema: public; Owner: - -- CREATE TYPE gbtreekey32 ( INTERNALLENGTH = 32, INPUT = gbtreekey32_in, OUTPUT = gbtreekey32_out, ALIGNMENT = int4, STORAGE = plain ); -- -- Name: gbtreekey4; Type: SHELL TYPE; Schema: public; Owner: - -- CREATE TYPE gbtreekey4; -- -- Name: gbtreekey4_in(cstring); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbtreekey4_in(cstring) RETURNS gbtreekey4 LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbtreekey_in'; -- -- Name: gbtreekey4_out(gbtreekey4); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbtreekey4_out(gbtreekey4) RETURNS cstring LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbtreekey_out'; -- -- Name: gbtreekey4; Type: TYPE; Schema: public; Owner: - -- CREATE TYPE gbtreekey4 ( INTERNALLENGTH = 4, INPUT = gbtreekey4_in, OUTPUT = gbtreekey4_out, ALIGNMENT = int4, STORAGE = plain ); -- -- Name: gbtreekey8; Type: SHELL TYPE; Schema: public; Owner: - -- CREATE TYPE gbtreekey8; -- -- Name: gbtreekey8_in(cstring); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbtreekey8_in(cstring) RETURNS gbtreekey8 LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbtreekey_in'; -- -- Name: gbtreekey8_out(gbtreekey8); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbtreekey8_out(gbtreekey8) RETURNS cstring LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbtreekey_out'; -- -- Name: gbtreekey8; Type: TYPE; Schema: public; Owner: - -- CREATE TYPE gbtreekey8 ( INTERNALLENGTH = 8, INPUT = gbtreekey8_in, OUTPUT = gbtreekey8_out, ALIGNMENT = int4, STORAGE = plain ); -- -- Name: gbtreekey_var; Type: SHELL TYPE; Schema: public; Owner: - -- CREATE TYPE gbtreekey_var; -- -- Name: gbtreekey_var_in(cstring); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbtreekey_var_in(cstring) RETURNS gbtreekey_var LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbtreekey_in'; -- -- Name: gbtreekey_var_out(gbtreekey_var); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbtreekey_var_out(gbtreekey_var) RETURNS cstring LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbtreekey_out'; -- -- Name: gbtreekey_var; Type: TYPE; Schema: public; Owner: - -- CREATE TYPE gbtreekey_var ( INTERNALLENGTH = variable, INPUT = gbtreekey_var_in, OUTPUT = gbtreekey_var_out, ALIGNMENT = int4, STORAGE = extended ); -- -- Name: gpx_visibility_enum; Type: TYPE; Schema: public; Owner: - -- CREATE TYPE gpx_visibility_enum AS ENUM ( 'private', 'public', 'trackable', 'identifiable' ); -- -- Name: nwr_enum; Type: TYPE; Schema: public; Owner: - -- CREATE TYPE nwr_enum AS ENUM ( 'Node', 'Way', 'Relation' ); -- -- Name: user_role_enum; Type: TYPE; Schema: public; Owner: - -- CREATE TYPE user_role_enum AS ENUM ( 'administrator', 'moderator' ); -- -- Name: user_status_enum; Type: TYPE; Schema: public; Owner: - -- CREATE TYPE user_status_enum AS ENUM ( 'pending', 'active', 'confirmed', 'suspended', 'deleted' ); -- -- Name: gbt_bit_compress(internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_bit_compress(internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_bit_compress'; -- -- Name: gbt_bit_consistent(internal, bit, smallint, oid, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_bit_consistent(internal, bit, smallint, oid, internal) RETURNS boolean LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_bit_consistent'; -- -- Name: gbt_bit_penalty(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_bit_penalty(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_bit_penalty'; -- -- Name: gbt_bit_picksplit(internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_bit_picksplit(internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_bit_picksplit'; -- -- Name: gbt_bit_same(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_bit_same(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_bit_same'; -- -- Name: gbt_bit_union(bytea, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_bit_union(bytea, internal) RETURNS gbtreekey_var LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_bit_union'; -- -- Name: gbt_bpchar_compress(internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_bpchar_compress(internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_bpchar_compress'; -- -- Name: gbt_bpchar_consistent(internal, character, smallint, oid, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_bpchar_consistent(internal, character, smallint, oid, internal) RETURNS boolean LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_bpchar_consistent'; -- -- Name: gbt_bytea_compress(internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_bytea_compress(internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_bytea_compress'; -- -- Name: gbt_bytea_consistent(internal, bytea, smallint, oid, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_bytea_consistent(internal, bytea, smallint, oid, internal) RETURNS boolean LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_bytea_consistent'; -- -- Name: gbt_bytea_penalty(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_bytea_penalty(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_bytea_penalty'; -- -- Name: gbt_bytea_picksplit(internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_bytea_picksplit(internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_bytea_picksplit'; -- -- Name: gbt_bytea_same(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_bytea_same(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_bytea_same'; -- -- Name: gbt_bytea_union(bytea, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_bytea_union(bytea, internal) RETURNS gbtreekey_var LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_bytea_union'; -- -- Name: gbt_cash_compress(internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_cash_compress(internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_cash_compress'; -- -- Name: gbt_cash_consistent(internal, money, smallint, oid, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_cash_consistent(internal, money, smallint, oid, internal) RETURNS boolean LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_cash_consistent'; -- -- Name: gbt_cash_penalty(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_cash_penalty(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_cash_penalty'; -- -- Name: gbt_cash_picksplit(internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_cash_picksplit(internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_cash_picksplit'; -- -- Name: gbt_cash_same(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_cash_same(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_cash_same'; -- -- Name: gbt_cash_union(bytea, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_cash_union(bytea, internal) RETURNS gbtreekey8 LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_cash_union'; -- -- Name: gbt_date_compress(internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_date_compress(internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_date_compress'; -- -- Name: gbt_date_consistent(internal, date, smallint, oid, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_date_consistent(internal, date, smallint, oid, internal) RETURNS boolean LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_date_consistent'; -- -- Name: gbt_date_penalty(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_date_penalty(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_date_penalty'; -- -- Name: gbt_date_picksplit(internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_date_picksplit(internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_date_picksplit'; -- -- Name: gbt_date_same(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_date_same(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_date_same'; -- -- Name: gbt_date_union(bytea, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_date_union(bytea, internal) RETURNS gbtreekey8 LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_date_union'; -- -- Name: gbt_decompress(internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_decompress(internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_decompress'; -- -- Name: gbt_float4_compress(internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_float4_compress(internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_float4_compress'; -- -- Name: gbt_float4_consistent(internal, real, smallint, oid, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_float4_consistent(internal, real, smallint, oid, internal) RETURNS boolean LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_float4_consistent'; -- -- Name: gbt_float4_penalty(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_float4_penalty(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_float4_penalty'; -- -- Name: gbt_float4_picksplit(internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_float4_picksplit(internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_float4_picksplit'; -- -- Name: gbt_float4_same(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_float4_same(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_float4_same'; -- -- Name: gbt_float4_union(bytea, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_float4_union(bytea, internal) RETURNS gbtreekey8 LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_float4_union'; -- -- Name: gbt_float8_compress(internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_float8_compress(internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_float8_compress'; -- -- Name: gbt_float8_consistent(internal, double precision, smallint, oid, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_float8_consistent(internal, double precision, smallint, oid, internal) RETURNS boolean LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_float8_consistent'; -- -- Name: gbt_float8_penalty(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_float8_penalty(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_float8_penalty'; -- -- Name: gbt_float8_picksplit(internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_float8_picksplit(internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_float8_picksplit'; -- -- Name: gbt_float8_same(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_float8_same(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_float8_same'; -- -- Name: gbt_float8_union(bytea, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_float8_union(bytea, internal) RETURNS gbtreekey16 LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_float8_union'; -- -- Name: gbt_inet_compress(internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_inet_compress(internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_inet_compress'; -- -- Name: gbt_inet_consistent(internal, inet, smallint, oid, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_inet_consistent(internal, inet, smallint, oid, internal) RETURNS boolean LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_inet_consistent'; -- -- Name: gbt_inet_penalty(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_inet_penalty(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_inet_penalty'; -- -- Name: gbt_inet_picksplit(internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_inet_picksplit(internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_inet_picksplit'; -- -- Name: gbt_inet_same(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_inet_same(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_inet_same'; -- -- Name: gbt_inet_union(bytea, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_inet_union(bytea, internal) RETURNS gbtreekey16 LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_inet_union'; -- -- Name: gbt_int2_compress(internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_int2_compress(internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_int2_compress'; -- -- Name: gbt_int2_consistent(internal, smallint, smallint, oid, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_int2_consistent(internal, smallint, smallint, oid, internal) RETURNS boolean LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_int2_consistent'; -- -- Name: gbt_int2_penalty(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_int2_penalty(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_int2_penalty'; -- -- Name: gbt_int2_picksplit(internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_int2_picksplit(internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_int2_picksplit'; -- -- Name: gbt_int2_same(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_int2_same(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_int2_same'; -- -- Name: gbt_int2_union(bytea, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_int2_union(bytea, internal) RETURNS gbtreekey4 LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_int2_union'; -- -- Name: gbt_int4_compress(internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_int4_compress(internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_int4_compress'; -- -- Name: gbt_int4_consistent(internal, integer, smallint, oid, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_int4_consistent(internal, integer, smallint, oid, internal) RETURNS boolean LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_int4_consistent'; -- -- Name: gbt_int4_penalty(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_int4_penalty(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_int4_penalty'; -- -- Name: gbt_int4_picksplit(internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_int4_picksplit(internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_int4_picksplit'; -- -- Name: gbt_int4_same(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_int4_same(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_int4_same'; -- -- Name: gbt_int4_union(bytea, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_int4_union(bytea, internal) RETURNS gbtreekey8 LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_int4_union'; -- -- Name: gbt_int8_compress(internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_int8_compress(internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_int8_compress'; -- -- Name: gbt_int8_consistent(internal, bigint, smallint, oid, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_int8_consistent(internal, bigint, smallint, oid, internal) RETURNS boolean LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_int8_consistent'; -- -- Name: gbt_int8_penalty(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_int8_penalty(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_int8_penalty'; -- -- Name: gbt_int8_picksplit(internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_int8_picksplit(internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_int8_picksplit'; -- -- Name: gbt_int8_same(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_int8_same(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_int8_same'; -- -- Name: gbt_int8_union(bytea, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_int8_union(bytea, internal) RETURNS gbtreekey16 LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_int8_union'; -- -- Name: gbt_intv_compress(internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_intv_compress(internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_intv_compress'; -- -- Name: gbt_intv_consistent(internal, interval, smallint, oid, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_intv_consistent(internal, interval, smallint, oid, internal) RETURNS boolean LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_intv_consistent'; -- -- Name: gbt_intv_decompress(internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_intv_decompress(internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_intv_decompress'; -- -- Name: gbt_intv_penalty(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_intv_penalty(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_intv_penalty'; -- -- Name: gbt_intv_picksplit(internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_intv_picksplit(internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_intv_picksplit'; -- -- Name: gbt_intv_same(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_intv_same(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_intv_same'; -- -- Name: gbt_intv_union(bytea, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_intv_union(bytea, internal) RETURNS gbtreekey32 LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_intv_union'; -- -- Name: gbt_macad_compress(internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_macad_compress(internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_macad_compress'; -- -- Name: gbt_macad_consistent(internal, macaddr, smallint, oid, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_macad_consistent(internal, macaddr, smallint, oid, internal) RETURNS boolean LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_macad_consistent'; -- -- Name: gbt_macad_penalty(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_macad_penalty(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_macad_penalty'; -- -- Name: gbt_macad_picksplit(internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_macad_picksplit(internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_macad_picksplit'; -- -- Name: gbt_macad_same(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_macad_same(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_macad_same'; -- -- Name: gbt_macad_union(bytea, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_macad_union(bytea, internal) RETURNS gbtreekey16 LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_macad_union'; -- -- Name: gbt_numeric_compress(internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_numeric_compress(internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_numeric_compress'; -- -- Name: gbt_numeric_consistent(internal, numeric, smallint, oid, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_numeric_consistent(internal, numeric, smallint, oid, internal) RETURNS boolean LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_numeric_consistent'; -- -- Name: gbt_numeric_penalty(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_numeric_penalty(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_numeric_penalty'; -- -- Name: gbt_numeric_picksplit(internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_numeric_picksplit(internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_numeric_picksplit'; -- -- Name: gbt_numeric_same(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_numeric_same(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_numeric_same'; -- -- Name: gbt_numeric_union(bytea, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_numeric_union(bytea, internal) RETURNS gbtreekey_var LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_numeric_union'; -- -- Name: gbt_oid_compress(internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_oid_compress(internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_oid_compress'; -- -- Name: gbt_oid_consistent(internal, oid, smallint, oid, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_oid_consistent(internal, oid, smallint, oid, internal) RETURNS boolean LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_oid_consistent'; -- -- Name: gbt_oid_penalty(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_oid_penalty(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_oid_penalty'; -- -- Name: gbt_oid_picksplit(internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_oid_picksplit(internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_oid_picksplit'; -- -- Name: gbt_oid_same(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_oid_same(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_oid_same'; -- -- Name: gbt_oid_union(bytea, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_oid_union(bytea, internal) RETURNS gbtreekey8 LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_oid_union'; -- -- Name: gbt_text_compress(internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_text_compress(internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_text_compress'; -- -- Name: gbt_text_consistent(internal, text, smallint, oid, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_text_consistent(internal, text, smallint, oid, internal) RETURNS boolean LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_text_consistent'; -- -- Name: gbt_text_penalty(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_text_penalty(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_text_penalty'; -- -- Name: gbt_text_picksplit(internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_text_picksplit(internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_text_picksplit'; -- -- Name: gbt_text_same(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_text_same(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_text_same'; -- -- Name: gbt_text_union(bytea, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_text_union(bytea, internal) RETURNS gbtreekey_var LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_text_union'; -- -- Name: gbt_time_compress(internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_time_compress(internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_time_compress'; -- -- Name: gbt_time_consistent(internal, time without time zone, smallint, oid, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_time_consistent(internal, time without time zone, smallint, oid, internal) RETURNS boolean LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_time_consistent'; -- -- Name: gbt_time_penalty(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_time_penalty(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_time_penalty'; -- -- Name: gbt_time_picksplit(internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_time_picksplit(internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_time_picksplit'; -- -- Name: gbt_time_same(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_time_same(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_time_same'; -- -- Name: gbt_time_union(bytea, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_time_union(bytea, internal) RETURNS gbtreekey16 LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_time_union'; -- -- Name: gbt_timetz_compress(internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_timetz_compress(internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_timetz_compress'; -- -- Name: gbt_timetz_consistent(internal, time with time zone, smallint, oid, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_timetz_consistent(internal, time with time zone, smallint, oid, internal) RETURNS boolean LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_timetz_consistent'; -- -- Name: gbt_ts_compress(internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_ts_compress(internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_ts_compress'; -- -- Name: gbt_ts_consistent(internal, timestamp without time zone, smallint, oid, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_ts_consistent(internal, timestamp without time zone, smallint, oid, internal) RETURNS boolean LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_ts_consistent'; -- -- Name: gbt_ts_penalty(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_ts_penalty(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_ts_penalty'; -- -- Name: gbt_ts_picksplit(internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_ts_picksplit(internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_ts_picksplit'; -- -- Name: gbt_ts_same(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_ts_same(internal, internal, internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_ts_same'; -- -- Name: gbt_ts_union(bytea, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_ts_union(bytea, internal) RETURNS gbtreekey16 LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_ts_union'; -- -- Name: gbt_tstz_compress(internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_tstz_compress(internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_tstz_compress'; -- -- Name: gbt_tstz_consistent(internal, timestamp with time zone, smallint, oid, internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_tstz_consistent(internal, timestamp with time zone, smallint, oid, internal) RETURNS boolean LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_tstz_consistent'; -- -- Name: gbt_var_decompress(internal); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION gbt_var_decompress(internal) RETURNS internal LANGUAGE c IMMUTABLE STRICT AS '$libdir/btree_gist', 'gbt_var_decompress'; -- -- Name: maptile_for_point(bigint, bigint, integer); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION maptile_for_point(bigint, bigint, integer) RETURNS integer LANGUAGE c STRICT AS '/path/to/libpgosm.so', 'maptile_for_point'; -- -- Name: tile_for_point(integer, integer); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION tile_for_point(integer, integer) RETURNS bigint LANGUAGE c STRICT AS '/path/to/libpgosm.so', 'tile_for_point'; -- -- Name: xid_to_int4(xid); Type: FUNCTION; Schema: public; Owner: - -- CREATE FUNCTION xid_to_int4(xid) RETURNS integer LANGUAGE c IMMUTABLE STRICT AS '/path/to/libpgosm.so', 'xid_to_int4'; -- -- Name: gist_bit_ops; Type: OPERATOR FAMILY; Schema: public; Owner: - -- CREATE OPERATOR FAMILY gist_bit_ops USING gist; -- -- Name: gist_bit_ops; Type: OPERATOR CLASS; Schema: public; Owner: - -- CREATE OPERATOR CLASS gist_bit_ops DEFAULT FOR TYPE bit USING gist AS STORAGE gbtreekey_var , OPERATOR 1 <(bit,bit) , OPERATOR 2 <=(bit,bit) , OPERATOR 3 =(bit,bit) , OPERATOR 4 >=(bit,bit) , OPERATOR 5 >(bit,bit) , FUNCTION 1 gbt_bit_consistent(internal,bit,smallint,oid,internal) , FUNCTION 2 gbt_bit_union(bytea,internal) , FUNCTION 3 gbt_bit_compress(internal) , FUNCTION 4 gbt_var_decompress(internal) , FUNCTION 5 gbt_bit_penalty(internal,internal,internal) , FUNCTION 6 gbt_bit_picksplit(internal,internal) , FUNCTION 7 gbt_bit_same(internal,internal,internal); -- -- Name: gist_bpchar_ops; Type: OPERATOR FAMILY; Schema: public; Owner: - -- CREATE OPERATOR FAMILY gist_bpchar_ops USING gist; -- -- Name: gist_bpchar_ops; Type: OPERATOR CLASS; Schema: public; Owner: - -- CREATE OPERATOR CLASS gist_bpchar_ops DEFAULT FOR TYPE character USING gist AS STORAGE gbtreekey_var , OPERATOR 1 <(character,character) , OPERATOR 2 <=(character,character) , OPERATOR 3 =(character,character) , OPERATOR 4 >=(character,character) , OPERATOR 5 >(character,character) , FUNCTION 1 gbt_bpchar_consistent(internal,character,smallint,oid,internal) , FUNCTION 2 gbt_text_union(bytea,internal) , FUNCTION 3 gbt_bpchar_compress(internal) , FUNCTION 4 gbt_var_decompress(internal) , FUNCTION 5 gbt_text_penalty(internal,internal,internal) , FUNCTION 6 gbt_text_picksplit(internal,internal) , FUNCTION 7 gbt_text_same(internal,internal,internal); -- -- Name: gist_bytea_ops; Type: OPERATOR FAMILY; Schema: public; Owner: - -- CREATE OPERATOR FAMILY gist_bytea_ops USING gist; -- -- Name: gist_bytea_ops; Type: OPERATOR CLASS; Schema: public; Owner: - -- CREATE OPERATOR CLASS gist_bytea_ops DEFAULT FOR TYPE bytea USING gist AS STORAGE gbtreekey_var , OPERATOR 1 <(bytea,bytea) , OPERATOR 2 <=(bytea,bytea) , OPERATOR 3 =(bytea,bytea) , OPERATOR 4 >=(bytea,bytea) , OPERATOR 5 >(bytea,bytea) , FUNCTION 1 gbt_bytea_consistent(internal,bytea,smallint,oid,internal) , FUNCTION 2 gbt_bytea_union(bytea,internal) , FUNCTION 3 gbt_bytea_compress(internal) , FUNCTION 4 gbt_var_decompress(internal) , FUNCTION 5 gbt_bytea_penalty(internal,internal,internal) , FUNCTION 6 gbt_bytea_picksplit(internal,internal) , FUNCTION 7 gbt_bytea_same(internal,internal,internal); -- -- Name: gist_cash_ops; Type: OPERATOR FAMILY; Schema: public; Owner: - -- CREATE OPERATOR FAMILY gist_cash_ops USING gist; -- -- Name: gist_cash_ops; Type: OPERATOR CLASS; Schema: public; Owner: - -- CREATE OPERATOR CLASS gist_cash_ops DEFAULT FOR TYPE money USING gist AS STORAGE gbtreekey16 , OPERATOR 1 <(money,money) , OPERATOR 2 <=(money,money) , OPERATOR 3 =(money,money) , OPERATOR 4 >=(money,money) , OPERATOR 5 >(money,money) , FUNCTION 1 gbt_cash_consistent(internal,money,smallint,oid,internal) , FUNCTION 2 gbt_cash_union(bytea,internal) , FUNCTION 3 gbt_cash_compress(internal) , FUNCTION 4 gbt_decompress(internal) , FUNCTION 5 gbt_cash_penalty(internal,internal,internal) , FUNCTION 6 gbt_cash_picksplit(internal,internal) , FUNCTION 7 gbt_cash_same(internal,internal,internal); -- -- Name: gist_cidr_ops; Type: OPERATOR FAMILY; Schema: public; Owner: - -- CREATE OPERATOR FAMILY gist_cidr_ops USING gist; -- -- Name: gist_cidr_ops; Type: OPERATOR CLASS; Schema: public; Owner: - -- CREATE OPERATOR CLASS gist_cidr_ops DEFAULT FOR TYPE cidr USING gist AS STORAGE gbtreekey16 , OPERATOR 1 <(inet,inet) , OPERATOR 2 <=(inet,inet) , OPERATOR 3 =(inet,inet) , OPERATOR 4 >=(inet,inet) , OPERATOR 5 >(inet,inet) , FUNCTION 1 gbt_inet_consistent(internal,inet,smallint,oid,internal) , FUNCTION 2 gbt_inet_union(bytea,internal) , FUNCTION 3 gbt_inet_compress(internal) , FUNCTION 4 gbt_decompress(internal) , FUNCTION 5 gbt_inet_penalty(internal,internal,internal) , FUNCTION 6 gbt_inet_picksplit(internal,internal) , FUNCTION 7 gbt_inet_same(internal,internal,internal); -- -- Name: gist_date_ops; Type: OPERATOR FAMILY; Schema: public; Owner: - -- CREATE OPERATOR FAMILY gist_date_ops USING gist; -- -- Name: gist_date_ops; Type: OPERATOR CLASS; Schema: public; Owner: - -- CREATE OPERATOR CLASS gist_date_ops DEFAULT FOR TYPE date USING gist AS STORAGE gbtreekey8 , OPERATOR 1 <(date,date) , OPERATOR 2 <=(date,date) , OPERATOR 3 =(date,date) , OPERATOR 4 >=(date,date) , OPERATOR 5 >(date,date) , FUNCTION 1 gbt_date_consistent(internal,date,smallint,oid,internal) , FUNCTION 2 gbt_date_union(bytea,internal) , FUNCTION 3 gbt_date_compress(internal) , FUNCTION 4 gbt_decompress(internal) , FUNCTION 5 gbt_date_penalty(internal,internal,internal) , FUNCTION 6 gbt_date_picksplit(internal,internal) , FUNCTION 7 gbt_date_same(internal,internal,internal); -- -- Name: gist_float4_ops; Type: OPERATOR FAMILY; Schema: public; Owner: - -- CREATE OPERATOR FAMILY gist_float4_ops USING gist; -- -- Name: gist_float4_ops; Type: OPERATOR CLASS; Schema: public; Owner: - -- CREATE OPERATOR CLASS gist_float4_ops DEFAULT FOR TYPE real USING gist AS STORAGE gbtreekey8 , OPERATOR 1 <(real,real) , OPERATOR 2 <=(real,real) , OPERATOR 3 =(real,real) , OPERATOR 4 >=(real,real) , OPERATOR 5 >(real,real) , FUNCTION 1 gbt_float4_consistent(internal,real,smallint,oid,internal) , FUNCTION 2 gbt_float4_union(bytea,internal) , FUNCTION 3 gbt_float4_compress(internal) , FUNCTION 4 gbt_decompress(internal) , FUNCTION 5 gbt_float4_penalty(internal,internal,internal) , FUNCTION 6 gbt_float4_picksplit(internal,internal) , FUNCTION 7 gbt_float4_same(internal,internal,internal); -- -- Name: gist_float8_ops; Type: OPERATOR FAMILY; Schema: public; Owner: - -- CREATE OPERATOR FAMILY gist_float8_ops USING gist; -- -- Name: gist_float8_ops; Type: OPERATOR CLASS; Schema: public; Owner: - -- CREATE OPERATOR CLASS gist_float8_ops DEFAULT FOR TYPE double precision USING gist AS STORAGE gbtreekey16 , OPERATOR 1 <(double precision,double precision) , OPERATOR 2 <=(double precision,double precision) , OPERATOR 3 =(double precision,double precision) , OPERATOR 4 >=(double precision,double precision) , OPERATOR 5 >(double precision,double precision) , FUNCTION 1 gbt_float8_consistent(internal,double precision,smallint,oid,internal) , FUNCTION 2 gbt_float8_union(bytea,internal) , FUNCTION 3 gbt_float8_compress(internal) , FUNCTION 4 gbt_decompress(internal) , FUNCTION 5 gbt_float8_penalty(internal,internal,internal) , FUNCTION 6 gbt_float8_picksplit(internal,internal) , FUNCTION 7 gbt_float8_same(internal,internal,internal); -- -- Name: gist_inet_ops; Type: OPERATOR FAMILY; Schema: public; Owner: - -- CREATE OPERATOR FAMILY gist_inet_ops USING gist; -- -- Name: gist_inet_ops; Type: OPERATOR CLASS; Schema: public; Owner: - -- CREATE OPERATOR CLASS gist_inet_ops DEFAULT FOR TYPE inet USING gist AS STORAGE gbtreekey16 , OPERATOR 1 <(inet,inet) , OPERATOR 2 <=(inet,inet) , OPERATOR 3 =(inet,inet) , OPERATOR 4 >=(inet,inet) , OPERATOR 5 >(inet,inet) , FUNCTION 1 gbt_inet_consistent(internal,inet,smallint,oid,internal) , FUNCTION 2 gbt_inet_union(bytea,internal) , FUNCTION 3 gbt_inet_compress(internal) , FUNCTION 4 gbt_decompress(internal) , FUNCTION 5 gbt_inet_penalty(internal,internal,internal) , FUNCTION 6 gbt_inet_picksplit(internal,internal) , FUNCTION 7 gbt_inet_same(internal,internal,internal); -- -- Name: gist_int2_ops; Type: OPERATOR FAMILY; Schema: public; Owner: - -- CREATE OPERATOR FAMILY gist_int2_ops USING gist; -- -- Name: gist_int2_ops; Type: OPERATOR CLASS; Schema: public; Owner: - -- CREATE OPERATOR CLASS gist_int2_ops DEFAULT FOR TYPE smallint USING gist AS STORAGE gbtreekey4 , OPERATOR 1 <(smallint,smallint) , OPERATOR 2 <=(smallint,smallint) , OPERATOR 3 =(smallint,smallint) , OPERATOR 4 >=(smallint,smallint) , OPERATOR 5 >(smallint,smallint) , FUNCTION 1 gbt_int2_consistent(internal,smallint,smallint,oid,internal) , FUNCTION 2 gbt_int2_union(bytea,internal) , FUNCTION 3 gbt_int2_compress(internal) , FUNCTION 4 gbt_decompress(internal) , FUNCTION 5 gbt_int2_penalty(internal,internal,internal) , FUNCTION 6 gbt_int2_picksplit(internal,internal) , FUNCTION 7 gbt_int2_same(internal,internal,internal); -- -- Name: gist_int4_ops; Type: OPERATOR FAMILY; Schema: public; Owner: - -- CREATE OPERATOR FAMILY gist_int4_ops USING gist; -- -- Name: gist_int4_ops; Type: OPERATOR CLASS; Schema: public; Owner: - -- CREATE OPERATOR CLASS gist_int4_ops DEFAULT FOR TYPE integer USING gist AS STORAGE gbtreekey8 , OPERATOR 1 <(integer,integer) , OPERATOR 2 <=(integer,integer) , OPERATOR 3 =(integer,integer) , OPERATOR 4 >=(integer,integer) , OPERATOR 5 >(integer,integer) , FUNCTION 1 gbt_int4_consistent(internal,integer,smallint,oid,internal) , FUNCTION 2 gbt_int4_union(bytea,internal) , FUNCTION 3 gbt_int4_compress(internal) , FUNCTION 4 gbt_decompress(internal) , FUNCTION 5 gbt_int4_penalty(internal,internal,internal) , FUNCTION 6 gbt_int4_picksplit(internal,internal) , FUNCTION 7 gbt_int4_same(internal,internal,internal); -- -- Name: gist_int8_ops; Type: OPERATOR FAMILY; Schema: public; Owner: - -- CREATE OPERATOR FAMILY gist_int8_ops USING gist; -- -- Name: gist_int8_ops; Type: OPERATOR CLASS; Schema: public; Owner: - -- CREATE OPERATOR CLASS gist_int8_ops DEFAULT FOR TYPE bigint USING gist AS STORAGE gbtreekey16 , OPERATOR 1 <(bigint,bigint) , OPERATOR 2 <=(bigint,bigint) , OPERATOR 3 =(bigint,bigint) , OPERATOR 4 >=(bigint,bigint) , OPERATOR 5 >(bigint,bigint) , FUNCTION 1 gbt_int8_consistent(internal,bigint,smallint,oid,internal) , FUNCTION 2 gbt_int8_union(bytea,internal) , FUNCTION 3 gbt_int8_compress(internal) , FUNCTION 4 gbt_decompress(internal) , FUNCTION 5 gbt_int8_penalty(internal,internal,internal) , FUNCTION 6 gbt_int8_picksplit(internal,internal) , FUNCTION 7 gbt_int8_same(internal,internal,internal); -- -- Name: gist_interval_ops; Type: OPERATOR FAMILY; Schema: public; Owner: - -- CREATE OPERATOR FAMILY gist_interval_ops USING gist; -- -- Name: gist_interval_ops; Type: OPERATOR CLASS; Schema: public; Owner: - -- CREATE OPERATOR CLASS gist_interval_ops DEFAULT FOR TYPE interval USING gist AS STORAGE gbtreekey32 , OPERATOR 1 <(interval,interval) , OPERATOR 2 <=(interval,interval) , OPERATOR 3 =(interval,interval) , OPERATOR 4 >=(interval,interval) , OPERATOR 5 >(interval,interval) , FUNCTION 1 gbt_intv_consistent(internal,interval,smallint,oid,internal) , FUNCTION 2 gbt_intv_union(bytea,internal) , FUNCTION 3 gbt_intv_compress(internal) , FUNCTION 4 gbt_intv_decompress(internal) , FUNCTION 5 gbt_intv_penalty(internal,internal,internal) , FUNCTION 6 gbt_intv_picksplit(internal,internal) , FUNCTION 7 gbt_intv_same(internal,internal,internal); -- -- Name: gist_macaddr_ops; Type: OPERATOR FAMILY; Schema: public; Owner: - -- CREATE OPERATOR FAMILY gist_macaddr_ops USING gist; -- -- Name: gist_macaddr_ops; Type: OPERATOR CLASS; Schema: public; Owner: - -- CREATE OPERATOR CLASS gist_macaddr_ops DEFAULT FOR TYPE macaddr USING gist AS STORAGE gbtreekey16 , OPERATOR 1 <(macaddr,macaddr) , OPERATOR 2 <=(macaddr,macaddr) , OPERATOR 3 =(macaddr,macaddr) , OPERATOR 4 >=(macaddr,macaddr) , OPERATOR 5 >(macaddr,macaddr) , FUNCTION 1 gbt_macad_consistent(internal,macaddr,smallint,oid,internal) , FUNCTION 2 gbt_macad_union(bytea,internal) , FUNCTION 3 gbt_macad_compress(internal) , FUNCTION 4 gbt_decompress(internal) , FUNCTION 5 gbt_macad_penalty(internal,internal,internal) , FUNCTION 6 gbt_macad_picksplit(internal,internal) , FUNCTION 7 gbt_macad_same(internal,internal,internal); -- -- Name: gist_numeric_ops; Type: OPERATOR FAMILY; Schema: public; Owner: - -- CREATE OPERATOR FAMILY gist_numeric_ops USING gist; -- -- Name: gist_numeric_ops; Type: OPERATOR CLASS; Schema: public; Owner: - -- CREATE OPERATOR CLASS gist_numeric_ops DEFAULT FOR TYPE numeric USING gist AS STORAGE gbtreekey_var , OPERATOR 1 <(numeric,numeric) , OPERATOR 2 <=(numeric,numeric) , OPERATOR 3 =(numeric,numeric) , OPERATOR 4 >=(numeric,numeric) , OPERATOR 5 >(numeric,numeric) , FUNCTION 1 gbt_numeric_consistent(internal,numeric,smallint,oid,internal) , FUNCTION 2 gbt_numeric_union(bytea,internal) , FUNCTION 3 gbt_numeric_compress(internal) , FUNCTION 4 gbt_var_decompress(internal) , FUNCTION 5 gbt_numeric_penalty(internal,internal,internal) , FUNCTION 6 gbt_numeric_picksplit(internal,internal) , FUNCTION 7 gbt_numeric_same(internal,internal,internal); -- -- Name: gist_oid_ops; Type: OPERATOR FAMILY; Schema: public; Owner: - -- CREATE OPERATOR FAMILY gist_oid_ops USING gist; -- -- Name: gist_oid_ops; Type: OPERATOR CLASS; Schema: public; Owner: - -- CREATE OPERATOR CLASS gist_oid_ops DEFAULT FOR TYPE oid USING gist AS STORAGE gbtreekey8 , OPERATOR 1 <(oid,oid) , OPERATOR 2 <=(oid,oid) , OPERATOR 3 =(oid,oid) , OPERATOR 4 >=(oid,oid) , OPERATOR 5 >(oid,oid) , FUNCTION 1 gbt_oid_consistent(internal,oid,smallint,oid,internal) , FUNCTION 2 gbt_oid_union(bytea,internal) , FUNCTION 3 gbt_oid_compress(internal) , FUNCTION 4 gbt_decompress(internal) , FUNCTION 5 gbt_oid_penalty(internal,internal,internal) , FUNCTION 6 gbt_oid_picksplit(internal,internal) , FUNCTION 7 gbt_oid_same(internal,internal,internal); -- -- Name: gist_text_ops; Type: OPERATOR FAMILY; Schema: public; Owner: - -- CREATE OPERATOR FAMILY gist_text_ops USING gist; -- -- Name: gist_text_ops; Type: OPERATOR CLASS; Schema: public; Owner: - -- CREATE OPERATOR CLASS gist_text_ops DEFAULT FOR TYPE text USING gist AS STORAGE gbtreekey_var , OPERATOR 1 <(text,text) , OPERATOR 2 <=(text,text) , OPERATOR 3 =(text,text) , OPERATOR 4 >=(text,text) , OPERATOR 5 >(text,text) , FUNCTION 1 gbt_text_consistent(internal,text,smallint,oid,internal) , FUNCTION 2 gbt_text_union(bytea,internal) , FUNCTION 3 gbt_text_compress(internal) , FUNCTION 4 gbt_var_decompress(internal) , FUNCTION 5 gbt_text_penalty(internal,internal,internal) , FUNCTION 6 gbt_text_picksplit(internal,internal) , FUNCTION 7 gbt_text_same(internal,internal,internal); -- -- Name: gist_time_ops; Type: OPERATOR FAMILY; Schema: public; Owner: - -- CREATE OPERATOR FAMILY gist_time_ops USING gist; -- -- Name: gist_time_ops; Type: OPERATOR CLASS; Schema: public; Owner: - -- CREATE OPERATOR CLASS gist_time_ops DEFAULT FOR TYPE time without time zone USING gist AS STORAGE gbtreekey16 , OPERATOR 1 <(time without time zone,time without time zone) , OPERATOR 2 <=(time without time zone,time without time zone) , OPERATOR 3 =(time without time zone,time without time zone) , OPERATOR 4 >=(time without time zone,time without time zone) , OPERATOR 5 >(time without time zone,time without time zone) , FUNCTION 1 gbt_time_consistent(internal,time without time zone,smallint,oid,internal) , FUNCTION 2 gbt_time_union(bytea,internal) , FUNCTION 3 gbt_time_compress(internal) , FUNCTION 4 gbt_decompress(internal) , FUNCTION 5 gbt_time_penalty(internal,internal,internal) , FUNCTION 6 gbt_time_picksplit(internal,internal) , FUNCTION 7 gbt_time_same(internal,internal,internal); -- -- Name: gist_timestamp_ops; Type: OPERATOR FAMILY; Schema: public; Owner: - -- CREATE OPERATOR FAMILY gist_timestamp_ops USING gist; -- -- Name: gist_timestamp_ops; Type: OPERATOR CLASS; Schema: public; Owner: - -- CREATE OPERATOR CLASS gist_timestamp_ops DEFAULT FOR TYPE timestamp without time zone USING gist AS STORAGE gbtreekey16 , OPERATOR 1 <(timestamp without time zone,timestamp without time zone) , OPERATOR 2 <=(timestamp without time zone,timestamp without time zone) , OPERATOR 3 =(timestamp without time zone,timestamp without time zone) , OPERATOR 4 >=(timestamp without time zone,timestamp without time zone) , OPERATOR 5 >(timestamp without time zone,timestamp without time zone) , FUNCTION 1 gbt_ts_consistent(internal,timestamp without time zone,smallint,oid,internal) , FUNCTION 2 gbt_ts_union(bytea,internal) , FUNCTION 3 gbt_ts_compress(internal) , FUNCTION 4 gbt_decompress(internal) , FUNCTION 5 gbt_ts_penalty(internal,internal,internal) , FUNCTION 6 gbt_ts_picksplit(internal,internal) , FUNCTION 7 gbt_ts_same(internal,internal,internal); -- -- Name: gist_timestamptz_ops; Type: OPERATOR FAMILY; Schema: public; Owner: - -- CREATE OPERATOR FAMILY gist_timestamptz_ops USING gist; -- -- Name: gist_timestamptz_ops; Type: OPERATOR CLASS; Schema: public; Owner: - -- CREATE OPERATOR CLASS gist_timestamptz_ops DEFAULT FOR TYPE timestamp with time zone USING gist AS STORAGE gbtreekey16 , OPERATOR 1 <(timestamp with time zone,timestamp with time zone) , OPERATOR 2 <=(timestamp with time zone,timestamp with time zone) , OPERATOR 3 =(timestamp with time zone,timestamp with time zone) , OPERATOR 4 >=(timestamp with time zone,timestamp with time zone) , OPERATOR 5 >(timestamp with time zone,timestamp with time zone) , FUNCTION 1 gbt_tstz_consistent(internal,timestamp with time zone,smallint,oid,internal) , FUNCTION 2 gbt_ts_union(bytea,internal) , FUNCTION 3 gbt_tstz_compress(internal) , FUNCTION 4 gbt_decompress(internal) , FUNCTION 5 gbt_ts_penalty(internal,internal,internal) , FUNCTION 6 gbt_ts_picksplit(internal,internal) , FUNCTION 7 gbt_ts_same(internal,internal,internal); -- -- Name: gist_timetz_ops; Type: OPERATOR FAMILY; Schema: public; Owner: - -- CREATE OPERATOR FAMILY gist_timetz_ops USING gist; -- -- Name: gist_timetz_ops; Type: OPERATOR CLASS; Schema: public; Owner: - -- CREATE OPERATOR CLASS gist_timetz_ops DEFAULT FOR TYPE time with time zone USING gist AS STORAGE gbtreekey16 , OPERATOR 1 <(time with time zone,time with time zone) , OPERATOR 2 <=(time with time zone,time with time zone) , OPERATOR 3 =(time with time zone,time with time zone) , OPERATOR 4 >=(time with time zone,time with time zone) , OPERATOR 5 >(time with time zone,time with time zone) , FUNCTION 1 gbt_timetz_consistent(internal,time with time zone,smallint,oid,internal) , FUNCTION 2 gbt_time_union(bytea,internal) , FUNCTION 3 gbt_timetz_compress(internal) , FUNCTION 4 gbt_decompress(internal) , FUNCTION 5 gbt_time_penalty(internal,internal,internal) , FUNCTION 6 gbt_time_picksplit(internal,internal) , FUNCTION 7 gbt_time_same(internal,internal,internal); -- -- Name: gist_vbit_ops; Type: OPERATOR FAMILY; Schema: public; Owner: - -- CREATE OPERATOR FAMILY gist_vbit_ops USING gist; -- -- Name: gist_vbit_ops; Type: OPERATOR CLASS; Schema: public; Owner: - -- CREATE OPERATOR CLASS gist_vbit_ops DEFAULT FOR TYPE bit varying USING gist AS STORAGE gbtreekey_var , OPERATOR 1 <(bit varying,bit varying) , OPERATOR 2 <=(bit varying,bit varying) , OPERATOR 3 =(bit varying,bit varying) , OPERATOR 4 >=(bit varying,bit varying) , OPERATOR 5 >(bit varying,bit varying) , FUNCTION 1 gbt_bit_consistent(internal,bit,smallint,oid,internal) , FUNCTION 2 gbt_bit_union(bytea,internal) , FUNCTION 3 gbt_bit_compress(internal) , FUNCTION 4 gbt_var_decompress(internal) , FUNCTION 5 gbt_bit_penalty(internal,internal,internal) , FUNCTION 6 gbt_bit_picksplit(internal,internal) , FUNCTION 7 gbt_bit_same(internal,internal,internal); SET default_tablespace = ''; SET default_with_oids = false; -- -- Name: acls; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE acls ( id integer NOT NULL, address inet NOT NULL, netmask inet NOT NULL, k character varying(255) NOT NULL, v character varying(255) ); -- -- Name: acls_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- CREATE SEQUENCE acls_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -- -- Name: acls_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - -- ALTER SEQUENCE acls_id_seq OWNED BY acls.id; -- -- Name: changeset_tags; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE changeset_tags ( changeset_id bigint NOT NULL, k character varying(255) DEFAULT ''::character varying NOT NULL, v character varying(255) DEFAULT ''::character varying NOT NULL ); -- -- Name: changesets; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE changesets ( id bigint NOT NULL, user_id bigint NOT NULL, created_at timestamp without time zone NOT NULL, min_lat integer, max_lat integer, min_lon integer, max_lon integer, closed_at timestamp without time zone NOT NULL, num_changes integer DEFAULT 0 NOT NULL ); -- -- Name: changesets_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- CREATE SEQUENCE changesets_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -- -- Name: changesets_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - -- ALTER SEQUENCE changesets_id_seq OWNED BY changesets.id; -- -- Name: client_applications; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE client_applications ( id integer NOT NULL, name character varying(255), url character varying(255), support_url character varying(255), callback_url character varying(255), key character varying(50), secret character varying(50), user_id integer, created_at timestamp without time zone, updated_at timestamp without time zone, allow_read_prefs boolean DEFAULT false NOT NULL, allow_write_prefs boolean DEFAULT false NOT NULL, allow_write_diary boolean DEFAULT false NOT NULL, allow_write_api boolean DEFAULT false NOT NULL, allow_read_gpx boolean DEFAULT false NOT NULL, allow_write_gpx boolean DEFAULT false NOT NULL ); -- -- Name: client_applications_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- CREATE SEQUENCE client_applications_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -- -- Name: client_applications_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - -- ALTER SEQUENCE client_applications_id_seq OWNED BY client_applications.id; -- -- Name: countries; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE countries ( id integer NOT NULL, code character varying(2) NOT NULL, min_lat double precision NOT NULL, max_lat double precision NOT NULL, min_lon double precision NOT NULL, max_lon double precision NOT NULL ); -- -- Name: countries_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- CREATE SEQUENCE countries_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -- -- Name: countries_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - -- ALTER SEQUENCE countries_id_seq OWNED BY countries.id; -- -- Name: current_node_tags; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE current_node_tags ( node_id bigint NOT NULL, k character varying(255) DEFAULT ''::character varying NOT NULL, v character varying(255) DEFAULT ''::character varying NOT NULL ); -- -- Name: current_nodes; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE current_nodes ( id bigint NOT NULL, latitude integer NOT NULL, longitude integer NOT NULL, changeset_id bigint NOT NULL, visible boolean NOT NULL, "timestamp" timestamp without time zone NOT NULL, tile bigint NOT NULL, version bigint NOT NULL ); -- -- Name: current_nodes_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- CREATE SEQUENCE current_nodes_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -- -- Name: current_nodes_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - -- ALTER SEQUENCE current_nodes_id_seq OWNED BY current_nodes.id; -- -- Name: current_relation_members; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE current_relation_members ( relation_id bigint NOT NULL, member_type nwr_enum NOT NULL, member_id bigint NOT NULL, member_role character varying(255) NOT NULL, sequence_id integer DEFAULT 0 NOT NULL ); -- -- Name: current_relation_tags; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE current_relation_tags ( relation_id bigint NOT NULL, k character varying(255) DEFAULT ''::character varying NOT NULL, v character varying(255) DEFAULT ''::character varying NOT NULL ); -- -- Name: current_relations; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE current_relations ( id bigint NOT NULL, changeset_id bigint NOT NULL, "timestamp" timestamp without time zone NOT NULL, visible boolean NOT NULL, version bigint NOT NULL ); -- -- Name: current_relations_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- CREATE SEQUENCE current_relations_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -- -- Name: current_relations_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - -- ALTER SEQUENCE current_relations_id_seq OWNED BY current_relations.id; -- -- Name: current_way_nodes; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE current_way_nodes ( way_id bigint NOT NULL, node_id bigint NOT NULL, sequence_id bigint NOT NULL ); -- -- Name: current_way_tags; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE current_way_tags ( way_id bigint NOT NULL, k character varying(255) DEFAULT ''::character varying NOT NULL, v character varying(255) DEFAULT ''::character varying NOT NULL ); -- -- Name: current_ways; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE current_ways ( id bigint NOT NULL, changeset_id bigint NOT NULL, "timestamp" timestamp without time zone NOT NULL, visible boolean NOT NULL, version bigint NOT NULL ); -- -- Name: current_ways_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- CREATE SEQUENCE current_ways_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -- -- Name: current_ways_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - -- ALTER SEQUENCE current_ways_id_seq OWNED BY current_ways.id; -- -- Name: diary_comments; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE diary_comments ( id bigint NOT NULL, diary_entry_id bigint NOT NULL, user_id bigint NOT NULL, body text NOT NULL, created_at timestamp without time zone NOT NULL, updated_at timestamp without time zone NOT NULL, visible boolean DEFAULT true NOT NULL ); -- -- Name: diary_comments_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- CREATE SEQUENCE diary_comments_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -- -- Name: diary_comments_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - -- ALTER SEQUENCE diary_comments_id_seq OWNED BY diary_comments.id; -- -- Name: diary_entries; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE diary_entries ( id bigint NOT NULL, user_id bigint NOT NULL, title character varying(255) NOT NULL, body text NOT NULL, created_at timestamp without time zone NOT NULL, updated_at timestamp without time zone NOT NULL, latitude double precision, longitude double precision, language_code character varying(255) DEFAULT 'en'::character varying NOT NULL, visible boolean DEFAULT true NOT NULL ); -- -- Name: diary_entries_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- CREATE SEQUENCE diary_entries_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -- -- Name: diary_entries_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - -- ALTER SEQUENCE diary_entries_id_seq OWNED BY diary_entries.id; -- -- Name: friends; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE friends ( id bigint NOT NULL, user_id bigint NOT NULL, friend_user_id bigint NOT NULL ); -- -- Name: friends_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- CREATE SEQUENCE friends_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -- -- Name: friends_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - -- ALTER SEQUENCE friends_id_seq OWNED BY friends.id; -- -- Name: gps_points; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE gps_points ( altitude double precision, trackid integer NOT NULL, latitude integer NOT NULL, longitude integer NOT NULL, gpx_id bigint NOT NULL, "timestamp" timestamp without time zone, tile bigint ); -- -- Name: gpx_file_tags; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE gpx_file_tags ( gpx_id bigint DEFAULT 0 NOT NULL, tag character varying(255) NOT NULL, id bigint NOT NULL ); -- -- Name: gpx_file_tags_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- CREATE SEQUENCE gpx_file_tags_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -- -- Name: gpx_file_tags_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - -- ALTER SEQUENCE gpx_file_tags_id_seq OWNED BY gpx_file_tags.id; -- -- Name: gpx_files; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE gpx_files ( id bigint NOT NULL, user_id bigint NOT NULL, visible boolean DEFAULT true NOT NULL, name character varying(255) DEFAULT ''::character varying NOT NULL, size bigint, latitude double precision, longitude double precision, "timestamp" timestamp without time zone NOT NULL, description character varying(255) DEFAULT ''::character varying NOT NULL, inserted boolean NOT NULL, visibility gpx_visibility_enum DEFAULT 'public'::gpx_visibility_enum NOT NULL ); -- -- Name: gpx_files_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- CREATE SEQUENCE gpx_files_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -- -- Name: gpx_files_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - -- ALTER SEQUENCE gpx_files_id_seq OWNED BY gpx_files.id; -- -- Name: languages; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE languages ( code character varying(255) NOT NULL, english_name character varying(255) NOT NULL, native_name character varying(255) ); -- -- Name: messages; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE messages ( id bigint NOT NULL, from_user_id bigint NOT NULL, title character varying(255) NOT NULL, body text NOT NULL, sent_on timestamp without time zone NOT NULL, message_read boolean DEFAULT false NOT NULL, to_user_id bigint NOT NULL, to_user_visible boolean DEFAULT true NOT NULL, from_user_visible boolean DEFAULT true NOT NULL ); -- -- Name: messages_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- CREATE SEQUENCE messages_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -- -- Name: messages_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - -- ALTER SEQUENCE messages_id_seq OWNED BY messages.id; -- -- Name: node_tags; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE node_tags ( node_id bigint NOT NULL, version bigint NOT NULL, k character varying(255) DEFAULT ''::character varying NOT NULL, v character varying(255) DEFAULT ''::character varying NOT NULL ); -- -- Name: nodes; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE nodes ( node_id bigint NOT NULL, latitude integer NOT NULL, longitude integer NOT NULL, changeset_id bigint NOT NULL, visible boolean NOT NULL, "timestamp" timestamp without time zone NOT NULL, tile bigint NOT NULL, version bigint NOT NULL, redaction_id integer ); -- -- Name: oauth_nonces; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE oauth_nonces ( id integer NOT NULL, nonce character varying(255), "timestamp" integer, created_at timestamp without time zone, updated_at timestamp without time zone ); -- -- Name: oauth_nonces_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- CREATE SEQUENCE oauth_nonces_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -- -- Name: oauth_nonces_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - -- ALTER SEQUENCE oauth_nonces_id_seq OWNED BY oauth_nonces.id; -- -- Name: oauth_tokens; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE oauth_tokens ( id integer NOT NULL, user_id integer, type character varying(20), client_application_id integer, token character varying(50), secret character varying(50), authorized_at timestamp without time zone, invalidated_at timestamp without time zone, created_at timestamp without time zone, updated_at timestamp without time zone, allow_read_prefs boolean DEFAULT false NOT NULL, allow_write_prefs boolean DEFAULT false NOT NULL, allow_write_diary boolean DEFAULT false NOT NULL, allow_write_api boolean DEFAULT false NOT NULL, allow_read_gpx boolean DEFAULT false NOT NULL, allow_write_gpx boolean DEFAULT false NOT NULL, callback_url character varying(255), verifier character varying(20) ); -- -- Name: oauth_tokens_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- CREATE SEQUENCE oauth_tokens_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -- -- Name: oauth_tokens_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - -- ALTER SEQUENCE oauth_tokens_id_seq OWNED BY oauth_tokens.id; -- -- Name: relation_members; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE relation_members ( relation_id bigint DEFAULT 0 NOT NULL, member_type nwr_enum NOT NULL, member_id bigint NOT NULL, member_role character varying(255) NOT NULL, version bigint DEFAULT 0 NOT NULL, sequence_id integer DEFAULT 0 NOT NULL ); -- -- Name: relation_tags; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE relation_tags ( relation_id bigint DEFAULT 0 NOT NULL, k character varying(255) DEFAULT ''::character varying NOT NULL, v character varying(255) DEFAULT ''::character varying NOT NULL, version bigint NOT NULL ); -- -- Name: relations; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE relations ( relation_id bigint DEFAULT 0 NOT NULL, changeset_id bigint NOT NULL, "timestamp" timestamp without time zone NOT NULL, version bigint NOT NULL, visible boolean DEFAULT true NOT NULL, redaction_id integer ); -- -- Name: schema_migrations; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE schema_migrations ( version character varying(255) NOT NULL ); -- -- Name: sessions; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE sessions ( id integer NOT NULL, session_id character varying(255), data text, created_at timestamp without time zone, updated_at timestamp without time zone ); -- -- Name: sessions_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- CREATE SEQUENCE sessions_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -- -- Name: sessions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - -- ALTER SEQUENCE sessions_id_seq OWNED BY sessions.id; -- -- Name: user_blocks; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE user_blocks ( id integer NOT NULL, user_id bigint NOT NULL, creator_id bigint NOT NULL, reason text NOT NULL, ends_at timestamp without time zone NOT NULL, needs_view boolean DEFAULT false NOT NULL, revoker_id bigint, created_at timestamp without time zone, updated_at timestamp without time zone ); -- -- Name: user_blocks_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- CREATE SEQUENCE user_blocks_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -- -- Name: user_blocks_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - -- ALTER SEQUENCE user_blocks_id_seq OWNED BY user_blocks.id; -- -- Name: user_preferences; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE user_preferences ( user_id bigint NOT NULL, k character varying(255) NOT NULL, v character varying(255) NOT NULL ); -- -- Name: user_roles; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE user_roles ( id integer NOT NULL, user_id bigint NOT NULL, created_at timestamp without time zone, updated_at timestamp without time zone, role user_role_enum NOT NULL, granter_id bigint NOT NULL ); -- -- Name: user_roles_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- CREATE SEQUENCE user_roles_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -- -- Name: user_roles_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - -- ALTER SEQUENCE user_roles_id_seq OWNED BY user_roles.id; -- -- Name: user_tokens; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE user_tokens ( id bigint NOT NULL, user_id bigint NOT NULL, token character varying(255) NOT NULL, expiry timestamp without time zone NOT NULL, referer text ); -- -- Name: user_tokens_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- CREATE SEQUENCE user_tokens_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -- -- Name: user_tokens_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - -- ALTER SEQUENCE user_tokens_id_seq OWNED BY user_tokens.id; -- -- Name: users; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE users ( email character varying(255) NOT NULL, id bigint NOT NULL, pass_crypt character varying(255) NOT NULL, creation_time timestamp without time zone NOT NULL, display_name character varying(255) DEFAULT ''::character varying NOT NULL, data_public boolean DEFAULT false NOT NULL, description text DEFAULT ''::text NOT NULL, home_lat double precision, home_lon double precision, home_zoom smallint DEFAULT 3, nearby integer DEFAULT 50, pass_salt character varying(255), image text, email_valid boolean DEFAULT false NOT NULL, new_email character varying(255), creation_ip character varying(255), languages character varying(255), status user_status_enum DEFAULT 'pending'::user_status_enum NOT NULL, terms_agreed timestamp without time zone, consider_pd boolean DEFAULT false NOT NULL, preferred_editor character varying(255), terms_seen boolean DEFAULT false NOT NULL, openid_url character varying(255) ); -- -- Name: users_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- CREATE SEQUENCE users_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -- -- Name: users_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - -- ALTER SEQUENCE users_id_seq OWNED BY users.id; -- -- Name: way_nodes; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE way_nodes ( way_id bigint NOT NULL, node_id bigint NOT NULL, version bigint NOT NULL, sequence_id bigint NOT NULL ); -- -- Name: way_tags; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE way_tags ( way_id bigint DEFAULT 0 NOT NULL, k character varying(255) NOT NULL, v character varying(255) NOT NULL, version bigint NOT NULL ); -- -- Name: ways; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE ways ( way_id bigint DEFAULT 0 NOT NULL, changeset_id bigint NOT NULL, "timestamp" timestamp without time zone NOT NULL, version bigint NOT NULL, visible boolean DEFAULT true NOT NULL, redaction_id integer ); -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- ALTER TABLE acls ALTER COLUMN id SET DEFAULT nextval('acls_id_seq'::regclass); -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- ALTER TABLE changesets ALTER COLUMN id SET DEFAULT nextval('changesets_id_seq'::regclass); -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- ALTER TABLE client_applications ALTER COLUMN id SET DEFAULT nextval('client_applications_id_seq'::regclass); -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- ALTER TABLE countries ALTER COLUMN id SET DEFAULT nextval('countries_id_seq'::regclass); -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- ALTER TABLE current_nodes ALTER COLUMN id SET DEFAULT nextval('current_nodes_id_seq'::regclass); -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- ALTER TABLE current_relations ALTER COLUMN id SET DEFAULT nextval('current_relations_id_seq'::regclass); -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- ALTER TABLE current_ways ALTER COLUMN id SET DEFAULT nextval('current_ways_id_seq'::regclass); -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- ALTER TABLE diary_comments ALTER COLUMN id SET DEFAULT nextval('diary_comments_id_seq'::regclass); -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- ALTER TABLE diary_entries ALTER COLUMN id SET DEFAULT nextval('diary_entries_id_seq'::regclass); -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- ALTER TABLE friends ALTER COLUMN id SET DEFAULT nextval('friends_id_seq'::regclass); -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- ALTER TABLE gpx_file_tags ALTER COLUMN id SET DEFAULT nextval('gpx_file_tags_id_seq'::regclass); -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- ALTER TABLE gpx_files ALTER COLUMN id SET DEFAULT nextval('gpx_files_id_seq'::regclass); -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- ALTER TABLE messages ALTER COLUMN id SET DEFAULT nextval('messages_id_seq'::regclass); -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- ALTER TABLE oauth_nonces ALTER COLUMN id SET DEFAULT nextval('oauth_nonces_id_seq'::regclass); -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- ALTER TABLE oauth_tokens ALTER COLUMN id SET DEFAULT nextval('oauth_tokens_id_seq'::regclass); -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- ALTER TABLE sessions ALTER COLUMN id SET DEFAULT nextval('sessions_id_seq'::regclass); -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- ALTER TABLE user_blocks ALTER COLUMN id SET DEFAULT nextval('user_blocks_id_seq'::regclass); -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- ALTER TABLE user_roles ALTER COLUMN id SET DEFAULT nextval('user_roles_id_seq'::regclass); -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- ALTER TABLE user_tokens ALTER COLUMN id SET DEFAULT nextval('user_tokens_id_seq'::regclass); -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- ALTER TABLE users ALTER COLUMN id SET DEFAULT nextval('users_id_seq'::regclass); -- -- Name: acls_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY acls ADD CONSTRAINT acls_pkey PRIMARY KEY (id); -- -- Name: changesets_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY changesets ADD CONSTRAINT changesets_pkey PRIMARY KEY (id); -- -- Name: client_applications_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY client_applications ADD CONSTRAINT client_applications_pkey PRIMARY KEY (id); -- -- Name: countries_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY countries ADD CONSTRAINT countries_pkey PRIMARY KEY (id); -- -- Name: current_node_tags_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY current_node_tags ADD CONSTRAINT current_node_tags_pkey PRIMARY KEY (node_id, k); -- -- Name: current_nodes_pkey1; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY current_nodes ADD CONSTRAINT current_nodes_pkey1 PRIMARY KEY (id); -- -- Name: current_relation_members_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY current_relation_members ADD CONSTRAINT current_relation_members_pkey PRIMARY KEY (relation_id, member_type, member_id, member_role, sequence_id); -- -- Name: current_relation_tags_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY current_relation_tags ADD CONSTRAINT current_relation_tags_pkey PRIMARY KEY (relation_id, k); -- -- Name: current_relations_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY current_relations ADD CONSTRAINT current_relations_pkey PRIMARY KEY (id); -- -- Name: current_way_nodes_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY current_way_nodes ADD CONSTRAINT current_way_nodes_pkey PRIMARY KEY (way_id, sequence_id); -- -- Name: current_way_tags_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY current_way_tags ADD CONSTRAINT current_way_tags_pkey PRIMARY KEY (way_id, k); -- -- Name: current_ways_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY current_ways ADD CONSTRAINT current_ways_pkey PRIMARY KEY (id); -- -- Name: diary_comments_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY diary_comments ADD CONSTRAINT diary_comments_pkey PRIMARY KEY (id); -- -- Name: diary_entries_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY diary_entries ADD CONSTRAINT diary_entries_pkey PRIMARY KEY (id); -- -- Name: friends_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY friends ADD CONSTRAINT friends_pkey PRIMARY KEY (id); -- -- Name: gpx_file_tags_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY gpx_file_tags ADD CONSTRAINT gpx_file_tags_pkey PRIMARY KEY (id); -- -- Name: gpx_files_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY gpx_files ADD CONSTRAINT gpx_files_pkey PRIMARY KEY (id); -- -- Name: languages_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY languages ADD CONSTRAINT languages_pkey PRIMARY KEY (code); -- -- Name: messages_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY messages ADD CONSTRAINT messages_pkey PRIMARY KEY (id); -- -- Name: node_tags_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY node_tags ADD CONSTRAINT node_tags_pkey PRIMARY KEY (node_id, version, k); -- -- Name: nodes_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY nodes ADD CONSTRAINT nodes_pkey PRIMARY KEY (node_id, version); -- -- Name: oauth_nonces_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY oauth_nonces ADD CONSTRAINT oauth_nonces_pkey PRIMARY KEY (id); -- -- Name: oauth_tokens_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY oauth_tokens ADD CONSTRAINT oauth_tokens_pkey PRIMARY KEY (id); -- -- Name: relation_members_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY relation_members ADD CONSTRAINT relation_members_pkey PRIMARY KEY (relation_id, version, member_type, member_id, member_role, sequence_id); -- -- Name: relation_tags_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY relation_tags ADD CONSTRAINT relation_tags_pkey PRIMARY KEY (relation_id, version, k); -- -- Name: relations_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY relations ADD CONSTRAINT relations_pkey PRIMARY KEY (relation_id, version); -- -- Name: sessions_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY sessions ADD CONSTRAINT sessions_pkey PRIMARY KEY (id); -- -- Name: user_blocks_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY user_blocks ADD CONSTRAINT user_blocks_pkey PRIMARY KEY (id); -- -- Name: user_preferences_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY user_preferences ADD CONSTRAINT user_preferences_pkey PRIMARY KEY (user_id, k); -- -- Name: user_roles_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY user_roles ADD CONSTRAINT user_roles_pkey PRIMARY KEY (id); -- -- Name: user_tokens_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY user_tokens ADD CONSTRAINT user_tokens_pkey PRIMARY KEY (id); -- -- Name: users_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY users ADD CONSTRAINT users_pkey PRIMARY KEY (id); -- -- Name: way_nodes_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY way_nodes ADD CONSTRAINT way_nodes_pkey PRIMARY KEY (way_id, version, sequence_id); -- -- Name: way_tags_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY way_tags ADD CONSTRAINT way_tags_pkey PRIMARY KEY (way_id, version, k); -- -- Name: ways_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY ways ADD CONSTRAINT ways_pkey PRIMARY KEY (way_id, version); -- -- Name: acls_k_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX acls_k_idx ON acls USING btree (k); -- -- Name: changeset_tags_id_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX changeset_tags_id_idx ON changeset_tags USING btree (changeset_id); -- -- Name: changesets_bbox_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX changesets_bbox_idx ON changesets USING gist (min_lat, max_lat, min_lon, max_lon); -- -- Name: changesets_closed_at_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX changesets_closed_at_idx ON changesets USING btree (closed_at); -- -- Name: changesets_created_at_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX changesets_created_at_idx ON changesets USING btree (created_at); -- -- Name: changesets_user_id_created_at_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX changesets_user_id_created_at_idx ON changesets USING btree (user_id, created_at); -- -- Name: changesets_user_id_id_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX changesets_user_id_id_idx ON changesets USING btree (user_id, id); -- -- Name: countries_code_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX countries_code_idx ON countries USING btree (code); -- -- Name: current_nodes_tile_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX current_nodes_tile_idx ON current_nodes USING btree (tile); -- -- Name: current_nodes_timestamp_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX current_nodes_timestamp_idx ON current_nodes USING btree ("timestamp"); -- -- Name: current_relation_members_member_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX current_relation_members_member_idx ON current_relation_members USING btree (member_type, member_id); -- -- Name: current_relation_tags_id_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX current_relation_tags_id_idx ON current_relation_tags USING btree (relation_id); -- -- Name: current_relation_tags_v_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX current_relation_tags_v_idx ON current_relation_tags USING btree (v); -- -- Name: current_relations_timestamp_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX current_relations_timestamp_idx ON current_relations USING btree ("timestamp"); -- -- Name: current_way_nodes_node_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX current_way_nodes_node_idx ON current_way_nodes USING btree (node_id); -- -- Name: current_way_tags_id_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX current_way_tags_id_idx ON current_way_tags USING btree (way_id); -- -- Name: current_way_tags_v_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX current_way_tags_v_idx ON current_way_tags USING btree (v); -- -- Name: current_ways_timestamp_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX current_ways_timestamp_idx ON current_ways USING btree ("timestamp"); -- -- Name: diary_comment_user_id_created_at_index; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX diary_comment_user_id_created_at_index ON diary_comments USING btree (user_id, created_at); -- -- Name: diary_comments_entry_id_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX diary_comments_entry_id_idx ON diary_comments USING btree (diary_entry_id, id); -- -- Name: diary_entry_created_at_index; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX diary_entry_created_at_index ON diary_entries USING btree (created_at); -- -- Name: diary_entry_language_code_created_at_index; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX diary_entry_language_code_created_at_index ON diary_entries USING btree (language_code, created_at); -- -- Name: diary_entry_user_id_created_at_index; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX diary_entry_user_id_created_at_index ON diary_entries USING btree (user_id, created_at); -- -- Name: friends_user_id_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX friends_user_id_idx ON friends USING btree (user_id); -- -- Name: gpx_file_tags_gpxid_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX gpx_file_tags_gpxid_idx ON gpx_file_tags USING btree (gpx_id); -- -- Name: gpx_file_tags_tag_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX gpx_file_tags_tag_idx ON gpx_file_tags USING btree (tag); -- -- Name: gpx_files_timestamp_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX gpx_files_timestamp_idx ON gpx_files USING btree ("timestamp"); -- -- Name: gpx_files_user_id_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX gpx_files_user_id_idx ON gpx_files USING btree (user_id); -- -- Name: gpx_files_visible_visibility_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX gpx_files_visible_visibility_idx ON gpx_files USING btree (visible, visibility); -- -- Name: index_client_applications_on_key; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX index_client_applications_on_key ON client_applications USING btree (key); -- -- Name: index_oauth_nonces_on_nonce_and_timestamp; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX index_oauth_nonces_on_nonce_and_timestamp ON oauth_nonces USING btree (nonce, "timestamp"); -- -- Name: index_oauth_tokens_on_token; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX index_oauth_tokens_on_token ON oauth_tokens USING btree (token); -- -- Name: index_user_blocks_on_user_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_user_blocks_on_user_id ON user_blocks USING btree (user_id); -- -- Name: messages_from_user_id_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX messages_from_user_id_idx ON messages USING btree (from_user_id); -- -- Name: messages_to_user_id_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX messages_to_user_id_idx ON messages USING btree (to_user_id); -- -- Name: nodes_changeset_id_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX nodes_changeset_id_idx ON nodes USING btree (changeset_id); -- -- Name: nodes_tile_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX nodes_tile_idx ON nodes USING btree (tile); -- -- Name: nodes_timestamp_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX nodes_timestamp_idx ON nodes USING btree ("timestamp"); -- -- Name: nodes_uid_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX nodes_uid_idx ON nodes USING btree (node_id); -- -- Name: points_gpxid_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX points_gpxid_idx ON gps_points USING btree (gpx_id); -- -- Name: points_tile_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX points_tile_idx ON gps_points USING btree (tile); -- -- Name: relation_members_member_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX relation_members_member_idx ON relation_members USING btree (member_type, member_id); -- -- Name: relation_tags_id_version_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX relation_tags_id_version_idx ON relation_tags USING btree (relation_id, version); -- -- Name: relations_changeset_id_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX relations_changeset_id_idx ON relations USING btree (changeset_id); -- -- Name: relations_timestamp_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX relations_timestamp_idx ON relations USING btree ("timestamp"); -- -- Name: sessions_session_id_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX sessions_session_id_idx ON sessions USING btree (session_id); -- -- Name: unique_schema_migrations; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX unique_schema_migrations ON schema_migrations USING btree (version); -- -- Name: user_id_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX user_id_idx ON friends USING btree (friend_user_id); -- -- Name: user_openid_url_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX user_openid_url_idx ON users USING btree (openid_url); -- -- Name: user_roles_id_role_unique; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX user_roles_id_role_unique ON user_roles USING btree (user_id, role); -- -- Name: user_tokens_token_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX user_tokens_token_idx ON user_tokens USING btree (token); -- -- Name: user_tokens_user_id_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX user_tokens_user_id_idx ON user_tokens USING btree (user_id); -- -- Name: users_display_name_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX users_display_name_idx ON users USING btree (display_name); -- -- Name: users_email_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX users_email_idx ON users USING btree (email); -- -- Name: way_nodes_node_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX way_nodes_node_idx ON way_nodes USING btree (node_id); -- -- Name: way_tags_id_version_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX way_tags_id_version_idx ON way_tags USING btree (way_id, version); -- -- Name: ways_changeset_id_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX ways_changeset_id_idx ON ways USING btree (changeset_id); -- -- Name: ways_timestamp_idx; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX ways_timestamp_idx ON ways USING btree ("timestamp"); -- -- Name: changeset_tags_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY changeset_tags ADD CONSTRAINT changeset_tags_id_fkey FOREIGN KEY (changeset_id) REFERENCES changesets(id); -- -- Name: changesets_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY changesets ADD CONSTRAINT changesets_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id); -- -- Name: client_applications_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY client_applications ADD CONSTRAINT client_applications_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id); -- -- Name: current_node_tags_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY current_node_tags ADD CONSTRAINT current_node_tags_id_fkey FOREIGN KEY (node_id) REFERENCES current_nodes(id); -- -- Name: current_nodes_changeset_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY current_nodes ADD CONSTRAINT current_nodes_changeset_id_fkey FOREIGN KEY (changeset_id) REFERENCES changesets(id); -- -- Name: current_relation_members_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY current_relation_members ADD CONSTRAINT current_relation_members_id_fkey FOREIGN KEY (relation_id) REFERENCES current_relations(id); -- -- Name: current_relation_tags_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY current_relation_tags ADD CONSTRAINT current_relation_tags_id_fkey FOREIGN KEY (relation_id) REFERENCES current_relations(id); -- -- Name: current_relations_changeset_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY current_relations ADD CONSTRAINT current_relations_changeset_id_fkey FOREIGN KEY (changeset_id) REFERENCES changesets(id); -- -- Name: current_way_nodes_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY current_way_nodes ADD CONSTRAINT current_way_nodes_id_fkey FOREIGN KEY (way_id) REFERENCES current_ways(id); -- -- Name: current_way_nodes_node_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY current_way_nodes ADD CONSTRAINT current_way_nodes_node_id_fkey FOREIGN KEY (node_id) REFERENCES current_nodes(id); -- -- Name: current_way_tags_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY current_way_tags ADD CONSTRAINT current_way_tags_id_fkey FOREIGN KEY (way_id) REFERENCES current_ways(id); -- -- Name: current_ways_changeset_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY current_ways ADD CONSTRAINT current_ways_changeset_id_fkey FOREIGN KEY (changeset_id) REFERENCES changesets(id); -- -- Name: diary_comments_diary_entry_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY diary_comments ADD CONSTRAINT diary_comments_diary_entry_id_fkey FOREIGN KEY (diary_entry_id) REFERENCES diary_entries(id); -- -- Name: diary_comments_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY diary_comments ADD CONSTRAINT diary_comments_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id); -- -- Name: diary_entries_language_code_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY diary_entries ADD CONSTRAINT diary_entries_language_code_fkey FOREIGN KEY (language_code) REFERENCES languages(code); -- -- Name: diary_entries_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY diary_entries ADD CONSTRAINT diary_entries_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id); -- -- Name: friends_friend_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY friends ADD CONSTRAINT friends_friend_user_id_fkey FOREIGN KEY (friend_user_id) REFERENCES users(id); -- -- Name: friends_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY friends ADD CONSTRAINT friends_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id); -- -- Name: gps_points_gpx_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY gps_points ADD CONSTRAINT gps_points_gpx_id_fkey FOREIGN KEY (gpx_id) REFERENCES gpx_files(id); -- -- Name: gpx_file_tags_gpx_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY gpx_file_tags ADD CONSTRAINT gpx_file_tags_gpx_id_fkey FOREIGN KEY (gpx_id) REFERENCES gpx_files(id); -- -- Name: gpx_files_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY gpx_files ADD CONSTRAINT gpx_files_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id); -- -- Name: messages_from_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY messages ADD CONSTRAINT messages_from_user_id_fkey FOREIGN KEY (from_user_id) REFERENCES users(id); -- -- Name: messages_to_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY messages ADD CONSTRAINT messages_to_user_id_fkey FOREIGN KEY (to_user_id) REFERENCES users(id); -- -- Name: node_tags_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY node_tags ADD CONSTRAINT node_tags_id_fkey FOREIGN KEY (node_id, version) REFERENCES nodes(node_id, version); -- -- Name: nodes_changeset_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY nodes ADD CONSTRAINT nodes_changeset_id_fkey FOREIGN KEY (changeset_id) REFERENCES changesets(id); -- -- Name: oauth_tokens_client_application_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY oauth_tokens ADD CONSTRAINT oauth_tokens_client_application_id_fkey FOREIGN KEY (client_application_id) REFERENCES client_applications(id); -- -- Name: oauth_tokens_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY oauth_tokens ADD CONSTRAINT oauth_tokens_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id); -- -- Name: relation_members_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY relation_members ADD CONSTRAINT relation_members_id_fkey FOREIGN KEY (relation_id, version) REFERENCES relations(relation_id, version); -- -- Name: relation_tags_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY relation_tags ADD CONSTRAINT relation_tags_id_fkey FOREIGN KEY (relation_id, version) REFERENCES relations(relation_id, version); -- -- Name: relations_changeset_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY relations ADD CONSTRAINT relations_changeset_id_fkey FOREIGN KEY (changeset_id) REFERENCES changesets(id); -- -- Name: user_blocks_moderator_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY user_blocks ADD CONSTRAINT user_blocks_moderator_id_fkey FOREIGN KEY (creator_id) REFERENCES users(id); -- -- Name: user_blocks_revoker_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY user_blocks ADD CONSTRAINT user_blocks_revoker_id_fkey FOREIGN KEY (revoker_id) REFERENCES users(id); -- -- Name: user_blocks_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY user_blocks ADD CONSTRAINT user_blocks_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id); -- -- Name: user_preferences_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY user_preferences ADD CONSTRAINT user_preferences_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id); -- -- Name: user_roles_granter_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY user_roles ADD CONSTRAINT user_roles_granter_id_fkey FOREIGN KEY (granter_id) REFERENCES users(id); -- -- Name: user_roles_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY user_roles ADD CONSTRAINT user_roles_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id); -- -- Name: user_tokens_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY user_tokens ADD CONSTRAINT user_tokens_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id); -- -- Name: way_nodes_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY way_nodes ADD CONSTRAINT way_nodes_id_fkey FOREIGN KEY (way_id, version) REFERENCES ways(way_id, version); -- -- Name: way_tags_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY way_tags ADD CONSTRAINT way_tags_id_fkey FOREIGN KEY (way_id, version) REFERENCES ways(way_id, version); -- -- Name: ways_changeset_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- ALTER TABLE ONLY ways ADD CONSTRAINT ways_changeset_id_fkey FOREIGN KEY (changeset_id) REFERENCES changesets(id); -- -- PostgreSQL database dump complete -- INSERT INTO schema_migrations (version) VALUES ('1'); INSERT INTO schema_migrations (version) VALUES ('2'); INSERT INTO schema_migrations (version) VALUES ('3'); INSERT INTO schema_migrations (version) VALUES ('4'); INSERT INTO schema_migrations (version) VALUES ('5'); INSERT INTO schema_migrations (version) VALUES ('6'); INSERT INTO schema_migrations (version) VALUES ('7'); INSERT INTO schema_migrations (version) VALUES ('8'); INSERT INTO schema_migrations (version) VALUES ('9'); INSERT INTO schema_migrations (version) VALUES ('10'); INSERT INTO schema_migrations (version) VALUES ('11'); INSERT INTO schema_migrations (version) VALUES ('12'); INSERT INTO schema_migrations (version) VALUES ('13'); INSERT INTO schema_migrations (version) VALUES ('14'); INSERT INTO schema_migrations (version) VALUES ('15'); INSERT INTO schema_migrations (version) VALUES ('16'); INSERT INTO schema_migrations (version) VALUES ('17'); INSERT INTO schema_migrations (version) VALUES ('18'); INSERT INTO schema_migrations (version) VALUES ('19'); INSERT INTO schema_migrations (version) VALUES ('20'); INSERT INTO schema_migrations (version) VALUES ('21'); INSERT INTO schema_migrations (version) VALUES ('22'); INSERT INTO schema_migrations (version) VALUES ('23'); INSERT INTO schema_migrations (version) VALUES ('24'); INSERT INTO schema_migrations (version) VALUES ('25'); INSERT INTO schema_migrations (version) VALUES ('26'); INSERT INTO schema_migrations (version) VALUES ('27'); INSERT INTO schema_migrations (version) VALUES ('28'); INSERT INTO schema_migrations (version) VALUES ('29'); INSERT INTO schema_migrations (version) VALUES ('30'); INSERT INTO schema_migrations (version) VALUES ('31'); INSERT INTO schema_migrations (version) VALUES ('32'); INSERT INTO schema_migrations (version) VALUES ('33'); INSERT INTO schema_migrations (version) VALUES ('34'); INSERT INTO schema_migrations (version) VALUES ('35'); INSERT INTO schema_migrations (version) VALUES ('36'); INSERT INTO schema_migrations (version) VALUES ('37'); INSERT INTO schema_migrations (version) VALUES ('38'); INSERT INTO schema_migrations (version) VALUES ('39'); INSERT INTO schema_migrations (version) VALUES ('40'); INSERT INTO schema_migrations (version) VALUES ('41'); INSERT INTO schema_migrations (version) VALUES ('42'); INSERT INTO schema_migrations (version) VALUES ('43'); INSERT INTO schema_migrations (version) VALUES ('44'); INSERT INTO schema_migrations (version) VALUES ('45'); INSERT INTO schema_migrations (version) VALUES ('46'); INSERT INTO schema_migrations (version) VALUES ('47'); INSERT INTO schema_migrations (version) VALUES ('48'); INSERT INTO schema_migrations (version) VALUES ('49'); INSERT INTO schema_migrations (version) VALUES ('50'); INSERT INTO schema_migrations (version) VALUES ('51'); INSERT INTO schema_migrations (version) VALUES ('52'); INSERT INTO schema_migrations (version) VALUES ('20100513171259'); INSERT INTO schema_migrations (version) VALUES ('20100910084426'); INSERT INTO schema_migrations (version) VALUES ('20101114011429'); INSERT INTO schema_migrations (version) VALUES ('20110322001319'); INSERT INTO schema_migrations (version) VALUES ('20100516124737'); INSERT INTO schema_migrations (version) VALUES ('20110925112722');osmosis-0.44.1/package/script/contrib/apidb_0.6_osmosis_xid_indexing.sql000066400000000000000000000014071253404521400263250ustar00rootroot00000000000000-- This script creates a function and indexes that allow osmosis to efficiently query based on transaction ids. CREATE OR REPLACE FUNCTION xid_to_int4(t xid) RETURNS integer AS $BODY$ DECLARE tl bigint; ti int; BEGIN tl := t; IF tl >= 2147483648 THEN tl := tl - 4294967296; END IF; ti := tl; RETURN ti; END; $BODY$ LANGUAGE 'plpgsql' IMMUTABLE STRICT; DROP INDEX IF EXISTS nodes_xmin_idx; DROP INDEX IF EXISTS ways_xmin_idx; DROP INDEX IF EXISTS relations_xmin_idx; CREATE INDEX nodes_xmin_idx ON nodes USING btree ((xid_to_int4(xmin))); CREATE INDEX ways_xmin_idx ON ways USING btree ((xid_to_int4(xmin))); CREATE INDEX relations_xmin_idx ON relations USING btree ((xid_to_int4(xmin))); osmosis-0.44.1/package/script/contrib/dump_apidb.sh000077500000000000000000000000721253404521400222750ustar00rootroot00000000000000#!/bin/sh /usr/bin/pg_dump -O -v -f "apidb_0.6.sql" api06 osmosis-0.44.1/package/script/contrib/replicate_osm_file.sh000077500000000000000000000020721253404521400240200ustar00rootroot00000000000000#!/bin/sh # This script automates the replication of changes into an offline osm file for a specific area of interest. This allows an up-to-date local snapshot of an area to be maintained. # The name of the replicated file. OSM_FILE=myfile.osm.gz # The name of the temp file to create during processing (Note: must have the same extension as OSM_FILE to ensure the same compression method is used. TEMP_OSM_FILE=tmp.osm.gz # The directory containing the state associated with the --read-change-interval task previously initiated with the --read-change-interval-init task. WORKING_DIRECTORY=./ # The bounding box to maintain. LEFT=-180 BOTTOM=-90 RIGHT=180 TOP=90 # The osmosis command. CMD="osmosis -q" # Launch the osmosis process. $CMD --read-change-interval $WORKING_DIRECTORY --read-xml $OSM_FILE --apply-change --bounding-box left=$LEFT bottom=$BOTTOM right=$RIGHT top=$TOP --write-xml $TEMP_OSM_FILE STATUS=$? # Verify that osmosis ran successfully. if [ "$STATUS" -ne "0" ]; then echo "Osmosis failed, aborting." exit $STATUS fi mv $TEMP_OSM_FILE $OSM_FILE osmosis-0.44.1/package/script/fix_line_endings.sh000077500000000000000000000011301253404521400220310ustar00rootroot00000000000000#!/bin/sh find . -iname "*.java" -exec dos2unix -U '{}' \; find . -iname "*.xml" -exec dos2unix -U '{}' \; find . -iname "*.txt" -exec dos2unix -U '{}' \; find . -iname "*.osm" -exec dos2unix -U '{}' \; find . -iname "*.osc" -exec dos2unix -U '{}' \; find . -iname "*.java" -exec svn propset svn:eol-style native '{}' \; find . -iname "*.xml" -exec svn propset svn:eol-style native '{}' \; find . -iname "*.txt" -exec svn propset svn:eol-style native '{}' \; find . -iname "*.osm" -exec svn propset svn:eol-style native '{}' \; find . -iname "*.osc" -exec svn propset svn:eol-style native '{}' \; osmosis-0.44.1/package/script/munin/000077500000000000000000000000001253404521400173215ustar00rootroot00000000000000osmosis-0.44.1/package/script/munin/README000066400000000000000000000006411253404521400202020ustar00rootroot00000000000000to activate the munin plugins - copy "osm_replication_lag" to "/usr/share/munin/plugins" - make "/usr/share/munin/plugins/osm_replication_lag" executable - symlink "/usr/share/munin/plugins/osm_replication_lag" to "/etc/munin/plugins" - copy "osm_replication.conf" to "/etc/munin/plugin-conf.d" - edit "/etc/munin/plugin-conf.d/osm_replication.conf" and set the workingDirectory - restart the munin-node osmosis-0.44.1/package/script/munin/osm_replication.conf000066400000000000000000000006641253404521400233650ustar00rootroot00000000000000[osm*] # the osmosis invocation may take some time timeout 60 # the system user that has access to the working directory, if it'S different # from "munin" #user osm # path to the osmosis binary. if not set, osmosis is assumed to be in $PATH #env.osmosis /opt/osmosis/bin/osmosis # working directory of the osmosis replication. # this must be set to make the munin plugin work #env.workingDirectory /path/to/state.txt osmosis-0.44.1/package/script/munin/osm_replication_lag000077500000000000000000000014271253404521400232650ustar00rootroot00000000000000#!/bin/sh # -*- sh -*- # load the munin plugin helper . $MUNIN_LIBDIR/plugins/plugin.sh # if no workingDirectory has been configures if [ ! $workingDirectory ]; then # exit with an error echo "no workingDirectory configured" >&2 exit 1 fi # path to osmosis binary [ $osmosis ] || osmosis="osmosis" # configuration section if [ "$1" = "config" ]; then echo 'graph_title OSM PostGIS Database Replag' echo 'graph_args --base 1000' echo 'graph_vlabel seconds behind main database' echo 'graph_category osm' echo 'lag.label replication lag' echo 'lag.draw LINE' exit 0 fi # invoke osmosis to calculate the replication lag lag=$($osmosis --read-replication-lag workingDirectory="$workingDirectory" 2>/dev/null) echo "lag.value $lag" exit 0 osmosis-0.44.1/package/script/pgsimple_load_0.6.sql000066400000000000000000000057201253404521400221220ustar00rootroot00000000000000-- Drop all primary keys and indexes to improve load speed. ALTER TABLE nodes DROP CONSTRAINT pk_nodes; ALTER TABLE ways DROP CONSTRAINT pk_ways; ALTER TABLE way_nodes DROP CONSTRAINT pk_way_nodes; ALTER TABLE relations DROP CONSTRAINT pk_relations; ALTER TABLE relation_members DROP CONSTRAINT pk_relation_members; DROP INDEX idx_node_tags_node_id; DROP INDEX idx_nodes_geom; DROP INDEX idx_way_tags_way_id; DROP INDEX idx_way_nodes_node_id; DROP INDEX idx_relation_tags_relation_id; DROP INDEX idx_ways_bbox; DROP INDEX idx_ways_linestring; -- Comment these out if the COPY files include bbox or linestring column values. SELECT DropGeometryColumn('ways', 'bbox'); SELECT DropGeometryColumn('ways', 'linestring'); -- Import the table data from the data files using the fast COPY method. \copy users FROM 'users.txt' \copy nodes FROM 'nodes.txt' \copy node_tags FROM 'node_tags.txt' \copy ways FROM 'ways.txt' \copy way_tags FROM 'way_tags.txt' \copy way_nodes FROM 'way_nodes.txt' \copy relations FROM 'relations.txt' \copy relation_tags FROM 'relation_tags.txt' \copy relation_members FROM 'relation_members.txt' -- Add the primary keys and indexes back again (except the way bbox index). ALTER TABLE ONLY nodes ADD CONSTRAINT pk_nodes PRIMARY KEY (id); ALTER TABLE ONLY ways ADD CONSTRAINT pk_ways PRIMARY KEY (id); ALTER TABLE ONLY way_nodes ADD CONSTRAINT pk_way_nodes PRIMARY KEY (way_id, sequence_id); ALTER TABLE ONLY relations ADD CONSTRAINT pk_relations PRIMARY KEY (id); ALTER TABLE ONLY relation_members ADD CONSTRAINT pk_relation_members PRIMARY KEY (relation_id, sequence_id); CREATE INDEX idx_node_tags_node_id ON node_tags USING btree (node_id); CREATE INDEX idx_nodes_geom ON nodes USING gist (geom); CREATE INDEX idx_way_tags_way_id ON way_tags USING btree (way_id); CREATE INDEX idx_way_nodes_node_id ON way_nodes USING btree (node_id); CREATE INDEX idx_relation_tags_relation_id ON relation_tags USING btree (relation_id); -- Comment these out if the COPY files include bbox or linestring column values. SELECT AddGeometryColumn('ways', 'bbox', 4326, 'GEOMETRY', 2); SELECT AddGeometryColumn('ways', 'linestring', 4326, 'GEOMETRY', 2); -- Comment these out if the COPY files include bbox or linestring column values. -- Update the bbox column of the way table. UPDATE ways SET bbox = ( SELECT ST_Envelope(ST_Collect(geom)) FROM nodes JOIN way_nodes ON way_nodes.node_id = nodes.id WHERE way_nodes.way_id = ways.id ); -- Update the linestring column of the way table. UPDATE ways w SET linestring = ( SELECT ST_MakeLine(c.geom) AS way_line FROM ( SELECT n.geom AS geom FROM nodes n INNER JOIN way_nodes wn ON n.id = wn.node_id WHERE (wn.way_id = w.id) ORDER BY wn.sequence_id ) c ) -- Index the way bounding box column. CREATE INDEX idx_ways_bbox ON ways USING gist (bbox); CREATE INDEX idx_ways_linestring ON ways USING gist (linestring); -- Perform database maintenance due to large database changes. VACUUM ANALYZE; osmosis-0.44.1/package/script/pgsimple_schema_0.6.sql000066400000000000000000000071701253404521400224440ustar00rootroot00000000000000-- Database creation script for the simple PostgreSQL schema. -- Drop all tables if they exist. DROP TABLE IF EXISTS actions; DROP TABLE IF EXISTS users; DROP TABLE IF EXISTS nodes; DROP TABLE IF EXISTS node_tags; DROP TABLE IF EXISTS ways; DROP TABLE IF EXISTS way_nodes; DROP TABLE IF EXISTS way_tags; DROP TABLE IF EXISTS relations; DROP TABLE IF EXISTS relation_members; DROP TABLE IF EXISTS relation_tags; DROP TABLE IF EXISTS schema_info; -- Drop all stored procedures if they exist. DROP FUNCTION IF EXISTS osmosisUpdate(); -- Create a table which will contain a single row defining the current schema version. CREATE TABLE schema_info ( version integer NOT NULL ); -- Create a table for users. CREATE TABLE users ( id int NOT NULL, name text NOT NULL ); -- Create a table for nodes. CREATE TABLE nodes ( id bigint NOT NULL, version int NOT NULL, user_id int NOT NULL, tstamp timestamp without time zone NOT NULL, changeset_id bigint NOT NULL ); -- Add a postgis point column holding the location of the node. SELECT AddGeometryColumn('nodes', 'geom', 4326, 'POINT', 2); -- Create a table for node tags. CREATE TABLE node_tags ( node_id bigint NOT NULL, k text NOT NULL, v text NOT NULL ); -- Create a table for ways. CREATE TABLE ways ( id bigint NOT NULL, version int NOT NULL, user_id int NOT NULL, tstamp timestamp without time zone NOT NULL, changeset_id bigint NOT NULL ); -- Create a table for representing way to node relationships. CREATE TABLE way_nodes ( way_id bigint NOT NULL, node_id bigint NOT NULL, sequence_id int NOT NULL ); -- Create a table for way tags. CREATE TABLE way_tags ( way_id bigint NOT NULL, k text NOT NULL, v text ); -- Create a table for relations. CREATE TABLE relations ( id bigint NOT NULL, version int NOT NULL, user_id int NOT NULL, tstamp timestamp without time zone NOT NULL, changeset_id bigint NOT NULL ); -- Create a table for representing relation member relationships. CREATE TABLE relation_members ( relation_id bigint NOT NULL, member_id bigint NOT NULL, member_type character(1) NOT NULL, member_role text NOT NULL, sequence_id int NOT NULL ); -- Create a table for relation tags. CREATE TABLE relation_tags ( relation_id bigint NOT NULL, k text NOT NULL, v text NOT NULL ); -- Configure the schema version. INSERT INTO schema_info (version) VALUES (5); -- Add primary keys to tables. ALTER TABLE ONLY schema_info ADD CONSTRAINT pk_schema_info PRIMARY KEY (version); ALTER TABLE ONLY users ADD CONSTRAINT pk_users PRIMARY KEY (id); ALTER TABLE ONLY nodes ADD CONSTRAINT pk_nodes PRIMARY KEY (id); ALTER TABLE ONLY ways ADD CONSTRAINT pk_ways PRIMARY KEY (id); ALTER TABLE ONLY way_nodes ADD CONSTRAINT pk_way_nodes PRIMARY KEY (way_id, sequence_id); ALTER TABLE ONLY relations ADD CONSTRAINT pk_relations PRIMARY KEY (id); ALTER TABLE ONLY relation_members ADD CONSTRAINT pk_relation_members PRIMARY KEY (relation_id, sequence_id); -- Add indexes to tables. CREATE INDEX idx_node_tags_node_id ON node_tags USING btree (node_id); CREATE INDEX idx_nodes_geom ON nodes USING gist (geom); CREATE INDEX idx_way_tags_way_id ON way_tags USING btree (way_id); CREATE INDEX idx_way_nodes_node_id ON way_nodes USING btree (node_id); CREATE INDEX idx_relation_tags_relation_id ON relation_tags USING btree (relation_id); -- Create stored procedures. CREATE FUNCTION osmosisUpdate() RETURNS void AS $$ DECLARE BEGIN END; $$ LANGUAGE plpgsql; osmosis-0.44.1/package/script/pgsimple_schema_0.6_action.sql000066400000000000000000000011701253404521400237730ustar00rootroot00000000000000-- Add an action table for the purpose of capturing all actions applied to a database. -- The table is populated during application of a changeset, then osmosisUpdate is called, -- then the table is cleared all within a single database transaction. -- The contents of this table can be used to update derivative tables by customising the -- osmosisUpdate stored procedure. -- Create a table for actions. CREATE TABLE actions ( data_type character(1) NOT NULL, action character(1) NOT NULL, id bigint NOT NULL ); -- Add primary key. ALTER TABLE ONLY actions ADD CONSTRAINT pk_actions PRIMARY KEY (data_type, id); osmosis-0.44.1/package/script/pgsimple_schema_0.6_bbox.sql000066400000000000000000000005211253404521400234470ustar00rootroot00000000000000-- Add a postgis GEOMETRY column to the way table for the purpose of indexing the location of the way. -- This will contain a bounding box surrounding the extremities of the way. SELECT AddGeometryColumn('ways', 'bbox', 4326, 'GEOMETRY', 2); -- Add an index to the bbox column. CREATE INDEX idx_ways_bbox ON ways USING gist (bbox);osmosis-0.44.1/package/script/pgsimple_schema_0.6_linestring.sql000066400000000000000000000004361253404521400247000ustar00rootroot00000000000000-- Add a postgis GEOMETRY column to the way table for the purpose of storing the full linestring of the way. SELECT AddGeometryColumn('ways', 'linestring', 4326, 'GEOMETRY', 2); -- Add an index to the bbox column. CREATE INDEX idx_ways_linestring ON ways USING gist (linestring); osmosis-0.44.1/package/script/pgsnapshot_and_pgsimple.txt000066400000000000000000000026701253404521400236510ustar00rootroot00000000000000Both the pgsimple and pgsnapshot schemas are PostgreSQL schemas utilising postgis extensions that are capable of storing snapshots of OSM data. No history is maintained. They can be populated by osmosis and kept up to date with osmosis daily, hourly and minute changesets. The pgsimple and pgsnapshot schemas are forked versions of the same schema. Up to version 5 of the schema they were known as the "simple" schema. The pgsimple schema is the "simple" schema and is unchanged. Since version 6, the pgsnapshot schema has deviated to include all tag information in hstore "tags" columns inside the parent entity tables. The purpose of the pgsimple schema is to provide a simplistic and generic schema for storing OSM data in a PostGIS format. The purpose of the pgsnapshot schema is similar but maximises performance through CLUSTERed indexes and embedded tag data. It imposes additional programming complexity. The following scripts are available for both schemas: pgxxx_schema_0.x.sql - The schema creation script. pgxxx_schema_0.x_bbox.sql - A script for adding way bbox column support. pgxxx_schema_0.x_linestring.sql - A script for adding way linestring column support. pgxxx_schema_0.x_action.sql - A script for adding an action table which is populated during changeset processing to allow derivative tables to be kept up to date. pgxxx_load_0.x.sql - A script for importing PostgreSQL "COPY" files as produced by the osmosis --write-pgxxx-dump tasks. osmosis-0.44.1/package/script/pgsnapshot_load_0.6.sql000066400000000000000000000072011253404521400224640ustar00rootroot00000000000000-- Allow data loss (but not corruption) in the case of a power outage. This is okay because we need to re-run the script anyways. SET synchronous_commit TO OFF; -- Drop all primary keys and indexes to improve load speed. ALTER TABLE nodes DROP CONSTRAINT pk_nodes; ALTER TABLE ways DROP CONSTRAINT pk_ways; ALTER TABLE way_nodes DROP CONSTRAINT pk_way_nodes; ALTER TABLE relations DROP CONSTRAINT pk_relations; ALTER TABLE relation_members DROP CONSTRAINT pk_relation_members; DROP INDEX idx_nodes_geom; DROP INDEX idx_way_nodes_node_id; DROP INDEX idx_relation_members_member_id_and_type; DROP INDEX idx_ways_bbox; DROP INDEX idx_ways_linestring; -- Uncomment these out if bbox or linestring columns are needed and the COPY -- files do not include them. If you want these columns you should use the -- enableBboxBuilder or enableLinestringBuilder options to --write-pgsql-dump -- as they are faster than the following SQL. /*SELECT DropGeometryColumn('ways', 'bbox'); SELECT DropGeometryColumn('ways', 'linestring');*/ -- Import the table data from the data files using the fast COPY method. \copy users FROM 'users.txt' \copy nodes FROM 'nodes.txt' \copy ways FROM 'ways.txt' \copy way_nodes FROM 'way_nodes.txt' \copy relations FROM 'relations.txt' \copy relation_members FROM 'relation_members.txt' -- Add the primary keys and indexes back again (except the way bbox index). ALTER TABLE ONLY nodes ADD CONSTRAINT pk_nodes PRIMARY KEY (id); ALTER TABLE ONLY ways ADD CONSTRAINT pk_ways PRIMARY KEY (id); ALTER TABLE ONLY way_nodes ADD CONSTRAINT pk_way_nodes PRIMARY KEY (way_id, sequence_id); ALTER TABLE ONLY relations ADD CONSTRAINT pk_relations PRIMARY KEY (id); ALTER TABLE ONLY relation_members ADD CONSTRAINT pk_relation_members PRIMARY KEY (relation_id, sequence_id); CREATE INDEX idx_nodes_geom ON nodes USING gist (geom); CREATE INDEX idx_way_nodes_node_id ON way_nodes USING btree (node_id); CREATE INDEX idx_relation_members_member_id_and_type ON relation_members USING btree (member_id, member_type); ALTER TABLE ONLY nodes CLUSTER ON idx_nodes_geom; ALTER TABLE ONLY way_nodes CLUSTER ON pk_way_nodes; ALTER TABLE ONLY relation_members CLUSTER ON pk_relation_members; -- Uncomment these if bbox or linestring columns are needed and the COPY files do not include them. -- Update the bbox column of the way table. /*SELECT AddGeometryColumn('ways', 'bbox', 4326, 'GEOMETRY', 2); UPDATE ways SET bbox = ( SELECT ST_Envelope(ST_Collect(geom)) FROM nodes JOIN way_nodes ON way_nodes.node_id = nodes.id WHERE way_nodes.way_id = ways.id );*/ -- Update the linestring column of the way table. /*SELECT AddGeometryColumn('ways', 'linestring', 4326, 'GEOMETRY', 2); UPDATE ways w SET linestring = ( SELECT ST_MakeLine(c.geom) AS way_line FROM ( SELECT n.geom AS geom FROM nodes n INNER JOIN way_nodes wn ON n.id = wn.node_id WHERE (wn.way_id = w.id) ORDER BY wn.sequence_id ) c );*/ -- Index the way bounding box column. If you don't have one of these columns, comment out the index CREATE INDEX idx_ways_bbox ON ways USING gist (bbox); CREATE INDEX idx_ways_linestring ON ways USING gist (linestring); ALTER TABLE ONLY ways CLUSTER ON idx_ways_bbox; ALTER TABLE ONLY ways CLUSTER ON idx_ways_linestring; -- Optional: CLUSTER imported tables. CLUSTER takes a significant amount of time to run and a -- significant amount of free disk space but speeds up some queries. --CLUSTER nodes; --CLUSTER ways; -- It is not necessary to CLUSTER way_nodes or relation_members after the initial load but you might want to do so later on -- Perform database maintenance due to large database changes. ANALYZE; osmosis-0.44.1/package/script/pgsnapshot_schema_0.6.sql000066400000000000000000000124311253404521400230060ustar00rootroot00000000000000-- Database creation script for the snapshot PostgreSQL schema. -- Drop all tables if they exist. DROP TABLE IF EXISTS actions; DROP TABLE IF EXISTS users; DROP TABLE IF EXISTS nodes; DROP TABLE IF EXISTS ways; DROP TABLE IF EXISTS way_nodes; DROP TABLE IF EXISTS relations; DROP TABLE IF EXISTS relation_members; DROP TABLE IF EXISTS schema_info; -- Drop all stored procedures if they exist. DROP FUNCTION IF EXISTS osmosisUpdate(); -- Create a table which will contain a single row defining the current schema version. CREATE TABLE schema_info ( version integer NOT NULL ); -- Create a table for users. CREATE TABLE users ( id int NOT NULL, name text NOT NULL ); -- Create a table for nodes. CREATE TABLE nodes ( id bigint NOT NULL, version int NOT NULL, user_id int NOT NULL, tstamp timestamp without time zone NOT NULL, changeset_id bigint NOT NULL, tags hstore ); -- Add a postgis point column holding the location of the node. SELECT AddGeometryColumn('nodes', 'geom', 4326, 'POINT', 2); -- Create a table for ways. CREATE TABLE ways ( id bigint NOT NULL, version int NOT NULL, user_id int NOT NULL, tstamp timestamp without time zone NOT NULL, changeset_id bigint NOT NULL, tags hstore, nodes bigint[] ); -- Create a table for representing way to node relationships. CREATE TABLE way_nodes ( way_id bigint NOT NULL, node_id bigint NOT NULL, sequence_id int NOT NULL ); -- Create a table for relations. CREATE TABLE relations ( id bigint NOT NULL, version int NOT NULL, user_id int NOT NULL, tstamp timestamp without time zone NOT NULL, changeset_id bigint NOT NULL, tags hstore ); -- Create a table for representing relation member relationships. CREATE TABLE relation_members ( relation_id bigint NOT NULL, member_id bigint NOT NULL, member_type character(1) NOT NULL, member_role text NOT NULL, sequence_id int NOT NULL ); -- Configure the schema version. INSERT INTO schema_info (version) VALUES (6); -- Add primary keys to tables. ALTER TABLE ONLY schema_info ADD CONSTRAINT pk_schema_info PRIMARY KEY (version); ALTER TABLE ONLY users ADD CONSTRAINT pk_users PRIMARY KEY (id); ALTER TABLE ONLY nodes ADD CONSTRAINT pk_nodes PRIMARY KEY (id); ALTER TABLE ONLY ways ADD CONSTRAINT pk_ways PRIMARY KEY (id); ALTER TABLE ONLY way_nodes ADD CONSTRAINT pk_way_nodes PRIMARY KEY (way_id, sequence_id); ALTER TABLE ONLY relations ADD CONSTRAINT pk_relations PRIMARY KEY (id); ALTER TABLE ONLY relation_members ADD CONSTRAINT pk_relation_members PRIMARY KEY (relation_id, sequence_id); -- Add indexes to tables. CREATE INDEX idx_nodes_geom ON nodes USING gist (geom); CREATE INDEX idx_way_nodes_node_id ON way_nodes USING btree (node_id); CREATE INDEX idx_relation_members_member_id_and_type ON relation_members USING btree (member_id, member_type); -- Set to cluster nodes by geographical location. ALTER TABLE ONLY nodes CLUSTER ON idx_nodes_geom; -- Set to cluster the tables showing relationship by parent ID and sequence ALTER TABLE ONLY way_nodes CLUSTER ON pk_way_nodes; ALTER TABLE ONLY relation_members CLUSTER ON pk_relation_members; -- There are no sensible CLUSTER orders for users or relations. -- Depending on geometry columns different clustings of ways may be desired. -- Create the function that provides "unnest" functionality while remaining compatible with 8.3. CREATE OR REPLACE FUNCTION unnest_bbox_way_nodes() RETURNS void AS $$ DECLARE previousId ways.id%TYPE; currentId ways.id%TYPE; result bigint[]; wayNodeRow way_nodes%ROWTYPE; wayNodes ways.nodes%TYPE; BEGIN FOR wayNodes IN SELECT bw.nodes FROM bbox_ways bw LOOP FOR i IN 1 .. array_upper(wayNodes, 1) LOOP INSERT INTO bbox_way_nodes (id) VALUES (wayNodes[i]); END LOOP; END LOOP; END; $$ LANGUAGE plpgsql; -- Create customisable hook function that is called within the replication update transaction. CREATE FUNCTION osmosisUpdate() RETURNS void AS $$ DECLARE BEGIN END; $$ LANGUAGE plpgsql; -- Manually set statistics for the way_nodes and relation_members table -- Postgres gets horrible counts of distinct values by sampling random pages -- and can be off by an 1-2 orders of magnitude -- Size of the ways table / size of the way_nodes table ALTER TABLE way_nodes ALTER COLUMN way_id SET (n_distinct = -0.08); -- Size of the nodes table / size of the way_nodes table * 0.998 -- 0.998 is a factor for nodes not in ways ALTER TABLE way_nodes ALTER COLUMN node_id SET (n_distinct = -0.83); -- API allows a maximum of 2000 nodes/way. Unlikely to impact query plans. ALTER TABLE way_nodes ALTER COLUMN sequence_id SET (n_distinct = 2000); -- Size of the relations table / size of the relation_members table ALTER TABLE relation_members ALTER COLUMN relation_id SET (n_distinct = -0.09); -- Based on June 2013 data ALTER TABLE relation_members ALTER COLUMN member_id SET (n_distinct = -0.62); -- Based on June 2013 data. Unlikely to impact query plans. ALTER TABLE relation_members ALTER COLUMN member_role SET (n_distinct = 6500); -- Based on June 2013 data. Unlikely to impact query plans. ALTER TABLE relation_members ALTER COLUMN sequence_id SET (n_distinct = 10000); osmosis-0.44.1/package/script/pgsnapshot_schema_0.6_action.sql000066400000000000000000000011701253404521400243410ustar00rootroot00000000000000-- Add an action table for the purpose of capturing all actions applied to a database. -- The table is populated during application of a changeset, then osmosisUpdate is called, -- then the table is cleared all within a single database transaction. -- The contents of this table can be used to update derivative tables by customising the -- osmosisUpdate stored procedure. -- Create a table for actions. CREATE TABLE actions ( data_type character(1) NOT NULL, action character(1) NOT NULL, id bigint NOT NULL ); -- Add primary key. ALTER TABLE ONLY actions ADD CONSTRAINT pk_actions PRIMARY KEY (data_type, id); osmosis-0.44.1/package/script/pgsnapshot_schema_0.6_bbox.sql000066400000000000000000000015021253404521400240150ustar00rootroot00000000000000-- Add a postgis GEOMETRY column to the way table for the purpose of indexing the location of the way. -- This will contain a bounding box surrounding the extremities of the way. SELECT AddGeometryColumn('ways', 'bbox', 4326, 'GEOMETRY', 2); -- Add an index to the bbox column. CREATE INDEX idx_ways_bbox ON ways USING gist (bbox); -- Cluster table by geographical location. CLUSTER ways USING idx_ways_bbox; -- Create an aggregate function that always returns the first non-NULL item. This is required for bbox queries. CREATE OR REPLACE FUNCTION first_agg (anyelement, anyelement) RETURNS anyelement AS $$ SELECT CASE WHEN $1 IS NULL THEN $2 ELSE $1 END; $$ LANGUAGE SQL STABLE; CREATE AGGREGATE first ( sfunc = first_agg, basetype = anyelement, stype = anyelement ); osmosis-0.44.1/package/script/pgsnapshot_schema_0.6_linestring.sql000066400000000000000000000005651253404521400252510ustar00rootroot00000000000000-- Add a postgis GEOMETRY column to the way table for the purpose of storing the full linestring of the way. SELECT AddGeometryColumn('ways', 'linestring', 4326, 'GEOMETRY', 2); -- Add an index to the bbox column. CREATE INDEX idx_ways_linestring ON ways USING gist (linestring); -- Cluster table by geographical location. CLUSTER ways USING idx_ways_linestring; osmosis-0.44.1/package/script/pgsnapshot_schema_0.6_upgrade_4-5.sql000066400000000000000000000003311253404521400250760ustar00rootroot00000000000000-- Add the relation members primary key. ALTER TABLE ONLY relation_members ADD CONSTRAINT pk_relation_members PRIMARY KEY (relation_id, sequence_id); -- Upgrade the schema version. UPDATE schema_info SET version = 5;osmosis-0.44.1/package/script/pgsnapshot_schema_0.6_upgrade_5-6.sql000066400000000000000000000140511253404521400251040ustar00rootroot00000000000000-- Database script for the simple PostgreSQL schema. This script moves all tags into hstore columns. -- Create functions for building hstore data. CREATE OR REPLACE FUNCTION build_node_tags() RETURNS void AS $$ DECLARE previousId nodes.id%TYPE; currentId nodes.id%TYPE; result hstore; tagRow node_tags%ROWTYPE; BEGIN SET enable_seqscan = false; SET enable_mergejoin = false; SET enable_hashjoin = false; FOR tagRow IN SELECT * FROM node_tags ORDER BY node_id LOOP currentId := tagRow.node_id; IF currentId <> previousId THEN IF previousId IS NOT NULL THEN IF result IS NOT NULL THEN UPDATE nodes SET tags = result WHERE id = previousId; IF ((currentId / 100000) <> (previousId / 100000)) THEN RAISE INFO 'node id: %', previousId; END IF; result := NULL; END IF; END IF; END IF; IF result IS NULL THEN result := tagRow.k => tagRow.v; ELSE result := result || (tagRow.k => tagRow.v); END IF; previousId := currentId; END LOOP; IF previousId IS NOT NULL THEN IF result IS NOT NULL THEN UPDATE nodes SET tags = result WHERE id = previousId; result := NULL; END IF; END IF; END; $$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION build_way_tags() RETURNS void AS $$ DECLARE previousId ways.id%TYPE; currentId ways.id%TYPE; result hstore; tagRow way_tags%ROWTYPE; BEGIN SET enable_seqscan = false; SET enable_mergejoin = false; SET enable_hashjoin = false; FOR tagRow IN SELECT * FROM way_tags ORDER BY way_id LOOP currentId := tagRow.way_id; IF currentId <> previousId THEN IF previousId IS NOT NULL THEN IF result IS NOT NULL THEN UPDATE ways SET tags = result WHERE id = previousId; IF ((currentId / 100000) <> (previousId / 100000)) THEN RAISE INFO 'way id: %', previousId; END IF; result := NULL; END IF; END IF; END IF; IF result IS NULL THEN result := tagRow.k => tagRow.v; ELSE result := result || (tagRow.k => tagRow.v); END IF; previousId := currentId; END LOOP; IF previousId IS NOT NULL THEN IF result IS NOT NULL THEN UPDATE ways SET tags = result WHERE id = previousId; result := NULL; END IF; END IF; END; $$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION build_relation_tags() RETURNS void AS $$ DECLARE previousId relations.id%TYPE; currentId relations.id%TYPE; result hstore; tagRow relation_tags%ROWTYPE; BEGIN SET enable_seqscan = false; SET enable_mergejoin = false; SET enable_hashjoin = false; FOR tagRow IN SELECT * FROM relation_tags ORDER BY relation_id LOOP currentId := tagRow.relation_id; IF currentId <> previousId THEN IF previousId IS NOT NULL THEN IF result IS NOT NULL THEN UPDATE relations SET tags = result WHERE id = previousId; IF ((currentId / 100000) <> (previousId / 100000)) THEN RAISE INFO 'relation id: %', previousId; END IF; result := NULL; END IF; END IF; END IF; IF result IS NULL THEN result := tagRow.k => tagRow.v; ELSE result := result || (tagRow.k => tagRow.v); END IF; previousId := currentId; END LOOP; IF previousId IS NOT NULL THEN IF result IS NOT NULL THEN UPDATE relations SET tags = result WHERE id = previousId; result := NULL; END IF; END IF; END; $$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION build_way_nodes() RETURNS void AS $$ DECLARE previousId ways.id%TYPE; currentId ways.id%TYPE; result bigint[]; wayNodeRow way_nodes%ROWTYPE; BEGIN SET enable_seqscan = false; SET enable_mergejoin = false; SET enable_hashjoin = false; FOR wayNodeRow IN SELECT * FROM way_nodes ORDER BY way_id, sequence_id LOOP currentId := wayNodeRow.way_id; IF currentId <> previousId THEN IF previousId IS NOT NULL THEN IF result IS NOT NULL THEN UPDATE ways SET nodes = result WHERE id = previousId; IF ((currentId / 100000) <> (previousId / 100000)) THEN RAISE INFO 'way id: %', previousId; END IF; result := NULL; END IF; END IF; END IF; IF result IS NULL THEN result = ARRAY[wayNodeRow.node_id]; ELSE result = array_append(result, wayNodeRow.node_id); END IF; previousId := currentId; END LOOP; IF previousId IS NOT NULL THEN IF result IS NOT NULL THEN UPDATE ways SET nodes = result WHERE id = previousId; result := NULL; END IF; END IF; END; $$ LANGUAGE plpgsql; -- Add hstore columns to entity tables. ALTER TABLE nodes ADD COLUMN tags hstore; ALTER TABLE ways ADD COLUMN tags hstore; ALTER TABLE relations ADD COLUMN tags hstore; -- Populate the hstore columns. SELECT build_node_tags(); SELECT build_way_tags(); SELECT build_relation_tags(); -- Remove the hstore functions. DROP FUNCTION build_node_tags(); DROP FUNCTION build_way_tags(); DROP FUNCTION build_relation_tags(); -- Drop the now redundant tag tables. DROP TABLE node_tags; DROP TABLE way_tags; DROP TABLE relation_tags; -- Add an index allowing relation_members to be queried by member id and type. CREATE INDEX idx_relation_members_member_id_and_type ON relation_members USING btree (member_id, member_type); -- Add the nodes column to the ways table. ALTER TABLE ways ADD COLUMN nodes bigint[]; -- Populate the new nodes column on the ways table. SELECT build_way_nodes(); --UPDATE ways w SET nodes = ARRAY(SELECT wn.node_id FROM way_nodes wn WHERE w.id = wn.way_id ORDER BY sequence_id); -- Remove the way nodes function. DROP FUNCTION build_way_nodes(); -- Organise data according to geographical location. CLUSTER nodes USING idx_nodes_geom; CLUSTER ways USING idx_ways_linestring; -- Create the function that provides "unnest" functionality while remaining compatible with 8.3. CREATE OR REPLACE FUNCTION unnest_bbox_way_nodes() RETURNS void AS $$ DECLARE previousId ways.id%TYPE; currentId ways.id%TYPE; result bigint[]; wayNodeRow way_nodes%ROWTYPE; wayNodes ways.nodes%TYPE; BEGIN FOR wayNodes IN SELECT bw.nodes FROM bbox_ways bw LOOP FOR i IN 1 .. array_upper(wayNodes, 1) LOOP INSERT INTO bbox_way_nodes (id) VALUES (wayNodes[i]); END LOOP; END LOOP; END; $$ LANGUAGE plpgsql; -- Update the schema version. UPDATE schema_info SET version = 6; VACUUM ANALYZE; osmosis-0.44.1/settings.gradle000066400000000000000000000010411253404521400163100ustar00rootroot00000000000000include 'build-support' include 'db-server' include 'osmosis-areafilter' include 'osmosis-apidb' include 'osmosis-core' include 'osmosis-dataset' include 'osmosis-extract' include 'osmosis-hstore-jdbc' include 'osmosis-osm-binary' include 'osmosis-pbf' include 'osmosis-pbf2' include 'osmosis-pgsimple' include 'osmosis-pgsnapshot' include 'osmosis-replication' include 'osmosis-replication-http' include 'osmosis-set' include 'osmosis-tagfilter' include 'osmosis-tagtransform' include 'osmosis-testutil' include 'osmosis-xml' include 'package'