├── .github └── ISSUE_TEMPLATE │ ├── bug.yml │ ├── default.yml │ ├── documentation.yaml │ └── feature.yml ├── .gitignore ├── CHANGELOG.md ├── CODE-OF-CONDUCT.md ├── Dockerfile ├── LICENSE.md ├── README.md ├── overture-tiles-cdk ├── .gitignore ├── .npmignore ├── README.md ├── bin │ └── overture-tiles-cdk.ts ├── cdk.json ├── lib │ └── overture-tiles-cdk-stack.ts ├── package-lock.json ├── package.json └── tsconfig.json ├── places.html ├── profiles ├── .gitignore ├── .idea │ ├── .gitignore │ ├── libraries │ │ └── planetiler.xml │ ├── misc.xml │ ├── modules.xml │ └── vcs.xml ├── Addresses.java ├── Base.java ├── Buildings.java ├── OvertureProfile.java ├── Transportation.java └── profiles.iml ├── run.sh └── scripts ├── 2024-04-16-beta ├── divisions.filter.json ├── divisions.sh ├── places.filter.json └── places.sh ├── 2024-05-16-beta ├── divisions.filter.json ├── divisions.sh ├── places.filter.json └── places.sh ├── 2024-06-13-beta ├── admins.filter.json ├── admins.sh ├── divisions.filter.json ├── divisions.sh ├── places.filter.json └── places.sh └── 2024-07-22 ├── divisions.filter.json ├── divisions.sh ├── places.filter.json └── places.sh /.github/ISSUE_TEMPLATE/bug.yml: -------------------------------------------------------------------------------- 1 | name: Bug report 2 | description: Create a report to help us improve 3 | title: "[Bug report]" 4 | labels: ["bug"] 5 | projects: ["Add project"] 6 | assignees: 7 | body: 8 | - type: textarea 9 | id: what-happened 10 | attributes: 11 | label: Outline bug 12 | description: Outline Outline bug Details 13 | placeholder: Tell us what you see 14 | value: "Add details" 15 | validations: 16 | required: true 17 | - type: dropdown 18 | id: TF-Groups 19 | attributes: 20 | label: Issue dependency with other TF Groups 21 | multiple: true 22 | options: 23 | - No Dependency 24 | - Add WG names 25 | 26 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/default.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | name: Report an Issue - no Config 4 | description: Issue form for reporting issues and requesting new features. 5 | 6 | body: 7 | - type: markdown 8 | attributes: 9 | value: Thanks for taking the time to fill out this issue! 10 | 11 | - type: dropdown 12 | id: without-policy 13 | attributes: 14 | label: Type of issue 15 | multiple: false 16 | options: 17 | - 'Bug Report' 18 | - 'Feature Request' 19 | - 'Other' 20 | validations: 21 | required: false 22 | 23 | - type: textarea 24 | id: description 25 | attributes: 26 | label: Description 27 | description: A clear and concise description of what the problem is. E.g. I'm always frustrated when [...] 28 | validations: 29 | required: false 30 | 31 | - type: textarea 32 | id: solution 33 | attributes: 34 | label: Describe the solution you'd like 35 | description: A clear and concise description of what you want to happen. 36 | validations: 37 | required: false 38 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/documentation.yaml: -------------------------------------------------------------------------------- 1 | name: Documentation 2 | description: Issue associated with Documentation 3 | title: "[Documentation]" 4 | labels: ["documentation"] 5 | projects: ["Add project"] 6 | assignees: 7 | body: 8 | - type: textarea 9 | id: what-happened 10 | attributes: 11 | label: Outline Action Item Details 12 | description: Outline Action Item Details 13 | placeholder: Tell us what you see 14 | value: "Add details" 15 | validations: 16 | required: true 17 | - type: dropdown 18 | id: TF-Groups 19 | attributes: 20 | label: Issue dependency with other TF Groups 21 | multiple: true 22 | options: 23 | - No Dependency 24 | - Admin 25 | - Address 26 | - Base 27 | - Data Platform 28 | - Dev Advocacy 29 | - GERs 30 | - Schema 31 | - Transportation 32 | 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature.yml: -------------------------------------------------------------------------------- 1 | name: Feature request 2 | description: Suggest an improvement 3 | labels: ["RFE 🎁"] 4 | 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: Thanks for taking the time to fill out this feature request! 9 | 10 | - type: dropdown 11 | id: component 12 | attributes: 13 | label: Component 14 | description: Please chose components related to this feature request. 15 | multiple: true 16 | options: 17 | - 'bootctl' 18 | - 'homectl' 19 | - 'journalctl' 20 | - 'loginctl' 21 | - 'networkctl' 22 | - 'nss-resolve' 23 | - 'pam_systemd' 24 | - 'pam_systemd_home' 25 | - 'resolvectl' 26 | - 'systemctl' 27 | - 'systemd' 28 | - 'systemd-boot' 29 | - 'systemd-homed' 30 | - 'systemd-journald' 31 | - 'systemd-logind' 32 | - 'systemd-networkd' 33 | - 'systemd-networkd-wait-online' 34 | - 'systemd-nspawn' 35 | - 'systemd-resolved' 36 | - 'systemd-stub' 37 | - 'systemd-udevd' 38 | - 'the bootloader itself' 39 | - 'udev builtins' 40 | - 'udevadm' 41 | - '.network files' 42 | - 'tests' 43 | - 'other' 44 | validations: 45 | required: false 46 | 47 | - type: textarea 48 | id: description 49 | attributes: 50 | label: Is your feature request related to a problem? Please describe 51 | description: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 52 | validations: 53 | required: false 54 | 55 | - type: textarea 56 | id: solution 57 | attributes: 58 | label: Describe the solution you'd like 59 | description: A clear and concise description of what you want to happen. 60 | validations: 61 | required: false 62 | 63 | - type: textarea 64 | id: alternatives 65 | attributes: 66 | label: Describe alternatives you've considered 67 | description: A clear and concise description of any alternative solutions or features you've considered. 68 | validations: 69 | required: false 70 | 71 | - type: input 72 | id: version 73 | attributes: 74 | label: The systemd version you checked that didn't have the feature you are asking for 75 | description: If this is not the most recently released upstream version, then please check first if it has that feature already. 76 | placeholder: '251' 77 | validations: 78 | required: false 79 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pmtiles 2 | *.parquet 3 | data 4 | *.jar 5 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | The format is based on Keep a Changelog, and this project adheres to Semantic Versioning. 4 | 5 | ## [Unreleased] 6 | ### Changed 7 | - Update and improvement of Polish translation from . 8 | ## [0.0.2] - 2014-06-09 9 | 10 | ### Added 11 | - Better explanation of the difference between the file ("CHANGELOG") and its function "the change log". 12 | ### Changed 13 | - Refer to a "change log" instead of a "CHANGELOG" throughout the site to differentiate between the file and the purpose of the file — the logging of changes. 14 | ### Removed 15 | - Remove empty sections from CHANGELOG, they occupy too much space and create too much noise in the file. People will have to assume that the missing sections were intentionally left out because they contained no notable changes. 16 | ## 0.0.1 - 2014-05-31 17 | ### Added 18 | - This CHANGELOG file to hopefully serve as an evolving example of a standardized open source project CHANGELOG. 19 | - CNAME file to enable GitHub Pages custom domain 20 | - README now contains answers to common questions about CHANGELOGs 21 | - Good examples and basic guidelines, including proper date formatting. 22 | - Counter-examples: "What makes unicorns cry?" 23 | -------------------------------------------------------------------------------- /CODE-OF-CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, caste, color, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | - Demonstrating empathy and kindness toward other people 21 | - Being respectful of differing opinions, viewpoints, and experiences 22 | - Giving and gracefully accepting constructive feedback 23 | - Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | - Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | - The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | - Trolling, insulting or derogatory comments, and personal or political attacks 33 | - Public or private harassment 34 | - Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | - Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be directly 62 | reported to the Executive Director of the Green Software Foundation at exec@greensoftware.foundation or any community leaders responsible for enforcement. 63 | 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | [https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0]. 120 | 121 | Community Impact Guidelines were inspired by 122 | [Mozilla's code of conduct enforcement ladder][mozilla coc]. 123 | 124 | For answers to common questions about this code of conduct, see the FAQ at 125 | [https://www.contributor-covenant.org/faq][faq]. Translations are available 126 | at [https://www.contributor-covenant.org/translations][translations]. 127 | 128 | [homepage]: https://www.contributor-covenant.org 129 | [v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html 130 | [mozilla coc]: https://github.com/mozilla/diversity 131 | [faq]: https://www.contributor-covenant.org/faq 132 | [translations]: https://www.contributor-covenant.org/translations 133 | 134 | --- 135 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM amazonlinux 2 | 3 | # Download tippecanoe deps and Java 22+ for single-file .java Planetiler profiles, for large themes. 4 | 5 | RUN yum update -y && yum install -y tar make gzip gcc-c++ sqlite-devel zlib-devel java-22-amazon-corretto-headless && yum clean all 6 | 7 | # Build tippecanoe for creating tilesets for small themes. 8 | 9 | RUN curl -L https://github.com/felt/tippecanoe/archive/refs/tags/2.55.0.tar.gz | tar xz -C /opt/ 10 | WORKDIR /opt/tippecanoe-2.55.0 11 | 12 | RUN make && make install 13 | 14 | WORKDIR / 15 | RUN rm -r /opt/tippecanoe-2.55.0 16 | 17 | # download and install duckdb for reading Overture Parquet files. 18 | 19 | RUN curl -L https://github.com/duckdb/duckdb/releases/download/v0.10.2/duckdb_cli-linux-aarch64.zip -o duckdb_cli-linux.zip && unzip duckdb_cli-linux.zip -d /usr/local/bin/ && rm duckdb_cli-linux.zip 20 | 21 | RUN duckdb -c "install httpfs; install spatial;" 22 | 23 | # Download and install aws cli for authenticated uploads to S3 buckets. 24 | 25 | RUN curl -L https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip -o awscliv2.zip && unzip awscliv2.zip && ./aws/install && rm awscliv2.zip && rm -r ./aws 26 | 27 | # Download planetiler JAR. 28 | 29 | RUN curl -L https://github.com/onthegomap/planetiler/releases/download/v0.8.0/planetiler.jar -o planetiler.jar 30 | 31 | # copy current scripts into image. 32 | 33 | COPY scripts /scripts 34 | COPY profiles /profiles 35 | COPY run.sh /run.sh 36 | 37 | ENTRYPOINT ["bash","/run.sh"] -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023-2024 Overture Maps 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Overture Tiles 2 | 3 | Create tilesets from [Overture Maps](http://overturemaps.org) data. 4 | 5 | See the [overture-tiles docs](https://docs.overturemaps.org/examples/overture-tiles) on how to access and generate the tiles. 6 | 7 | ## Organization 8 | 9 | * Java profiles: `/profiles` 10 | * Tippecanoe scripts: `/scripts` 11 | * AWS CDK constructs: `/overture-tiles-cdk` 12 | 13 | -------------------------------------------------------------------------------- /overture-tiles-cdk/.gitignore: -------------------------------------------------------------------------------- 1 | *.js 2 | *.d.ts 3 | node_modules 4 | 5 | # CDK asset staging directory 6 | .cdk.staging 7 | cdk.out 8 | -------------------------------------------------------------------------------- /overture-tiles-cdk/.npmignore: -------------------------------------------------------------------------------- 1 | *.ts 2 | !*.d.ts 3 | 4 | # CDK asset staging directory 5 | .cdk.staging 6 | cdk.out 7 | -------------------------------------------------------------------------------- /overture-tiles-cdk/README.md: -------------------------------------------------------------------------------- 1 | # Overture Tiles CDK 2 | 3 | Overture Tiles CDK creates the AWS infrastructure for generating tiles from Overture data. 4 | 5 | ## Useful commands 6 | 7 | * `npm run build` compile typescript to js 8 | * `npm run watch` watch for changes and compile 9 | * `npx cdk deploy` deploy this stack to your default AWS account/region 10 | * `npx cdk diff` compare deployed stack with current state 11 | * `npx cdk synth` emits the synthesized CloudFormation template 12 | 13 | ## Deploying 14 | - See the [overture-tiles docs](https://docs.overturemaps.org/examples/overture-tiles) 15 | -------------------------------------------------------------------------------- /overture-tiles-cdk/bin/overture-tiles-cdk.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import 'source-map-support/register'; 3 | import * as cdk from 'aws-cdk-lib'; 4 | import { 5 | OvertureTilesCdkStack, 6 | OvertureTilesCdkStackProps 7 | } from '../lib/overture-tiles-cdk-stack'; 8 | 9 | const props: OvertureTilesCdkStackProps = { 10 | bucketName: 'overturemaps-tiles-us-west-2-beta' 11 | } 12 | 13 | const app = new cdk.App(); 14 | new OvertureTilesCdkStack(app, 'OvertureTilesCdkStack', { 15 | ...props, 16 | 17 | /* If you don't specify 'env', this stack will be environment-agnostic. 18 | * Account/Region-dependent features and context lookups will not work, 19 | * but a single synthesized template can be deployed anywhere. */ 20 | 21 | /* Uncomment the next line to specialize this stack for the AWS Account 22 | * and Region that are implied by the current CLI configuration. */ 23 | // env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION }, 24 | 25 | /* Uncomment the next line if you know exactly what Account and Region you 26 | * want to deploy the stack to. */ 27 | // env: { account: '123456789012', region: 'us-east-1' }, 28 | 29 | /* For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html */ 30 | }); -------------------------------------------------------------------------------- /overture-tiles-cdk/cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "npx ts-node --prefer-ts-exts bin/overture-tiles-cdk.ts", 3 | "watch": { 4 | "include": [ 5 | "**" 6 | ], 7 | "exclude": [ 8 | "README.md", 9 | "cdk*.json", 10 | "**/*.d.ts", 11 | "**/*.js", 12 | "tsconfig.json", 13 | "package*.json", 14 | "yarn.lock", 15 | "node_modules", 16 | "test" 17 | ] 18 | }, 19 | "context": { 20 | "@aws-cdk/aws-lambda:recognizeLayerVersion": true, 21 | "@aws-cdk/core:checkSecretUsage": true, 22 | "@aws-cdk/core:target-partitions": [ 23 | "aws", 24 | "aws-cn" 25 | ], 26 | "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, 27 | "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, 28 | "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true, 29 | "@aws-cdk/aws-iam:minimizePolicies": true, 30 | "@aws-cdk/core:validateSnapshotRemovalPolicy": true, 31 | "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true, 32 | "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true, 33 | "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true, 34 | "@aws-cdk/aws-apigateway:disableCloudWatchRole": true, 35 | "@aws-cdk/core:enablePartitionLiterals": true, 36 | "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true, 37 | "@aws-cdk/aws-iam:standardizedServicePrincipals": true, 38 | "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true, 39 | "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true, 40 | "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, 41 | "@aws-cdk/aws-route53-patters:useCertificate": true, 42 | "@aws-cdk/customresources:installLatestAwsSdkDefault": false, 43 | "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true, 44 | "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true, 45 | "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true, 46 | "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true, 47 | "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true, 48 | "@aws-cdk/aws-redshift:columnId": true, 49 | "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true, 50 | "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true, 51 | "@aws-cdk/aws-apigateway:requestValidatorUniqueId": true, 52 | "@aws-cdk/aws-kms:aliasNameRef": true, 53 | "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true, 54 | "@aws-cdk/core:includePrefixInUniqueNameGeneration": true, 55 | "@aws-cdk/aws-efs:denyAnonymousAccess": true, 56 | "@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true, 57 | "@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true, 58 | "@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true, 59 | "@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true, 60 | "@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true, 61 | "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true, 62 | "@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true, 63 | "@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true, 64 | "@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true, 65 | "@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true, 66 | "@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true, 67 | "@aws-cdk/aws-eks:nodegroupNameAttribute": true, 68 | "@aws-cdk/aws-ec2:ebsDefaultGp3Volume": true, 69 | "@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": true, 70 | "@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /overture-tiles-cdk/lib/overture-tiles-cdk-stack.ts: -------------------------------------------------------------------------------- 1 | import * as cdk from "aws-cdk-lib"; 2 | import { Construct } from "constructs"; 3 | import { aws_s3 as s3, aws_ec2 as ec2 } from "aws-cdk-lib"; 4 | import { 5 | aws_cloudfront as cloudfront, 6 | aws_cloudfront_origins as origins, 7 | } from "aws-cdk-lib"; 8 | import { aws_batch as batch, aws_ecs as ecs } from "aws-cdk-lib"; 9 | import { aws_iam as iam } from "aws-cdk-lib"; 10 | import { aws_ecr as ecr } from "aws-cdk-lib"; 11 | 12 | const ID = "OvertureTiles"; 13 | 14 | export type OvertureTilesCdkStackProps = cdk.StackProps & { 15 | bucketName: string; 16 | }; 17 | 18 | export class OvertureTilesCdkStack extends cdk.Stack { 19 | constructor(scope: Construct, id: string, props: OvertureTilesCdkStackProps) { 20 | super(scope, id, props); 21 | 22 | const userData = ec2.UserData.forLinux(); 23 | userData.addCommands( 24 | "#!/bin/bash", 25 | "volume_name=`lsblk -x SIZE -o NAME | tail -n 1`", 26 | "mkfs -t ext4 /dev/$volume_name", 27 | "mkdir /docker", 28 | "mount /dev/$volume_name /docker", 29 | 'echo \'{"data-root": "/docker"}\' > /etc/docker/daemon.json', 30 | "systemctl restart docker", 31 | ); 32 | 33 | const multipartUserData = new ec2.MultipartUserData(); 34 | multipartUserData.addPart(ec2.MultipartBody.fromUserData(userData)); 35 | 36 | const launchTemplate = new ec2.LaunchTemplate(this, `${ID}LaunchTemplate`, { 37 | machineImage: ecs.EcsOptimizedImage.amazonLinux2023( 38 | ecs.AmiHardwareType.ARM, 39 | ), 40 | userData: multipartUserData, 41 | }); 42 | 43 | const bucket = new s3.Bucket(this, `${ID}Bucket`, { 44 | bucketName: props.bucketName, 45 | blockPublicAccess: new s3.BlockPublicAccess({ 46 | blockPublicAcls: false, 47 | blockPublicPolicy: false, 48 | ignorePublicAcls: false, 49 | restrictPublicBuckets: false, 50 | }), 51 | publicReadAccess: true, 52 | cors: [ 53 | { 54 | allowedMethods: [s3.HttpMethods.GET], 55 | allowedOrigins: ["*"], 56 | }, 57 | ], 58 | }); 59 | bucket.applyRemovalPolicy(cdk.RemovalPolicy.RETAIN); 60 | 61 | const distribution = new cloudfront.Distribution( 62 | this, 63 | `${ID}Distribution`, 64 | { 65 | defaultBehavior: { 66 | origin: new origins.S3Origin(bucket), 67 | }, 68 | }, 69 | ); 70 | distribution.applyRemovalPolicy(cdk.RemovalPolicy.RETAIN); 71 | 72 | const repository = new ecr.Repository(this, `${ID}Repository`); 73 | 74 | const role = new iam.Role(this, `${ID}JobRole`, { 75 | assumedBy: new iam.ServicePrincipal("ecs-tasks.amazonaws.com"), 76 | }); 77 | 78 | role.addToPolicy( 79 | new iam.PolicyStatement({ 80 | actions: ["s3:PutObject", "s3:PutObjectAcl"], 81 | resources: [`${bucket.bucketArn}/*`], 82 | }), 83 | ); 84 | 85 | const executionRole = new iam.Role(this, `${ID}ExecutionRole`, { 86 | assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'), 87 | }); 88 | 89 | executionRole.addToPolicy( 90 | new iam.PolicyStatement({ 91 | actions: [ 92 | "logs:CreateLogStream", 93 | "logs:PutLogEvents", 94 | "sts:AssumeRole" 95 | ], 96 | resources: ["*"], 97 | }), 98 | ); 99 | 100 | executionRole.addManagedPolicy( 101 | iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonEC2ContainerRegistryReadOnly') 102 | ); 103 | 104 | for (let theme of [ 105 | "addresses", 106 | "admins", 107 | "places", 108 | "divisions", 109 | "buildings", 110 | "transportation", 111 | "base", 112 | ]) { 113 | new batch.EcsJobDefinition(this, `${ID}Job_${theme}`, { 114 | container: new batch.EcsEc2ContainerDefinition( 115 | this, 116 | `${ID}Container_${theme}`, 117 | { 118 | image: ecs.ContainerImage.fromRegistry( 119 | `${repository.repositoryUri}:latest`, 120 | ), 121 | memory: cdk.Size.gibibytes(60), 122 | cpu: 30, 123 | jobRole: role, 124 | executionRole: executionRole 125 | }, 126 | ), 127 | }); 128 | } 129 | 130 | const vpc = new ec2.Vpc(this, `${ID}Vpc`, { 131 | maxAzs: 1, 132 | }); 133 | 134 | new batch.JobQueue(this, `${ID}Queue`, { 135 | computeEnvironments: [ 136 | { 137 | computeEnvironment: new batch.ManagedEc2EcsComputeEnvironment( 138 | this, 139 | `${ID}ComputeEnvironment`, 140 | { 141 | vpc: vpc, 142 | spot: false, 143 | vpcSubnets: { subnetType: ec2.SubnetType.PUBLIC }, 144 | launchTemplate: launchTemplate, 145 | replaceComputeEnvironment: true, 146 | allocationStrategy: batch.AllocationStrategy.BEST_FIT, 147 | instanceTypes: [ 148 | ec2.InstanceType.of( 149 | ec2.InstanceClass.C7GD, 150 | ec2.InstanceSize.XLARGE8, 151 | ), 152 | ], 153 | useOptimalInstanceClasses: false, 154 | }, 155 | ), 156 | order: 1, 157 | }, 158 | ], 159 | }); 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /overture-tiles-cdk/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "overture-tiles-cdk", 3 | "version": "0.1.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "overture-tiles-cdk", 9 | "version": "0.1.0", 10 | "dependencies": { 11 | "aws-cdk-lib": "2.146.0", 12 | "constructs": "^10.0.0", 13 | "source-map-support": "^0.5.21" 14 | }, 15 | "bin": { 16 | "overture-tiles-cdk": "bin/overture-tiles-cdk.js" 17 | }, 18 | "devDependencies": { 19 | "@types/node": "20.12.7", 20 | "aws-cdk": "2.148.1", 21 | "ts-node": "^10.9.2", 22 | "typescript": "~5.4.5" 23 | } 24 | }, 25 | "node_modules/@aws-cdk/asset-awscli-v1": { 26 | "version": "2.2.202", 27 | "resolved": "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.202.tgz", 28 | "integrity": "sha512-JqlF0D4+EVugnG5dAsNZMqhu3HW7ehOXm5SDMxMbXNDMdsF0pxtQKNHRl52z1U9igsHmaFpUgSGjbhAJ+0JONg==", 29 | "license": "Apache-2.0" 30 | }, 31 | "node_modules/@aws-cdk/asset-kubectl-v20": { 32 | "version": "2.1.2", 33 | "resolved": "https://registry.npmjs.org/@aws-cdk/asset-kubectl-v20/-/asset-kubectl-v20-2.1.2.tgz", 34 | "integrity": "sha512-3M2tELJOxQv0apCIiuKQ4pAbncz9GuLwnKFqxifWfe77wuMxyTRPmxssYHs42ePqzap1LT6GDcPygGs+hHstLg==", 35 | "license": "Apache-2.0" 36 | }, 37 | "node_modules/@aws-cdk/asset-node-proxy-agent-v6": { 38 | "version": "2.0.3", 39 | "resolved": "https://registry.npmjs.org/@aws-cdk/asset-node-proxy-agent-v6/-/asset-node-proxy-agent-v6-2.0.3.tgz", 40 | "integrity": "sha512-twhuEG+JPOYCYPx/xy5uH2+VUsIEhPTzDY0F1KuB+ocjWWB/KEDiOVL19nHvbPCB6fhWnkykXEMJ4HHcKvjtvg==", 41 | "license": "Apache-2.0" 42 | }, 43 | "node_modules/@cspotcode/source-map-support": { 44 | "version": "0.8.1", 45 | "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", 46 | "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", 47 | "dev": true, 48 | "license": "MIT", 49 | "dependencies": { 50 | "@jridgewell/trace-mapping": "0.3.9" 51 | }, 52 | "engines": { 53 | "node": ">=12" 54 | } 55 | }, 56 | "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { 57 | "version": "0.3.9", 58 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", 59 | "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", 60 | "dev": true, 61 | "license": "MIT", 62 | "dependencies": { 63 | "@jridgewell/resolve-uri": "^3.0.3", 64 | "@jridgewell/sourcemap-codec": "^1.4.10" 65 | } 66 | }, 67 | "node_modules/@jridgewell/resolve-uri": { 68 | "version": "3.1.2", 69 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", 70 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", 71 | "dev": true, 72 | "license": "MIT", 73 | "engines": { 74 | "node": ">=6.0.0" 75 | } 76 | }, 77 | "node_modules/@jridgewell/sourcemap-codec": { 78 | "version": "1.4.15", 79 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", 80 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", 81 | "dev": true, 82 | "license": "MIT" 83 | }, 84 | "node_modules/@tsconfig/node10": { 85 | "version": "1.0.11", 86 | "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", 87 | "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", 88 | "dev": true, 89 | "license": "MIT" 90 | }, 91 | "node_modules/@tsconfig/node12": { 92 | "version": "1.0.11", 93 | "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", 94 | "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", 95 | "dev": true, 96 | "license": "MIT" 97 | }, 98 | "node_modules/@tsconfig/node14": { 99 | "version": "1.0.3", 100 | "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", 101 | "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", 102 | "dev": true, 103 | "license": "MIT" 104 | }, 105 | "node_modules/@tsconfig/node16": { 106 | "version": "1.0.4", 107 | "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", 108 | "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", 109 | "dev": true, 110 | "license": "MIT" 111 | }, 112 | "node_modules/@types/node": { 113 | "version": "20.12.7", 114 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", 115 | "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", 116 | "dev": true, 117 | "license": "MIT", 118 | "dependencies": { 119 | "undici-types": "~5.26.4" 120 | } 121 | }, 122 | "node_modules/acorn": { 123 | "version": "8.11.3", 124 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", 125 | "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", 126 | "dev": true, 127 | "license": "MIT", 128 | "bin": { 129 | "acorn": "bin/acorn" 130 | }, 131 | "engines": { 132 | "node": ">=0.4.0" 133 | } 134 | }, 135 | "node_modules/acorn-walk": { 136 | "version": "8.3.2", 137 | "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", 138 | "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", 139 | "dev": true, 140 | "license": "MIT", 141 | "engines": { 142 | "node": ">=0.4.0" 143 | } 144 | }, 145 | "node_modules/arg": { 146 | "version": "4.1.3", 147 | "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", 148 | "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", 149 | "dev": true, 150 | "license": "MIT" 151 | }, 152 | "node_modules/aws-cdk": { 153 | "version": "2.148.1", 154 | "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.148.1.tgz", 155 | "integrity": "sha512-wiAi4vFJ52A42PpU3zRi2gVDqbTXSBVFrqKRqEd8wYL1mqa0qMv9FR35NsgbM1RL9s7g5ZljYvl+G2tXpcp5Eg==", 156 | "dev": true, 157 | "bin": { 158 | "cdk": "bin/cdk" 159 | }, 160 | "engines": { 161 | "node": ">= 14.15.0" 162 | }, 163 | "optionalDependencies": { 164 | "fsevents": "2.3.2" 165 | } 166 | }, 167 | "node_modules/aws-cdk-lib": { 168 | "version": "2.146.0", 169 | "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.146.0.tgz", 170 | "integrity": "sha512-W3F2zH+P7hUxmu2dlEKJBBi6Twc4//NsJJW00h2LN0dKU+2302QY8jR+P7jgEYzZ7U50phtH4zO6BPmJrhLVEg==", 171 | "bundleDependencies": [ 172 | "@balena/dockerignore", 173 | "case", 174 | "fs-extra", 175 | "ignore", 176 | "jsonschema", 177 | "minimatch", 178 | "punycode", 179 | "semver", 180 | "table", 181 | "yaml", 182 | "mime-types" 183 | ], 184 | "license": "Apache-2.0", 185 | "dependencies": { 186 | "@aws-cdk/asset-awscli-v1": "^2.2.202", 187 | "@aws-cdk/asset-kubectl-v20": "^2.1.2", 188 | "@aws-cdk/asset-node-proxy-agent-v6": "^2.0.3", 189 | "@balena/dockerignore": "^1.0.2", 190 | "case": "1.6.3", 191 | "fs-extra": "^11.2.0", 192 | "ignore": "^5.3.1", 193 | "jsonschema": "^1.4.1", 194 | "mime-types": "^2.1.35", 195 | "minimatch": "^3.1.2", 196 | "punycode": "^2.3.1", 197 | "semver": "^7.6.2", 198 | "table": "^6.8.2", 199 | "yaml": "1.10.2" 200 | }, 201 | "engines": { 202 | "node": ">= 14.15.0" 203 | }, 204 | "peerDependencies": { 205 | "constructs": "^10.0.0" 206 | } 207 | }, 208 | "node_modules/aws-cdk-lib/node_modules/@balena/dockerignore": { 209 | "version": "1.0.2", 210 | "inBundle": true, 211 | "license": "Apache-2.0" 212 | }, 213 | "node_modules/aws-cdk-lib/node_modules/ajv": { 214 | "version": "8.16.0", 215 | "inBundle": true, 216 | "license": "MIT", 217 | "dependencies": { 218 | "fast-deep-equal": "^3.1.3", 219 | "json-schema-traverse": "^1.0.0", 220 | "require-from-string": "^2.0.2", 221 | "uri-js": "^4.4.1" 222 | }, 223 | "funding": { 224 | "type": "github", 225 | "url": "https://github.com/sponsors/epoberezkin" 226 | } 227 | }, 228 | "node_modules/aws-cdk-lib/node_modules/ansi-regex": { 229 | "version": "5.0.1", 230 | "inBundle": true, 231 | "license": "MIT", 232 | "engines": { 233 | "node": ">=8" 234 | } 235 | }, 236 | "node_modules/aws-cdk-lib/node_modules/ansi-styles": { 237 | "version": "4.3.0", 238 | "inBundle": true, 239 | "license": "MIT", 240 | "dependencies": { 241 | "color-convert": "^2.0.1" 242 | }, 243 | "engines": { 244 | "node": ">=8" 245 | }, 246 | "funding": { 247 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 248 | } 249 | }, 250 | "node_modules/aws-cdk-lib/node_modules/astral-regex": { 251 | "version": "2.0.0", 252 | "inBundle": true, 253 | "license": "MIT", 254 | "engines": { 255 | "node": ">=8" 256 | } 257 | }, 258 | "node_modules/aws-cdk-lib/node_modules/balanced-match": { 259 | "version": "1.0.2", 260 | "inBundle": true, 261 | "license": "MIT" 262 | }, 263 | "node_modules/aws-cdk-lib/node_modules/brace-expansion": { 264 | "version": "1.1.11", 265 | "inBundle": true, 266 | "license": "MIT", 267 | "dependencies": { 268 | "balanced-match": "^1.0.0", 269 | "concat-map": "0.0.1" 270 | } 271 | }, 272 | "node_modules/aws-cdk-lib/node_modules/case": { 273 | "version": "1.6.3", 274 | "inBundle": true, 275 | "license": "(MIT OR GPL-3.0-or-later)", 276 | "engines": { 277 | "node": ">= 0.8.0" 278 | } 279 | }, 280 | "node_modules/aws-cdk-lib/node_modules/color-convert": { 281 | "version": "2.0.1", 282 | "inBundle": true, 283 | "license": "MIT", 284 | "dependencies": { 285 | "color-name": "~1.1.4" 286 | }, 287 | "engines": { 288 | "node": ">=7.0.0" 289 | } 290 | }, 291 | "node_modules/aws-cdk-lib/node_modules/color-name": { 292 | "version": "1.1.4", 293 | "inBundle": true, 294 | "license": "MIT" 295 | }, 296 | "node_modules/aws-cdk-lib/node_modules/concat-map": { 297 | "version": "0.0.1", 298 | "inBundle": true, 299 | "license": "MIT" 300 | }, 301 | "node_modules/aws-cdk-lib/node_modules/emoji-regex": { 302 | "version": "8.0.0", 303 | "inBundle": true, 304 | "license": "MIT" 305 | }, 306 | "node_modules/aws-cdk-lib/node_modules/fast-deep-equal": { 307 | "version": "3.1.3", 308 | "inBundle": true, 309 | "license": "MIT" 310 | }, 311 | "node_modules/aws-cdk-lib/node_modules/fs-extra": { 312 | "version": "11.2.0", 313 | "inBundle": true, 314 | "license": "MIT", 315 | "dependencies": { 316 | "graceful-fs": "^4.2.0", 317 | "jsonfile": "^6.0.1", 318 | "universalify": "^2.0.0" 319 | }, 320 | "engines": { 321 | "node": ">=14.14" 322 | } 323 | }, 324 | "node_modules/aws-cdk-lib/node_modules/graceful-fs": { 325 | "version": "4.2.11", 326 | "inBundle": true, 327 | "license": "ISC" 328 | }, 329 | "node_modules/aws-cdk-lib/node_modules/ignore": { 330 | "version": "5.3.1", 331 | "inBundle": true, 332 | "license": "MIT", 333 | "engines": { 334 | "node": ">= 4" 335 | } 336 | }, 337 | "node_modules/aws-cdk-lib/node_modules/is-fullwidth-code-point": { 338 | "version": "3.0.0", 339 | "inBundle": true, 340 | "license": "MIT", 341 | "engines": { 342 | "node": ">=8" 343 | } 344 | }, 345 | "node_modules/aws-cdk-lib/node_modules/json-schema-traverse": { 346 | "version": "1.0.0", 347 | "inBundle": true, 348 | "license": "MIT" 349 | }, 350 | "node_modules/aws-cdk-lib/node_modules/jsonfile": { 351 | "version": "6.1.0", 352 | "inBundle": true, 353 | "license": "MIT", 354 | "dependencies": { 355 | "universalify": "^2.0.0" 356 | }, 357 | "optionalDependencies": { 358 | "graceful-fs": "^4.1.6" 359 | } 360 | }, 361 | "node_modules/aws-cdk-lib/node_modules/jsonschema": { 362 | "version": "1.4.1", 363 | "inBundle": true, 364 | "license": "MIT", 365 | "engines": { 366 | "node": "*" 367 | } 368 | }, 369 | "node_modules/aws-cdk-lib/node_modules/lodash.truncate": { 370 | "version": "4.4.2", 371 | "inBundle": true, 372 | "license": "MIT" 373 | }, 374 | "node_modules/aws-cdk-lib/node_modules/mime-db": { 375 | "version": "1.52.0", 376 | "inBundle": true, 377 | "license": "MIT", 378 | "engines": { 379 | "node": ">= 0.6" 380 | } 381 | }, 382 | "node_modules/aws-cdk-lib/node_modules/mime-types": { 383 | "version": "2.1.35", 384 | "inBundle": true, 385 | "license": "MIT", 386 | "dependencies": { 387 | "mime-db": "1.52.0" 388 | }, 389 | "engines": { 390 | "node": ">= 0.6" 391 | } 392 | }, 393 | "node_modules/aws-cdk-lib/node_modules/minimatch": { 394 | "version": "3.1.2", 395 | "inBundle": true, 396 | "license": "ISC", 397 | "dependencies": { 398 | "brace-expansion": "^1.1.7" 399 | }, 400 | "engines": { 401 | "node": "*" 402 | } 403 | }, 404 | "node_modules/aws-cdk-lib/node_modules/punycode": { 405 | "version": "2.3.1", 406 | "inBundle": true, 407 | "license": "MIT", 408 | "engines": { 409 | "node": ">=6" 410 | } 411 | }, 412 | "node_modules/aws-cdk-lib/node_modules/require-from-string": { 413 | "version": "2.0.2", 414 | "inBundle": true, 415 | "license": "MIT", 416 | "engines": { 417 | "node": ">=0.10.0" 418 | } 419 | }, 420 | "node_modules/aws-cdk-lib/node_modules/semver": { 421 | "version": "7.6.2", 422 | "inBundle": true, 423 | "license": "ISC", 424 | "bin": { 425 | "semver": "bin/semver.js" 426 | }, 427 | "engines": { 428 | "node": ">=10" 429 | } 430 | }, 431 | "node_modules/aws-cdk-lib/node_modules/slice-ansi": { 432 | "version": "4.0.0", 433 | "inBundle": true, 434 | "license": "MIT", 435 | "dependencies": { 436 | "ansi-styles": "^4.0.0", 437 | "astral-regex": "^2.0.0", 438 | "is-fullwidth-code-point": "^3.0.0" 439 | }, 440 | "engines": { 441 | "node": ">=10" 442 | }, 443 | "funding": { 444 | "url": "https://github.com/chalk/slice-ansi?sponsor=1" 445 | } 446 | }, 447 | "node_modules/aws-cdk-lib/node_modules/string-width": { 448 | "version": "4.2.3", 449 | "inBundle": true, 450 | "license": "MIT", 451 | "dependencies": { 452 | "emoji-regex": "^8.0.0", 453 | "is-fullwidth-code-point": "^3.0.0", 454 | "strip-ansi": "^6.0.1" 455 | }, 456 | "engines": { 457 | "node": ">=8" 458 | } 459 | }, 460 | "node_modules/aws-cdk-lib/node_modules/strip-ansi": { 461 | "version": "6.0.1", 462 | "inBundle": true, 463 | "license": "MIT", 464 | "dependencies": { 465 | "ansi-regex": "^5.0.1" 466 | }, 467 | "engines": { 468 | "node": ">=8" 469 | } 470 | }, 471 | "node_modules/aws-cdk-lib/node_modules/table": { 472 | "version": "6.8.2", 473 | "inBundle": true, 474 | "license": "BSD-3-Clause", 475 | "dependencies": { 476 | "ajv": "^8.0.1", 477 | "lodash.truncate": "^4.4.2", 478 | "slice-ansi": "^4.0.0", 479 | "string-width": "^4.2.3", 480 | "strip-ansi": "^6.0.1" 481 | }, 482 | "engines": { 483 | "node": ">=10.0.0" 484 | } 485 | }, 486 | "node_modules/aws-cdk-lib/node_modules/universalify": { 487 | "version": "2.0.1", 488 | "inBundle": true, 489 | "license": "MIT", 490 | "engines": { 491 | "node": ">= 10.0.0" 492 | } 493 | }, 494 | "node_modules/aws-cdk-lib/node_modules/uri-js": { 495 | "version": "4.4.1", 496 | "inBundle": true, 497 | "license": "BSD-2-Clause", 498 | "dependencies": { 499 | "punycode": "^2.1.0" 500 | } 501 | }, 502 | "node_modules/aws-cdk-lib/node_modules/yaml": { 503 | "version": "1.10.2", 504 | "inBundle": true, 505 | "license": "ISC", 506 | "engines": { 507 | "node": ">= 6" 508 | } 509 | }, 510 | "node_modules/buffer-from": { 511 | "version": "1.1.2", 512 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", 513 | "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", 514 | "license": "MIT" 515 | }, 516 | "node_modules/constructs": { 517 | "version": "10.3.0", 518 | "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.3.0.tgz", 519 | "integrity": "sha512-vbK8i3rIb/xwZxSpTjz3SagHn1qq9BChLEfy5Hf6fB3/2eFbrwt2n9kHwQcS0CPTRBesreeAcsJfMq2229FnbQ==", 520 | "license": "Apache-2.0", 521 | "engines": { 522 | "node": ">= 16.14.0" 523 | } 524 | }, 525 | "node_modules/create-require": { 526 | "version": "1.1.1", 527 | "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", 528 | "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", 529 | "dev": true, 530 | "license": "MIT" 531 | }, 532 | "node_modules/diff": { 533 | "version": "4.0.2", 534 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 535 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", 536 | "dev": true, 537 | "license": "BSD-3-Clause", 538 | "engines": { 539 | "node": ">=0.3.1" 540 | } 541 | }, 542 | "node_modules/fsevents": { 543 | "version": "2.3.2", 544 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 545 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 546 | "dev": true, 547 | "hasInstallScript": true, 548 | "license": "MIT", 549 | "optional": true, 550 | "os": [ 551 | "darwin" 552 | ], 553 | "engines": { 554 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 555 | } 556 | }, 557 | "node_modules/make-error": { 558 | "version": "1.3.6", 559 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", 560 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", 561 | "dev": true, 562 | "license": "ISC" 563 | }, 564 | "node_modules/source-map": { 565 | "version": "0.6.1", 566 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 567 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 568 | "license": "BSD-3-Clause", 569 | "engines": { 570 | "node": ">=0.10.0" 571 | } 572 | }, 573 | "node_modules/source-map-support": { 574 | "version": "0.5.21", 575 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", 576 | "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", 577 | "license": "MIT", 578 | "dependencies": { 579 | "buffer-from": "^1.0.0", 580 | "source-map": "^0.6.0" 581 | } 582 | }, 583 | "node_modules/ts-node": { 584 | "version": "10.9.2", 585 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", 586 | "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", 587 | "dev": true, 588 | "license": "MIT", 589 | "dependencies": { 590 | "@cspotcode/source-map-support": "^0.8.0", 591 | "@tsconfig/node10": "^1.0.7", 592 | "@tsconfig/node12": "^1.0.7", 593 | "@tsconfig/node14": "^1.0.0", 594 | "@tsconfig/node16": "^1.0.2", 595 | "acorn": "^8.4.1", 596 | "acorn-walk": "^8.1.1", 597 | "arg": "^4.1.0", 598 | "create-require": "^1.1.0", 599 | "diff": "^4.0.1", 600 | "make-error": "^1.1.1", 601 | "v8-compile-cache-lib": "^3.0.1", 602 | "yn": "3.1.1" 603 | }, 604 | "bin": { 605 | "ts-node": "dist/bin.js", 606 | "ts-node-cwd": "dist/bin-cwd.js", 607 | "ts-node-esm": "dist/bin-esm.js", 608 | "ts-node-script": "dist/bin-script.js", 609 | "ts-node-transpile-only": "dist/bin-transpile.js", 610 | "ts-script": "dist/bin-script-deprecated.js" 611 | }, 612 | "peerDependencies": { 613 | "@swc/core": ">=1.2.50", 614 | "@swc/wasm": ">=1.2.50", 615 | "@types/node": "*", 616 | "typescript": ">=2.7" 617 | }, 618 | "peerDependenciesMeta": { 619 | "@swc/core": { 620 | "optional": true 621 | }, 622 | "@swc/wasm": { 623 | "optional": true 624 | } 625 | } 626 | }, 627 | "node_modules/typescript": { 628 | "version": "5.4.5", 629 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", 630 | "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", 631 | "dev": true, 632 | "license": "Apache-2.0", 633 | "bin": { 634 | "tsc": "bin/tsc", 635 | "tsserver": "bin/tsserver" 636 | }, 637 | "engines": { 638 | "node": ">=14.17" 639 | } 640 | }, 641 | "node_modules/undici-types": { 642 | "version": "5.26.5", 643 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 644 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", 645 | "dev": true, 646 | "license": "MIT" 647 | }, 648 | "node_modules/v8-compile-cache-lib": { 649 | "version": "3.0.1", 650 | "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", 651 | "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", 652 | "dev": true, 653 | "license": "MIT" 654 | }, 655 | "node_modules/yn": { 656 | "version": "3.1.1", 657 | "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", 658 | "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", 659 | "dev": true, 660 | "license": "MIT", 661 | "engines": { 662 | "node": ">=6" 663 | } 664 | } 665 | } 666 | } 667 | -------------------------------------------------------------------------------- /overture-tiles-cdk/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "overture-tiles-cdk", 3 | "version": "0.1.0", 4 | "bin": { 5 | "overture-tiles-cdk": "bin/overture-tiles-cdk.js" 6 | }, 7 | "scripts": { 8 | "build": "tsc", 9 | "watch": "tsc -w", 10 | "cdk": "cdk" 11 | }, 12 | "devDependencies": { 13 | "@types/node": "20.12.7", 14 | "aws-cdk": "2.148.1", 15 | "ts-node": "^10.9.2", 16 | "typescript": "~5.4.5" 17 | }, 18 | "dependencies": { 19 | "aws-cdk-lib": "2.146.0", 20 | "constructs": "^10.0.0", 21 | "source-map-support": "^0.5.21" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /overture-tiles-cdk/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "commonjs", 5 | "lib": [ 6 | "es2020", 7 | "dom" 8 | ], 9 | "declaration": true, 10 | "strict": true, 11 | "noImplicitAny": true, 12 | "strictNullChecks": true, 13 | "noImplicitThis": true, 14 | "alwaysStrict": true, 15 | "noUnusedLocals": false, 16 | "noUnusedParameters": false, 17 | "noImplicitReturns": true, 18 | "noFallthroughCasesInSwitch": false, 19 | "inlineSourceMap": true, 20 | "inlineSources": true, 21 | "experimentalDecorators": true, 22 | "strictPropertyInitialization": false, 23 | "typeRoots": [ 24 | "./node_modules/@types" 25 | ] 26 | }, 27 | "exclude": [ 28 | "node_modules", 29 | "cdk.out" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /places.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Overture Places 4 | 5 | 6 | 7 | 8 | 9 | 10 | 27 | 28 | 29 |
30 |
31 | 34 | Filter by confidence >= 0.0 35 | 36 |
37 | 194 | 195 | 196 | -------------------------------------------------------------------------------- /profiles/.gitignore: -------------------------------------------------------------------------------- 1 | out/ 2 | -------------------------------------------------------------------------------- /profiles/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /profiles/.idea/libraries/planetiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /profiles/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /profiles/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /profiles/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /profiles/Addresses.java: -------------------------------------------------------------------------------- 1 | import com.onthegomap.planetiler.FeatureCollector; 2 | import com.onthegomap.planetiler.config.Arguments; 3 | import com.onthegomap.planetiler.reader.SourceFeature; 4 | 5 | public class Addresses implements OvertureProfile.Theme { 6 | 7 | @Override 8 | public void processFeature(SourceFeature source, FeatureCollector features) { 9 | String layer = source.getSourceLayer(); 10 | var point = features.point(layer).setMinZoom(14); 11 | OvertureProfile.addFullTags(source, point, 14); 12 | } 13 | 14 | @Override 15 | public String name() { 16 | return "addresses"; 17 | } 18 | 19 | public static void main(String[] args) throws Exception { 20 | OvertureProfile.run(Arguments.fromArgsOrConfigFile(args), new Addresses()); 21 | } 22 | } -------------------------------------------------------------------------------- /profiles/Base.java: -------------------------------------------------------------------------------- 1 | import com.onthegomap.planetiler.FeatureCollector; 2 | import com.onthegomap.planetiler.config.Arguments; 3 | import com.onthegomap.planetiler.reader.SourceFeature; 4 | 5 | public class Base implements OvertureProfile.Theme { 6 | final static int MAXZOOM = 13; 7 | 8 | @Override 9 | public void processFeature(SourceFeature source, FeatureCollector features) { 10 | String layer = source.getSourceLayer(); 11 | String clazz = source.getString("class"); 12 | var feature = OvertureProfile.createAnyFeature(source, features); 13 | if (layer.equals("infrastructure")) { 14 | feature.setMinZoom(13); 15 | OvertureProfile.addFullTags(source, feature, MAXZOOM); 16 | } else if (layer.equals("land")) { 17 | int minzoom = 7; 18 | if (source.isPoint()) { 19 | minzoom = 13; 20 | } else if (clazz.equals("land") || clazz.equals("glacier")) { 21 | minzoom = 0; 22 | } 23 | if (minzoom == 0) { 24 | feature.setMinPixelSize(0); 25 | } 26 | feature.setMinZoom(minzoom); 27 | OvertureProfile.addFullTags(source, feature, MAXZOOM); 28 | } else if (layer.equals("bathymetry")) { 29 | feature.setMinPixelSize(0); 30 | feature.setMinZoom(0); 31 | OvertureProfile.addFullTags(source, feature, MAXZOOM); 32 | } else if (layer.equals("land_use")) { 33 | int minzoom = 9; 34 | if (source.isPoint()) { 35 | minzoom = 13; 36 | } else if (clazz.equals("residential")) { 37 | minzoom = 6; 38 | } 39 | feature.setMinZoom(minzoom); 40 | OvertureProfile.addFullTags(source, feature, MAXZOOM); 41 | } else if (layer.equals("land_cover")) { 42 | var cartography = source.getStruct("cartography"); 43 | var minZoom = cartography.get("min_zoom").asInt(); 44 | feature.setMaxZoom(cartography.get("max_zoom").asInt()); 45 | feature.setMinZoom(minZoom); 46 | OvertureProfile.addFullTags(source, feature, minZoom); 47 | } else if (layer.equals("water")) { 48 | int minzoom = 13; 49 | if (source.isPoint()) { 50 | if (clazz.equals("ocean")) { 51 | minzoom = 0; 52 | } else { 53 | minzoom = 8; 54 | } 55 | } else { 56 | if (clazz.equals("ocean")) { 57 | minzoom = 0; 58 | } 59 | if (clazz.equals("lake") || clazz.equals("reservoir")) { 60 | minzoom = 4; 61 | } else if (clazz.equals("river")) { 62 | minzoom = 9; 63 | } else if (clazz.equals("canal")) { 64 | minzoom = 12; 65 | } else if (clazz.equals("stream")) { 66 | minzoom = 13; 67 | } 68 | } 69 | feature.setMinZoom(minzoom); 70 | if (minzoom == 0) { 71 | feature.setMinPixelSize(0); 72 | } 73 | OvertureProfile.addFullTags(source, feature, MAXZOOM); 74 | } 75 | } 76 | 77 | 78 | @Override 79 | public String name() { 80 | return "base"; 81 | } 82 | 83 | public static void main(String[] args) throws Exception { 84 | OvertureProfile.run(Arguments.fromArgsOrConfigFile(args).orElse(Arguments.of("maxzoom", MAXZOOM)), new Base()); 85 | } 86 | } 87 | 88 | -------------------------------------------------------------------------------- /profiles/Buildings.java: -------------------------------------------------------------------------------- 1 | import com.onthegomap.planetiler.FeatureCollector; 2 | import com.onthegomap.planetiler.config.Arguments; 3 | import com.onthegomap.planetiler.reader.SourceFeature; 4 | import com.onthegomap.planetiler.reader.parquet.ParquetFeature; 5 | import org.apache.parquet.schema.MessageType; 6 | 7 | public class Buildings implements OvertureProfile.Theme { 8 | 9 | @Override 10 | public void processFeature(SourceFeature source, FeatureCollector features) { 11 | String layer = source.getSourceLayer(); 12 | var polygon = features.polygon(layer); 13 | 14 | if (source instanceof ParquetFeature pf) { 15 | var sources = pf.getStruct("sources").asList(); 16 | 17 | // set @height_source helper 18 | sources.stream().filter(s -> s.get("property").asString().equals("properties/height")).findFirst().ifPresentOrElse( 19 | s -> polygon.setAttr("@height_source", s.get("dataset")), 20 | () -> { 21 | if (pf.hasTag("height")) { 22 | sources.stream().filter(s -> s.get("property").asString().isEmpty()).findFirst().ifPresent( 23 | s -> polygon.setAttr("@height_source", s.get("dataset")) 24 | ); 25 | } 26 | } 27 | ); 28 | 29 | // set @geometry_source helper 30 | sources.stream().filter(s -> s.get("property").asString().equals("properties/geometry")).findFirst().ifPresentOrElse( 31 | s -> polygon.setAttr("@geometry_source", s.get("dataset")), 32 | () -> { 33 | sources.stream().filter(s -> s.get("property").asString().isEmpty()).findFirst().ifPresent( 34 | s -> polygon.setAttr("@geometry_source", s.get("dataset")) 35 | ); 36 | } 37 | ); 38 | } 39 | 40 | OvertureProfile.addFullTags(source, polygon, 14); 41 | } 42 | 43 | @Override 44 | public String name() { 45 | return "buildings"; 46 | } 47 | 48 | public static void main(String[] args) throws Exception { 49 | OvertureProfile.run(Arguments.fromArgsOrConfigFile(args), new Buildings()); 50 | } 51 | } -------------------------------------------------------------------------------- /profiles/OvertureProfile.java: -------------------------------------------------------------------------------- 1 | import com.onthegomap.planetiler.FeatureCollector; 2 | import com.onthegomap.planetiler.Planetiler; 3 | import com.onthegomap.planetiler.Profile; 4 | import com.onthegomap.planetiler.config.Arguments; 5 | import com.onthegomap.planetiler.reader.SourceFeature; 6 | import com.onthegomap.planetiler.util.Glob; 7 | import com.onthegomap.planetiler.reader.parquet.ParquetFeature; 8 | import org.apache.parquet.schema.MessageType; 9 | 10 | import java.nio.file.Path; 11 | import java.util.List; 12 | 13 | public class OvertureProfile implements Profile { 14 | 15 | public interface Theme { 16 | void processFeature(SourceFeature source, FeatureCollector features); 17 | 18 | String name(); 19 | } 20 | 21 | private Theme theme; 22 | 23 | public OvertureProfile(Theme theme) { 24 | this.theme = theme; 25 | } 26 | 27 | protected static void addFullTags(SourceFeature source, FeatureCollector.Feature feature, int minZoomToShowAlways) { 28 | if (source instanceof ParquetFeature pf) { 29 | MessageType schema = pf.parquetSchema(); 30 | for (var field : schema.getFields()) { 31 | var name = field.getName(); 32 | if (!pf.hasTag(name)) continue; 33 | if (name.equals("bbox") || name.equals("geometry")) continue; 34 | if (name.equals("names")) { 35 | var names = pf.getStruct("names"); 36 | if (names.get("rules").isNull() || (names.get("rules").asList().size() == 1 && names.get("rules").get(0).get("between").isNull())) { 37 | var primaryName = pf.getStruct("names").get("primary"); 38 | feature.setAttrWithMinSize("@name", primaryName, 16, 0, minZoomToShowAlways); 39 | } 40 | } 41 | if (field.isPrimitive()) { 42 | feature.inheritAttrFromSource(name); 43 | feature.setAttrWithMinSize(name, source.getTag(name), 16, 0, minZoomToShowAlways); 44 | } else { 45 | feature.setAttrWithMinSize(name, source.getStruct(name).asJson(), 16, 0, minZoomToShowAlways); 46 | } 47 | } 48 | } 49 | } 50 | 51 | protected static FeatureCollector.Feature createAnyFeature(SourceFeature feature, 52 | FeatureCollector features) { 53 | return feature.isPoint() ? features.point(feature.getSourceLayer()) : 54 | feature.canBePolygon() ? features.polygon(feature.getSourceLayer()) : 55 | features.line(feature.getSourceLayer()); 56 | } 57 | 58 | @Override 59 | public void processFeature(SourceFeature source, FeatureCollector features) { 60 | this.theme.processFeature(source, features); 61 | } 62 | 63 | @Override 64 | public boolean isOverlay() { 65 | return true; 66 | } 67 | 68 | @Override 69 | public String name() { 70 | return "Overture " + this.theme.name(); 71 | } 72 | 73 | @Override 74 | public String description() { 75 | return "A tileset generated from Overture data"; 76 | } 77 | 78 | @Override 79 | public String attribution() { 80 | return """ 81 | © OpenStreetMap 82 | © Overture Maps Foundation 83 | """ 84 | .replace("\n", " ") 85 | .trim(); 86 | } 87 | 88 | static void run(Arguments args, Theme theme) throws Exception { 89 | Path base = args.inputFile("data", "overture base directory", Path.of("data", "overture")); 90 | var paths = Glob.of(base).resolve("theme=" + theme.name(), "*", "*.parquet").find(); 91 | Planetiler.create(args) 92 | .setProfile(new OvertureProfile(theme)) 93 | .addParquetSource("overture", 94 | paths, 95 | true, // hive-partitioning 96 | fields -> fields.get("id"), // hash the ID field to generate unique long IDs 97 | fields -> fields.get("type")) // extract "type={}" from the filename to get layer 98 | .overwriteOutput(Path.of("data", theme.name() + ".pmtiles")) 99 | .run(); 100 | } 101 | } -------------------------------------------------------------------------------- /profiles/Transportation.java: -------------------------------------------------------------------------------- 1 | import com.onthegomap.planetiler.FeatureCollector; 2 | import com.onthegomap.planetiler.config.Arguments; 3 | import com.onthegomap.planetiler.reader.SourceFeature; 4 | 5 | public class Transportation implements OvertureProfile.Theme { 6 | 7 | @Override 8 | public void processFeature(SourceFeature source, FeatureCollector features) { 9 | String layer = source.getSourceLayer(); 10 | String clazz = source.getString("class"); 11 | String subtype = source.getString("subtype"); 12 | if (layer.equals("connector")) { 13 | var point = features.point(layer); 14 | point.setMinZoom(13); 15 | OvertureProfile.addFullTags(source, point, 14); 16 | } else if (layer.equals("segment")) { 17 | int minzoom = switch (subtype) { 18 | case "road" -> switch (clazz) { 19 | case "motorway" -> 4; 20 | case "trunk" -> 5; 21 | case "primary" -> 7; 22 | case "secondary" -> 9; 23 | case "tertiary" -> 11; 24 | case "residential" -> 12; 25 | case "living_street" -> 13; 26 | default -> 14; 27 | }; 28 | case "rail" -> 8; 29 | case "water" -> 10; 30 | default -> 10; 31 | }; 32 | var line = features.line(layer); 33 | line.setMinZoom(minzoom); 34 | line.setMinPixelSize(0); 35 | OvertureProfile.addFullTags(source, line, 14); 36 | } 37 | } 38 | 39 | @Override 40 | public String name() { 41 | return "transportation"; 42 | } 43 | 44 | public static void main(String[] args) throws Exception { 45 | OvertureProfile.run(Arguments.fromArgsOrConfigFile(args), new Transportation()); 46 | } 47 | } -------------------------------------------------------------------------------- /profiles/profiles.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | set -u 3 | set -x 4 | 5 | # Automation script for running inside Docker on AWS Batch. 6 | 7 | RELEASE_DATA=$1 8 | BUCKET=$2 9 | THEME=$3 10 | 11 | # The most recent major version used in the /scripts directory 12 | SCRIPTS_VERSION="2024-07-22" 13 | 14 | # Trim the patch version: 2024-06-13-beta.1 -> 2024-06-13-beta 15 | RELEASE_TILESET="${RELEASE_DATA%%.*}" 16 | 17 | # Download the full theme to /data. 18 | aws s3 sync --no-progress --region us-west-2 --no-sign-request s3://overturemaps-us-west-2/release/$RELEASE_DATA/theme=$THEME /data/theme=$THEME 19 | 20 | # Tile and upload the theme to the target bucket. 21 | if [ "$THEME" == "admins" ] || [ "$THEME" == "places" ] || [ "$THEME" == "divisions" ]; then 22 | # Target a specific set of release scripts for generating tiles 23 | if test -d scripts/$RELEASE_TILESET/$THEME.sh; then 24 | bash scripts/$RELEASE_TILESET/$THEME.sh /data $THEME.pmtiles 25 | # Generate tiles using the latest release scripts 26 | else 27 | bash scripts/$SCRIPTS_VERSION/$THEME.sh /data $THEME.pmtiles 28 | fi 29 | 30 | aws s3 cp --no-progress $THEME.pmtiles s3://$BUCKET/$RELEASE_TILESET/$THEME.pmtiles 31 | else 32 | className="${THEME^}" 33 | java -cp planetiler.jar /profiles/$className.java --data=/data 34 | aws s3 cp --no-progress /data/$THEME.pmtiles s3://$BUCKET/$RELEASE_TILESET/$THEME.pmtiles 35 | fi 36 | -------------------------------------------------------------------------------- /scripts/2024-04-16-beta/divisions.filter.json: -------------------------------------------------------------------------------- 1 | { 2 | "*": [ 3 | "all", 4 | ["attribute-filter", "id", [">=", "$zoom", 9]], 5 | ["attribute-filter", "divisions", [">=", "$zoom", 9]], 6 | ["attribute-filter", "version", [">=", "$zoom", 9]], 7 | ["attribute-filter", "update_time", [">=", "$zoom", 9]], 8 | ["attribute-filter", "sources", [">=", "$zoom", 9]], 9 | ["attribute-filter", "country", [">=", "$zoom", 9]], 10 | ["attribute-filter", "region", [">=", "$zoom", 9]], 11 | ["attribute-filter", "hierarchies", [">=", "$zoom", 9]], 12 | ["attribute-filter", "parent_division_id", [">=", "$zoom", 9]], 13 | ["attribute-filter", "perspectives", [">=", "$zoom", 9]], 14 | ["attribute-filter", "norms", [">=", "$zoom", 9]], 15 | ["attribute-filter", "population", [">=", "$zoom", 9]], 16 | ["attribute-filter", "capital_division_id", [">=", "$zoom", 9]], 17 | ["attribute-filter", "wikidata", [">=", "$zoom", 9]], 18 | ["attribute-filter", "names", [">=", "$zoom", 9]] 19 | ] 20 | } -------------------------------------------------------------------------------- /scripts/2024-04-16-beta/divisions.sh: -------------------------------------------------------------------------------- 1 | duckdb -c " 2 | load spatial; 3 | load httpfs; 4 | set s3_region='us-west-2'; 5 | 6 | COPY ( 7 | (SELECT 8 | 'Feature' AS type, 9 | json(st_asgeojson(st_geomfromwkb(geometry))) AS geometry, 10 | json_object( 11 | 'layer', 'boundary', 12 | 'minzoom', CASE WHEN subtype = 'country' THEN 0 WHEN subtype = 'region' THEN 4 WHEN subtype = 'county' THEN 8 ELSE 10 END 13 | ) as tippecanoe, 14 | json_object( 15 | 'id', id, 16 | 'subtype', subtype, 17 | 'class', class, 18 | 'divisions', divisions, 19 | 'version', version, 20 | 'update_time', update_time, 21 | 'sources', sources 22 | ) AS properties, 23 | row_number() over () as id 24 | FROM read_parquet('/srv/data/overture/2024-04-16-beta.0/theme=divisions/type=boundary/*')) 25 | UNION ALL 26 | (SELECT 27 | 'Feature' AS type, 28 | json(st_asgeojson(st_geomfromwkb(geometry))) AS geometry, 29 | json_object( 30 | 'layer', 'division', 31 | 'minzoom', CASE WHEN subtype = 'country' THEN 0 WHEN subtype = 'region' THEN 4 WHEN subtype = 'county' THEN 8 ELSE 10 END 32 | ) as tippecanoe, 33 | json_object( 34 | 'id', id, 35 | '@name', json_extract_string(names, '$.primary'), 36 | 'subtype', subtype, 37 | 'country', country, 38 | 'region', region, 39 | 'hierarchies', hierarchies, 40 | 'parent_division_id', parent_division_id, 41 | 'perspectives', perspectives, 42 | 'norms', norms, 43 | 'population', population, 44 | 'capital_division_id', capital_division_id, 45 | 'wikidata', wikidata, 46 | 'names', names, 47 | 'version', version, 48 | 'update_time', update_time, 49 | 'sources', sources 50 | ) AS properties, 51 | row_number() over () as id 52 | FROM read_parquet('/srv/data/overture/2024-04-16-beta.0/theme=divisions/type=division/*')) 53 | UNION ALL 54 | (SELECT 55 | 'Feature' AS type, 56 | json(st_asgeojson(st_geomfromwkb(geometry))) AS geometry, 57 | json_object( 58 | 'layer', 'division_area', 59 | 'minzoom', CASE WHEN subtype = 'country' THEN 0 WHEN subtype = 'region' THEN 4 WHEN subtype = 'county' THEN 8 ELSE 10 END 60 | ) as tippecanoe, 61 | json_object( 62 | 'id', id, 63 | 'subtype', subtype, 64 | 'class', class, 65 | 'division_id', division_id, 66 | 'country', country, 67 | 'region', region, 68 | 'names', names, 69 | 'version', version, 70 | 'update_time', update_time, 71 | 'sources', sources 72 | ) AS properties, 73 | row_number() over () as id 74 | FROM read_parquet('s3://overturemaps-us-west-2/release/2024-05-16-beta.0/theme=divisions/type=division_area/*')) 75 | ) TO STDOUT (FORMAT json); 76 | " | tippecanoe -o $1 -J divisions.filter.json --force --drop-densest-as-needed -z 12 77 | 78 | -------------------------------------------------------------------------------- /scripts/2024-04-16-beta/places.filter.json: -------------------------------------------------------------------------------- 1 | { 2 | "places": [ 3 | "all", 4 | ["attribute-filter", "@name", [">=", "$zoom", 14]], 5 | ["attribute-filter", "id", [">=", "$zoom", 14]], 6 | ["attribute-filter", "names", [">=", "$zoom", 14]], 7 | ["attribute-filter", "categories", [">=", "$zoom", 14]], 8 | ["attribute-filter", "websites", [">=", "$zoom", 14]], 9 | ["attribute-filter", "socials", [">=", "$zoom", 14]], 10 | ["attribute-filter", "emails", [">=", "$zoom", 14]], 11 | ["attribute-filter", "phones", [">=", "$zoom", 14]], 12 | ["attribute-filter", "brand", [">=", "$zoom", 14]], 13 | ["attribute-filter", "addresses", [">=", "$zoom", 14]], 14 | ["attribute-filter", "version", [">=", "$zoom", 14]], 15 | ["attribute-filter", "update_time", [">=", "$zoom", 14]], 16 | ["attribute-filter", "sources", [">=", "$zoom", 14]] 17 | ] 18 | } -------------------------------------------------------------------------------- /scripts/2024-04-16-beta/places.sh: -------------------------------------------------------------------------------- 1 | duckdb -c " 2 | load spatial; 3 | load httpfs; 4 | set s3_region='us-west-2'; 5 | 6 | COPY ( 7 | SELECT 8 | 'Feature' AS type, 9 | json(st_asgeojson(st_geomfromwkb(geometry))) AS geometry, 10 | json_object( 11 | 'id', id, 12 | '@name', json_extract_string(names, '$.primary'), 13 | '@category', json_extract_string(categories, '$.main'), 14 | 'names', names, 15 | 'confidence', confidence, 16 | 'categories', categories, 17 | 'websites', websites, 18 | 'socials', socials, 19 | 'emails', emails, 20 | 'phones', phones, 21 | 'brand', brand, 22 | 'addresses', addresses, 23 | 'version', version, 24 | 'update_time', update_time, 25 | 'sources', sources 26 | ) AS properties, 27 | row_number() over () as id, 28 | FROM read_parquet('/srv/data/overture/2024-04-16-beta.0/theme=places/type=place/*') 29 | ) TO STDOUT (FORMAT json); 30 | " | tippecanoe -o $1 --force -J places.filter.json -l places -rg --drop-densest-as-needed 31 | 32 | -------------------------------------------------------------------------------- /scripts/2024-05-16-beta/divisions.filter.json: -------------------------------------------------------------------------------- 1 | { 2 | "*": [ 3 | "all", 4 | ["attribute-filter", "id", [">=", "$zoom", 9]], 5 | ["attribute-filter", "divisions", [">=", "$zoom", 9]], 6 | ["attribute-filter", "version", [">=", "$zoom", 9]], 7 | ["attribute-filter", "update_time", [">=", "$zoom", 9]], 8 | ["attribute-filter", "sources", [">=", "$zoom", 9]], 9 | ["attribute-filter", "local_type", [">=", "$zoom", 9]], 10 | ["attribute-filter", "country", [">=", "$zoom", 9]], 11 | ["attribute-filter", "region", [">=", "$zoom", 9]], 12 | ["attribute-filter", "hierarchies", [">=", "$zoom", 9]], 13 | ["attribute-filter", "parent_division_id", [">=", "$zoom", 9]], 14 | ["attribute-filter", "perspectives", [">=", "$zoom", 9]], 15 | ["attribute-filter", "norms", [">=", "$zoom", 9]], 16 | ["attribute-filter", "population", [">=", "$zoom", 9]], 17 | ["attribute-filter", "capital_division_id", [">=", "$zoom", 9]], 18 | ["attribute-filter", "wikidata", [">=", "$zoom", 9]], 19 | ["attribute-filter", "names", [">=", "$zoom", 9]] 20 | ] 21 | } -------------------------------------------------------------------------------- /scripts/2024-05-16-beta/divisions.sh: -------------------------------------------------------------------------------- 1 | duckdb -c " 2 | load spatial; 3 | load httpfs; 4 | set s3_region='us-west-2'; 5 | 6 | COPY ( 7 | (SELECT 8 | 'Feature' AS type, 9 | json(st_asgeojson(st_geomfromwkb(geometry))) AS geometry, 10 | json_object( 11 | 'layer', 'boundary', 12 | 'minzoom', CASE WHEN subtype = 'country' THEN 0 WHEN subtype = 'region' THEN 4 WHEN subtype = 'county' THEN 8 ELSE 10 END 13 | ) as tippecanoe, 14 | json_object( 15 | 'id', id, 16 | 'subtype', subtype, 17 | 'class', class, 18 | 'divisions', divisions, 19 | 'version', version, 20 | 'update_time', update_time, 21 | 'sources', sources 22 | ) AS properties, 23 | row_number() over () as id 24 | FROM read_parquet('/srv/data/overture/2024-05-16-beta.0/theme=divisions/type=boundary/*')) 25 | UNION ALL 26 | (SELECT 27 | 'Feature' AS type, 28 | json(st_asgeojson(st_geomfromwkb(geometry))) AS geometry, 29 | json_object( 30 | 'layer', 'division', 31 | 'minzoom', CASE WHEN subtype = 'country' THEN 0 WHEN subtype = 'region' THEN 4 WHEN subtype = 'county' THEN 8 ELSE 10 END 32 | ) as tippecanoe, 33 | json_object( 34 | 'id', id, 35 | '@name', json_extract_string(names, '$.primary'), 36 | 'subtype', subtype, 37 | 'local_type', local_type, 38 | 'country', country, 39 | 'region', region, 40 | 'hierarchies', hierarchies, 41 | 'parent_division_id', parent_division_id, 42 | 'perspectives', perspectives, 43 | 'norms', norms, 44 | 'population', population, 45 | 'capital_division_id', capital_division_id, 46 | 'wikidata', wikidata, 47 | 'names', names, 48 | 'version', version, 49 | 'update_time', update_time, 50 | 'sources', sources 51 | ) AS properties, 52 | row_number() over () as id 53 | FROM read_parquet('/srv/data/overture/2024-05-16-beta.0/theme=divisions/type=division/*')) 54 | UNION ALL 55 | (SELECT 56 | 'Feature' AS type, 57 | json(st_asgeojson(st_geomfromwkb(geometry))) AS geometry, 58 | json_object( 59 | 'layer', 'division_area', 60 | 'minzoom', CASE WHEN subtype = 'country' THEN 0 WHEN subtype = 'region' THEN 4 WHEN subtype = 'county' THEN 8 ELSE 10 END 61 | ) as tippecanoe, 62 | json_object( 63 | 'id', id, 64 | 'subtype', subtype, 65 | 'class', class, 66 | 'division_id', division_id, 67 | 'country', country, 68 | 'region', region, 69 | 'names', names, 70 | 'version', version, 71 | 'update_time', update_time, 72 | 'sources', sources 73 | ) AS properties, 74 | row_number() over () as id 75 | FROM read_parquet('/srv/data/overture/2024-05-16-beta.0/theme=divisions/type=division_area/*')) 76 | ) TO STDOUT (FORMAT json); 77 | " | tippecanoe -o $1 -J divisions.filter.json --force --drop-densest-as-needed -z 12 78 | 79 | -------------------------------------------------------------------------------- /scripts/2024-05-16-beta/places.filter.json: -------------------------------------------------------------------------------- 1 | { 2 | "place": [ 3 | "all", 4 | ["attribute-filter", "@name", [">=", "$zoom", 14]], 5 | ["attribute-filter", "id", [">=", "$zoom", 14]], 6 | ["attribute-filter", "names", [">=", "$zoom", 14]], 7 | ["attribute-filter", "categories", [">=", "$zoom", 14]], 8 | ["attribute-filter", "websites", [">=", "$zoom", 14]], 9 | ["attribute-filter", "socials", [">=", "$zoom", 14]], 10 | ["attribute-filter", "emails", [">=", "$zoom", 14]], 11 | ["attribute-filter", "phones", [">=", "$zoom", 14]], 12 | ["attribute-filter", "brand", [">=", "$zoom", 14]], 13 | ["attribute-filter", "addresses", [">=", "$zoom", 14]], 14 | ["attribute-filter", "version", [">=", "$zoom", 14]], 15 | ["attribute-filter", "update_time", [">=", "$zoom", 14]], 16 | ["attribute-filter", "sources", [">=", "$zoom", 14]] 17 | ] 18 | } -------------------------------------------------------------------------------- /scripts/2024-05-16-beta/places.sh: -------------------------------------------------------------------------------- 1 | duckdb -c " 2 | load spatial; 3 | 4 | COPY ( 5 | SELECT 6 | 'Feature' AS type, 7 | json(st_asgeojson(st_geomfromwkb(geometry))) AS geometry, 8 | json_object( 9 | 'id', id, 10 | '@name', json_extract_string(names, '$.primary'), 11 | '@category', json_extract_string(categories, '$.main'), 12 | 'names', names, 13 | 'confidence', confidence, 14 | 'categories', categories, 15 | 'websites', websites, 16 | 'socials', socials, 17 | 'emails', emails, 18 | 'phones', phones, 19 | 'brand', brand, 20 | 'addresses', addresses, 21 | 'version', version, 22 | 'update_time', update_time, 23 | 'sources', sources 24 | ) AS properties, 25 | row_number() over () as id, 26 | FROM read_parquet('/srv/data/overture/2024-05-16-beta.0/theme=places/type=place/*') 27 | ) TO STDOUT (FORMAT json); 28 | " | tippecanoe -o $1 --force -J places.filter.json -l place -rg --drop-densest-as-needed 29 | 30 | -------------------------------------------------------------------------------- /scripts/2024-06-13-beta/admins.filter.json: -------------------------------------------------------------------------------- 1 | { 2 | "*": [ 3 | "all", 4 | ["attribute-filter", "id", [">=", "$zoom", 9]], 5 | ["attribute-filter", "admin_level", [">=", "$zoom", 9]], 6 | ["attribute-filter", "is_maritime", [">=", "$zoom", 9]], 7 | ["attribute-filter", "geopol_display", [">=", "$zoom", 9]], 8 | ["attribute-filter", "version", [">=", "$zoom", 9]], 9 | ["attribute-filter", "update_time", [">=", "$zoom", 9]], 10 | ["attribute-filter", "sources", [">=", "$zoom", 9]], 11 | ["attribute-filter", "names", [">=", "$zoom", 9]], 12 | ["attribute-filter", "locality_type", [">=", "$zoom", 9]], 13 | ["attribute-filter", "wikidata", [">=", "$zoom", 9]], 14 | ["attribute-filter", "context_id", [">=", "$zoom", 9]], 15 | ["attribute-filter", "population", [">=", "$zoom", 9]], 16 | ["attribute-filter", "locality_id", [">=", "$zoom", 9]] 17 | ] 18 | } -------------------------------------------------------------------------------- /scripts/2024-06-13-beta/admins.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | set -u 3 | set -o pipefail 4 | 5 | SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) 6 | 7 | duckdb -c " 8 | load spatial; 9 | set s3_region='us-west-2'; 10 | 11 | COPY ( 12 | (SELECT 13 | 'Feature' AS type, 14 | json(st_asgeojson(st_geomfromwkb(geometry))) AS geometry, 15 | json_object( 16 | 'layer', 'administrative_boundary', 17 | 'minzoom', CASE WHEN admin_level = 2 THEN 0 WHEN admin_level = 2 THEN 4 WHEN admin_level = 3 THEN 8 ELSE 10 END 18 | ) as tippecanoe, 19 | json_object( 20 | 'id', id, 21 | 'admin_level', admin_level, 22 | 'is_maritime', is_maritime, 23 | 'geopol_display', geopol_display, 24 | 'version', version, 25 | 'update_time', update_time, 26 | 'sources', sources 27 | ) AS properties, 28 | row_number() over () as id 29 | FROM read_parquet('$1/theme=admins/type=administrative_boundary/*')) 30 | UNION ALL 31 | (SELECT 32 | 'Feature' AS type, 33 | json(st_asgeojson(st_geomfromwkb(geometry))) AS geometry, 34 | json_object( 35 | 'layer', 'locality', 36 | 'minzoom', CASE WHEN locality_type = 'country' THEN 0 WHEN locality_type = 'region' THEN 4 WHEN locality_type = 'county' THEN 8 ELSE 10 END 37 | ) as tippecanoe, 38 | json_object( 39 | 'id', id, 40 | '@name', json_extract_string(names, '$.primary'), 41 | 'names', names, 42 | 'subtype', subtype, 43 | 'locality_type', locality_type, 44 | 'wikidata', wikidata, 45 | 'context_id', context_id, 46 | 'population', population, 47 | 'version', version, 48 | 'update_time', update_time, 49 | 'sources', sources 50 | ) AS properties, 51 | row_number() over () as id 52 | FROM read_parquet('$1/theme=admins/type=locality/*')) 53 | UNION ALL 54 | (SELECT 55 | 'Feature' AS type, 56 | json(st_asgeojson(st_geomfromwkb(geometry))) AS geometry, 57 | json_object( 58 | 'layer', 'locality_area' 59 | ) as tippecanoe, 60 | json_object( 61 | 'id', id, 62 | 'locality_id', locality_id, 63 | 'version', version, 64 | 'update_time', update_time, 65 | 'sources', sources 66 | ) AS properties, 67 | row_number() over () as id 68 | FROM read_parquet('$1/theme=admins/type=locality_area/*')) 69 | ) TO STDOUT (FORMAT json); 70 | " | tippecanoe -o $2 -J $SCRIPT_DIR/admins.filter.json --force --drop-densest-as-needed -z 12 --progress-interval=10 71 | -------------------------------------------------------------------------------- /scripts/2024-06-13-beta/divisions.filter.json: -------------------------------------------------------------------------------- 1 | { 2 | "*": [ 3 | "all", 4 | ["attribute-filter", "id", [">=", "$zoom", 9]], 5 | ["attribute-filter", "divisions", [">=", "$zoom", 9]], 6 | ["attribute-filter", "version", [">=", "$zoom", 9]], 7 | ["attribute-filter", "update_time", [">=", "$zoom", 9]], 8 | ["attribute-filter", "sources", [">=", "$zoom", 9]], 9 | ["attribute-filter", "local_type", [">=", "$zoom", 9]], 10 | ["attribute-filter", "country", [">=", "$zoom", 9]], 11 | ["attribute-filter", "region", [">=", "$zoom", 9]], 12 | ["attribute-filter", "hierarchies", [">=", "$zoom", 9]], 13 | ["attribute-filter", "parent_division_id", [">=", "$zoom", 9]], 14 | ["attribute-filter", "perspectives", [">=", "$zoom", 9]], 15 | ["attribute-filter", "norms", [">=", "$zoom", 9]], 16 | ["attribute-filter", "population", [">=", "$zoom", 9]], 17 | ["attribute-filter", "capital_division_ids", [">=", "$zoom", 9]], 18 | ["attribute-filter", "wikidata", [">=", "$zoom", 9]], 19 | ["attribute-filter", "names", [">=", "$zoom", 9]] 20 | ] 21 | } -------------------------------------------------------------------------------- /scripts/2024-06-13-beta/divisions.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | set -u 3 | set -o pipefail 4 | 5 | SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) 6 | 7 | duckdb -c " 8 | load spatial; 9 | 10 | COPY ( 11 | (SELECT 12 | 'Feature' AS type, 13 | json(st_asgeojson(st_geomfromwkb(geometry))) AS geometry, 14 | json_object( 15 | 'layer', 'boundary', 16 | 'minzoom', CASE WHEN subtype = 'country' THEN 0 WHEN subtype = 'region' THEN 4 WHEN subtype = 'county' THEN 8 ELSE 10 END 17 | ) as tippecanoe, 18 | json_object( 19 | 'id', id, 20 | 'subtype', subtype, 21 | 'class', class, 22 | 'divisions', divisions, 23 | 'version', version, 24 | 'update_time', update_time, 25 | 'sources', sources 26 | ) AS properties, 27 | row_number() over () as id 28 | FROM read_parquet('$1/theme=divisions/type=boundary/*')) 29 | UNION ALL 30 | (SELECT 31 | 'Feature' AS type, 32 | json(st_asgeojson(st_geomfromwkb(geometry))) AS geometry, 33 | json_object( 34 | 'layer', 'division', 35 | 'minzoom', CASE WHEN subtype = 'country' THEN 0 WHEN subtype = 'region' THEN 4 WHEN subtype = 'county' THEN 8 ELSE 10 END 36 | ) as tippecanoe, 37 | json_object( 38 | 'id', id, 39 | '@name', json_extract_string(names, '$.primary'), 40 | 'subtype', subtype, 41 | 'local_type', local_type, 42 | 'country', country, 43 | 'region', region, 44 | 'hierarchies', hierarchies, 45 | 'parent_division_id', parent_division_id, 46 | 'perspectives', perspectives, 47 | 'norms', norms, 48 | 'population', population, 49 | 'capital_division_ids', capital_division_ids, 50 | 'wikidata', wikidata, 51 | 'names', names, 52 | 'version', version, 53 | 'update_time', update_time, 54 | 'sources', sources 55 | ) AS properties, 56 | row_number() over () as id 57 | FROM read_parquet('$1/theme=divisions/type=division/*')) 58 | UNION ALL 59 | (SELECT 60 | 'Feature' AS type, 61 | json(st_asgeojson(st_geomfromwkb(geometry))) AS geometry, 62 | json_object( 63 | 'layer', 'division_area', 64 | 'minzoom', CASE WHEN subtype = 'country' THEN 0 WHEN subtype = 'region' THEN 4 WHEN subtype = 'county' THEN 8 ELSE 10 END 65 | ) as tippecanoe, 66 | json_object( 67 | 'id', id, 68 | 'subtype', subtype, 69 | 'class', class, 70 | 'division_id', division_id, 71 | 'country', country, 72 | 'region', region, 73 | 'names', names, 74 | 'version', version, 75 | 'update_time', update_time, 76 | 'sources', sources 77 | ) AS properties, 78 | row_number() over () as id 79 | FROM read_parquet('$1/theme=divisions/type=division_area/*')) 80 | ) TO STDOUT (FORMAT json); 81 | " | tippecanoe -o $2 -J $SCRIPT_DIR/divisions.filter.json --force --drop-densest-as-needed -z 12 --progress-interval=10 82 | 83 | -------------------------------------------------------------------------------- /scripts/2024-06-13-beta/places.filter.json: -------------------------------------------------------------------------------- 1 | { 2 | "place": [ 3 | "all", 4 | ["attribute-filter", "@name", [">=", "$zoom", 14]], 5 | ["attribute-filter", "id", [">=", "$zoom", 14]], 6 | ["attribute-filter", "names", [">=", "$zoom", 14]], 7 | ["attribute-filter", "categories", [">=", "$zoom", 14]], 8 | ["attribute-filter", "websites", [">=", "$zoom", 14]], 9 | ["attribute-filter", "socials", [">=", "$zoom", 14]], 10 | ["attribute-filter", "emails", [">=", "$zoom", 14]], 11 | ["attribute-filter", "phones", [">=", "$zoom", 14]], 12 | ["attribute-filter", "brand", [">=", "$zoom", 14]], 13 | ["attribute-filter", "addresses", [">=", "$zoom", 14]], 14 | ["attribute-filter", "version", [">=", "$zoom", 14]], 15 | ["attribute-filter", "update_time", [">=", "$zoom", 14]], 16 | ["attribute-filter", "sources", [">=", "$zoom", 14]] 17 | ] 18 | } -------------------------------------------------------------------------------- /scripts/2024-06-13-beta/places.sh: -------------------------------------------------------------------------------- 1 | SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) 2 | 3 | set -e 4 | set -u 5 | set -o pipefail 6 | duckdb -c " 7 | load spatial; 8 | 9 | COPY ( 10 | SELECT 11 | 'Feature' AS type, 12 | json(st_asgeojson(st_geomfromwkb(geometry))) AS geometry, 13 | json_object( 14 | 'id', id, 15 | '@name', json_extract_string(names, '$.primary'), 16 | '@category', json_extract_string(categories, '$.main'), 17 | 'names', names, 18 | 'confidence', confidence, 19 | 'categories', categories, 20 | 'websites', websites, 21 | 'socials', socials, 22 | 'emails', emails, 23 | 'phones', phones, 24 | 'brand', brand, 25 | 'addresses', addresses, 26 | 'version', version, 27 | 'update_time', update_time, 28 | 'sources', sources 29 | ) AS properties, 30 | row_number() over () as id, 31 | FROM read_parquet('$1/theme=places/type=place/*') 32 | ) TO STDOUT (FORMAT json); 33 | " | tippecanoe -o $2 --force -J $SCRIPT_DIR/places.filter.json -l place -rg --drop-densest-as-needed --extend-zooms-if-still-dropping --maximum-tile-bytes=2500000 --progress-interval=10 34 | -------------------------------------------------------------------------------- /scripts/2024-07-22/divisions.filter.json: -------------------------------------------------------------------------------- 1 | { 2 | "*": [ 3 | "all", 4 | ["attribute-filter", "id", [">=", "$zoom", 9]], 5 | ["attribute-filter", "division_ids", [">=", "$zoom", 9]], 6 | ["attribute-filter", "version", [">=", "$zoom", 9]], 7 | ["attribute-filter", "sources", [">=", "$zoom", 9]], 8 | ["attribute-filter", "local_type", [">=", "$zoom", 9]], 9 | ["attribute-filter", "country", [">=", "$zoom", 9]], 10 | ["attribute-filter", "region", [">=", "$zoom", 9]], 11 | ["attribute-filter", "hierarchies", [">=", "$zoom", 9]], 12 | ["attribute-filter", "parent_division_id", [">=", "$zoom", 9]], 13 | ["attribute-filter", "perspectives", [">=", "$zoom", 9]], 14 | ["attribute-filter", "norms", [">=", "$zoom", 9]], 15 | ["attribute-filter", "population", [">=", "$zoom", 9]], 16 | ["attribute-filter", "capital_division_ids", [">=", "$zoom", 9]], 17 | ["attribute-filter", "wikidata", [">=", "$zoom", 9]], 18 | ["attribute-filter", "names", [">=", "$zoom", 9]] 19 | ] 20 | } -------------------------------------------------------------------------------- /scripts/2024-07-22/divisions.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | set -u 3 | set -o pipefail 4 | 5 | SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) 6 | 7 | duckdb -c " 8 | load spatial; 9 | 10 | COPY ( 11 | (SELECT 12 | 'Feature' AS type, 13 | json(st_asgeojson(st_geomfromwkb(geometry))) AS geometry, 14 | json_object( 15 | 'layer', 'division_boundary', 16 | 'minzoom', CASE WHEN (subtype = 'country' OR subtype = 'dependency') THEN 0 WHEN subtype = 'region' THEN 4 WHEN subtype = 'county' THEN 8 ELSE 10 END 17 | ) as tippecanoe, 18 | json_object( 19 | 'id', id, 20 | 'subtype', subtype, 21 | 'class', class, 22 | 'division_ids', division_ids, 23 | 'version', version, 24 | 'sources', sources 25 | ) AS properties, 26 | row_number() over () as id 27 | FROM read_parquet('$1/theme=divisions/type=division_boundary/*')) 28 | UNION ALL 29 | (SELECT 30 | 'Feature' AS type, 31 | json(st_asgeojson(st_geomfromwkb(geometry))) AS geometry, 32 | json_object( 33 | 'layer', 'division', 34 | 'minzoom', CASE WHEN (subtype = 'country' OR subtype = 'dependency') THEN 0 WHEN subtype = 'region' THEN 4 WHEN subtype = 'county' THEN 8 ELSE 10 END 35 | ) as tippecanoe, 36 | json_object( 37 | 'id', id, 38 | '@name', json_extract_string(names, '$.primary'), 39 | 'subtype', subtype, 40 | 'local_type', local_type, 41 | 'country', country, 42 | 'region', region, 43 | 'hierarchies', hierarchies, 44 | 'parent_division_id', parent_division_id, 45 | 'perspectives', perspectives, 46 | 'norms', norms, 47 | 'population', population, 48 | 'capital_division_ids', capital_division_ids, 49 | 'wikidata', wikidata, 50 | 'names', names, 51 | 'version', version, 52 | 'sources', sources 53 | ) AS properties, 54 | row_number() over () as id 55 | FROM read_parquet('$1/theme=divisions/type=division/*')) 56 | UNION ALL 57 | (SELECT 58 | 'Feature' AS type, 59 | json(st_asgeojson(st_geomfromwkb(geometry))) AS geometry, 60 | json_object( 61 | 'layer', 'division_area', 62 | 'minzoom', CASE WHEN (subtype = 'country' OR subtype = 'dependency') THEN 0 WHEN subtype = 'region' THEN 4 WHEN subtype = 'county' THEN 8 ELSE 10 END 63 | ) as tippecanoe, 64 | json_object( 65 | 'id', id, 66 | 'subtype', subtype, 67 | 'class', class, 68 | 'division_id', division_id, 69 | 'country', country, 70 | 'region', region, 71 | 'names', names, 72 | 'version', version, 73 | 'sources', sources 74 | ) AS properties, 75 | row_number() over () as id 76 | FROM read_parquet('$1/theme=divisions/type=division_area/*')) 77 | ) TO STDOUT (FORMAT json); 78 | " | tippecanoe -o $2 -J $SCRIPT_DIR/divisions.filter.json --force --drop-densest-as-needed -z 12 --progress-interval=10 79 | 80 | -------------------------------------------------------------------------------- /scripts/2024-07-22/places.filter.json: -------------------------------------------------------------------------------- 1 | { 2 | "place": [ 3 | "all", 4 | ["attribute-filter", "@name", [">=", "$zoom", 14]], 5 | ["attribute-filter", "id", [">=", "$zoom", 14]], 6 | ["attribute-filter", "names", [">=", "$zoom", 14]], 7 | ["attribute-filter", "categories", [">=", "$zoom", 14]], 8 | ["attribute-filter", "websites", [">=", "$zoom", 14]], 9 | ["attribute-filter", "socials", [">=", "$zoom", 14]], 10 | ["attribute-filter", "emails", [">=", "$zoom", 14]], 11 | ["attribute-filter", "phones", [">=", "$zoom", 14]], 12 | ["attribute-filter", "brand", [">=", "$zoom", 14]], 13 | ["attribute-filter", "addresses", [">=", "$zoom", 14]], 14 | ["attribute-filter", "version", [">=", "$zoom", 14]], 15 | ["attribute-filter", "sources", [">=", "$zoom", 14]] 16 | ] 17 | } -------------------------------------------------------------------------------- /scripts/2024-07-22/places.sh: -------------------------------------------------------------------------------- 1 | SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) 2 | 3 | set -e 4 | set -u 5 | set -o pipefail 6 | duckdb -c " 7 | load spatial; 8 | 9 | COPY ( 10 | SELECT 11 | 'Feature' AS type, 12 | json(st_asgeojson(st_geomfromwkb(geometry))) AS geometry, 13 | json_object( 14 | 'id', id, 15 | '@name', json_extract_string(names, '$.primary'), 16 | '@category', json_extract_string(categories, '$.main'), 17 | 'names', names, 18 | 'confidence', confidence, 19 | 'categories', categories, 20 | 'websites', websites, 21 | 'socials', socials, 22 | 'emails', emails, 23 | 'phones', phones, 24 | 'brand', brand, 25 | 'addresses', addresses, 26 | 'version', version, 27 | 'sources', sources 28 | ) AS properties, 29 | row_number() over () as id, 30 | FROM read_parquet('$1/theme=places/type=place/*') 31 | ) TO STDOUT (FORMAT json); 32 | " | tippecanoe -o $2 --force -J $SCRIPT_DIR/places.filter.json -l place -rg --drop-densest-as-needed --extend-zooms-if-still-dropping --maximum-tile-bytes=2500000 --progress-interval=10 33 | --------------------------------------------------------------------------------