提交 74ac51e4705b7c7ca4c183ee6dda089baf29ffea

作者 nheweijun
0 个父辈

init

正在显示 112 个修改的文件 包含 9654 行增加0 行删除
  1 +*.pyc
  2 +app.db
  3 +./tmp
  4 +./build/*
  5 +.idea
  6 +env
  7 +venv
  8 +.venv/
  9 +.venv
  10 +*.sublime*
  11 +tmp
  12 +tmp/
  13 +
  14 +venv/
  15 +whls/
  16 +tmp/
  17 +depoly/
  18 +logs/
  19 +*.pyc
  20 +__pycache__/
  21 +
  22 +instance/
  23 +
  24 +.pytest_cache/
  25 +.coverage
  26 +htmlcov/
  27 +kservice/tmp
  28 +dist/
  29 +build/
  30 +*.egg-info/
  31 +.git/
  1 +
  2 +
  1 +import decimal
  2 +
  3 +from flask import Flask as _Flask
  4 +from flask.json import JSONEncoder as _JSONEncoder
  5 +from flask_cors import CORS
  6 +import time
  7 +import configure
  8 +from app.util import BlueprintApi
  9 +from app.util import find_class
  10 +from app.models import db,Table,InsertingLayerName,Database,DES,Task
  11 +
  12 +from flasgger import Swagger
  13 +# from rtree import index
  14 +import logging
  15 +from sqlalchemy.orm import Session
  16 +import multiprocessing
  17 +from app.util.component.EntryData import EntryData
  18 +from app.util.component.EntryDataVacuate import EntryDataVacuate
  19 +import json
  20 +import threading
  21 +import traceback
  22 +from sqlalchemy import distinct
  23 +import uuid
  24 +from osgeo.ogr import DataSource
  25 +import datetime
  26 +from sqlalchemy import or_
  27 +from app.util.component.StructuredPrint import StructurePrint
  28 +from app.util.component.PGUtil import PGUtil
  29 +import os
  30 +
  31 +"""
  32 +因为decimal不能序列化,增加Flask对decimal类的解析
  33 +"""
  34 +class JSONEncoder(_JSONEncoder):
  35 + def default(self, o):
  36 + if isinstance(o, decimal.Decimal):
  37 + return float(o)
  38 + super(JSONEncoder, self).default(o)
  39 +
  40 +class Flask(_Flask):
  41 + json_encoder = JSONEncoder
  42 +
  43 +
  44 +# idx =None
  45 +# url_json_list=None
  46 +# sqlite3_connect= None
  47 +def create_app():
  48 +
  49 + # app基本设置
  50 + app = Flask(__name__)
  51 + app.config['SQLALCHEMY_DATABASE_URI'] = configure.SQLALCHEMY_DATABASE_URI
  52 + app.config['echo'] = True
  53 + app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
  54 + app.config['JSON_AS_ASCII'] = False
  55 + # app.config['SQLALCHEMY_ECHO'] = True
  56 +
  57 + # 跨域设置
  58 + CORS(app)
  59 +
  60 + #swagger设置
  61 + swagger_config = Swagger.DEFAULT_CONFIG
  62 + swagger_config.update(configure.swagger_configure)
  63 + Swagger(app, config=swagger_config)
  64 +
  65 + # 创建数据库
  66 + db.init_app(app)
  67 + db.create_all(app=app)
  68 +
  69 +
  70 + # 日志
  71 + logging.basicConfig(level=logging.INFO)
  72 + log_file = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))),"logs","log.txt")
  73 + handler = logging.FileHandler(log_file, encoding='UTF-8') # 设置日志字符集和存储路径名字
  74 + logging_format = logging.Formatter('[%(levelname)s] %(asctime)s %(message)s')
  75 + handler.setFormatter(logging_format)
  76 + app.logger.addHandler(handler)
  77 +
  78 +
  79 + # 注册blueprint,查找BlueprintApi的子类
  80 + for scan in configure.scan_module:
  81 + for api in find_class(scan, BlueprintApi):
  82 + app.register_blueprint(api.bp)
  83 +
  84 +
  85 + # 入库监测线程
  86 + @app.before_first_request
  87 + def data_entry_process():
  88 + StructurePrint.print("start listen")
  89 + process = threading.Thread(target=data_entry_center)
  90 + process.start()
  91 +
  92 + return app
  93 +
  94 +
  95 +
  96 +
  97 +def data_entry_center():
  98 + running_dict = {}
  99 + sys_session: Session = PGUtil.get_db_session(configure.SQLALCHEMY_DATABASE_URI)
  100 +
  101 + while True:
  102 +
  103 +
  104 + try:
  105 + time.sleep(3)
  106 +
  107 + # 已经结束的进程 从监测中删除
  108 + remove_process = []
  109 +
  110 + # structured_print(running_dict.__len__().__str__())
  111 +
  112 + for process,layer_names in running_dict.items():
  113 + if not process.is_alive():
  114 + for l in layer_names:
  115 + inserted = sys_session.query(InsertingLayerName).filter_by(name=l).one_or_none()
  116 + if inserted:
  117 + sys_session.delete(inserted)
  118 + sys_session.commit()
  119 + remove_process.append(process)
  120 + for process in remove_process:
  121 + running_dict.pop(process)
  122 +
  123 + # StructurePrint.print("listening...")
  124 +
  125 + # 入库进程少于阈值,开启入库进程
  126 +
  127 + inter_size = sys_session.query(distinct(InsertingLayerName.task_guid)).count()
  128 +
  129 + if inter_size < configure.entry_data_thread:
  130 + # 锁表啊
  131 + ready_task:Task = sys_session.query(Task).filter_by(state=0).order_by(Task.create_time).with_lockmode("update").limit(1).one_or_none()
  132 + if ready_task:
  133 +
  134 + try:
  135 + parameter = json.loads(ready_task.parameter)
  136 + StructurePrint.print("检测到入库任务")
  137 + ready_task.state=2
  138 + ready_task.process="入库中"
  139 + sys_session.commit()
  140 +
  141 + metas: list = json.loads(parameter.get("meta").__str__())
  142 + parameter["meta"] = metas
  143 +
  144 +
  145 + database = sys_session.query(Database).filter_by(guid=ready_task.database_guid).one_or_none()
  146 + pg_ds: DataSource = PGUtil.open_pg_data_source(1,DES.decode(database.sqlalchemy_uri))
  147 +
  148 + this_task_layer = []
  149 + for meta in metas:
  150 + overwrite = parameter.get("overwrite", "no")
  151 +
  152 +
  153 +
  154 + for layer_name_origin, layer_name in meta.get("layer").items():
  155 + origin_name = layer_name
  156 + no = 1
  157 +
  158 + while (overwrite.__eq__("no") and pg_ds.GetLayerByName(layer_name)) or sys_session.query(InsertingLayerName).filter_by(name=layer_name).one_or_none() :
  159 + layer_name = origin_name + "_{}".format(no)
  160 + no += 1
  161 +
  162 + # 添加到正在入库的列表中
  163 + iln = InsertingLayerName(guid=uuid.uuid1().__str__(),
  164 + task_guid=ready_task.guid,
  165 + name=layer_name)
  166 +
  167 + sys_session.add(iln)
  168 + sys_session.commit()
  169 + this_task_layer.append(layer_name)
  170 + # 修改表名
  171 + meta["layer"][layer_name_origin] = layer_name
  172 +
  173 + pg_ds.Destroy()
  174 + entry_data_process = multiprocessing.Process(target=EntryDataVacuate().entry,args=(parameter,))
  175 + entry_data_process.start()
  176 + running_dict[entry_data_process] = this_task_layer
  177 + except Exception as e:
  178 + sys_session.query(Task).filter_by(guid=ready_task.guid).update(
  179 + {"state": -1, "process": "入库失败"})
  180 + sys_session.commit()
  181 + StructurePrint.print(e.__str__(), "error")
  182 + else:
  183 + # 解表啊
  184 + sys_session.commit()
  185 + except Exception as e:
  186 + sys_session.commit()
  187 + StructurePrint.print(e.__str__(),"error")
  1 +# coding=utf-8
  2 +import base64
  3 +import os
  4 +from flask_sqlalchemy import SQLAlchemy,Model
  5 +import importlib
  6 +from sqlalchemy import Column, Integer, String, ForeignKey, Text, DateTime, Time,Float
  7 +from sqlalchemy.orm import relationship
  8 +import base64
  9 +from pyDes import *
  10 +import datetime
  11 +
  12 +from app.util.component.PGUtil import PGUtil
  13 +import glob
  14 +
  15 +class DES():
  16 + '''
  17 + DES密码加解密
  18 + '''
  19 + Des: des = des("Chinadci", ECB, "\0\0\0\0\0\0\0\0", pad=None, padmode=PAD_PKCS5)
  20 +
  21 + @classmethod
  22 + def encode(cls, data):
  23 + return str(base64.b64encode(cls.Des.encrypt(data)), encoding="utf8")
  24 +
  25 +
  26 + @classmethod
  27 + def decode(cls, data):
  28 + if data:
  29 + return str(cls.Des.decrypt(base64.b64decode(data.encode("utf-8"))), encoding="utf8")
  30 +
  31 + else:
  32 + return data
  33 +
  34 +db = SQLAlchemy()
  35 +
  36 +# 动态加载Model
  37 +module_dir = "modules"
  38 +model_pkg = "models"
  39 +current_dir = os.path.abspath(os.path.dirname(__file__))
  40 +for pkg in glob.glob('%s/%s/*/%s' % (current_dir,module_dir,model_pkg)) :
  41 + module = os.path.basename(os.path.dirname(pkg))
  42 + base_name = os.path.basename(pkg).split('.')[0]
  43 + pkg_name = ".".join(["app.modules",module,base_name])
  44 + try:
  45 + __import__(pkg_name)
  46 + except:
  47 + pass
  48 +
  49 +
  50 +
  51 +class Table(db.Model):
  52 + '''
  53 + 数据表元数据
  54 + '''
  55 + __tablename__ = 'dmdms_table'
  56 + guid = Column(String(256), primary_key=True)
  57 + # 数据源外键
  58 + database_guid = Column(String(256), ForeignKey('dmdms_database.guid'))
  59 +
  60 + # 点线面123
  61 + table_type = Column(Integer)
  62 +
  63 + name = Column(String(256))
  64 + alias = Column(Text)
  65 + create_time = Column(DateTime)
  66 + update_time = Column(DateTime)
  67 +
  68 + feature_count = Column(Integer)
  69 +
  70 + description = Column(Text)
  71 + extent = Column(Text)
  72 +
  73 + #用户
  74 + creator = Column(Text)
  75 +
  76 + # 目录外键
  77 + catalog_guid = Column(String(256), ForeignKey('dmdms_catalog.guid'))
  78 +
  79 + relate_columns = relationship('Columns', backref='relate_table', lazy='dynamic')
  80 + relate_table_vacuates = relationship('TableVacuate', backref='relate_table', lazy='dynamic')
  81 +
  82 +
  83 +class TableVacuate(db.Model):
  84 + '''
  85 + sub数据表元数据
  86 + '''
  87 + __tablename__ = 'dmdms_table_vacuate'
  88 + guid = Column(String(256), primary_key=True)
  89 + name = Column(String(256))
  90 + level = Column(Integer)
  91 + pixel_distance = Column(Float)
  92 + table_guid = Column(String(256), ForeignKey('dmdms_table.guid'))
  93 +
  94 +
  95 +
  96 +class Columns(db.Model):
  97 + '''
  98 + 数据表的列
  99 + '''
  100 + __tablename__ = 'dmdms_column'
  101 + guid = Column(String(256), primary_key=True)
  102 + # 表外键
  103 + table_guid= Column(String(256), ForeignKey('dmdms_table.guid'))
  104 + name=Column(String(256))
  105 + alias = Column(String(256))
  106 + create_time = Column(DateTime)
  107 + update_time = Column(DateTime)
  108 +
  109 +class Task(db.Model):
  110 + '''
  111 + 任务表
  112 + '''
  113 + __tablename__ = 'dmdms_task'
  114 + guid = Column(String(256), primary_key=True)
  115 + name = Column(Text)
  116 + process = Column(Text)
  117 + create_time = Column(DateTime)
  118 + update_time = Column(DateTime)
  119 + state = Column(Integer)
  120 + # 数据源外键
  121 + database_guid = Column(String(256), ForeignKey('dmdms_database.guid'))
  122 + # 目录外键
  123 + catalog_guid = Column(String(256), ForeignKey('dmdms_catalog.guid'))
  124 +
  125 + creator = Column(Text)
  126 + file_name = Column(Text)
  127 +
  128 + relate_processes = relationship('Process', backref='relate_task', lazy='dynamic')
  129 +
  130 + # 入库参数
  131 + parameter= Column(Text)
  132 +
  133 +
  134 +
  135 +class Process(db.Model):
  136 + '''
  137 + 过程信息表
  138 + '''
  139 + __tablename__ = 'dmdms_process'
  140 + guid = Column(String(256), primary_key=True)
  141 + # 任务外键
  142 + task_guid = Column(String(256), ForeignKey('dmdms_task.guid'))
  143 + time = Column(DateTime)
  144 + message = Column(Text)
  145 +
  146 +
  147 +class Catalog(db.Model):
  148 + '''
  149 + 目录表
  150 + '''
  151 + __tablename__ = 'dmdms_catalog'
  152 + guid = Column(String(256), primary_key=True)
  153 + database_guid = Column(String(256), ForeignKey('dmdms_database.guid'))
  154 + pguid = Column(String(256))
  155 + path = Column(Text)
  156 + name = Column(String(256))
  157 + sort = Column(Integer)
  158 + description = Column(Text)
  159 + relate_tables = relationship('Table', backref='relate_catalog', lazy='dynamic')
  160 + relate_tasks = relationship('Task', backref='relate_catalog', lazy='dynamic')
  161 +
  162 +class Database(db.Model):
  163 + '''
  164 + 数据源表
  165 + '''
  166 + __tablename__ = 'dmdms_database'
  167 + guid = Column(String(256), primary_key=True)
  168 + name = Column(String(256))
  169 + alias = Column(String(256))
  170 + sqlalchemy_uri = Column(String(256))
  171 + description = Column(Text)
  172 + # 唯一性约束,不能注册相同连接的库
  173 + connectstr= Column(Text,unique=True)
  174 +
  175 + creator = Column(String(256))
  176 +
  177 + create_time = Column(DateTime)
  178 + update_time = Column(DateTime)
  179 +
  180 + relate_catalogs = relationship('Catalog', backref='relate_database', lazy='dynamic')
  181 + relate_tables = relationship('Table', backref='relate_database', lazy='dynamic')
  182 + relate_tasks = relationship('Task', backref='relate_database', lazy='dynamic')
  183 +
  184 +
  185 +
  186 +class InsertingLayerName(db.Model):
  187 + '''
  188 + 正在入库的数据
  189 + '''
  190 + __tablename__ = 'dmdms_iln'
  191 + guid = Column(String(256), primary_key=True)
  192 + task_guid = Column(String(256))
  193 + name = Column(String(256))
  194 +
  1 +# coding=utf-8
  2 +# author: 4N
  3 +# createtime: 2020/8/27
  4 +# email: nheweijun@sina.com
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/3/1
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +from flasgger import swag_from
  8 +from flask import Blueprint
  9 +from app.util import BlueprintApi
  10 +from . import catalog_create
  11 +from . import catalog_next
  12 +from . import catalog_tree
  13 +from . import catalog_delete
  14 +from . import catalog_edit
  15 +from . import catalog_real_tree
  16 +
  17 +
  18 +class DataManager(BlueprintApi):
  19 +
  20 + bp = Blueprint("Category", __name__, url_prefix="/API/Category")
  21 +
  22 +
  23 + @staticmethod
  24 + @bp.route('/Create', methods=['POST'])
  25 + @swag_from(catalog_create.Api.api_doc)
  26 + def catalog_create():
  27 + """
  28 + 创建目录
  29 + """
  30 + return catalog_create.Api().result
  31 +
  32 + @staticmethod
  33 + @bp.route('/Next', methods=['POST'])
  34 + @swag_from(catalog_next.Api.api_doc)
  35 + def catalog_next():
  36 + """
  37 + 下一级目录
  38 + """
  39 + return catalog_next.Api().result
  40 +
  41 + @staticmethod
  42 + @bp.route('/Tree', methods=['POST'])
  43 + @swag_from(catalog_tree.Api.api_doc)
  44 + def catalog_tree():
  45 + """
  46 + 目录树
  47 + """
  48 + return catalog_tree.Api().result
  49 +
  50 +
  51 + @staticmethod
  52 + @bp.route('/RealTree', methods=['POST'])
  53 + @swag_from(catalog_real_tree.Api.api_doc)
  54 + def catalog_real_tree():
  55 + """
  56 + 目录树
  57 + """
  58 + return catalog_real_tree.Api().result
  59 +
  60 +
  61 + @staticmethod
  62 + @bp.route('/Edit', methods=['POST'])
  63 + @swag_from(catalog_edit.Api.api_doc)
  64 + def catalog_edit():
  65 + """
  66 + 修改目录
  67 + """
  68 + return catalog_edit.Api().result
  69 +
  70 + @staticmethod
  71 + @bp.route('/Delete', methods=['POST'])
  72 + @swag_from(catalog_delete.Api.api_doc)
  73 + def catalog_delete():
  74 + """
  75 + 删除目录
  76 + """
  77 + return catalog_delete.Api().result
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/3/9
  4 +#email: nheweijun@sina.com
  5 +
  6 +import uuid
  7 +from app.models import *
  8 +from app.util.component.ApiTemplate import ApiTemplate
  9 +class Api(ApiTemplate):
  10 + api_name = "创建目录"
  11 + def para_check(self):
  12 + if not self.para.get("database_guid"):
  13 + raise Exception("缺乏database_guid参数")
  14 + if not self.para.get("pguid"):
  15 + raise Exception("缺乏pguid参数")
  16 + if not self.para.get("name"):
  17 + raise Exception("缺乏name参数")
  18 +
  19 + def process(self):
  20 +
  21 + # 返回结果
  22 + res = {}
  23 + res["result"] = False
  24 + try:
  25 + # 业务逻辑
  26 +
  27 + if not Database.query.filter_by(guid=self.para.get("database_guid")).one_or_none():
  28 + res["msg"]="数据库不存在!"
  29 + return res
  30 +
  31 +
  32 + # 可以创建已有数据目录的子目录
  33 + # if Table.query.filter_by(catalog_guid=self.para.get("pguid")).all():
  34 + # raise Exception("父目录挂载了数据,不能创建子目录")
  35 +
  36 + if Catalog.query.filter_by(name=self.para.get("name"),pguid=self.para.get("pguid"),database_guid=self.para.get("database_guid")).one_or_none():
  37 + res["msg"]="目录已经存在!"
  38 + return res
  39 +
  40 +
  41 + # if Catalog.query.filter_by(pguid="0",database_guid=self.para.get("database_guid")).one_or_none() and self.para.get("pguid").__eq__("0"):
  42 + # raise Exception("只能有一个根目录!")
  43 +
  44 + guid = uuid.uuid1().__str__()
  45 + path = guid
  46 +
  47 + # 获得目录的全路径
  48 + pguid = self.para.get("pguid")
  49 + count = 0
  50 + while pguid !="0" and count<100:
  51 + count+=1
  52 + path = pguid+":"+path
  53 + p_catalog = Catalog.query.filter_by(guid=pguid).one_or_none()
  54 + pguid = p_catalog.pguid
  55 + if count==100:
  56 + raise Exception("目录结构出现问题!")
  57 + path = "0" + ":" + path
  58 +
  59 + sort = Catalog.query.filter_by(pguid=self.para.get("pguid")).count()
  60 +
  61 + catalog = Catalog(guid=guid,pguid=self.para.get("pguid"),name=self.para.get("name"),
  62 + sort=sort,description=self.para.get("description"),
  63 + database_guid=self.para.get("database_guid"),path=path)
  64 + db.session.add(catalog)
  65 + db.session.commit()
  66 +
  67 +
  68 + res["msg"] = "目录创建成功!"
  69 + res["data"] = guid
  70 + res["result"] = True
  71 + except Exception as e:
  72 + db.session.rollback()
  73 + raise e
  74 + return res
  75 +
  76 + api_doc={
  77 +
  78 + "tags":["目录接口"],
  79 + "parameters":[
  80 + {"name": "name",
  81 + "in": "formData",
  82 + "type": "string",
  83 + "description":"目录名"},
  84 + {"name": "pguid",
  85 + "in": "formData",
  86 + "type": "string","description":"父目录guid,创建根目录时为0"},
  87 + {"name": "database_guid",
  88 + "in": "formData",
  89 + "type": "string","description":"数据库guid"}
  90 +
  91 + ],
  92 + "responses":{
  93 + 200:{
  94 + "schema":{
  95 + "properties":{
  96 + }
  97 + }
  98 + }
  99 + }
  100 + }
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/3/9
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +
  8 +from app.models import *
  9 +from app.util.component.ApiTemplate import ApiTemplate
  10 +class Api(ApiTemplate):
  11 + api_name = "删除目录"
  12 + def process(self):
  13 +
  14 +
  15 + # 返回结果
  16 + res = {}
  17 + try:
  18 + # 业务逻辑
  19 +
  20 +
  21 + # 啥情况都能删
  22 + # if Table.query.filter_by(catalog_guid=self.para.get("guid")).all():
  23 + # raise Exception("目录挂载了数据,不可删除,可将数据移出目录后删除!")
  24 + # if Catalog.query.filter_by(pguid=self.para.get("guid")).all():
  25 + # raise Exception("目录非子目录,不可删除,请先将子目录删除!")
  26 +
  27 + catalog_guid = self.para.get("guid")
  28 +
  29 + catalog = Catalog.query.filter_by(guid=catalog_guid).one_or_none()
  30 + if not catalog:
  31 + res["msg"]="目录不存在!"
  32 + return res
  33 +
  34 + else:
  35 +
  36 + # 转移目录下的数据
  37 +
  38 + # # 删除根节点
  39 + # if catalog.pguid.__eq__("0"):
  40 + # database_guid = catalog.database_guid
  41 + # Table.query.filter_by(database_guid=database_guid).update({"catalog_guid": None})
  42 + # catalogs = Catalog.query.filter(Catalog.path.like("%" + catalog_guid + "%")).all()
  43 + # for cata in catalogs:
  44 + # db.session.delete(cata)
  45 + #
  46 + # # 获取所有子目录:
  47 + # else:
  48 +
  49 + pguid = catalog.pguid
  50 + # 所有目录
  51 + catalogs = Catalog.query.filter(Catalog.path.like("%" + catalog_guid + "%")).all()
  52 + for cata in catalogs:
  53 + if pguid.__eq__("0"):
  54 + Table.query.filter_by(catalog_guid=cata.guid).update({"catalog_guid": None})
  55 + db.session.delete(cata)
  56 + else:
  57 + Table.query.filter_by(catalog_guid=cata.guid).update({"catalog_guid": pguid})
  58 + db.session.delete(cata)
  59 +
  60 + db.session.commit()
  61 + res["msg"] = "目录删除成功!"
  62 + res["result"] = True
  63 + except Exception as e:
  64 + db.session.rollback()
  65 + raise e
  66 + return res
  67 +
  68 +
  69 + api_doc = {
  70 + "tags": ["目录接口"],
  71 + "parameters": [
  72 + {"name": "guid",
  73 + "in": "formData",
  74 + "type": "string",
  75 + "description": "目录guid", "required": "true"},
  76 + ],
  77 + "responses": {
  78 + 200: {
  79 + "schema": {
  80 + "properties": {
  81 + }
  82 + }
  83 + }
  84 + }
  85 + }
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/3/9
  4 +#email: nheweijun@sina.com
  5 +
  6 +from app.models import *
  7 +
  8 +from app.util.component.ApiTemplate import ApiTemplate
  9 +class Api(ApiTemplate):
  10 + api_name = "修改目录"
  11 + def process(self):
  12 +
  13 +
  14 + # 返回结果
  15 + res = {}
  16 + try:
  17 + # 业务逻辑
  18 + if not Catalog.query.filter_by(guid=self.para.get("guid")).one_or_none():
  19 + res["msg"]="目录不存在!"
  20 + res["result"]=False
  21 + return res
  22 + else:
  23 + if self.para.get("name"):
  24 + Catalog.query.filter_by(guid=self.para.get("guid")).update({"name":self.para.get("name")})
  25 + if self.para.__contains__("description"):
  26 + Catalog.query.filter_by(guid=self.para.get("guid")).update({"description":self.para.get("description")})
  27 + db.session.commit()
  28 + res["msg"] = "目录修改成功!"
  29 + res["result"] = True
  30 + except Exception as e:
  31 + db.session.rollback()
  32 + raise e
  33 + return res
  34 +
  35 +
  36 + api_doc = {
  37 + "tags": ["目录接口"],
  38 + "parameters": [
  39 + {"name": "guid",
  40 + "in": "formData",
  41 + "type": "string",
  42 + "description": "目录guid", "required": "true"},
  43 + {"name": "name",
  44 + "in": "formData",
  45 + "type": "string",
  46 + "description": "目录名", "required": "true"}
  47 + ],
  48 + "responses": {
  49 + 200: {
  50 + "schema": {
  51 + "properties": {
  52 + }
  53 + }
  54 + }
  55 + }
  56 + }
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/3/9
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +from app.models import *
  8 +
  9 +from app.util.component.ApiTemplate import ApiTemplate
  10 +from app.util.component.ModelVisitor import ModelVisitor
  11 +class Api(ApiTemplate):
  12 + api_name = "下一级目录"
  13 + def process(self):
  14 +
  15 + # 返回结果
  16 + res = {}
  17 + try:
  18 + # 业务逻辑
  19 +
  20 + res["data"] = []
  21 + catalogs = Catalog.query.filter_by(pguid=self.para.get("catalog_guid"),database_guid=self.para.get("database_guid")).all()
  22 + for cata in catalogs:
  23 + catalog_guids = [c.guid for c in Catalog.query.filter(Catalog.path.like("%" + cata.guid + "%")).all()]
  24 + table_count = Table.query.filter(Table.catalog_guid.in_(catalog_guids)).count()
  25 + database_alias = cata.relate_database.alias
  26 + cata_json = ModelVisitor.object_to_json(cata)
  27 + cata_json["table_count"]=table_count
  28 + cata_json["database_alias"] = database_alias
  29 +
  30 + res["data"].append(cata_json)
  31 + res["result"] = True
  32 + except Exception as e:
  33 + raise e
  34 + return res
  35 +
  36 + api_doc={
  37 +
  38 + "tags":["目录接口"],
  39 + "parameters":[
  40 + {"name": "catalog_guid",
  41 + "in": "formData",
  42 + "type": "string",
  43 + "description":"目录guid","required": "true"},
  44 + {"name": "database_guid",
  45 + "in": "formData",
  46 + "type": "string",
  47 + "description": "数据库guid", "required": "true"},
  48 +
  49 + ],
  50 + "responses":{
  51 + 200:{
  52 + "schema":{
  53 + "properties":{
  54 + }
  55 + }
  56 + }
  57 + }
  58 + }
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/3/9
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +from app.models import *
  8 +
  9 +from app.util.component.ApiTemplate import ApiTemplate
  10 +class Api(ApiTemplate):
  11 + api_name = "目录树"
  12 + def process(self):
  13 +
  14 + # 返回结果
  15 + res = {}
  16 + try:
  17 + # 业务逻辑
  18 + database_guid = self.para.get("database_guid")
  19 + catalogs = Catalog.query.filter_by(database_guid=database_guid).all()
  20 +
  21 + tree_origin = []
  22 + for cata in catalogs:
  23 + catalog_guids = [c.guid for c in Catalog.query.filter(Catalog.path.like("%" + cata.guid + "%")).all()]
  24 + table_count = Table.query.filter(Table.catalog_guid.in_(catalog_guids)).count()
  25 +
  26 + # cata_json = object_to_json(cata)
  27 + cata_json ={}
  28 + cata_json["database_guid"]=cata.database_guid
  29 + cata_json["description"] = cata.description
  30 + cata_json["guid"] = cata.guid
  31 + cata_json["name"] = cata.name
  32 + cata_json["path"] = cata.path
  33 + cata_json["pguid"] = cata.pguid
  34 + cata_json["sort"] = cata.sort
  35 + cata_json["table_count"]=table_count
  36 + cata_json["children"] = []
  37 + tree_origin.append(cata_json)
  38 +
  39 + for cata in tree_origin:
  40 + cata_pguid = cata["pguid"]
  41 + if not cata_pguid=="0":
  42 + for c in tree_origin:
  43 + if c["guid"].__eq__(cata_pguid):
  44 + c["children"].append(cata)
  45 +
  46 + res["data"] = [cata for cata in tree_origin if cata["pguid"].__eq__("0")]
  47 + res["result"] = True
  48 + except Exception as e:
  49 + raise e
  50 + return res
  51 +
  52 + api_doc={
  53 +
  54 + "tags":["目录接口"],
  55 + "parameters":[
  56 + {"name": "database_guid",
  57 + "in": "formData",
  58 + "type": "string",
  59 + "description": "数据库guid", "required": "true"},
  60 +
  61 + ],
  62 + "responses":{
  63 + 200:{
  64 + "schema":{
  65 + "properties":{
  66 + }
  67 + }
  68 + }
  69 + }
  70 + }
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/3/9
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +from app.models import *
  8 +
  9 +from app.util.component.ApiTemplate import ApiTemplate
  10 +class Api(ApiTemplate):
  11 + api_name = "目录"
  12 + def process(self):
  13 +
  14 + # 返回结果
  15 + res = {}
  16 + try:
  17 + # 业务逻辑
  18 + database_guid = self.para.get("database_guid")
  19 + catalogs = Catalog.query.filter_by(database_guid=database_guid).all()
  20 + res["data"]=[]
  21 + for cata in catalogs:
  22 + catalog_guids = [c.guid for c in Catalog.query.filter(Catalog.path.like("%" + cata.guid + "%")).all()]
  23 + table_count = Table.query.filter(Table.catalog_guid.in_(catalog_guids)).count()
  24 +
  25 + # cata_json = object_to_json(cata)
  26 + cata_json ={}
  27 + cata_json["database_guid"]=cata.database_guid
  28 + cata_json["description"] = cata.description
  29 + cata_json["guid"] = cata.guid
  30 + cata_json["name"] = cata.name
  31 + cata_json["path"] = cata.path
  32 + cata_json["pguid"] = cata.pguid
  33 + cata_json["sort"] = cata.sort
  34 + cata_json["table_count"]=table_count
  35 + res["data"].append(cata_json)
  36 +
  37 + res["result"] = True
  38 +
  39 + except Exception as e:
  40 + raise e
  41 + return res
  42 +
  43 + api_doc={
  44 +
  45 + "tags":["目录接口"],
  46 + "parameters":[
  47 + {"name": "database_guid",
  48 + "in": "formData",
  49 + "type": "string",
  50 + "description": "数据库guid", "required": "true"},
  51 +
  52 + ],
  53 + "responses":{
  54 + 200:{
  55 + "schema":{
  56 + "properties":{
  57 + }
  58 + }
  59 + }
  60 + }
  61 + }
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/3/9
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +
  8 +from flasgger import swag_from
  9 +from flask import Blueprint
  10 +from app.util import BlueprintApi
  11 +
  12 +from . import database_register
  13 +from . import database_test
  14 +from . import database_list
  15 +from . import database_delete
  16 +from . import database_edit
  17 +from . import database_alias_check
  18 +from . import database_connect_test
  19 +from . import database_info
  20 +
  21 +class DataManager(BlueprintApi):
  22 +
  23 + bp = Blueprint("Database", __name__, url_prefix="/API/Database")
  24 +
  25 +
  26 + @staticmethod
  27 + @bp.route('/Register', methods=['POST'])
  28 + @swag_from(database_register.Api.api_doc)
  29 + def api_database_register():
  30 + """
  31 + 数据源注册
  32 + """
  33 + return database_register.Api().result
  34 +
  35 + @staticmethod
  36 + @bp.route('/List', methods=['POST'])
  37 + @swag_from(database_list.Api.api_doc)
  38 + def api_database_list():
  39 + """
  40 + 数据源列表
  41 + """
  42 + return database_list.Api().result
  43 +
  44 + @staticmethod
  45 + @bp.route('/Delete', methods=['POST'])
  46 + @swag_from(database_delete.Api.api_doc)
  47 + def api_database_delete():
  48 + """
  49 + 数据源注销
  50 + """
  51 + return database_delete.Api().result
  52 +
  53 + @staticmethod
  54 + @bp.route('/Edit', methods=['POST'])
  55 + @swag_from(database_edit.Api.api_doc)
  56 + def database_edit():
  57 + """
  58 + 修改数据源
  59 + """
  60 + return database_edit.Api().result
  61 +
  62 + @staticmethod
  63 + @bp.route('/Test', methods=['POST'])
  64 + @swag_from(database_test.Api.api_doc)
  65 + def api_database_test():
  66 + """
  67 + 数据源测试
  68 + """
  69 + return database_test.Api().result
  70 +
  71 + @staticmethod
  72 + @bp.route('/CheckAlias', methods=['POST'])
  73 + @swag_from(database_alias_check.Api.api_doc)
  74 + def api_database_alias_check():
  75 + """
  76 + 数据源别名测试
  77 + """
  78 + return database_alias_check.Api().result
  79 +
  80 + @staticmethod
  81 + @bp.route('/CheckConnect', methods=['POST'])
  82 + @swag_from(database_connect_test.Api.api_doc)
  83 + def api_database_connect_test():
  84 + """
  85 + 数据源连接测试
  86 + """
  87 + return database_connect_test.Api().result
  88 +
  89 +
  90 + @staticmethod
  91 + @bp.route('/Info', methods=['POST'])
  92 + @swag_from(database_info.Api.api_doc)
  93 + def api_database_info():
  94 + """
  95 + 数据源信息
  96 + """
  97 + return database_info.Api().result
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/3/9
  4 +#email: nheweijun@sina.com
  5 +
  6 +from app.models import Database,db
  7 +
  8 +
  9 +
  10 +from app.util.component.ApiTemplate import ApiTemplate
  11 +class Api(ApiTemplate):
  12 + api_name = "测试数据库别名"
  13 +
  14 + def process(self):
  15 + res ={}
  16 + try:
  17 + database = db.session.query(Database).filter_by(alias=self.para.get("alias")).one_or_none()
  18 + if database:
  19 + res["msg"]="数据库重名!"
  20 + res["result"]=False
  21 + else:
  22 + res["result"] = True
  23 + except Exception as e:
  24 + raise e
  25 + return res
  26 +
  27 + api_doc={
  28 + "tags":["数据库接口"],
  29 + "parameters":[
  30 + {"name": "alias",
  31 + "in": "formData",
  32 + "type": "string","description":"数据库别名","required": "true"},
  33 +
  34 + ],
  35 + "responses":{
  36 + 200:{
  37 + "schema":{
  38 + "properties":{
  39 + }
  40 + }
  41 + }
  42 + }
  43 + }
  1 +# coding=utf-8
  2 +# author: 4N
  3 +# createtime: 2020/6/22
  4 +# email: nheweijun@sina.com
  5 +from contextlib import closing
  6 +
  7 +from sqlalchemy import create_engine
  8 +
  9 +from app.models import DES,Database
  10 +
  11 +
  12 +from app.util.component.ApiTemplate import ApiTemplate
  13 +class Api(ApiTemplate):
  14 + api_name = "测试数据库连接"
  15 + def process(self):
  16 + res = {}
  17 + try:
  18 + guid = self.para.get("guid")
  19 + database = Database.query.filter_by(guid=guid)
  20 + dbase:Database = database.one_or_none()
  21 + engine = create_engine(DES.decode(dbase.sqlalchemy_uri), connect_args={'connect_timeout': 1})
  22 + with closing(engine.connect()):
  23 + pass
  24 + res["result"]=True
  25 + res["msg"] = "测试连接成功!"
  26 + except:
  27 + raise Exception("测试连接失败!")
  28 + return res
  29 +
  30 + api_doc={
  31 + "tags":["数据库接口"],
  32 + "parameters":[
  33 +
  34 + {"name": "guid",
  35 + "in": "formData",
  36 + "type": "string", "required": "true"},
  37 +
  38 +
  39 + ],
  40 + "responses":{
  41 + 200:{
  42 + "schema":{
  43 + "properties":{
  44 + }
  45 + }
  46 + }
  47 + }
  48 + }
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/3/9
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +from app.models import Database,db
  8 +
  9 +
  10 +from app.util.component.ApiTemplate import ApiTemplate
  11 +class Api(ApiTemplate):
  12 + api_name = "删除数据库"
  13 + def process(self):
  14 + res ={}
  15 + try:
  16 +
  17 + database = db.session.query(Database).filter_by(guid=self.para.get("guid")).one_or_none()
  18 + if database:
  19 + db.session.delete(database)
  20 + db.session.commit()
  21 + res["msg"] = "数据库删除成功!"
  22 + res["result"] = True
  23 + else:
  24 + res["msg"] = "数据库不存在!"
  25 + res["result"] = False
  26 + except Exception as e:
  27 + db.session.rollback()
  28 + raise e
  29 + return res
  30 +
  31 +
  32 +
  33 + api_doc={
  34 + "tags":["数据库接口"],
  35 + "parameters":[
  36 + {"name": "guid",
  37 + "in": "formData",
  38 + "type": "string","description":"数据库guid","required": "true"},
  39 +
  40 + ],
  41 + "responses":{
  42 + 200:{
  43 + "schema":{
  44 + "properties":{
  45 + }
  46 + }
  47 + }
  48 + }
  49 + }
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/3/9
  4 +#email: nheweijun@sina.com
  5 +
  6 +from app.models import Database,db
  7 +from contextlib import closing
  8 +
  9 +from sqlalchemy import create_engine
  10 +
  11 +from app.models import DES
  12 +import datetime
  13 +from . import database_alias_check
  14 +
  15 +from app.util.component.ApiTemplate import ApiTemplate
  16 +
  17 +from app.util.component.PGUtil import PGUtil
  18 +class Api(ApiTemplate):
  19 + api_name = "修改数据库"
  20 + def process(self):
  21 +
  22 + res = {}
  23 + res["result"] = False
  24 + try:
  25 + guid = self.para.get("guid")
  26 + alias = self.para.get("alias")
  27 +
  28 + passwd = self.para.get("passwd")
  29 + database = Database.query.filter_by(guid=guid)
  30 + dbase:Database = database.one_or_none()
  31 +
  32 + update_dict={}
  33 +
  34 + if not dbase:
  35 + res["msg"] = "数据库不存在!"
  36 + return res
  37 + if not alias and not passwd:
  38 + res["msg"] = "请填写参数!"
  39 + return res
  40 +
  41 +
  42 + if alias:
  43 + # 检测一波别名
  44 + check_alias = database_alias_check.Api().result
  45 + if not check_alias["result"]:
  46 + return check_alias
  47 + update_dict["alias"]=alias
  48 +
  49 + if passwd:
  50 + try:
  51 + user, password, host, port, database = PGUtil.get_info_from_sqlachemy_uri(DES.decode(dbase.sqlalchemy_uri))
  52 +
  53 + sqlalchemy_uri = "postgresql://{}:{}@{}:{}/{}".format(user, passwd,host,
  54 + port, database)
  55 +
  56 + connectsrt = "hostaddr={} port={} dbname='{}' user='{}' password='{}'".format(host, port, database, user,
  57 + passwd)
  58 + engine = create_engine(sqlalchemy_uri, connect_args={'connect_timeout': 2})
  59 + with closing(engine.connect()):
  60 + pass
  61 +
  62 + except :
  63 + res["msg"] = "密码错误!"
  64 + return res
  65 +
  66 + update_dict["sqlalchemy_uri"]= DES.encode(sqlalchemy_uri)
  67 + update_dict["connectstr"] = DES.encode(connectsrt)
  68 +
  69 + if update_dict:
  70 + update_dict["update_time"]=datetime.datetime.now()
  71 + Database.query.filter_by(guid=guid).update(update_dict)
  72 + db.session.commit()
  73 + res["result"] = True
  74 + res["msg"] = "数据修改成功!"
  75 + except Exception as e:
  76 + db.session.rollback()
  77 + raise e
  78 + return res
  79 +
  80 +
  81 +
  82 + api_doc={
  83 + "tags":["数据库接口"],
  84 + "parameters":[
  85 + {"name": "guid",
  86 + "in": "formData",
  87 + "type": "string"},
  88 + {"name": "alias",
  89 + "in": "formData",
  90 + "type": "string","description":"数据库别名"},
  91 + {"name": "passwd",
  92 + "in": "formData",
  93 + "type": "string", "description": "数据库密码"}
  94 + ],
  95 + "responses":{
  96 + 200:{
  97 + "schema":{
  98 + "properties":{
  99 + }
  100 + }
  101 + }
  102 + }
  103 + }
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/3/9
  4 +#email: nheweijun@sina.com
  5 +from app.models import Database,DES
  6 +from contextlib import closing
  7 +from sqlalchemy import create_engine,or_
  8 +
  9 +from app.models import Database,Catalog,Table
  10 +
  11 +
  12 +from app.util.component.ApiTemplate import ApiTemplate
  13 +
  14 +
  15 +class Api(ApiTemplate):
  16 + api_name = "获取数据库信息"
  17 + def process(self):
  18 + # 返回结果
  19 + res = {}
  20 + try:
  21 + # 业务逻辑
  22 + database_guid = self.para.get("guid")
  23 + table_type = self.para.get("table_type")
  24 + catalogs = Catalog.query.filter_by(database_guid=database_guid).all()
  25 +
  26 + tree_origin = []
  27 + for cata in catalogs:
  28 + cata_json = {}
  29 + cata_json["type"] = "catalog"
  30 + cata_json["guid"] = cata.guid
  31 + cata_json["name"] = cata.name
  32 + cata_json["pguid"] = cata.pguid
  33 + cata_json["children"] = []
  34 + tree_origin.append(cata_json)
  35 +
  36 + #挂接表
  37 + tables =Table.query.filter_by(database_guid=database_guid,catalog_guid=cata.guid).filter(Table.table_type != 0)
  38 + if table_type:
  39 + tables = tables.filter_by(table_type=table_type)
  40 + tables = tables.order_by(Table.name).all()
  41 +
  42 + for table in tables:
  43 + table_json= {}
  44 + table_json["name"]=table.name
  45 + table_json["alias"] = table.alias
  46 + table_json["guid"] = table.guid
  47 + table_json["type"] = "table"
  48 + table_json["table_type"] = table.table_type
  49 + cata_json["children"].append(table_json)
  50 +
  51 + for cata in tree_origin:
  52 + cata_pguid = cata["pguid"]
  53 + if not cata_pguid == "0":
  54 + for c in tree_origin:
  55 + if c["guid"].__eq__(cata_pguid):
  56 + c["children"].append(cata)
  57 + res["data"] = [cata for cata in tree_origin if cata["pguid"].__eq__("0")]
  58 +
  59 + # 挂接表
  60 + tables = Table.query.filter_by(database_guid=database_guid, catalog_guid=None).filter(
  61 + Table.table_type != 0)
  62 + if table_type:
  63 + tables = tables.filter_by(table_type=table_type)
  64 + tables = tables.order_by(Table.name).all()
  65 +
  66 + for table in tables:
  67 + table_json = {}
  68 + table_json["name"] = table.name
  69 + table_json["alias"] = table.alias
  70 + table_json["guid"] = table.guid
  71 + table_json["type"] = "table"
  72 + table_json["table_type"] = table.table_type
  73 + res["data"].append(table_json)
  74 +
  75 + res["result"] = True
  76 + except Exception as e:
  77 + raise e
  78 + return res
  79 +
  80 + api_doc={
  81 + "tags":["数据库接口"],
  82 + "parameters":[
  83 + {"name": "guid",
  84 + "in": "formData",
  85 + "type": "string", "description": "数据库guid"},
  86 + {"name": "table_type",
  87 + "in": "formData",
  88 + "type": "int", "description": "表类型","enum":[1,2,3]}
  89 + ],
  90 + "responses":{
  91 + 200:{
  92 + "schema":{
  93 + "properties":{
  94 + }
  95 + }
  96 + }
  97 + }
  98 + }
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/3/9
  4 +#email: nheweijun@sina.com
  5 +from app.models import Database,DES
  6 +from contextlib import closing
  7 +from sqlalchemy import create_engine
  8 +
  9 +from app.models import Database
  10 +
  11 +
  12 +from app.util.component.ApiTemplate import ApiTemplate
  13 +from app.util.component.ModelVisitor import ModelVisitor
  14 +class Api(ApiTemplate):
  15 + api_name = "获取数据库列表"
  16 + def process(self):
  17 + res = {}
  18 + res["data"]={}
  19 + try:
  20 + page_index = int(self.para.get("pageIndex", "0"))
  21 + page_size = int(self.para.get("pageSize", "10"))
  22 + alias = self.para.get("alias")
  23 + database_guid = self.para.get("guid")
  24 + database = Database.query.order_by(Database.create_time.desc())
  25 +
  26 + if alias:
  27 + database = database.filter(Database.alias.like("%" + alias + "%"))
  28 + if database_guid:
  29 + database = database.filter_by(guid = database_guid)
  30 +
  31 + res["data"]["count"] = database.count()
  32 +
  33 + database = database.limit(page_size).offset(page_index * page_size).all()
  34 + res["data"]["list"] =[]
  35 + for datab in database:
  36 + # 测试连接
  37 + try:
  38 + engine = create_engine(DES.decode(datab.sqlalchemy_uri), connect_args={'connect_timeout': 1})
  39 + with closing(engine.connect()):
  40 + pass
  41 + available=1
  42 + except:
  43 + available=-1
  44 + table_count = datab.relate_tables.count()
  45 + datab_json = ModelVisitor.database_to_json(datab)
  46 + datab_json["table_count"] = table_count
  47 + datab_json["available"] = available
  48 + res["data"]["list"].append(datab_json)
  49 +
  50 + # 可用非可用排序
  51 + sorted_list = [dat for dat in res["data"]["list"] if dat["available"]==1]
  52 + sorted_list.extend([dat for dat in res["data"]["list"] if dat["available"] == -1])
  53 + res["data"]["list"] = sorted_list
  54 + res["result"]=True
  55 + except Exception as e:
  56 + raise e
  57 + return res
  58 +
  59 +
  60 +
  61 + api_doc={
  62 + "tags":["数据库接口"],
  63 + "parameters":[
  64 + {"name": "page_index",
  65 + "in": "formData",
  66 + "type": "int",
  67 + "default": "0"},
  68 + {"name": "page_size",
  69 + "in": "formData",
  70 + "type": "int",
  71 + "default": "10"},
  72 + {"name": "alias",
  73 + "in": "formData",
  74 + "type": "string","description":"数据库别名"},
  75 + {"name": "guid",
  76 + "in": "formData",
  77 + "type": "string", "description": "数据库guid"}
  78 + ],
  79 + "responses":{
  80 + 200:{
  81 + "schema":{
  82 + "properties":{
  83 + }
  84 + }
  85 + }
  86 + }
  87 + }
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/3/9
  4 +#email: nheweijun@sina.com
  5 +import datetime
  6 +from app.models import Database,db,DES,Table,Columns,TableVacuate
  7 +# from app.util import get_db_session,get_info_from_sqlachemy_uri
  8 +import uuid
  9 +from . import database_test
  10 +# from app.util import open_pg_data_source
  11 +from osgeo.ogr import DataSource,Layer,FeatureDefn,FieldDefn,Feature
  12 +from sqlalchemy.orm import Session
  13 +from sqlalchemy import create_engine
  14 +from sqlalchemy.orm import sessionmaker
  15 +from app.util.component.ApiTemplate import ApiTemplate
  16 +from app.util.component.PGUtil import PGUtil
  17 +from app.util.component.GeometryAdapter import GeometryAdapter
  18 +class Api(ApiTemplate):
  19 + api_name = "数据库注册"
  20 + def process(self):
  21 + res ={}
  22 + res["result"] = False
  23 + try:
  24 + host = self.para.get("host")
  25 + port = self.para.get("port")
  26 + user = self.para.get("user")
  27 + passwd = self.para.get("passwd")
  28 + database = self.para.get("database")
  29 + encryption = int(self.para.get("encryption","0"))
  30 + if encryption:
  31 + passwd = DES.decode(passwd)
  32 +
  33 + sqlalchemy_uri = "postgresql://{}:{}@{}:{}/{}".format(user,passwd,host,port,database)
  34 + connectsrt = "hostaddr={} port={} dbname='{}' user='{}' password='{}'".format(host,port,database,user,passwd)
  35 +
  36 + #测试连接
  37 + test = database_test.Api().result
  38 +
  39 + if not test["result"]:
  40 + return test
  41 +
  42 + #判断数据库是否存在
  43 + database = db.session.query(Database).filter_by(alias=self.para.get("alias")).one_or_none()
  44 +
  45 + #真实的数据库
  46 + real_database = db.session.query(Database).filter_by(connectstr=DES.encode(connectsrt)).all()
  47 +
  48 + if database:
  49 + res["msg"] = "数据库已存在,请修改别名!"
  50 + return res
  51 +
  52 + elif real_database:
  53 + res["msg"] = "数据库连接已存在,请修改数据库连接!"
  54 + return res
  55 + elif not self.check_space(sqlalchemy_uri):
  56 + res["msg"] = "数据不是空间数据库!"
  57 + return res
  58 +
  59 + else:
  60 + this_time = datetime.datetime.now()
  61 + database_guid = uuid.uuid1().__str__()
  62 +
  63 + db_tuple = PGUtil.get_info_from_sqlachemy_uri(sqlalchemy_uri)
  64 +
  65 + database = Database(guid= database_guid,
  66 + name = db_tuple[4],
  67 + alias=self.para.get("alias"),
  68 + sqlalchemy_uri=DES.encode(sqlalchemy_uri),
  69 + description=self.para.get("description"),
  70 + creator=self.para.get("creator"),
  71 + create_time=this_time,
  72 + update_time=this_time,
  73 + connectstr=DES.encode(connectsrt))
  74 + db.session.add(database)
  75 +
  76 + # 将该库中的数据都注册进来
  77 + self.register_table(database)
  78 + db.session.commit()
  79 + res["msg"] = "注册成功!"
  80 + res["result"]=True
  81 + res["data"] = database_guid
  82 + except Exception as e:
  83 + db.session.rollback()
  84 + raise e
  85 + return res
  86 +
  87 +
  88 + def register_table(self,database):
  89 + this_time = datetime.datetime.now()
  90 + pg_ds: DataSource = PGUtil.open_pg_data_source(1, DES.decode(database.sqlalchemy_uri))
  91 +
  92 + # 注册空间表
  93 + spatial_table_name,tables = self.register_spatial_table(pg_ds, database, this_time)
  94 +
  95 + #注册抽稀表
  96 + self.regiser_vacuate_talbe(pg_ds,tables)
  97 +
  98 + #注册普通表
  99 + self.register_common_table(this_time,database,spatial_table_name)
  100 +
  101 + pg_ds.Destroy()
  102 +
  103 +
  104 + def register_spatial_table(self,pg_ds,database,this_time):
  105 + spatial_table_name =[]
  106 + tables=[]
  107 + for i in range(pg_ds.GetLayerCount()):
  108 + layer: Layer = pg_ds.GetLayer(i)
  109 + l_name = layer.GetName()
  110 + # 只注册public的空间表,其他表空间的表名会有.
  111 + if layer.GetName().__contains__("."):
  112 + continue
  113 +
  114 + # 不注册抽稀表
  115 + if layer.GetName().__contains__("_vacuate_"):
  116 + spatial_table_name.append(layer.GetName())
  117 + continue
  118 +
  119 + # 范围统计和数量统计以100w为界限
  120 + query_count_layer: Layer = pg_ds.ExecuteSQL(
  121 + "SELECT reltuples::bigint AS ec FROM pg_class WHERE oid = 'public.{}'::regclass".format(l_name))
  122 + feature_count = query_count_layer.GetFeature(0).GetField("ec")
  123 + # 要素少于100w可以精确统计
  124 + if feature_count < 1000000:
  125 + feature_count = layer.GetFeatureCount()
  126 + ext = layer.GetExtent()
  127 + else:
  128 + query_ext_layer: Layer = pg_ds.ExecuteSQL(
  129 + "select geometry(ST_EstimatedExtent('public', '{}','{}'))".format(l_name,
  130 + layer.GetGeometryColumn()))
  131 + ext = query_ext_layer.GetExtent()
  132 + if ext[0] < 360:
  133 + ext = [round(e, 6) for e in ext]
  134 + else:
  135 + ext = [round(e, 2) for e in ext]
  136 + extent = "{},{},{},{}".format(ext[0], ext[1], ext[2], ext[3])
  137 +
  138 + table_guid = uuid.uuid1().__str__()
  139 +
  140 + table = Table(guid=table_guid,
  141 + database_guid=database.guid,
  142 + # alias=layer.GetName(),
  143 + name=layer.GetName(), create_time=this_time, update_time=this_time,
  144 + table_type=GeometryAdapter.get_table_type(layer.GetGeomType()),
  145 + extent=extent,
  146 + feature_count=feature_count
  147 + )
  148 +
  149 + db.session.add(table)
  150 + tables.append(table)
  151 +
  152 + feature_defn: FeatureDefn = layer.GetLayerDefn()
  153 +
  154 + for i in range(feature_defn.GetFieldCount()):
  155 + field_defn: FieldDefn = feature_defn.GetFieldDefn(i)
  156 + field_name = field_defn.GetName().lower()
  157 + field_alias = field_name if field_defn.GetAlternativeName() is None or field_defn.GetAlternativeName().__eq__(
  158 + "") else field_defn.GetAlternativeName()
  159 + column = Columns(guid=uuid.uuid1().__str__(), table_guid=table_guid,
  160 + name=field_name, alias=field_alias, create_time=this_time, update_time=this_time)
  161 + db.session.add(column)
  162 +
  163 + spatial_table_name.append(layer.GetName())
  164 + return spatial_table_name,tables
  165 +
  166 +
  167 + def register_common_table(self,this_time,database,spatial_table_name):
  168 + # 注册普通表
  169 + db_session: Session = PGUtil.get_db_session(DES.decode(database.sqlalchemy_uri))
  170 +
  171 + # 只注册public中的表
  172 + result = db_session.execute(
  173 + "select relname as tabname from pg_class c where relkind = 'r' and relnamespace=2200 and relname not like 'pg_%' and relname not like 'sql_%' order by relname").fetchall()
  174 + for re in result:
  175 + table_name = re[0]
  176 + if table_name not in spatial_table_name:
  177 +
  178 + table_guid = uuid.uuid1().__str__()
  179 + count = db_session.execute('select count(*) from "{}"'.format(table_name)).fetchone()[0]
  180 +
  181 + table = Table(guid=table_guid,
  182 + database_guid=database.guid,
  183 + # alias=layer.GetName(),
  184 + name=table_name, create_time=this_time, update_time=this_time,
  185 + table_type=0,
  186 + feature_count=count
  187 + )
  188 +
  189 + db.session.add(table)
  190 +
  191 + sql = '''
  192 + SELECT
  193 + a.attnum,
  194 + a.attname AS field
  195 + FROM
  196 + pg_class c,
  197 + pg_attribute a,
  198 + pg_type t
  199 + WHERE
  200 + c.relname = '{}'
  201 + and a.attnum > 0
  202 + and a.attrelid = c.oid
  203 + and a.atttypid = t.oid
  204 + ORDER BY a.attnum
  205 + '''.format(table_name)
  206 +
  207 + cols = db_session.execute(sql).fetchall()
  208 + for col in cols:
  209 + column = Columns(guid=uuid.uuid1().__str__(), table_guid=table_guid,
  210 + name=col[1], create_time=this_time, update_time=this_time)
  211 + db.session.add(column)
  212 + db_session.close()
  213 +
  214 + def regiser_vacuate_talbe(self,pg_ds,tables):
  215 +
  216 + # 注册抽稀表
  217 + for i in range(pg_ds.GetLayerCount()):
  218 + layer:Layer = pg_ds.GetLayer(i)
  219 + l_name = layer.GetName()
  220 + if l_name.__contains__("_vacuate_"):
  221 + base_layer_name=l_name.split("_vacuate_")[0]
  222 + level = l_name.split("_")[-2]
  223 + pixel_distance_str: str ="0"
  224 + try:
  225 + pixel_distance_str :str= l_name.split("_")[-1]
  226 + if pixel_distance_str.startswith("0"):
  227 + pixel_distance_str="0.{}".format(pixel_distance_str)
  228 + except:
  229 + pass
  230 + base_table = [table for table in tables if table.name.__eq__(base_layer_name)][0]
  231 + table_vacuate = TableVacuate(guid=uuid.uuid1().__str__(),
  232 + table_guid=base_table.guid,
  233 + level=level,
  234 + name=l_name,
  235 + pixel_distance=float(pixel_distance_str))
  236 + db.session.add(table_vacuate)
  237 +
  238 +
  239 +
  240 + def check_space(self,sqlachemy_uri):
  241 + system_session = None
  242 + check = True
  243 + try:
  244 + test_sql = "select st_geometryfromtext('POINT(1 1)')"
  245 + engine = create_engine(sqlachemy_uri)
  246 + system_session = sessionmaker(bind=engine)()
  247 + system_session.execute(test_sql).fetchone()
  248 +
  249 + except:
  250 + check = False
  251 + finally:
  252 + if system_session:
  253 + system_session.close()
  254 +
  255 + return check
  256 +
  257 + api_doc={
  258 + "tags":["数据库接口"],
  259 + "parameters":[
  260 + {"name": "host",
  261 + "in": "formData",
  262 + "type": "string", "required": "true"},
  263 + {"name": "port",
  264 + "in": "formData",
  265 + "type": "string", "required": "true"},
  266 + {"name": "user",
  267 + "in": "formData",
  268 + "type": "string", "required": "true"},
  269 + {"name": "passwd",
  270 + "in": "formData",
  271 + "type": "string", "required": "true"},
  272 + {"name": "database",
  273 + "in": "formData",
  274 + "type": "string", "required": "true"},
  275 + {"name": "creator",
  276 + "in": "formData",
  277 + "type": "string", "required": "true"},
  278 +
  279 + {"name": "alias",
  280 + "in": "formData",
  281 + "type": "string","description":"数据库别名","required": "true"},
  282 +
  283 + {"name": "encryption",
  284 + "in": "formData",
  285 + "type": "integer", "description": "密码是否加密", "enum": [0,1]},
  286 + ],
  287 + "responses":{
  288 + 200:{
  289 + "schema":{
  290 + "properties":{
  291 + }
  292 + }
  293 + }
  294 + }
  295 +}
  1 +# coding=utf-8
  2 +# author: 4N
  3 +# createtime: 2020/6/22
  4 +# email: nheweijun@sina.com
  5 +from contextlib import closing
  6 +
  7 +from sqlalchemy import create_engine
  8 +
  9 +from app.models import DES,Database,db
  10 +
  11 +from sqlalchemy.orm import sessionmaker
  12 +from app.util.component.ApiTemplate import ApiTemplate
  13 +class Api(ApiTemplate):
  14 + api_name = "数据库连接测试"
  15 + def process(self):
  16 + res = {}
  17 + res["result"] = False
  18 + try:
  19 +
  20 +
  21 + host = self.para.get("host")
  22 + port = self.para.get("port")
  23 + user = self.para.get("user")
  24 + passwd = self.para.get("passwd")
  25 + database = self.para.get("database")
  26 +
  27 + encryption = int(self.para.get("encryption", "0"))
  28 + if encryption:
  29 + passwd = DES.decode(passwd)
  30 +
  31 +
  32 + sqlalchemy_uri = "postgresql://{}:{}@{}:{}/{}".format(user,passwd,host,port,database)
  33 +
  34 + # if is_encrypt == "1":
  35 + # sqlalchemy_uri=DES.decode(sqlalchemy_uri)
  36 +
  37 + engine = create_engine(sqlalchemy_uri, connect_args={'connect_timeout': 2})
  38 + with closing(engine.connect()):
  39 + pass
  40 +
  41 +
  42 + #判断数据库是否存在
  43 + datab = db.session.query(Database).filter_by(alias=self.para.get("alias")).one_or_none()
  44 + #真实的数据库
  45 + connectsrt = "hostaddr={} port={} dbname='{}' user='{}' password='{}'".format(host, port, database, user,
  46 + passwd)
  47 + real_database = db.session.query(Database).filter_by(connectstr=DES.encode(connectsrt)).all()
  48 +
  49 + if datab:
  50 + res["msg"] = "数据库已存在,请修改别名!"
  51 + return res
  52 +
  53 + elif real_database:
  54 + res["msg"] = "数据库连接已存在,请修改数据库连接!"
  55 + return res
  56 +
  57 + elif not self.check_space(sqlalchemy_uri):
  58 + res["msg"] = "数据不是空间数据库!"
  59 + return res
  60 + else:
  61 + res["result"] = True
  62 + res["msg"] = "测试连接成功"
  63 + except:
  64 + raise Exception("测试连接失败!")
  65 + return res
  66 +
  67 +
  68 + def check_space(self,sqlachemy_uri):
  69 + system_session = None
  70 + check = True
  71 + try:
  72 + test_sql = "select st_geometryfromtext('POINT(1 1)')"
  73 + engine = create_engine(sqlachemy_uri)
  74 + system_session = sessionmaker(bind=engine)()
  75 + system_session.execute(test_sql).fetchone()
  76 + except:
  77 + check = False
  78 + finally:
  79 + if system_session:
  80 + system_session.close()
  81 +
  82 + return check
  83 +
  84 + api_doc={
  85 + "tags":["数据库接口"],
  86 + "parameters":[
  87 + # {"name": "sqlalchemy_uri",
  88 + # "in": "formData",
  89 + # "type": "string","description":"数据库uri","required": "true"},
  90 + {"name": "host",
  91 + "in": "formData",
  92 + "type": "string", "required": "true"},
  93 + {"name": "port",
  94 + "in": "formData",
  95 + "type": "string", "required": "true"},
  96 + {"name": "user",
  97 + "in": "formData",
  98 + "type": "string", "required": "true"},
  99 + {"name": "passwd",
  100 + "in": "formData",
  101 + "type": "string", "required": "true"},
  102 + {"name": "database",
  103 + "in": "formData",
  104 + "type": "string", "required": "true"},
  105 + # {"name": "alias",
  106 + # "in": "formData",
  107 + # "type": "string", "required": "true"},
  108 + {"name": "encryption",
  109 + "in": "formData",
  110 + "type": "int", "description": "密码是否加密", "enum": [0, 1]},
  111 +
  112 + ],
  113 + "responses":{
  114 + 200:{
  115 + "schema":{
  116 + "properties":{
  117 + }
  118 + }
  119 + }
  120 + }
  121 +}
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/2/23
  4 +#email: nheweijun@sina.com
  5 +
  6 +from flask import Blueprint
  7 +from app.util import BlueprintApi
  8 +from flasgger import swag_from
  9 +from . import index
  10 +from . import release
  11 +from . import get_app_name
  12 +class Template(BlueprintApi):
  13 +
  14 + bp = Blueprint("Index", __name__, url_prefix="/")
  15 +
  16 + @staticmethod
  17 + @bp.route('/', methods=['GET'])
  18 + @swag_from(index.Api.api_doc)
  19 + def api_index():
  20 + """
  21 + Index接口
  22 + """
  23 + return index.Api().result
  24 +
  25 + @staticmethod
  26 + @bp.route('/release', methods=['GET'])
  27 + @swag_from(release.Api.api_doc)
  28 + def release():
  29 + """
  30 + release接口
  31 + """
  32 + return release.Api().result
  33 +
  34 + @staticmethod
  35 + @bp.route('/GetAppName', methods=['GET'])
  36 + @swag_from(get_app_name.Api.api_doc)
  37 + def get_app_name():
  38 + """
  39 + GetAppName接口
  40 + """
  41 + return get_app_name.Api().result
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/7/20
  4 +#email: nheweijun@sina.com
  5 +
  6 +import hashlib
  7 +from flask import current_app as app
  8 +import socket
  9 +import configure
  10 +
  11 +from app.util.component.ApiTemplate import ApiTemplate
  12 +class Api(ApiTemplate):
  13 +
  14 + def process(self):
  15 + return configure.application_name
  16 +
  17 + api_doc={
  18 + "tags":["Index接口"],
  19 + "description":"Index接口",
  20 + "parameters":[
  21 + ],
  22 + "responses":{
  23 + 200:{
  24 + "schema":{
  25 + "properties":{
  26 + "content":{
  27 + "type": "string",
  28 + "description": "The name of the user"
  29 + }
  30 + }
  31 + }
  32 + }
  33 + }
  34 + }
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/2/23
  4 +#email: nheweijun@sina.com
  5 +import hashlib
  6 +from flask import current_app as app
  7 +import socket
  8 +
  9 +from app.util.component.ApiTemplate import ApiTemplate
  10 +class Api(ApiTemplate):
  11 +
  12 + def process(self):
  13 + return {"Name":socket.gethostname(),"Type":"DMapDMS"}
  14 +
  15 + api_doc={
  16 + "tags":["Index接口"],
  17 + "description":"Index接口",
  18 + "parameters":[
  19 + ],
  20 + "responses":{
  21 + 200:{
  22 + "schema":{
  23 + "properties":{
  24 + "content":{
  25 + "type": "string",
  26 + "description": "The name of the user"
  27 + }
  28 + }
  29 + }
  30 + }
  31 + }
  32 + }
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/2/23
  4 +#email: nheweijun@sina.com
  5 +import hashlib
  6 +from flask import current_app as app
  7 +import socket
  8 +
  9 +from app.util.component.ApiTemplate import ApiTemplate
  10 +from app.models import Task,InsertingLayerName,db
  11 +import datetime
  12 +import traceback
  13 +from sqlalchemy import or_
  14 +class Api(ApiTemplate):
  15 +
  16 + def process(self):
  17 + try:
  18 + # 遗留任务变成失败
  19 + last_tasks = db.session.query(Task).filter(or_(Task.state == 0, Task.state == 2))
  20 + last_tasks.update({"state": -1,"process":"入库失败","update_time":datetime.datetime.now()})
  21 + last_lins = db.session.query(InsertingLayerName).all()
  22 + if last_lins:
  23 + for lin in last_lins:
  24 + db.session.delete(lin)
  25 + db.session.commit()
  26 + except Exception as e:
  27 + # print(e)
  28 + print(traceback.format_exc())
  29 +
  30 + return {"state": 1}
  31 +
  32 + api_doc={
  33 + "tags":["Index接口"],
  34 + "description":"Index接口",
  35 + "parameters":[
  36 + ],
  37 + "responses":{
  38 + 200:{
  39 + "schema":{
  40 + "properties":{
  41 + "content":{
  42 + "type": "string",
  43 + "description": "The name of the user"
  44 + }
  45 + }
  46 + }
  47 + }
  48 + }
  49 + }
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2020/12/8
  4 +#email: nheweijun@sina.com
  5 +from flasgger import swag_from
  6 +from flask import Blueprint
  7 +from app.util import BlueprintApi
  8 +
  9 +from flask import send_from_directory,current_app,send_file
  10 +import os
  11 +import shutil
  12 +from . import data_download
  13 +from . import get_meta
  14 +from . import data_entry_by_meta
  15 +from . import get_data_list
  16 +from flask import after_this_request
  17 +import time
  18 +
  19 +class DataManager(BlueprintApi):
  20 +
  21 + bp:Blueprint = Blueprint("DataTool", __name__, url_prefix="/API/IO")
  22 +
  23 +
  24 + @staticmethod
  25 + @bp.route('/Download/<file>', methods=['GET'])
  26 + def table_download_file(file):
  27 + parent = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
  28 + dirpath = os.path.join(parent,"file_tmp")
  29 +
  30 + # @staticmethod
  31 + # @after_this_request
  32 + # def delete(response):
  33 + # try:
  34 + # os.remove(os.path.join(dirpath,file))
  35 + # # shutil.rmtree(dirpath)
  36 + # print("删除文件成功!")
  37 + # except Exception as e:
  38 + # print(e)
  39 + # print("删除文件失败!")
  40 + # return response
  41 +
  42 + return send_from_directory(dirpath, filename=file, as_attachment=True)
  43 +
  44 + @staticmethod
  45 + @bp.route('/DeleteFile/<file>', methods=['GET'])
  46 + def d_file(file):
  47 + parent = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
  48 + dirpath = os.path.join(parent, "file_tmp")
  49 +
  50 + result={}
  51 + try:
  52 + os.remove(os.path.join(dirpath, file))
  53 + # shutil.rmtree(dirpath)
  54 + result["message"]="删除文件成功!"
  55 + except Exception as e:
  56 + print(e)
  57 + result["message"] ="删除文件失败!"
  58 + return result
  59 +
  60 + @staticmethod
  61 + @bp.route('/DataDownload', methods=['POST'])
  62 + @swag_from(data_download.Api.api_doc)
  63 + def table_download():
  64 + """
  65 + 下载数据
  66 + """
  67 + return data_download.Api().result
  68 +
  69 +
  70 + @staticmethod
  71 + @bp.route('/GetMeta', methods=['POST'])
  72 + @swag_from(get_meta.Api.api_doc)
  73 + def get_meta():
  74 + """
  75 + 数据Meta
  76 + """
  77 + return get_meta.Api().result
  78 +
  79 + @staticmethod
  80 + @bp.route('/GetDataList', methods=['POST'])
  81 + @swag_from(get_data_list.Api.api_doc)
  82 + def get_data_list():
  83 + """
  84 + 本地数据list
  85 + """
  86 + return get_data_list.Api().result
  87 +
  88 + @staticmethod
  89 + @bp.route('/DataEntryByMeta', methods=['POST'])
  90 + @swag_from(data_entry_by_meta.Api.api_doc)
  91 + def data_entry_by_meta():
  92 + """
  93 + 数据入库ByMeta
  94 + """
  95 + return data_entry_by_meta.Api().result
  1 +# coding=utf-8
  2 +# author: 4N
  3 +# createtime: 2021/1/27
  4 +# email: nheweijun@sina.com
  5 +
  6 +from osgeo.ogr import *
  7 +import uuid
  8 +
  9 +import time
  10 +from app.models import *
  11 +import json
  12 +import re
  13 +from app.util.component.ApiTemplate import ApiTemplate
  14 +from app.util.component.PGUtil import PGUtil
  15 +
  16 +
  17 +class Api(ApiTemplate):
  18 + api_name = "检查meta"
  19 + def process(self):
  20 +
  21 + # 设置任务信息
  22 + self.para["task_guid"] = uuid.uuid1().__str__()
  23 + self.para["task_time"] = time.time()
  24 +
  25 + # 返回结果
  26 + res = {}
  27 +
  28 + try:
  29 +
  30 +
  31 + # 图层重名检查
  32 +
  33 + meta_list: list = json.loads(self.para.get("meta").__str__())
  34 + check_meta_only = int(self.para.get("check_meta_only", 0))
  35 +
  36 + res["data"] = {}
  37 +
  38 +
  39 + database = Database.query.filter_by(guid=self.para.get("database_guid")).one_or_none()
  40 + if not database:
  41 + raise Exception("数据库不存在!")
  42 + pg_ds: DataSource = PGUtil.open_pg_data_source(1, DES.decode(database.sqlalchemy_uri))
  43 +
  44 + res["result"] = True
  45 +
  46 + for meta in meta_list:
  47 + layers: dict = meta.get("layer")
  48 + for layer_name_origin in layers.keys():
  49 + layer_name = layers.get(layer_name_origin)
  50 + if pg_ds.GetLayerByName(layer_name) or InsertingLayerName.query.filter_by(
  51 + name=layer_name).one_or_none():
  52 + res["data"][layer_name_origin] = 0
  53 + res["result"] = False
  54 + # 判断特殊字符
  55 + elif re.search(r"\W", layer_name):
  56 + res["data"][layer_name_origin] = -1
  57 + res["result"] = False
  58 + else:
  59 + res["data"][layer_name_origin] = 1
  60 + if pg_ds:
  61 + try:
  62 + pg_ds.Destroy()
  63 + except:
  64 + print("关闭数据库失败!")
  65 +
  66 + except Exception as e:
  67 + raise e
  68 +
  69 + return res
  70 +
  71 + api_doc = {
  72 + "tags": ["IO接口"],
  73 + "parameters": [
  74 + {"name": "meta",
  75 + "in": "formData",
  76 + "type": "string",
  77 + "description": "数据meta"}
  78 + ],
  79 + "responses": {
  80 + 200: {
  81 + "schema": {
  82 + "properties": {
  83 + }
  84 + }
  85 + }
  86 + }
  87 + }
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2020/11/27
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +from app.models import *
  8 +
  9 +import traceback
  10 +
  11 +from osgeo.ogr import DataSource,Layer,FeatureDefn,FieldDefn
  12 +from osgeo import gdal ,ogr
  13 +import os
  14 +import uuid
  15 +import configure
  16 +from app.util.component.ApiTemplate import ApiTemplate
  17 +from app.util.component.PGUtil import PGUtil
  18 +from app.util.component.ZipUtil import ZipUtil
  19 +class Api(ApiTemplate):
  20 +
  21 + api_name = "下载数据"
  22 + def process(self):
  23 + #获取参数
  24 +
  25 + #返回结果
  26 + res={}
  27 + #设置编码
  28 + encoding = self.para.get("encoding")
  29 + if encoding:
  30 + gdal.SetConfigOption("SHAPE_ENCODING",encoding)
  31 + else:
  32 + gdal.SetConfigOption("SHAPE_ENCODING", "GBK")
  33 +
  34 + ds:DataSource = None
  35 + try:
  36 + table_names = self.para.get("table_name").split(",")
  37 + database_guid = self.para.get("database_guid")
  38 + database = Database.query.filter_by(guid=database_guid).one_or_none()
  39 + if not database:
  40 + raise Exception("数据库不存在!")
  41 +
  42 + ds:DataSource = PGUtil.open_pg_data_source(0,DES.decode(database.sqlalchemy_uri))
  43 +
  44 + download_type = self.para.get("download_type")
  45 +
  46 + data = None
  47 + if download_type.__eq__("shp"):
  48 + data = self.download_shp(table_names,ds)
  49 + if download_type.__eq__("gdb"):
  50 + data = self.download_gdb(table_names, ds,database_guid)
  51 +
  52 + res["data"] = data
  53 + res["result"] = True
  54 + except Exception as e:
  55 + print(traceback.format_exc())
  56 + res["msg"]= e.__str__()
  57 + res["result"]=False
  58 + finally:
  59 + if ds:
  60 + ds.Destroy()
  61 + return res
  62 +
  63 +
  64 + def download_shp(self,table_names,ds):
  65 + data = []
  66 + for table_name in table_names:
  67 + url = self.download_one(ds, table_name)
  68 + data.append({"name": table_name, "download_url": url})
  69 + return data
  70 +
  71 + def download_one(self,ds,table_name):
  72 +
  73 + layer: Layer = ds.GetLayerByName(table_name)
  74 + driver = ogr.GetDriverByName("ESRI Shapefile")
  75 + uuid_ = uuid.uuid1().__str__()
  76 + parent = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
  77 + dirpath = os.path.join(parent, "file_tmp", uuid_)
  78 + os.makedirs(dirpath)
  79 + data_source: DataSource = driver.CreateDataSource(dirpath + "/{}.shp".format(table_name))
  80 + data_source.CopyLayer(layer, table_name)
  81 + data_source.Destroy()
  82 + ZipUtil.create_zip(os.path.join(parent, "file_tmp", table_name+"_"+uuid_) + ".zip", [dirpath])
  83 + return "http://" + configure.deploy_ip_host + "/API/IO/Download/{}".format(table_name+"_"+uuid_ + ".zip")
  84 +
  85 +
  86 + def download_gdb(self,table_names,ds,database_guid):
  87 + ogr.RegisterAll()
  88 + data = []
  89 + gdal.UseExceptions()
  90 + gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES")
  91 +
  92 + # 创建一个gdb datasource
  93 + gdb_driver = ogr.GetDriverByName('FileGDB')
  94 + uuid_ = uuid.uuid1().__str__()
  95 + parent = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
  96 + gdb_path = os.path.join(parent, "file_tmp", uuid_+".gdb")
  97 + gdb_ds: DataSource = gdb_driver.CreateDataSource(gdb_path)
  98 +
  99 +
  100 + for table_name in table_names:
  101 +
  102 + layer: Layer = ds.GetLayerByName(table_name)
  103 + table = Table.query.filter_by(name=table_name, database_guid=database_guid).one_or_none()
  104 + feature_defn: FeatureDefn = layer.GetLayerDefn()
  105 +
  106 + for i in range(feature_defn.GetFieldCount()):
  107 + field_defn:FieldDefn = feature_defn.GetFieldDefn(i)
  108 + field_alias = Columns.query.filter_by(table_guid=table.guid,name=field_defn.GetName()).one_or_none().alias
  109 + field_defn.SetAlternativeName(field_alias)
  110 +
  111 + table_alias= table.alias
  112 +
  113 + # if is_chinese(table_name):
  114 + # if not table_alias:
  115 + # table_alias = table_name
  116 + # table_name = "table{}".format(table_name.__hash__())
  117 +
  118 + gdb_ds.CopyLayer(layer, table_name,["LAYER_ALIAS={}".format(table_alias)])
  119 +
  120 + gdb_ds.Destroy()
  121 + ZipUtil.create_zip(gdb_path + ".zip", [gdb_path])
  122 + data.append({"name": ",".join(table_names), "download_url": "http://" + configure.deploy_ip_host + "/API/IO/Download/{}".format(uuid_+".gdb" + ".zip")})
  123 +
  124 +
  125 + return data
  126 +
  127 +
  128 +
  129 + api_doc={
  130 + "tags":["IO接口"],
  131 + "description":"下载数据",
  132 + "parameters":[
  133 + {"name": "table_name",
  134 + "in": "formData",
  135 + "type":"string","description":"支持多图层下载,以逗号相隔","required":"true"},
  136 + {"name": "encoding",
  137 + "in": "formData",
  138 + "type": "string",
  139 + "enum":["GBK","UTF-8"]},
  140 + {"name": "download_type",
  141 + "in": "formData",
  142 + "type": "string",
  143 + "enum": ["shp", "gdb"],"required":"true"
  144 + },
  145 + {"name": "database_guid",
  146 + "in": "formData",
  147 + "type": "string","required":"true"
  148 + }
  149 + ],
  150 + "responses":{
  151 + 200:{
  152 + "schema":{
  153 + "properties":{
  154 + "content":{
  155 + "type": "string",
  156 + "description": "The name of the user"
  157 + }
  158 + }
  159 + }
  160 + }
  161 + }
  162 +}
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/1/27
  4 +#email: nheweijun@sina.com
  5 +
  6 +from osgeo.ogr import *
  7 +import uuid
  8 +
  9 +import time
  10 +from app.models import *
  11 +import json
  12 +import re
  13 +from app.util.component.ApiTemplate import ApiTemplate
  14 +from app.util.component.PGUtil import PGUtil
  15 +
  16 +
  17 +
  18 +class Api(ApiTemplate):
  19 +
  20 + api_name = "通过meta入库"
  21 +
  22 + def process(self):
  23 +
  24 + #设置任务信息
  25 + self.para["task_guid"] = uuid.uuid1().__str__()
  26 + self.para["task_time"] = time.time()
  27 +
  28 + #返回结果
  29 + res={}
  30 +
  31 + try:
  32 + #检测目录
  33 + if Catalog.query.filter_by(pguid=self.para.get("guid")).all():
  34 + raise Exception("目录非子目录,不可入库!")
  35 +
  36 + # 图层重名检查
  37 + meta_list:list = json.loads(self.para.get("meta").__str__())
  38 + check_meta_only = int(self.para.get("check_meta_only",0))
  39 +
  40 + res["data"] = {}
  41 + if check_meta_only:
  42 +
  43 + database = Database.query.filter_by(guid=self.para.get("database_guid")).one_or_none()
  44 + if not database:
  45 + raise Exception("数据库不存在!")
  46 + pg_ds: DataSource = PGUtil.open_pg_data_source(1, DES.decode(database.sqlalchemy_uri))
  47 +
  48 + res["result"] = True
  49 +
  50 + for meta in meta_list:
  51 + layers:dict = meta.get("layer")
  52 + for layer_name_origin in layers.keys():
  53 + layer_name = layers.get(layer_name_origin)
  54 + if pg_ds.GetLayerByName(layer_name) or InsertingLayerName.query.filter_by(name=layer_name).one_or_none():
  55 + res["data"][layer_name_origin]=0
  56 + res["result"] = False
  57 + # 判断特殊字符
  58 + elif re.search(r"\W",layer_name):
  59 + res["data"][layer_name_origin]=-1
  60 + res["result"] = False
  61 + else :
  62 + res["data"][layer_name_origin] = 1
  63 +
  64 + if pg_ds:
  65 + try:
  66 + pg_ds.Destroy()
  67 + except:
  68 + print("关闭数据库失败!")
  69 + return res
  70 +
  71 + # 录入数据后台进程,录入主函数为entry
  72 + # 初始化task
  73 + task = Task(guid=self.para.get("task_guid"),
  74 + name=self.para.get("task_name"),
  75 + create_time=datetime.datetime.now(),
  76 + state=0,
  77 + creator=self.para.get("creator"),
  78 + file_name=meta_list[0].get("filename"),
  79 + database_guid=self.para.get("database_guid"),
  80 + catalog_guid=self.para.get("catalog_guid"),
  81 + process="等待入库",
  82 + parameter=json.dumps(self.para))
  83 + db.session.add(task)
  84 + db.session.commit()
  85 +
  86 + res["result"] = True
  87 + res["msg"] = "数据录入提交成功!"
  88 + res["data"] = self.para["task_guid"]
  89 + except Exception as e:
  90 + raise e
  91 + return res
  92 +
  93 +
  94 + api_doc={
  95 + "tags":["IO接口"],
  96 + "parameters":[
  97 + {"name": "meta",
  98 + "in": "formData",
  99 + "type": "string",
  100 + "description": "数据meta"},
  101 + {"name": "encoding",
  102 + "in": "formData",
  103 + "type": "string",
  104 + "description": "原shp文件编码,非必要,优先使用cpg文件中编码,没有则默认GBK","enum":["UTF-8","GBK"]},
  105 + {"name": "overwrite",
  106 + "in": "formData",
  107 + "type": "string",
  108 + "description": "是否覆盖",
  109 + "enum":["yes","no"]},
  110 + {"name": "fid",
  111 + "in": "formData",
  112 + "type": "string",
  113 + "description": "fid列名"},
  114 + {"name": "geom_name",
  115 + "in": "formData",
  116 + "type": "string",
  117 + "description": "空间属性列名"},
  118 + {"name": "task_name",
  119 + "in": "formData",
  120 + "type": "string",
  121 + "description": "任务名",
  122 + "required":"true"},
  123 + {"name": "creator",
  124 + "in": "formData",
  125 + "type": "string",
  126 + "description": "创建人"},
  127 + {"name": "database_guid",
  128 + "in": "formData",
  129 + "type": "string",
  130 + "description": "数据库guid",
  131 + "required": "true"},
  132 + {"name": "catalog_guid",
  133 + "in": "formData",
  134 + "type": "string",
  135 + "description": "目录guid"},
  136 + {"name": "check_meta_only",
  137 + "in": "formData",
  138 + "type": "int",
  139 + "description": "是否只检查meta","enum":[0,1]}
  140 +
  141 + ],
  142 + "responses":{
  143 + 200:{
  144 + "schema":{
  145 + "properties":{
  146 + }
  147 + }
  148 + }
  149 + }
  150 + }
  1 +# coding=utf-8
  2 +# author: 4N
  3 +# createtime: 2020/9/4
  4 +# email: nheweijun@sina.com
  5 +
  6 +import traceback
  7 +from osgeo.ogr import *
  8 +from osgeo import ogr
  9 +
  10 +from flask import request
  11 +import os
  12 +import uuid
  13 +
  14 +import json
  15 +from app.util.component.ApiTemplate import ApiTemplate
  16 +from app.util.component.ZipUtil import ZipUtil
  17 +from app.util.component.FileProcess import FileProcess
  18 +import datetime
  19 +import time
  20 +class Api(ApiTemplate):
  21 + api_name = "本地数据list"
  22 + def process(self):
  23 + res = {}
  24 +
  25 + try:
  26 + project_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))
  27 + base_path = os.path.join(project_path,"tmp")
  28 + if self.para.get("data_path"):
  29 + base_path = os.path.normpath(self.para.get("data_path"))
  30 + data_list:list = []
  31 + for f in os.listdir(base_path):
  32 +
  33 + file_path = os.path.normpath(os.path.join(base_path, f))
  34 + file_size = FileProcess.get_file_size(file_path)
  35 +
  36 + fctime = datetime.datetime.fromtimestamp(os.path.getctime(file_path)).strftime('%Y-%m-%d %H:%M:%S')
  37 +
  38 + file_info ={"name":f,"path":file_path,"size":file_size,"create_time":fctime}
  39 +
  40 + if file_path.endswith("shp"):
  41 + file_info["type"]="shp"
  42 + data_list.append(file_info)
  43 + elif file_path.endswith("gdb"):
  44 + file_info["type"]="gdb"
  45 + data_list.append(file_info)
  46 + elif file_path.endswith("zip"):
  47 + file_info["type"]="zip"
  48 + data_list.append(file_info)
  49 + elif os.path.isdir(file_path):
  50 + bn = os.path.basename(file_path)
  51 + if not len(bn.split("-"))==5:
  52 + file_info["type"] = "dir"
  53 + data_list.append(file_info)
  54 +
  55 + data_list_sorted = sorted(data_list, key=lambda x: x["name"])
  56 + res["data"]=data_list_sorted
  57 + res["result"]=True
  58 + except Exception as e:
  59 + raise e
  60 + return res
  61 +
  62 +
  63 +
  64 + api_doc={
  65 + "tags":["IO接口"],
  66 + "parameters":[
  67 + {"name": "data_path",
  68 + "in": "formData",
  69 + "type": "string",
  70 + "description": "数据文件路径"}
  71 + ],
  72 + "responses":{
  73 + 200:{
  74 + "schema":{
  75 + "properties":{
  76 + }
  77 + }
  78 + }
  79 + }
  80 +}
  1 +# coding=utf-8
  2 +# author: 4N
  3 +# createtime: 2020/9/4
  4 +# email: nheweijun@sina.com
  5 +
  6 +import traceback
  7 +from osgeo.ogr import *
  8 +from osgeo import ogr
  9 +
  10 +from flask import request
  11 +import os
  12 +import uuid
  13 +
  14 +import json
  15 +from app.util.component.ApiTemplate import ApiTemplate
  16 +from app.util.component.ZipUtil import ZipUtil
  17 +from app.util.component.FileProcess import FileProcess
  18 +
  19 +
  20 +class Api(ApiTemplate):
  21 + api_name = "获取meta"
  22 + def process(self):
  23 + res = {}
  24 +
  25 + try:
  26 +
  27 + spatial_files=[]
  28 + if self.para.get("data_path"):
  29 + filename = os.path.basename(self.para.get("data_path"))
  30 + #处理
  31 +
  32 + if self.para.get("data_path").endswith("zip"):
  33 +
  34 + store_path = ZipUtil.unzip(self.para.get("data_path"),True)
  35 + spatial_files = FileProcess.get_spatial_file(store_path)
  36 +
  37 + elif self.para.get("data_path").endswith("shp"):
  38 + data_path=self.para.get("data_path")
  39 + encoding_cpg_path = data_path.split(".shp")[0]+".cpg"
  40 + with open(encoding_cpg_path) as fd:
  41 + encoding_cpg = fd.readline().strip()
  42 + if not os.path.exists(encoding_cpg_path):
  43 + encoding_cpg=None
  44 + spatial_files.append((data_path, encoding_cpg))
  45 + elif self.para.get("data_path").endswith("gdb"):
  46 + data_path=self.para.get("data_path")
  47 + encoding_cpg=None
  48 + spatial_files.append((data_path, encoding_cpg))
  49 + else:
  50 + raise Exception("文件不符合规格!")
  51 +
  52 + else:
  53 + # 保存文件
  54 + parent = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
  55 + dir_path, store_file = FileProcess.save(parent)
  56 + store_path = ZipUtil.unzip(store_file)
  57 +
  58 + spatial_files = FileProcess.get_spatial_file(store_path)
  59 +
  60 + file = request.files['file']
  61 + filename = file.filename.split('"')[0]
  62 +
  63 + res["data"] =[]
  64 +
  65 + for data_path,code in spatial_files:
  66 + one_data = self.get_meta(data_path)
  67 + one_data["encoding"]=code
  68 + one_data["filename"] = filename
  69 + res["data"].append(one_data)
  70 + res["result"] = True
  71 +
  72 + except Exception as e:
  73 + raise e
  74 + return json.dumps(res,ensure_ascii=False)
  75 +
  76 +
  77 + def get_meta(self,data_path):
  78 + ds: DataSource = None
  79 + info = {}
  80 + layer_name = {}
  81 + info["data_path"] = os.path.normpath(data_path)
  82 + info["layer"] =layer_name
  83 + try:
  84 + # 分为shp和gdb 2种
  85 + if data_path.endswith("shp"):
  86 + info["type"]="shp"
  87 + driver: Driver = ogr.GetDriverByName("ESRI Shapefile")
  88 + ds: DataSource = driver.Open(data_path, 1)
  89 + if not ds:
  90 + raise Exception("打开数据失败!")
  91 + layer: Layer = ds.GetLayer(0)
  92 + layer_name[layer.GetName().lower()] = layer.GetName().lower()
  93 +
  94 + if data_path.endswith("gdb"):
  95 + info["type"] = "gdb"
  96 + driver: Driver = ogr.GetDriverByName("OpenFileGDB")
  97 + ds: DataSource = driver.Open(data_path, 0)
  98 + if not ds:
  99 + raise Exception("打开数据失败!")
  100 + for i in range(ds.GetLayerCount()):
  101 + layer: Layer = ds.GetLayer(i)
  102 + layer_name[layer.GetName().lower()] = layer.GetName().lower()
  103 + except Exception as e :
  104 + print(traceback.format_exc())
  105 + info={}
  106 + finally:
  107 + if ds:
  108 + ds.Destroy()
  109 + return info
  110 +
  111 +
  112 + api_doc={
  113 + "tags":["IO接口"],
  114 + "parameters":[
  115 + {"name": "file",
  116 + "in": "formData",
  117 + "type":"file",
  118 + "description":"数据文件zip压缩包"},
  119 + {"name": "data_path",
  120 + "in": "formData",
  121 + "type": "string",
  122 + "description": "数据文件路径"}
  123 + ],
  124 + "responses":{
  125 + 200:{
  126 + "schema":{
  127 + "properties":{
  128 + }
  129 + }
  130 + }
  131 + }
  132 +}
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2020/11/30
  4 +#email: nheweijun@sina.com
  5 +from app.util import *
  6 +import configure
  7 +from osgeo import ogr
  8 +
  9 +from configure import SQLALCHEMY_DATABASE_URI
  10 +from sqlalchemy import create_engine
  11 +from sqlalchemy.orm import sessionmaker, session
  12 +
  13 +
  14 +
  15 +
  16 +
  17 +
  18 +
  19 +
  20 +
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/3/1
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +from flasgger import swag_from
  8 +from flask import Blueprint
  9 +from app.util import BlueprintApi
  10 +
  11 +from . import field_edit
  12 +
  13 +from . import table_list
  14 +from . import field_list
  15 +from . import table_edit
  16 +from . import table_info
  17 +from . import table_refresh
  18 +from . import table_delete
  19 +from . import table_view
  20 +class DataManager(BlueprintApi):
  21 +
  22 + bp = Blueprint("DataManager", __name__, url_prefix="/API/Manager")
  23 +
  24 + @staticmethod
  25 + @bp.route('/FieldEdit', methods=['POST'])
  26 + @swag_from(field_edit.Api.api_doc)
  27 + def field_edit():
  28 + """
  29 + 修改属性别名
  30 + """
  31 + return field_edit.Api().result
  32 +
  33 + @staticmethod
  34 + @bp.route('/FieldList', methods=['POST'])
  35 + @swag_from(field_list.Api.api_doc)
  36 + def field_list():
  37 + """
  38 + 属性列表
  39 + """
  40 + return field_list.Api().result
  41 +
  42 + @staticmethod
  43 + @bp.route('/TableList', methods=['POST'])
  44 + @swag_from(table_list.Api.api_doc)
  45 + def table_list():
  46 + """
  47 + 数据列表
  48 + """
  49 + return table_list.Api().result
  50 +
  51 +
  52 + @staticmethod
  53 + @bp.route('/TableEdit', methods=['POST'])
  54 + @swag_from(table_edit.Api.api_doc)
  55 + def table_edit():
  56 + """
  57 + 修改数据
  58 + """
  59 + return table_edit.Api().result
  60 +
  61 +
  62 + @staticmethod
  63 + @bp.route('/TableDelete', methods=['POST'])
  64 + @swag_from(table_delete.Api.api_doc)
  65 + def table_delete():
  66 + """
  67 + 删除数据
  68 + """
  69 + return table_delete.Api().result
  70 +
  71 +
  72 + @staticmethod
  73 + @bp.route('/TableInfo', methods=['POST'])
  74 + @swag_from(table_info.Api.api_doc)
  75 + def table_info():
  76 + """
  77 + 数据信息
  78 + """
  79 + return table_info.Api().result
  80 +
  81 +
  82 + @staticmethod
  83 + @bp.route('/TableRefresh', methods=['POST'])
  84 + @swag_from(table_refresh.Api.api_doc)
  85 + def table_refresh():
  86 + """
  87 + 刷新数据
  88 + """
  89 + return table_refresh.Api().result
  90 +
  91 + @staticmethod
  92 + @bp.route('/TableView', methods=['POST'])
  93 + @swag_from(table_view.Api.api_doc)
  94 + def table_view():
  95 + """
  96 + 数据浏览
  97 + """
  98 + return table_view.Api().result
  1 +#author: 4N
  2 +#createtime: 2021/1/27
  3 +#email: nheweijun@sina.com
  4 +
  5 +from app.models import Columns
  6 +import datetime
  7 +
  8 +
  9 +from app.models import db
  10 +from app.util.component.ApiTemplate import ApiTemplate
  11 +
  12 +
  13 +class Api(ApiTemplate):
  14 + api_name = "修改属性"
  15 + def process(self):
  16 +
  17 + #返回结果
  18 + res={}
  19 +
  20 + column_guid = self.para.get("column_guid")
  21 + try:
  22 + Columns.query.filter_by(guid = column_guid).update({"alias":self.para.get("column_alias"),"update_time":datetime.datetime.now()})
  23 + db.session.commit()
  24 + res["result"] = True
  25 + res["msg"] = "属性别名修改成功!"
  26 +
  27 + except Exception as e:
  28 + raise e
  29 +
  30 + return res
  31 +
  32 + api_doc={
  33 + "tags":["管理接口"],
  34 + "parameters":[
  35 + {"name": "column_guid",
  36 + "in": "formData",
  37 + "type": "string",
  38 + "description": "属性guid","required":"true"},
  39 + {"name": "column_alias",
  40 + "in": "formData",
  41 + "type": "string",
  42 + "description": "属性别名","required":"true"},
  43 +
  44 + ],
  45 + "responses":{
  46 + 200:{
  47 + "schema":{
  48 + "properties":{
  49 + }
  50 + }
  51 + }
  52 + }
  53 + }
  1 +#author: 4N
  2 +#createtime: 2021/1/27
  3 +#email: nheweijun@sina.com
  4 +
  5 +
  6 +import traceback
  7 +from app.models import Table
  8 +from app.util.component.ApiTemplate import ApiTemplate
  9 +from app.util.component.ModelVisitor import ModelVisitor
  10 +
  11 +class Api(ApiTemplate):
  12 + api_name = "属性列表"
  13 + def process(self):
  14 +
  15 + #返回结果
  16 + dir_path = None
  17 + res={}
  18 +
  19 + try:
  20 + table_guid = self.para.get("guid")
  21 + table:Table = Table.query.filter_by(guid=table_guid).one_or_none()
  22 + if table:
  23 + res["result"]=True
  24 + res["data"] = ModelVisitor.objects_to_jsonarray(table.relate_columns)
  25 + else:
  26 + res["result"]=False
  27 + res["msg"] = "数据表不存在!"
  28 + except Exception as e:
  29 + print(traceback.format_exc())
  30 + raise e
  31 +
  32 + return res
  33 +
  34 + api_doc={
  35 + "tags":["管理接口"],
  36 + "parameters":[
  37 + {"name": "guid",
  38 + "in": "formData",
  39 + "type": "string",
  40 + "description": "表guid"},
  41 +
  42 + ],
  43 + "responses":{
  44 + 200:{
  45 + "schema":{
  46 + "properties":{
  47 + }
  48 + }
  49 + }
  50 + }
  51 + }
  1 +#author: 4N
  2 +#createtime: 2021/1/27
  3 +#email: nheweijun@sina.com
  4 +
  5 +
  6 +
  7 +import traceback
  8 +from app.models import Table,Database,DES
  9 +
  10 +from osgeo.ogr import DataSource
  11 +
  12 +
  13 +from app.models import db
  14 +from app.util.component.ApiTemplate import ApiTemplate
  15 +
  16 +from app.util.component.PGUtil import PGUtil
  17 +class Api(ApiTemplate):
  18 + api_name = "删除表"
  19 + def process(self):
  20 +
  21 + res = {}
  22 + pg_ds = None
  23 + try:
  24 +
  25 + table_guid = self.para.get("guid")
  26 +
  27 + table = Table.query.filter_by(guid=table_guid)
  28 +
  29 + if not table.one_or_none():
  30 + res["result"]=False
  31 + res["msg"]= "数据不存在!"
  32 + return res
  33 +
  34 +
  35 + table = table.one_or_none()
  36 +
  37 +
  38 +
  39 + # 删除真实数据
  40 + database = Database.query.filter_by(guid=table.database_guid).one_or_none()
  41 + if not database:
  42 + res["result"]=False
  43 + res["msg"]= "数据库不存在!"
  44 + return res
  45 +
  46 +
  47 + pg_ds: DataSource = PGUtil.open_pg_data_source(1, DES.decode(database.sqlalchemy_uri))
  48 +
  49 +
  50 + #删除抽稀表
  51 + vacuate_tables=table.relate_table_vacuates.all()
  52 + for vt in vacuate_tables:
  53 + pg_ds.DeleteLayer(vt.name)
  54 +
  55 + pg_ds.DeleteLayer(table.name)
  56 +
  57 + # 删除元数据
  58 +
  59 + db.session.delete(table)
  60 + db.session.commit()
  61 + res["result"] = True
  62 + res["msg"] ="删除成功!"
  63 + except Exception as e:
  64 + raise e
  65 + finally:
  66 + if pg_ds:
  67 + pg_ds.Destroy()
  68 + return res
  69 +
  70 + api_doc={
  71 + "tags":["管理接口"],
  72 + "parameters":[
  73 + {"name": "guid",
  74 + "in": "formData",
  75 + "type": "string",
  76 + "description": "表guid","required":"true"},
  77 + ],
  78 + "responses":{
  79 + 200:{
  80 + "schema":{
  81 + "properties":{
  82 + }
  83 + }
  84 + }
  85 + }
  86 + }
  1 +#author: 4N
  2 +#createtime: 2021/1/27
  3 +#email: nheweijun@sina.com
  4 +
  5 +
  6 +
  7 +from app.models import Table,Catalog,Database,DES
  8 +
  9 +from app.models import db,Columns
  10 +import json
  11 +
  12 +from sqlalchemy.orm import Session
  13 +import datetime
  14 +from app.util.component.ApiTemplate import ApiTemplate
  15 +from app.util.component.PGUtil import PGUtil
  16 +
  17 +class Api(ApiTemplate):
  18 + api_name = "修改表信息"
  19 + def process(self):
  20 +
  21 + res = {}
  22 + try:
  23 +
  24 + table_guid = self.para.get("guid")
  25 + table_alias = self.para.get("alias")
  26 + catalog_guid = self.para.get("catalog_guid")
  27 + description = self.para.get("description")
  28 + name = self.para.get("name")
  29 + columns_edit = self.para.get("columns_edit")
  30 +
  31 +
  32 + table = Table.query.filter_by(guid=table_guid)
  33 + if not table.one_or_none():
  34 + res["result"]=False
  35 + res["msg"]= "数据不存在!"
  36 + return res
  37 +
  38 +
  39 + if self.para.__contains__("catalog_guid"):
  40 + if catalog_guid is None:
  41 + table.update({"catalog_guid": None})
  42 +
  43 + else:
  44 + # 检测目录的有效性
  45 +
  46 + if not Catalog.query.filter_by(guid=catalog_guid).one_or_none():
  47 + raise Exception("目录不存在!")
  48 +
  49 + if not table.one_or_none().database_guid.__eq__(
  50 + Catalog.query.filter_by(guid=catalog_guid).one_or_none().database_guid
  51 + ):
  52 + raise Exception("该目录不属于表所在的数据库!")
  53 + table.update({"catalog_guid": catalog_guid})
  54 +
  55 +
  56 + if self.para.__contains__("alias"):
  57 + table.update({"alias":table_alias})
  58 +
  59 + if self.para.__contains__("description"):
  60 + table.update({"description":description})
  61 +
  62 + if columns_edit:
  63 + columns_edit_list = json.loads(columns_edit)
  64 + for ce in columns_edit_list:
  65 + Columns.query.filter_by(guid=ce["guid"]).update({"alias": ce.get("alias")})
  66 +
  67 + if name:
  68 + sys_session=None
  69 + try:
  70 + this_table = table.one_or_none()
  71 + database:Database= this_table.relate_database
  72 + sys_session: Session = PGUtil.get_db_session(DES.decode(database.sqlalchemy_uri))
  73 + rename_sql = 'alter table "{}" rename to "{}"'.format(this_table.name,name)
  74 + sys_session.execute(rename_sql)
  75 + sys_session.commit()
  76 + print(rename_sql)
  77 + # 更新所有相关业务表
  78 + same_databases = Database.query.filter_by(sqlalchemy_uri=this_table.relate_database.sqlalchemy_uri).all()
  79 + same_databases_database_guid = [d.guid for d in same_databases]
  80 + re_tables = Table.query.filter(Table.name==this_table.name).filter(Table.database_guid.in_(same_databases_database_guid))
  81 + re_tables.update({"name": name},synchronize_session=False)
  82 + except:
  83 + raise Exception("表名更新失败,表名已存在!")
  84 + finally:
  85 + if sys_session:
  86 + sys_session.close()
  87 + db.session.commit()
  88 +
  89 + if catalog_guid or table_alias or name or columns_edit:
  90 + Table.query.filter_by(guid=table_guid).update({"update_time":datetime.datetime.now()})
  91 + db.session.commit()
  92 + res["result"] = True
  93 + res["msg"] = "更新成功!"
  94 + except Exception as e:
  95 + db.session.rollback()
  96 + raise e
  97 + return res
  98 +
  99 + api_doc={
  100 + "tags":["管理接口"],
  101 + "parameters":[
  102 + {"name": "guid",
  103 + "in": "formData",
  104 + "type": "string",
  105 + "description": "表guid","required":"true"},
  106 + {"name": "alias",
  107 + "in": "formData",
  108 + "type": "string",
  109 + "description": "表别名"},
  110 + {"name": "name",
  111 + "in": "formData",
  112 + "type": "string",
  113 + "description": "表名"},
  114 + {"name": "description",
  115 + "in": "formData",
  116 + "type": "string",
  117 + "description": "表描述"},
  118 + {"name": "catalog_guid",
  119 + "in": "formData",
  120 + "type": "string",
  121 + "description": "目录guid,如果要撤销挂载目录,传None"},
  122 + {"name": "columns_edit",
  123 + "in": "formData",
  124 + "type": "string",
  125 + "description": '需要修改的属性的列表,如 [{"guid":"1fda","alias":"测试"}]'},
  126 +
  127 + ],
  128 + "responses":{
  129 + 200:{
  130 + "schema":{
  131 + "properties":{
  132 + }
  133 + }
  134 + }
  135 + }
  136 + }
  1 +#author: 4N
  2 +#createtime: 2021/1/27
  3 +#email: nheweijun@sina.com
  4 +
  5 +from app.models import Table,Columns
  6 +
  7 +from app.util.component.ApiTemplate import ApiTemplate
  8 +from app.util.component.ModelVisitor import ModelVisitor
  9 +
  10 +class Api(ApiTemplate):
  11 + api_name = "表信息"
  12 + def process(self):
  13 + res = {}
  14 + try:
  15 + table_guid = self.para.get("guid")
  16 + table = Table.query.filter_by(guid=table_guid)
  17 + if not table.one_or_none():
  18 + raise Exception("数据不存在!")
  19 + table = table.one_or_none()
  20 + columns = table.relate_columns.order_by(Columns.name).all()
  21 + res["data"]=ModelVisitor.table_to_json(table)
  22 + res["data"]["columns"] = ModelVisitor.objects_to_jsonarray(columns)
  23 + res["result"] = True
  24 +
  25 + except Exception as e:
  26 + raise e
  27 + return res
  28 +
  29 + api_doc={
  30 + "tags":["管理接口"],
  31 + "parameters":[
  32 + {"name": "guid",
  33 + "in": "formData",
  34 + "type": "string",
  35 + "description": "表guid","required":"true"},
  36 + ],
  37 + "responses":{
  38 + 200:{
  39 + "schema":{
  40 + "properties":{
  41 + }
  42 + }
  43 + }
  44 + }
  45 + }
  1 +#author: 4N
  2 +#createtime: 2021/1/27
  3 +#email: nheweijun@sina.com
  4 +
  5 +
  6 +from app.models import Table,Catalog,Database,DES,Columns,db
  7 +
  8 +from sqlalchemy import or_,and_
  9 +
  10 +from app.util.component.ApiTemplate import ApiTemplate
  11 +
  12 +from app.util.component.ModelVisitor import ModelVisitor
  13 +class Api(ApiTemplate):
  14 + api_name = "表列表"
  15 + def process(self):
  16 +
  17 + res = {}
  18 + try:
  19 +
  20 + page_index = int(self.para.get("page_index", "0"))
  21 + page_size = int(self.para.get("page_size", "10"))
  22 +
  23 + alias = self.para.get("alias")
  24 + name = self.para.get("name")
  25 +
  26 +
  27 + database_guid = self.para.get("database_guid")
  28 + catalog_guid = self.para.get("catalog_guid")
  29 + table_type = self.para.get("table_type")
  30 +
  31 + start_time = self.para.get("start_time")
  32 + end_time = self.para.get("end_time")
  33 +
  34 +
  35 +
  36 + recursion = int(self.para.get("recursion","0"))
  37 +
  38 + sort = int(self.para.get("sort","1"))
  39 + if sort.__eq__(1):
  40 + tables = Table.query.order_by(Table.update_time.desc())
  41 + else:
  42 + tables = Table.query.order_by(Table.name)
  43 +
  44 + if database_guid:
  45 + tables = tables.filter_by(database_guid=database_guid)
  46 + if catalog_guid:
  47 +
  48 + if recursion.__eq__(0):
  49 + tables = tables.filter_by(catalog_guid=catalog_guid)
  50 + else:
  51 + #所有子目录id
  52 + catalog_guids = [c.guid for c in Catalog.query.filter(Catalog.path.like("%" + catalog_guid + "%")).all()]
  53 + tables = tables.filter(Table.catalog_guid.in_(catalog_guids))
  54 +
  55 + if table_type:
  56 + tables = tables.filter_by(table_type=table_type)
  57 + if start_time and end_time:
  58 + tables = tables.filter(Table.create_time.between(start_time, end_time))
  59 +
  60 + # 并集
  61 + if alias and name:
  62 + tables = tables.filter(or_(Table.alias.like("%" + alias + "%") , Table.name.like("%" + name + "%")))
  63 + else:
  64 + if alias:
  65 + tables = tables.filter(Table.alias.like("%" + alias + "%"))
  66 + if name:
  67 + tables = tables.filter(Table.name.like("%" + name + "%"))
  68 + res["data"]={}
  69 + res["data"]["count"] = tables.count()
  70 + tables = tables.limit(page_size).offset(page_index * page_size).all()
  71 + res["data"]["list"]=[]
  72 +
  73 + for t in tables:
  74 + res["data"]["list"].append(ModelVisitor.table_to_json(t))
  75 +
  76 + res["result"] = True
  77 + except Exception as e:
  78 + raise e
  79 + return res
  80 +
  81 +
  82 +
  83 +
  84 +
  85 + api_doc={
  86 + "tags":["管理接口"],
  87 + "parameters":[
  88 + {"name": "page_index",
  89 + "in": "formData",
  90 + "type": "int",
  91 + "description": "页"},
  92 + {"name": "page_size",
  93 + "in": "formData",
  94 + "type": "int",
  95 + "description": "页大小"},
  96 + {"name": "alias",
  97 + "in": "formData",
  98 + "type": "string",
  99 + "description": "表别名"},
  100 + {"name": "name",
  101 + "in": "formData",
  102 + "type": "string",
  103 + "description": "表名"},
  104 + {"name": "table_type",
  105 + "in": "formData",
  106 + "type": "int",
  107 + "description": "点线面123","enum":[1,2,3]},
  108 + {"name": "database_guid",
  109 + "in": "formData",
  110 + "type": "string",
  111 + "description": "数据库guid"},
  112 + {"name": "catalog_guid",
  113 + "in": "formData",
  114 + "type": "string",
  115 + "description": "目录guid"},
  116 + {"name": "recursion",
  117 + "in": "formData",
  118 + "type": "int",
  119 + "description": "是否递归目录,0不递归,1递归","enum":[0,1]},
  120 + {"name": "start_time",
  121 + "in": "formData",
  122 + "type": "string",
  123 + "description": "开始时间 2020-12-12 00:00:00"},
  124 + {"name": "end_time",
  125 + "in": "formData",
  126 + "type": "string",
  127 + "description": "结束时间"},
  128 + {"name": "sort",
  129 + "in": "formData",
  130 + "type": "int",
  131 + "description": "排序","enum":[1,2]},
  132 + ],
  133 + "responses":{
  134 + 200:{
  135 + "schema":{
  136 + "properties":{
  137 + }
  138 + }
  139 + }
  140 + }
  141 + }
  1 +#author: 4N
  2 +#createtime: 2021/1/27
  3 +#email: nheweijun@sina.com
  4 +
  5 +
  6 +
  7 +import traceback
  8 +from app.models import Table,Database,DES,Columns,db,TableVacuate
  9 +
  10 +from osgeo.ogr import DataSource,FeatureDefn,FieldDefn,Layer
  11 +
  12 +import datetime
  13 +import uuid
  14 +
  15 +from sqlalchemy.orm import Session
  16 +
  17 +from app.util.component.PGUtil import PGUtil
  18 +from app.util.component.ModelVisitor import ModelVisitor
  19 +from app.util.component.StructuredPrint import StructurePrint
  20 +from app.util.component.ApiTemplate import ApiTemplate
  21 +from app.util.component.GeometryAdapter import GeometryAdapter
  22 +
  23 +class Api(ApiTemplate):
  24 + api_name = "数据刷新"
  25 + def process(self):
  26 +
  27 + res = {}
  28 + pg_ds =None
  29 + data_session=None
  30 + this_time = datetime.datetime.now()
  31 + try:
  32 +
  33 + database_guid = self.para.get("database_guid")
  34 + database = Database.query.filter_by(guid=database_guid).one_or_none()
  35 +
  36 + if not database:
  37 + raise Exception("数据库不存在!")
  38 + spatial_tables = Table.query.order_by(Table.create_time.desc()).filter_by(database_guid=database_guid).filter(Table.table_type!=0).all()
  39 + spatial_tables_names = [table.name for table in spatial_tables]
  40 + db_tables_names = []
  41 +
  42 +
  43 + pg_ds: DataSource = PGUtil.open_pg_data_source(1, DES.decode(database.sqlalchemy_uri))
  44 + # 更新空间表
  45 + # 增加表
  46 + self.add_spatail_table(database, pg_ds, spatial_tables_names, db_tables_names, this_time)
  47 +
  48 + # 删除/修改表
  49 + self.edit_spatial_table(pg_ds, spatial_tables, db_tables_names, this_time)
  50 +
  51 + # 处理抽稀表
  52 + self.deal_vacuate_table(pg_ds,database.guid)
  53 +
  54 +
  55 + # 空间表处理完毕
  56 + db.session.commit()
  57 +
  58 +
  59 + # 注册普通表
  60 + # 实体库连接
  61 + data_session: Session = PGUtil.get_db_session(DES.decode(database.sqlalchemy_uri))
  62 +
  63 + # 空间表
  64 + spatial_tables = Table.query.order_by(Table.create_time.desc()).filter_by(database_guid=database_guid).filter(Table.table_type!=0).all()
  65 + spatial_tables_names = [table.name for table in spatial_tables]
  66 +
  67 +
  68 + #原有普通表
  69 + common_tables = Table.query.order_by(Table.create_time.desc()).filter_by(database_guid=database_guid).filter(Table.table_type==0).all()
  70 + origin_common_tables_name = [table.name for table in common_tables]
  71 +
  72 +
  73 + # 现有普通表
  74 + real_common_tables_name =[]
  75 + # 只注册public中的表
  76 + common_result = data_session.execute(
  77 + "select relname as tabname from pg_class c where relkind = 'r' and relnamespace=2200 and relname not like 'pg_%' and relname not like 'sql_%' order by relname").fetchall()
  78 + for re in common_result:
  79 + table_name = re[0]
  80 + if table_name not in spatial_tables_names and (not table_name.__contains__("_vacuate_")):
  81 + real_common_tables_name.append(table_name)
  82 +
  83 + # 增加新普通表
  84 +
  85 + self.add_common_table(data_session, database_guid, real_common_tables_name, origin_common_tables_name,
  86 + this_time)
  87 +
  88 +
  89 + #删除、修改普通表
  90 + self.edit_common_table(data_session, database_guid, real_common_tables_name, origin_common_tables_name,
  91 + this_time)
  92 +
  93 + db.session.commit()
  94 + res["msg"] = "刷新数据成功!"
  95 + res["result"] = True
  96 +
  97 + except Exception as e:
  98 + raise e
  99 +
  100 + finally:
  101 + if pg_ds:
  102 + pg_ds.Destroy()
  103 + if data_session:
  104 + data_session.close()
  105 +
  106 + return res
  107 +
  108 +
  109 + def add_spatail_table(self,database,pg_ds,spatial_tables_names,db_tables_names,this_time):
  110 + # 更新空间表
  111 + # 增加表
  112 +
  113 + for i in range(pg_ds.GetLayerCount()):
  114 + layer: Layer = pg_ds.GetLayer(i)
  115 + geom_column = layer.GetGeometryColumn()
  116 + db_tables_names.append(layer.GetName())
  117 + if not geom_column:
  118 + continue
  119 + if layer.GetName() not in spatial_tables_names:
  120 + l_name = layer.GetName()
  121 +
  122 + # 只注册public的空间表,其他表空间的表名会有.
  123 + if layer.GetName().__contains__("."):
  124 + continue
  125 +
  126 + if layer.GetName().__contains__("_vacuate_"):
  127 + continue
  128 +
  129 + # 范围统计和数量统计以100w为界限
  130 + query_count_layer: Layer = pg_ds.ExecuteSQL(
  131 + "SELECT reltuples::bigint AS ec FROM pg_class WHERE oid = 'public.{}'::regclass".format(
  132 + l_name))
  133 + feature_count = query_count_layer.GetFeature(0).GetField("ec")
  134 + # 要素少于100w可以精确统计
  135 + if feature_count < 1000000:
  136 + feature_count = layer.GetFeatureCount()
  137 + ext = layer.GetExtent()
  138 + else:
  139 + query_ext_layer: Layer = pg_ds.ExecuteSQL(
  140 + "select geometry(ST_EstimatedExtent('public', '{}','{}'))".format(l_name,
  141 + layer.GetGeometryColumn()))
  142 + ext = query_ext_layer.GetExtent()
  143 + if ext[0] < 360:
  144 + ext = [round(e, 6) for e in ext]
  145 + else:
  146 + ext = [round(e, 2) for e in ext]
  147 + extent = "{},{},{},{}".format(ext[0], ext[1], ext[2], ext[3])
  148 +
  149 + StructurePrint.print("空间表增加!")
  150 +
  151 + table_guid = uuid.uuid1().__str__()
  152 + table = Table(guid=table_guid,
  153 + database_guid=database.guid,
  154 + alias=layer.GetName(),
  155 + name=layer.GetName(), create_time=this_time, update_time=this_time,
  156 + table_type=GeometryAdapter.get_table_type(layer.GetGeomType()),
  157 + extent=extent,
  158 + feature_count=feature_count
  159 + )
  160 + db.session.add(table)
  161 +
  162 + feature_defn: FeatureDefn = layer.GetLayerDefn()
  163 +
  164 + for i in range(feature_defn.GetFieldCount()):
  165 + field_defn: FieldDefn = feature_defn.GetFieldDefn(i)
  166 + field_name = field_defn.GetName().lower()
  167 + field_alias = field_name if field_defn.GetAlternativeName() is None or field_defn.GetAlternativeName().__eq__(
  168 + "") else field_defn.GetAlternativeName()
  169 + column = Columns(guid=uuid.uuid1().__str__(), table_guid=table_guid,
  170 + name=field_name, alias=field_alias, create_time=this_time, update_time=this_time)
  171 + db.session.add(column)
  172 +
  173 + def deal_vacuate_table(self,pg_ds,database_guid):
  174 +
  175 +
  176 + for i in range(pg_ds.GetLayerCount()):
  177 + layer: Layer = pg_ds.GetLayer(i)
  178 + geom_column = layer.GetGeometryColumn()
  179 +
  180 + if not geom_column:
  181 + continue
  182 +
  183 +
  184 +
  185 + if layer.GetName().__contains__("_vacuate_"):
  186 + l_name = layer.GetName()
  187 +
  188 +
  189 + base_layer_name = l_name.split("_vacuate_")[0]
  190 + level = l_name.split("_")[-2]
  191 +
  192 + pixel_distance_str: str ="0"
  193 + try:
  194 + pixel_distance_str: str = l_name.split("_")[-1]
  195 + if pixel_distance_str.startswith("0"):
  196 + pixel_distance_str = "0.{}".format(pixel_distance_str)
  197 + except:
  198 + pass
  199 +
  200 + base_table =Table.query.filter_by(name=base_layer_name,database_guid=database_guid).one_or_none()
  201 + if base_table:
  202 + if not TableVacuate.query.filter_by(table_guid=base_table.guid,name=l_name).one_or_none():
  203 + table_vacuate = TableVacuate(guid=uuid.uuid1().__str__(),
  204 + table_guid=base_table.guid,
  205 + level=level,
  206 + name=l_name,
  207 + pixel_distance=float(pixel_distance_str))
  208 + db.session.add(table_vacuate)
  209 + else:
  210 + kk=1
  211 +
  212 +
  213 +
  214 +
  215 + def edit_spatial_table(self,pg_ds,spatial_tables,db_tables_names,this_time):
  216 +
  217 + for table in spatial_tables:
  218 +
  219 + # 删除表
  220 + if table.name not in db_tables_names:
  221 + StructurePrint.print("空间表减少!")
  222 + db.session.delete(table)
  223 + # 修改表
  224 + else:
  225 + layer: Layer = pg_ds.GetLayerByName(table.name)
  226 + l_name = layer.GetName()
  227 +
  228 + # 只注册public的空间表,其他表空间的表名会有.
  229 + if layer.GetName().__contains__("."):
  230 + continue
  231 +
  232 + if layer.GetName().__contains__("_vacuate_"):
  233 + continue
  234 +
  235 + columns = table.relate_columns
  236 + columns_names = [column.name for column in columns]
  237 + feature_defn: FeatureDefn = layer.GetLayerDefn()
  238 + db_columns_names = []
  239 +
  240 + # 增加列
  241 + for i in range(feature_defn.GetFieldCount()):
  242 + field_defn: FieldDefn = feature_defn.GetFieldDefn(i)
  243 + field_name = field_defn.GetName().lower()
  244 + db_columns_names.append(field_name)
  245 +
  246 + if field_name not in columns_names:
  247 + StructurePrint.print("{}空间表属性增加!".format(table.name))
  248 + field_alias = field_name if field_defn.GetAlternativeName() is None or field_defn.GetAlternativeName().__eq__(
  249 + "") else field_defn.GetAlternativeName()
  250 + column = Columns(guid=uuid.uuid1().__str__(), table_guid=table.guid,
  251 + name=field_name, alias=field_alias, create_time=this_time,
  252 + update_time=this_time)
  253 + db.session.add(column)
  254 +
  255 + # 删除列
  256 + for column in columns:
  257 + if column.name not in db_columns_names:
  258 + StructurePrint.print("{}空间表属性减少!".format(table.name))
  259 + db.session.delete(column)
  260 +
  261 +
  262 +
  263 + # 范围统计和数量统计以100w为界限
  264 + query_count_layer: Layer = pg_ds.ExecuteSQL(
  265 + "SELECT reltuples::bigint AS ec FROM pg_class WHERE oid = 'public.{}'::regclass".format(
  266 + l_name))
  267 + feature_count = query_count_layer.GetFeature(0).GetField("ec")
  268 + # 要素少于100w可以精确统计
  269 + if feature_count < 1000000:
  270 + feature_count = layer.GetFeatureCount()
  271 + ext = layer.GetExtent()
  272 + else:
  273 + query_ext_layer: Layer = pg_ds.ExecuteSQL(
  274 + "select geometry(ST_EstimatedExtent('public', '{}','{}'))".format(l_name,
  275 + layer.GetGeometryColumn()))
  276 + ext = query_ext_layer.GetExtent()
  277 + if ext[0] < 360:
  278 + ext = [round(e, 6) for e in ext]
  279 + else:
  280 + ext = [round(e, 2) for e in ext]
  281 + extent = "{},{},{},{}".format(ext[0], ext[1], ext[2], ext[3])
  282 +
  283 + # 修改要素量
  284 + if not table.feature_count.__eq__(feature_count):
  285 + StructurePrint.print("{}空间表要素!".format(table.name))
  286 + Table.query.filter_by(guid=table.guid).update({"feature_count": feature_count,
  287 + "extent": extent})
  288 +
  289 +
  290 + def add_common_table(self,data_session,database_guid,real_common_tables_name,origin_common_tables_name,this_time):
  291 + for table_name in real_common_tables_name:
  292 + if table_name not in origin_common_tables_name:
  293 + StructurePrint.print("{}非空间表增加!".format(table_name))
  294 + table_guid = uuid.uuid1().__str__()
  295 + count = data_session.execute('select count(*) from "{}"'.format(table_name)).fetchone()[0]
  296 +
  297 + table = Table(guid=table_guid,
  298 + database_guid=database_guid,
  299 + name=table_name, create_time=this_time, update_time=this_time,
  300 + table_type=0,
  301 + feature_count=count
  302 + )
  303 +
  304 + db.session.add(table)
  305 +
  306 + sql = '''
  307 + SELECT
  308 + a.attnum,
  309 + a.attname AS field
  310 + FROM
  311 + pg_class c,
  312 + pg_attribute a,
  313 + pg_type t
  314 + WHERE
  315 + c.relname = '{}'
  316 + and a.attnum > 0
  317 + and a.attrelid = c.oid
  318 + and a.atttypid = t.oid
  319 + ORDER BY a.attnum
  320 + '''.format(table_name)
  321 +
  322 + cols = data_session.execute(sql).fetchall()
  323 + for col in cols:
  324 + column = Columns(guid=uuid.uuid1().__str__(), table_guid=table_guid,
  325 + name=col[1], create_time=this_time, update_time=this_time)
  326 + db.session.add(column)
  327 +
  328 + # 删除不存在的表
  329 + for n in origin_common_tables_name:
  330 + if n not in real_common_tables_name:
  331 + table = Table.query.filter_by(name=n).filter_by(database_guid=database_guid).one_or_none()
  332 + if table:
  333 + db.session.delete(table)
  334 +
  335 + def edit_common_table(self,data_session,database_guid,real_common_tables_name,origin_common_tables_name,this_time):
  336 + for table_name in origin_common_tables_name:
  337 + table = Table.query.filter_by(name=table_name).filter_by(database_guid=database_guid).one_or_none()
  338 + if table:
  339 + if table_name not in real_common_tables_name:
  340 + StructurePrint.print("{}非空间表减少!".format(table_name))
  341 + db.session.delete(table)
  342 + # 修改表
  343 + else:
  344 + columns = table.relate_columns
  345 + columns_names = [column.name for column in columns]
  346 +
  347 + sql = '''
  348 + SELECT
  349 + a.attnum,
  350 + a.attname AS field
  351 + FROM
  352 + pg_class c,
  353 + pg_attribute a,
  354 + pg_type t
  355 + WHERE
  356 + c.relname = '{}'
  357 + and a.attnum > 0
  358 + and a.attrelid = c.oid
  359 + and a.atttypid = t.oid
  360 + ORDER BY a.attnum
  361 + '''.format(table_name)
  362 +
  363 + cols = data_session.execute(sql).fetchall()
  364 + real_cols_name = [col[1] for col in cols]
  365 +
  366 + # 属性增加
  367 + for col in real_cols_name:
  368 + if col not in columns_names:
  369 + StructurePrint.print("{}表要素属性增加!".format(table_name))
  370 + column = Columns(guid=uuid.uuid1().__str__(), table_guid=table.guid,
  371 + name=col, create_time=this_time, update_time=this_time)
  372 + db.session.add(column)
  373 +
  374 + # 属性减少
  375 + for column in columns:
  376 + if column.name not in real_cols_name:
  377 + StructurePrint.print("{}表要素属性减少!".format(table_name))
  378 + db.session.delete(column)
  379 +
  380 + # 修改要素量
  381 + sql = 'select count(*) from "{}"'.format(table_name)
  382 +
  383 + count = data_session.execute(sql).fetchone()[0]
  384 + if not table.feature_count.__eq__(count):
  385 + StructurePrint.print("{}表要素变化!".format(table_name))
  386 + Table.query.filter_by(guid=table.guid).update({"feature_count": count})
  387 +
  388 +
  389 +
  390 +
  391 + api_doc={
  392 + "tags":["管理接口"],
  393 + "parameters":[
  394 + {"name": "database_guid",
  395 + "in": "formData",
  396 + "type": "string",
  397 + "description": "数据库guid",
  398 + "required":"true"},
  399 + {"name": "user",
  400 + "in": "formData",
  401 + "type": "string",
  402 + "description": "用户"}
  403 +
  404 + ],
  405 + "responses":{
  406 + 200:{
  407 + "schema":{
  408 + "properties":{
  409 + }
  410 + }
  411 + }
  412 + }
  413 +}
  1 +#author: 4N
  2 +#createtime: 2021/1/27
  3 +#email: nheweijun@sina.com
  4 +
  5 +
  6 +import datetime
  7 +import traceback
  8 +from app.models import Table,Database,DES
  9 +
  10 +from sqlalchemy.engine import ResultProxy
  11 +from app.util.component.ApiTemplate import ApiTemplate
  12 +from app.util.component.PGUtil import PGUtil
  13 +
  14 +class Api(ApiTemplate):
  15 + api_name = "数据浏览"
  16 + def process(self):
  17 +
  18 + res = {}
  19 + res["data"] = {}
  20 + db_session=None
  21 + try:
  22 + table_guid = self.para.get("guid")
  23 + limit = int(self.para.get("limit",50))
  24 + offset = int(self.para.get("offset", 0))
  25 + table :Table= Table.query.filter_by(guid=table_guid).one_or_none()
  26 +
  27 + if not table:
  28 + raise Exception("数据不存在!")
  29 +
  30 + database:Database = table.relate_database
  31 +
  32 + db_session = PGUtil.get_db_session(DES.decode(database.sqlalchemy_uri))
  33 +
  34 + geom_col = PGUtil.get_geo_column(table.name,db_session)
  35 +
  36 + query_result : ResultProxy = db_session.execute('select * from "{}" limit {} offset {}'.format(table.name,limit,offset))
  37 +
  38 + res["data"]["count"]=PGUtil.get_table_count(table.name,db_session)
  39 +
  40 + res["data"]["list"]=[]
  41 + for row_proxy in query_result:
  42 + d = {}
  43 + for column, value in row_proxy.items():
  44 + #跳过空间列
  45 + if geom_col:
  46 + if column.__eq__(geom_col):
  47 + continue
  48 + #格式化时间列
  49 + if isinstance(value, datetime.datetime):
  50 + d[column] = value.strftime('%Y-%m-%d %H:%M:%S')
  51 + else:
  52 + d[column]=value
  53 + res["data"]["list"].append(d)
  54 + res["result"]=True
  55 + except Exception as e:
  56 + raise Exception("数据库连接失败!")
  57 + finally:
  58 + if db_session:
  59 + db_session.close()
  60 + return res
  61 +
  62 + api_doc={
  63 + "tags":["管理接口"],
  64 + "parameters":[
  65 + {"name": "guid",
  66 + "in": "formData",
  67 + "type": "string",
  68 + "description": "表guid","required":"true"},
  69 + {"name": "limit",
  70 + "in": "formData",
  71 + "type": "int"
  72 + },
  73 + {"name": "offset",
  74 + "in": "formData",
  75 + "type": "int"},
  76 + ],
  77 + "responses":{
  78 + 200:{
  79 + "schema":{
  80 + "properties":{
  81 + }
  82 + }
  83 + }
  84 + }
  85 + }
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/5/18
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +from flasgger import swag_from
  8 +from flask import Blueprint
  9 +from app.util import BlueprintApi
  10 +
  11 +from . import monitor_info
  12 +class DataManager():
  13 +
  14 + bp = Blueprint("Monitor", __name__, url_prefix="/API/Monitor")
  15 +
  16 + @staticmethod
  17 + @bp.route('/Info', methods=['GET'])
  18 + @swag_from(monitor_info.Api.api_doc)
  19 + def monitor_info():
  20 + """
  21 + 性能监控
  22 + """
  23 + return monitor_info.Api().result
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/6/11
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +from sqlalchemy import Column, Integer, String, ForeignKey, Text, DateTime, Time
  8 +from app.models import db
  9 +
  10 +class TestModel(db.Model):
  11 + '''
  12 + 数据表元数据
  13 + '''
  14 + __tablename__ = 'test_model'
  15 + guid = Column(String(256), primary_key=True)
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/7/9
  4 +#email: nheweijun@sina.com
  5 +
  6 +from app.models import *
  7 +
  8 +from app.util.component.ApiTemplate import ApiTemplate
  9 +from app.util.component.ModelVisitor import ModelVisitor
  10 +import psutil
  11 +
  12 +class Api(ApiTemplate):
  13 + api_name = "监控"
  14 +
  15 + def process(self):
  16 +
  17 + # 返回结果
  18 + res = {}
  19 + res["data"] = {}
  20 + try:
  21 + # 业务逻辑
  22 + cpu_count = psutil.cpu_count(False)
  23 + cpu_per = int(psutil.cpu_percent())
  24 + res["data"]["cpu"] ={"count":cpu_count,"percent":"{}%".format(cpu_per)}
  25 +
  26 +
  27 + mem_total = int(psutil.virtual_memory()[0])
  28 + mem_used = int(psutil.virtual_memory()[3])
  29 + mem_per = int(psutil.virtual_memory()[2])
  30 +
  31 + res["data"]["memory"] = {
  32 + 'total': self.format_value(mem_total),
  33 + 'used': self.format_value(mem_used),
  34 + 'percent': "{}%".format(mem_per)
  35 + }
  36 +
  37 +
  38 +
  39 + network_sent = int(psutil.net_io_counters()[0] / 8 ) # 每秒接受的kb
  40 + network_recv = int(psutil.net_io_counters()[1] / 8 )
  41 +
  42 + res["data"]["network"] = {
  43 + 'sent': self.format_value(network_sent),
  44 + 'recv': self.format_value(network_recv)
  45 + }
  46 +
  47 +
  48 + res["result"] = True
  49 + except Exception as e:
  50 + raise e
  51 + return res
  52 +
  53 + api_doc = {
  54 +
  55 + "tags": ["监控接口"],
  56 + "parameters": [
  57 + ],
  58 + "responses": {
  59 + 200: {
  60 + "schema": {
  61 + "properties": {
  62 + }
  63 + }
  64 + }
  65 + }
  66 + }
  67 +
  68 + def format_value(self,value):
  69 + if value>1024**3:
  70 + value = "{}GB".format(format(value/1024.0**3,'.1f'))
  71 + elif value>1024**2:
  72 + value = "{}MB".format(format(value / 1024.0 ** 2, '.1f'))
  73 + elif value>1024:
  74 + value = "{}KB".format(format(value / 1024.0, '.1f'))
  75 + else:
  76 + value = "{}B".format(format(value, '.1f'))
  77 + return value
  78 +
  79 +if __name__ == '__main__':
  80 + api = Api()
  81 + api.process()
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/3/1
  4 +#email: nheweijun@sina.com
  5 +
  6 +from app.util import BlueprintApi
  7 +from flasgger import swag_from
  8 +from flask import Blueprint
  9 +from . import task_list
  10 +from . import task_detail
  11 +from . import task_delete
  12 +from . import task_count
  13 +
  14 +class DataManager(BlueprintApi):
  15 +
  16 + bp = Blueprint("Task", __name__, url_prefix="/API/Task")
  17 +
  18 +
  19 + @staticmethod
  20 + @bp.route('/List', methods=['POST'])
  21 + @swag_from(task_list.Api.api_doc)
  22 + def api_task_list():
  23 + """
  24 + 任务列表
  25 + """
  26 + return task_list.Api().result
  27 +
  28 + @staticmethod
  29 + @bp.route('/Detail', methods=['POST'])
  30 + @swag_from(task_detail.Api.api_doc)
  31 + def api_task_detail():
  32 + """
  33 + 任务详情
  34 + """
  35 + return task_detail.Api().result
  36 +
  37 + @staticmethod
  38 + @bp.route('/Delete', methods=['POST'])
  39 + @swag_from(task_delete.Api.api_doc)
  40 + def task_delete():
  41 + """
  42 + 删除任务
  43 + """
  44 + return task_delete.Api().result
  45 +
  46 + @staticmethod
  47 + @bp.route('/Count', methods=['POST'])
  48 + @swag_from(task_count.Api.api_doc)
  49 + def task_count():
  50 + """
  51 + 任务统计
  52 + """
  53 + return task_count.Api().result
  54 +
  55 +
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/6/15
  4 +#email: nheweijun@sina.com
  1 +# coding=utf-8
  2 +# author: 4N
  3 +# createtime: 2020/9/4
  4 +# email: nheweijun@sina.com
  5 +
  6 +from app.models import db,Task
  7 +
  8 +from sqlalchemy import func
  9 +from app.util.component.ApiTemplate import ApiTemplate
  10 +
  11 +
  12 +class Api(ApiTemplate):
  13 + api_name = "任务统计"
  14 + def process(self):
  15 + res= {}
  16 + try:
  17 + tasks = db.session.query(func.count(Task.state), Task.state)
  18 + creator = self.para.get("creator")
  19 +
  20 + if creator:
  21 + tasks = tasks.filter_by(creator=creator)
  22 +
  23 + tasks = tasks.group_by(Task.state).all()
  24 + res["data"] = {}
  25 + for task in tasks:
  26 + res["data"][task[1].__str__()] = task[0]
  27 +
  28 + for status in ["-1", "0", "1", "2"]:
  29 + if not res["data"].get(status):
  30 + res["data"][status] = 0
  31 +
  32 + res["result"] = True
  33 + except Exception as e:
  34 + raise e
  35 + return res
  36 +
  37 +
  38 +
  39 + api_doc = {
  40 + "tags": ["任务接口"],
  41 + "parameters": [
  42 + {"name": "creator",
  43 + "in": "formData",
  44 + "type": "string"}
  45 + ],
  46 + "responses": {
  47 + 200: {
  48 + "schema": {
  49 + "properties": {
  50 + }
  51 + }
  52 + }
  53 + }
  54 + }
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2020/9/4
  4 +#email: nheweijun@sina.com
  5 +
  6 +from app.models import db,Task
  7 +
  8 +
  9 +from app.util.component.ApiTemplate import ApiTemplate
  10 +
  11 +
  12 +class Api(ApiTemplate):
  13 + api_name = "删除任务"
  14 + def para_check(self):
  15 + pass
  16 +
  17 + def process(self):
  18 + res = {}
  19 + try:
  20 + task_guid = self.para.get("task_guid")
  21 + state = self.para.get("state")
  22 + creator = self.para.get("creator")
  23 +
  24 + tasks = Task.query
  25 + if task_guid:
  26 + tasks = tasks.filter_by(guid=task_guid)
  27 + if state:
  28 + state = int(state)
  29 + tasks = tasks.filter_by(state=state)
  30 + if creator:
  31 + tasks = tasks.filter_by(creator=creator)
  32 + tasks = tasks.all()
  33 +
  34 + if not tasks:
  35 + res["result"] = False
  36 + res["msg"] = "数据不存在!"
  37 + return res
  38 + else:
  39 + for task in tasks:
  40 + db.session.delete(task)
  41 + db.session.commit()
  42 + res["msg"] = "删除成功!"
  43 + res["result"] = True
  44 + except Exception as e:
  45 + db.session.rollback()
  46 + raise e
  47 + return res
  48 +
  49 +
  50 + api_doc = {
  51 + "tags": ["任务接口"],
  52 + "parameters": [
  53 + {"name": "task_guid",
  54 + "in": "formData",
  55 + "type": "string"},
  56 + {"name": "state",
  57 + "in": "formData",
  58 + "type": "string"},
  59 + {"name": "creator",
  60 + "in": "formData",
  61 + "type": "string"},
  62 +
  63 + ],
  64 + "responses": {
  65 + 200: {
  66 + "schema": {
  67 + "properties": {
  68 + }
  69 + }
  70 + }
  71 + }
  72 + }
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2020/9/4
  4 +#email: nheweijun@sina.com
  5 +
  6 +from app.models import db,Task,Process
  7 +from app.util.component.ApiTemplate import ApiTemplate
  8 +from app.util.component.ModelVisitor import ModelVisitor
  9 +class Api(ApiTemplate):
  10 + api_name = "任务详情"
  11 + def para_check(self):
  12 + if not self.para.get("task_guid"):
  13 + raise Exception("缺乏task_guid参数。")
  14 +
  15 + def process(self):
  16 +
  17 + res = {}
  18 + try:
  19 + task_guid = self.para.get("task_guid")
  20 + task:Task = Task.query.filter_by(guid=task_guid).one_or_none()
  21 +
  22 + if not task :
  23 + raise Exception("任务不存在!")
  24 + else:
  25 + task_processes = task.relate_processes.order_by(Process.time).all()
  26 + res["data"] = ModelVisitor.objects_to_jsonarray(task_processes)
  27 +
  28 + res["result"] = True
  29 + except Exception as e:
  30 + raise e
  31 + return res
  32 +
  33 + api_doc={
  34 + "tags":["任务接口"],
  35 + "parameters":[
  36 + {"name": "task_guid",
  37 + "in": "formData",
  38 + "type": "string"},
  39 +
  40 + ],
  41 + "responses":{
  42 + 200:{
  43 + "schema":{
  44 + "properties":{
  45 + }
  46 + }
  47 + }
  48 + }
  49 + }
  1 +# coding=utf-8
  2 +# author: 4N
  3 +# createtime: 2020/9/4
  4 +# email: nheweijun@sina.com
  5 +import datetime
  6 +
  7 +
  8 +
  9 +from app.models import Task
  10 +from app.util.component.ApiTemplate import ApiTemplate
  11 +from app.util.component.ModelVisitor import ModelVisitor
  12 +class Api(ApiTemplate):
  13 + api_name = "任务列表"
  14 + def para_check(self):
  15 + pass
  16 +
  17 + def process(self):
  18 +
  19 + res = {}
  20 + res["data"] = {}
  21 + try:
  22 + parameter = self.para
  23 + page_index = int(parameter.get("page_index", "0"))
  24 + page_size = int(parameter.get("page_size", "10"))
  25 + name = parameter.get("name")
  26 + tasks = Task.query.order_by(Task.create_time.desc())
  27 + start_time = parameter.get("start_time")
  28 + end_time = parameter.get("end_time")
  29 + creator = parameter.get("creator")
  30 +
  31 + state = parameter.get("state")
  32 +
  33 + if creator:
  34 + tasks = tasks.filter_by(creator=creator)
  35 + if start_time and end_time:
  36 + tasks = tasks.filter(Task.create_time.between(start_time, end_time))
  37 + if name:
  38 + tasks = tasks.filter(Task.name.like("%" + name + "%"))
  39 + if state is not None:
  40 + state_list = state.split(",")
  41 + state_list =[int(x) for x in state_list]
  42 +
  43 + tasks = tasks.filter(Task.state.in_(state_list))
  44 +
  45 + res["data"]["count"] = tasks.count()
  46 +
  47 + tasks = tasks.limit(page_size).offset(page_index * page_size).all()
  48 +
  49 + res["data"]["list"] = [ModelVisitor.task_to_json(task) for task in tasks]
  50 + res["result"] = True
  51 + except Exception as e:
  52 + raise e
  53 + return res
  54 +
  55 +
  56 +
  57 + api_doc={
  58 + "tags":["任务接口"],
  59 + "parameters":[
  60 + {"name": "page_index",
  61 + "in": "formData",
  62 + "type": "int",
  63 + "default": "0"},
  64 + {"name": "page_size",
  65 + "in": "formData",
  66 + "type": "int",
  67 + "default": "10"},
  68 + {"name": "start_time",
  69 + "in": "formData",
  70 + "type": "string"},
  71 + {"name": "end_time",
  72 + "in": "formData",
  73 + "type": "string"},
  74 + {"name": "name",
  75 + "in": "formData",
  76 + "type": "string"},
  77 + {"name": "creator",
  78 + "in": "formData",
  79 + "type": "string"},
  80 + {"name": "state",
  81 + "in": "formData",
  82 + "type": "string"}
  83 + ],
  84 + "responses":{
  85 + 200:{
  86 + "schema":{
  87 + "properties":{
  88 + }
  89 + }
  90 + }
  91 + }
  92 + }
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2020/8/27
  4 +#email: nheweijun@sina.com
  5 +
  6 +from flask import Blueprint,request
  7 +from app.util import BlueprintApi
  8 +from . import sample
  9 +from flasgger import swag_from
  10 +
  11 +class Template(BlueprintApi):
  12 +
  13 + bp = Blueprint("Template", __name__, url_prefix="/API/Template")
  14 +
  15 + @staticmethod
  16 + @bp.route('/Sample', methods=['GET'])
  17 + @swag_from(sample.Api.api_doc)
  18 + def api_sample():
  19 + """
  20 + 测试接口
  21 + """
  22 + return sample.Api().result
  23 +
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2020/8/27
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +from flask import current_app
  8 +import os
  9 +
  10 +from app.util.component.ApiTemplate import ApiTemplate
  11 +from app.util.component.StructuredPrint import StructurePrint
  12 +
  13 +from flask import current_app
  14 +class Api(ApiTemplate):
  15 +
  16 + def para_check(self):
  17 + if self.para.get("content") is None:
  18 + raise Exception("缺乏content参数")
  19 +
  20 + def log(self):
  21 + current_app.logger.info('info log')
  22 +
  23 + def process(self):
  24 +
  25 + result=dict()
  26 + result.update(self.para)
  27 + result["root_path"] = os.path.dirname(current_app.instance_path)
  28 + return result
  29 +
  30 +
  31 + api_doc= {
  32 + "tags": ["测试接口"],
  33 + "description": "测试接口",
  34 + "parameters": [
  35 + {"name": "content",
  36 + "in": "query"}
  37 + ],
  38 + "responses": {
  39 + 200: {
  40 + "schema": {
  41 + "properties": {
  42 + "content": {
  43 + "type": "string",
  44 + "description": "The name of the user"
  45 + }
  46 + }
  47 + }
  48 + }
  49 + }
  50 + }
  51 +
  52 +
  1 +.mapboxgl-map {
  2 + font: 12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif;
  3 + overflow: hidden;
  4 + position: relative;
  5 + -webkit-tap-highlight-color: rgba(0,0,0,0);
  6 +}
  7 +
  8 +.mapboxgl-canvas-container.mapboxgl-interactive,
  9 +.mapboxgl-ctrl-nav-compass {
  10 + cursor: -webkit-grab;
  11 + cursor: -moz-grab;
  12 + cursor: grab;
  13 +}
  14 +.mapboxgl-canvas-container.mapboxgl-interactive:active,
  15 +.mapboxgl-ctrl-nav-compass:active {
  16 + cursor: -webkit-grabbing;
  17 + cursor: -moz-grabbing;
  18 + cursor: grabbing;
  19 +}
  20 +
  21 +.mapboxgl-canvas-container.mapboxgl-touch-zoom-rotate {
  22 + -ms-touch-action: pan-x pan-y;
  23 + touch-action: pan-x pan-y;
  24 +}
  25 +.mapboxgl-canvas-container.mapboxgl-touch-drag-pan {
  26 + -ms-touch-action: pinch-zoom;
  27 +}
  28 +.mapboxgl-canvas-container.mapboxgl-touch-zoom-rotate.mapboxgl-touch-drag-pan {
  29 + -ms-touch-action: none;
  30 + touch-action: none;
  31 +}
  32 +.mapboxgl-ctrl-top-left,
  33 +.mapboxgl-ctrl-top-right,
  34 +.mapboxgl-ctrl-bottom-left,
  35 +.mapboxgl-ctrl-bottom-right { position:absolute; pointer-events:none; z-index:2; }
  36 +.mapboxgl-ctrl-top-left { top:0; left:0; }
  37 +.mapboxgl-ctrl-top-right { top:0; right:0; }
  38 +.mapboxgl-ctrl-bottom-left { bottom:0; left:0; }
  39 +.mapboxgl-ctrl-bottom-right { right:0; bottom:0; }
  40 +
  41 +.mapboxgl-ctrl { clear:both; pointer-events:auto }
  42 +.mapboxgl-ctrl-top-left .mapboxgl-ctrl { margin:10px 0 0 10px; float:left; }
  43 +.mapboxgl-ctrl-top-right .mapboxgl-ctrl{ margin:10px 10px 0 0; float:right; }
  44 +.mapboxgl-ctrl-bottom-left .mapboxgl-ctrl { margin:0 0 10px 10px; float:left; }
  45 +.mapboxgl-ctrl-bottom-right .mapboxgl-ctrl { margin:0 10px 10px 0; float:right; }
  46 +
  47 +.mapboxgl-ctrl-group {
  48 + border-radius: 4px;
  49 + -moz-box-shadow: 0px 0px 2px rgba(0,0,0,0.1);
  50 + -webkit-box-shadow: 0px 0px 2px rgba(0,0,0,0.1);
  51 + box-shadow: 0px 0px 0px 2px rgba(0,0,0,0.1);
  52 + overflow: hidden;
  53 + background: #fff;
  54 +}
  55 +.mapboxgl-ctrl-group > button {
  56 + width: 30px;
  57 + height: 30px;
  58 + display: block;
  59 + padding: 0;
  60 + outline: none;
  61 + border: none;
  62 + border-bottom: 1px solid #ddd;
  63 + box-sizing: border-box;
  64 + background-color: rgba(0,0,0,0);
  65 + cursor: pointer;
  66 +}
  67 +/* https://bugzilla.mozilla.org/show_bug.cgi?id=140562 */
  68 +.mapboxgl-ctrl > button::-moz-focus-inner {
  69 + border: 0;
  70 + padding: 0;
  71 +}
  72 +.mapboxgl-ctrl > button:last-child {
  73 + border-bottom: 0;
  74 +}
  75 +.mapboxgl-ctrl > button:hover {
  76 + background-color: rgba(0,0,0,0.05);
  77 +}
  78 +.mapboxgl-ctrl-icon,
  79 +.mapboxgl-ctrl-icon > .mapboxgl-ctrl-compass-arrow {
  80 + speak: none;
  81 + -webkit-font-smoothing: antialiased;
  82 + -moz-osx-font-smoothing: grayscale;
  83 +}
  84 +.mapboxgl-ctrl-icon {
  85 + padding: 5px;
  86 +}
  87 +.mapboxgl-ctrl-icon.mapboxgl-ctrl-zoom-out {
  88 + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20viewBox%3D%270%200%2020%2020%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%0A%20%20%3Cpath%20style%3D%27fill%3A%23333333%3B%27%20d%3D%27m%207%2C9%20c%20-0.554%2C0%20-1%2C0.446%20-1%2C1%200%2C0.554%200.446%2C1%201%2C1%20l%206%2C0%20c%200.554%2C0%201%2C-0.446%201%2C-1%200%2C-0.554%20-0.446%2C-1%20-1%2C-1%20z%27%20%2F%3E%0A%3C%2Fsvg%3E%0A");
  89 +}
  90 +.mapboxgl-ctrl-icon.mapboxgl-ctrl-zoom-in {
  91 + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20viewBox%3D%270%200%2020%2020%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%0A%20%20%3Cpath%20style%3D%27fill%3A%23333333%3B%27%20d%3D%27M%2010%206%20C%209.446%206%209%206.4459904%209%207%20L%209%209%20L%207%209%20C%206.446%209%206%209.446%206%2010%20C%206%2010.554%206.446%2011%207%2011%20L%209%2011%20L%209%2013%20C%209%2013.55401%209.446%2014%2010%2014%20C%2010.554%2014%2011%2013.55401%2011%2013%20L%2011%2011%20L%2013%2011%20C%2013.554%2011%2014%2010.554%2014%2010%20C%2014%209.446%2013.554%209%2013%209%20L%2011%209%20L%2011%207%20C%2011%206.4459904%2010.554%206%2010%206%20z%27%20%2F%3E%0A%3C%2Fsvg%3E%0A");
  92 +}
  93 +.mapboxgl-ctrl-icon.mapboxgl-ctrl-geolocate {
  94 + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D%270%200%2020%2020%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%0D%0A%20%20%3Cpath%20style%3D%27fill%3A%23333%3B%27%20d%3D%27M10%204C9%204%209%205%209%205L9%205.1A5%205%200%200%200%205.1%209L5%209C5%209%204%209%204%2010%204%2011%205%2011%205%2011L5.1%2011A5%205%200%200%200%209%2014.9L9%2015C9%2015%209%2016%2010%2016%2011%2016%2011%2015%2011%2015L11%2014.9A5%205%200%200%200%2014.9%2011L15%2011C15%2011%2016%2011%2016%2010%2016%209%2015%209%2015%209L14.9%209A5%205%200%200%200%2011%205.1L11%205C11%205%2011%204%2010%204zM10%206.5A3.5%203.5%200%200%201%2013.5%2010%203.5%203.5%200%200%201%2010%2013.5%203.5%203.5%200%200%201%206.5%2010%203.5%203.5%200%200%201%2010%206.5zM10%208.3A1.8%201.8%200%200%200%208.3%2010%201.8%201.8%200%200%200%2010%2011.8%201.8%201.8%200%200%200%2011.8%2010%201.8%201.8%200%200%200%2010%208.3z%27%20%2F%3E%0D%0A%3C%2Fsvg%3E");
  95 +}
  96 +.mapboxgl-ctrl-icon.mapboxgl-ctrl-geolocate.mapboxgl-watching {
  97 + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D%270%200%2020%2020%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%0D%0A%20%20%3Cpath%20style%3D%27fill%3A%2300f%3B%27%20d%3D%27M10%204C9%204%209%205%209%205L9%205.1A5%205%200%200%200%205.1%209L5%209C5%209%204%209%204%2010%204%2011%205%2011%205%2011L5.1%2011A5%205%200%200%200%209%2014.9L9%2015C9%2015%209%2016%2010%2016%2011%2016%2011%2015%2011%2015L11%2014.9A5%205%200%200%200%2014.9%2011L15%2011C15%2011%2016%2011%2016%2010%2016%209%2015%209%2015%209L14.9%209A5%205%200%200%200%2011%205.1L11%205C11%205%2011%204%2010%204zM10%206.5A3.5%203.5%200%200%201%2013.5%2010%203.5%203.5%200%200%201%2010%2013.5%203.5%203.5%200%200%201%206.5%2010%203.5%203.5%200%200%201%2010%206.5zM10%208.3A1.8%201.8%200%200%200%208.3%2010%201.8%201.8%200%200%200%2010%2011.8%201.8%201.8%200%200%200%2011.8%2010%201.8%201.8%200%200%200%2010%208.3z%27%20%2F%3E%0D%0A%3C%2Fsvg%3E");
  98 +}
  99 +.mapboxgl-ctrl-icon.mapboxgl-ctrl-fullscreen {
  100 + background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxOS4wLjEsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4KCjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgdmVyc2lvbj0iMS4xIgogICBpZD0iTGF5ZXJfMSIKICAgeD0iMHB4IgogICB5PSIwcHgiCiAgIHZpZXdCb3g9IjAgMCAyMCAyMCIKICAgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMjAgMjA7IgogICB4bWw6c3BhY2U9InByZXNlcnZlIgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjkxIHIxMzcyNSIKICAgc29kaXBvZGk6ZG9jbmFtZT0iZnVsbHNjcmVlbi5zdmciPjxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTQxODUiPjxyZGY6UkRGPjxjYzpXb3JrCiAgICAgICAgIHJkZjphYm91dD0iIj48ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD48ZGM6dHlwZQogICAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+PGRjOnRpdGxlPjwvZGM6dGl0bGU+PC9jYzpXb3JrPjwvcmRmOlJERj48L21ldGFkYXRhPjxkZWZzCiAgICAgaWQ9ImRlZnM0MTgzIiAvPjxzb2RpcG9kaTpuYW1lZHZpZXcKICAgICBwYWdlY29sb3I9IiNmZmZmZmYiCiAgICAgYm9yZGVyY29sb3I9IiM2NjY2NjYiCiAgICAgYm9yZGVyb3BhY2l0eT0iMSIKICAgICBvYmplY3R0b2xlcmFuY2U9IjEwIgogICAgIGdyaWR0b2xlcmFuY2U9IjEwIgogICAgIGd1aWRldG9sZXJhbmNlPSIxMCIKICAgICBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMCIKICAgICBpbmtzY2FwZTpwYWdlc2hhZG93PSIyIgogICAgIGlua3NjYXBlOndpbmRvdy13aWR0aD0iMTQ3MSIKICAgICBpbmtzY2FwZTp3aW5kb3ctaGVpZ2h0PSI2OTUiCiAgICAgaWQ9Im5hbWVkdmlldzQxODEiCiAgICAgc2hvd2dyaWQ9ImZhbHNlIgogICAgIGlua3NjYXBlOnpvb209IjExLjMxMzcwOCIKICAgICBpbmtzY2FwZTpjeD0iMTQuNjk4MjgiCiAgICAgaW5rc2NhcGU6Y3k9IjEwLjUyNjY4OSIKICAgICBpbmtzY2FwZTp3aW5kb3cteD0iNjk3IgogICAgIGlua3NjYXBlOndpbmRvdy15PSIyOTgiCiAgICAgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMCIKICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJMYXllcl8xIgogICAgIGlua3NjYXBlOnNuYXAtYmJveD0idHJ1ZSIKICAgICBpbmtzY2FwZTpiYm94LXBhdGhzPSJ0cnVlIgogICAgIGlua3NjYXBlOm9iamVjdC1wYXRocz0idHJ1ZSIKICAgICBpbmtzY2FwZTpiYm94LW5vZGVzPSJ0cnVlIgogICAgIGlua3NjYXBlOm9iamVjdC1ub2Rlcz0idHJ1ZSI+PGlua3NjYXBlOmdyaWQKICAgICAgIHR5cGU9Inh5Z3JpZCIKICAgICAgIGlkPSJncmlkNjA3NiIgLz48L3NvZGlwb2RpOm5hbWVkdmlldz48cGF0aAogICAgIGQ9Ik0gNSA0IEMgNC41IDQgNCA0LjUgNCA1IEwgNCA2IEwgNCA5IEwgNC41IDkgTCA1Ljc3NzM0MzggNy4yOTY4NzUgQyA2Ljc3NzEzMTkgOC4wNjAyMTMxIDcuODM1NzY1IDguOTU2NTcyOCA4Ljg5MDYyNSAxMCBDIDcuODI1NzEyMSAxMS4wNjMzIDYuNzc2MTc5MSAxMS45NTE2NzUgNS43ODEyNSAxMi43MDcwMzEgTCA0LjUgMTEgTCA0IDExIEwgNCAxNSBDIDQgMTUuNSA0LjUgMTYgNSAxNiBMIDkgMTYgTCA5IDE1LjUgTCA3LjI3MzQzNzUgMTQuMjA1MDc4IEMgOC4wNDI4OTMxIDEzLjE4Nzg4NiA4LjkzOTU0NDEgMTIuMTMzNDgxIDkuOTYwOTM3NSAxMS4wNjgzNTkgQyAxMS4wNDIzNzEgMTIuMTQ2OTkgMTEuOTQyMDkzIDEzLjIxMTIgMTIuNzA3MDMxIDE0LjIxODc1IEwgMTEgMTUuNSBMIDExIDE2IEwgMTQgMTYgTCAxNSAxNiBDIDE1LjUgMTYgMTYgMTUuNSAxNiAxNSBMIDE2IDE0IEwgMTYgMTEgTCAxNS41IDExIEwgMTQuMjA1MDc4IDEyLjcyNjU2MiBDIDEzLjE3Nzk4NSAxMS45NDk2MTcgMTIuMTEyNzE4IDExLjA0MzU3NyAxMS4wMzcxMDkgMTAuMDA5NzY2IEMgMTIuMTUxODU2IDguOTgxMDYxIDEzLjIyNDM0NSA4LjA3OTg2MjQgMTQuMjI4NTE2IDcuMzA0Njg3NSBMIDE1LjUgOSBMIDE2IDkgTCAxNiA1IEMgMTYgNC41IDE1LjUgNCAxNSA0IEwgMTEgNCBMIDExIDQuNSBMIDEyLjcwMzEyNSA1Ljc3NzM0MzggQyAxMS45MzI2NDcgNi43ODY0ODM0IDExLjAyNjY5MyA3Ljg1NTQ3MTIgOS45NzA3MDMxIDguOTE5OTIxOSBDIDguOTU4NDczOSA3LjgyMDQ5NDMgOC4wNjk4NzY3IDYuNzYyNzE4OCA3LjMwNDY4NzUgNS43NzE0ODQ0IEwgOSA0LjUgTCA5IDQgTCA2IDQgTCA1IDQgeiAiCiAgICAgaWQ9InBhdGg0MTY5IiAvPjwvc3ZnPg==");
  101 +}
  102 +.mapboxgl-ctrl-icon.mapboxgl-ctrl-shrink {
  103 + background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxOS4wLjEsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4KCjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgdmVyc2lvbj0iMS4xIgogICBpZD0iTGF5ZXJfMSIKICAgeD0iMHB4IgogICB5PSIwcHgiCiAgIHZpZXdCb3g9IjAgMCAyMCAyMCIKICAgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMjAgMjA7IgogICB4bWw6c3BhY2U9InByZXNlcnZlIgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjkxIHIxMzcyNSIKICAgc29kaXBvZGk6ZG9jbmFtZT0ic2hyaW5rLnN2ZyI+PG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhMTkiPjxyZGY6UkRGPjxjYzpXb3JrCiAgICAgICAgIHJkZjphYm91dD0iIj48ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD48ZGM6dHlwZQogICAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+PGRjOnRpdGxlPjwvZGM6dGl0bGU+PC9jYzpXb3JrPjwvcmRmOlJERj48L21ldGFkYXRhPjxkZWZzCiAgICAgaWQ9ImRlZnMxNyIgLz48c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIgogICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICAgIGJvcmRlcm9wYWNpdHk9IjEiCiAgICAgb2JqZWN0dG9sZXJhbmNlPSIxMCIKICAgICBncmlkdG9sZXJhbmNlPSIxMCIKICAgICBndWlkZXRvbGVyYW5jZT0iMTAiCiAgICAgaW5rc2NhcGU6cGFnZW9wYWNpdHk9IjAiCiAgICAgaW5rc2NhcGU6cGFnZXNoYWRvdz0iMiIKICAgICBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjIwMjEiCiAgICAgaW5rc2NhcGU6d2luZG93LWhlaWdodD0iOTA4IgogICAgIGlkPSJuYW1lZHZpZXcxNSIKICAgICBzaG93Z3JpZD0iZmFsc2UiCiAgICAgaW5rc2NhcGU6em9vbT0iMSIKICAgICBpbmtzY2FwZTpjeD0iNC45NTAxMDgyIgogICAgIGlua3NjYXBlOmN5PSIxMC44NTQ3NDciCiAgICAgaW5rc2NhcGU6d2luZG93LXg9IjAiCiAgICAgaW5rc2NhcGU6d2luZG93LXk9IjAiCiAgICAgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMCIKICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJMYXllcl8xIgogICAgIGlua3NjYXBlOnNuYXAtYmJveD0idHJ1ZSIKICAgICBpbmtzY2FwZTpiYm94LXBhdGhzPSJ0cnVlIgogICAgIGlua3NjYXBlOnNuYXAtYmJveC1lZGdlLW1pZHBvaW50cz0idHJ1ZSIKICAgICBpbmtzY2FwZTpiYm94LW5vZGVzPSJ0cnVlIgogICAgIGlua3NjYXBlOnNuYXAtYmJveC1taWRwb2ludHM9InRydWUiCiAgICAgaW5rc2NhcGU6b2JqZWN0LXBhdGhzPSJ0cnVlIgogICAgIGlua3NjYXBlOm9iamVjdC1ub2Rlcz0idHJ1ZSI+PGlua3NjYXBlOmdyaWQKICAgICAgIHR5cGU9Inh5Z3JpZCIKICAgICAgIGlkPSJncmlkNDE0NyIgLz48L3NvZGlwb2RpOm5hbWVkdmlldz48cGF0aAogICAgIHN0eWxlPSJmaWxsOiMwMDAwMDAiCiAgICAgZD0iTSA0LjI0MjE4NzUgMy40OTIxODc1IEEgMC43NTAwNzUgMC43NTAwNzUgMCAwIDAgMy43MTg3NSA0Ljc4MTI1IEwgNS45NjQ4NDM4IDcuMDI3MzQzOCBMIDQgOC41IEwgNCA5IEwgOCA5IEMgOC41MDAwMDEgOC45OTk5OTg4IDkgOC40OTk5OTkyIDkgOCBMIDkgNCBMIDguNSA0IEwgNy4wMTc1NzgxIDUuOTU1MDc4MSBMIDQuNzgxMjUgMy43MTg3NSBBIDAuNzUwMDc1IDAuNzUwMDc1IDAgMCAwIDQuMjQyMTg3NSAzLjQ5MjE4NzUgeiBNIDE1LjczNDM3NSAzLjQ5MjE4NzUgQSAwLjc1MDA3NSAwLjc1MDA3NSAwIDAgMCAxNS4yMTg3NSAzLjcxODc1IEwgMTIuOTg0Mzc1IDUuOTUzMTI1IEwgMTEuNSA0IEwgMTEgNCBMIDExIDggQyAxMSA4LjQ5OTk5OTIgMTEuNDk5OTk5IDguOTk5OTk4OCAxMiA5IEwgMTYgOSBMIDE2IDguNSBMIDE0LjAzNTE1NiA3LjAyNzM0MzggTCAxNi4yODEyNSA0Ljc4MTI1IEEgMC43NTAwNzUgMC43NTAwNzUgMCAwIDAgMTUuNzM0Mzc1IDMuNDkyMTg3NSB6IE0gNCAxMSBMIDQgMTEuNSBMIDUuOTY0ODQzOCAxMi45NzI2NTYgTCAzLjcxODc1IDE1LjIxODc1IEEgMC43NTEzMDA5NiAwLjc1MTMwMDk2IDAgMSAwIDQuNzgxMjUgMTYuMjgxMjUgTCA3LjAyNzM0MzggMTQuMDM1MTU2IEwgOC41IDE2IEwgOSAxNiBMIDkgMTIgQyA5IDExLjUwMDAwMSA4LjUwMDAwMSAxMS4wMDAwMDEgOCAxMSBMIDQgMTEgeiBNIDEyIDExIEMgMTEuNDk5OTk5IDExLjAwMDAwMSAxMSAxMS41MDAwMDEgMTEgMTIgTCAxMSAxNiBMIDExLjUgMTYgTCAxMi45NzI2NTYgMTQuMDM1MTU2IEwgMTUuMjE4NzUgMTYuMjgxMjUgQSAwLjc1MTMwMDk2IDAuNzUxMzAwOTYgMCAxIDAgMTYuMjgxMjUgMTUuMjE4NzUgTCAxNC4wMzUxNTYgMTIuOTcyNjU2IEwgMTYgMTEuNSBMIDE2IDExIEwgMTIgMTEgeiAiCiAgICAgaWQ9InBhdGg3IiAvPjwvc3ZnPg==");
  104 +}
  105 +.mapboxgl-ctrl-icon.mapboxgl-ctrl-compass > .mapboxgl-ctrl-compass-arrow {
  106 + width: 20px;
  107 + height: 20px;
  108 + margin: 5px;
  109 + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2020%2020%27%3E%0A%09%3Cpolygon%20fill%3D%27%23333333%27%20points%3D%276%2C9%2010%2C1%2014%2C9%27%2F%3E%0A%09%3Cpolygon%20fill%3D%27%23CCCCCC%27%20points%3D%276%2C11%2010%2C19%2014%2C11%20%27%2F%3E%0A%3C%2Fsvg%3E");
  110 + background-repeat: no-repeat;
  111 + display: inline-block;
  112 +}
  113 +
  114 +a.mapboxgl-ctrl-logo {
  115 + width: 85px;
  116 + height: 21px;
  117 + margin: 0 0 -3px -3px;
  118 + display: block;
  119 + background-repeat: no-repeat;
  120 + cursor: pointer;
  121 + background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiAgIHZpZXdCb3g9IjAgMCA4NC40OSAyMSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgODQuNDkgMjE7IiB4bWw6c3BhY2U9InByZXNlcnZlIj48Zz4gIDxwYXRoIGNsYXNzPSJzdDAiIHN0eWxlPSJvcGFjaXR5OjAuOTsgZmlsbDogI0ZGRkZGRjsgZW5hYmxlLWJhY2tncm91bmQ6IG5ldzsiIGQ9Ik04My4yNSwxNC4yNmMwLDAuMTItMC4wOSwwLjIxLTAuMjEsMC4yMWgtMS42MWMtMC4xMywwLTAuMjQtMC4wNi0wLjMtMC4xN2wtMS40NC0yLjM5bC0xLjQ0LDIuMzkgICAgYy0wLjA2LDAuMTEtMC4xOCwwLjE3LTAuMywwLjE3aC0xLjYxYy0wLjA0LDAtMC4wOC0wLjAxLTAuMTItMC4wM2MtMC4wOS0wLjA2LTAuMTMtMC4xOS0wLjA2LTAuMjhsMCwwbDIuNDMtMy42OEw3Ni4yLDYuODQgICAgYy0wLjAyLTAuMDMtMC4wMy0wLjA3LTAuMDMtMC4xMmMwLTAuMTIsMC4wOS0wLjIxLDAuMjEtMC4yMWgxLjYxYzAuMTMsMCwwLjI0LDAuMDYsMC4zLDAuMTdsMS40MSwyLjM2bDEuNC0yLjM1ICAgIGMwLjA2LTAuMTEsMC4xOC0wLjE3LDAuMy0wLjE3SDgzYzAuMDQsMCwwLjA4LDAuMDEsMC4xMiwwLjAzYzAuMDksMC4wNiwwLjEzLDAuMTksMC4wNiwwLjI4bDAsMGwtMi4zNywzLjYzbDIuNDMsMy42NyAgICBDODMuMjQsMTQuMTgsODMuMjUsMTQuMjIsODMuMjUsMTQuMjZ6Ii8+ICA8cGF0aCBjbGFzcz0ic3QwIiBzdHlsZT0ib3BhY2l0eTowLjk7IGZpbGw6ICNGRkZGRkY7IGVuYWJsZS1iYWNrZ3JvdW5kOiBuZXc7IiBkPSJNNjYuMjQsOS41OWMtMC4zOS0xLjg4LTEuOTYtMy4yOC0zLjg0LTMuMjhjLTEuMDMsMC0yLjAzLDAuNDItMi43MywxLjE4VjMuNTFjMC0wLjEzLTAuMS0wLjIzLTAuMjMtMC4yM2gtMS40ICAgIGMtMC4xMywwLTAuMjMsMC4xMS0wLjIzLDAuMjN2MTAuNzJjMCwwLjEzLDAuMSwwLjIzLDAuMjMsMC4yM2gxLjRjMC4xMywwLDAuMjMtMC4xMSwwLjIzLTAuMjNWMTMuNWMwLjcxLDAuNzUsMS43LDEuMTgsMi43MywxLjE4ICAgIGMxLjg4LDAsMy40NS0xLjQxLDMuODQtMy4yOUM2Ni4zNywxMC43OSw2Ni4zNywxMC4xOCw2Ni4yNCw5LjU5TDY2LjI0LDkuNTl6IE02Mi4wOCwxM2MtMS4zMiwwLTIuMzktMS4xMS0yLjQxLTIuNDh2LTAuMDYgICAgYzAuMDItMS4zOCwxLjA5LTIuNDgsMi40MS0yLjQ4czIuNDIsMS4xMiwyLjQyLDIuNTFTNjMuNDEsMTMsNjIuMDgsMTN6Ii8+ICA8cGF0aCBjbGFzcz0ic3QwIiBzdHlsZT0ib3BhY2l0eTowLjk7IGZpbGw6ICNGRkZGRkY7IGVuYWJsZS1iYWNrZ3JvdW5kOiBuZXc7IiBkPSJNNzEuNjcsNi4zMmMtMS45OC0wLjAxLTMuNzIsMS4zNS00LjE2LDMuMjljLTAuMTMsMC41OS0wLjEzLDEuMTksMCwxLjc3YzAuNDQsMS45NCwyLjE3LDMuMzIsNC4xNywzLjMgICAgYzIuMzUsMCw0LjI2LTEuODcsNC4yNi00LjE5Uzc0LjA0LDYuMzIsNzEuNjcsNi4zMnogTTcxLjY1LDEzLjAxYy0xLjMzLDAtMi40Mi0xLjEyLTIuNDItMi41MXMxLjA4LTIuNTIsMi40Mi0yLjUyICAgIGMxLjMzLDAsMi40MiwxLjEyLDIuNDIsMi41MVM3Mi45OSwxMyw3MS42NSwxMy4wMUw3MS42NSwxMy4wMXoiLz4gIDxwYXRoIGNsYXNzPSJzdDEiIHN0eWxlPSJvcGFjaXR5OjAuMzU7IGVuYWJsZS1iYWNrZ3JvdW5kOm5ldzsiIGQ9Ik02Mi4wOCw3Ljk4Yy0xLjMyLDAtMi4zOSwxLjExLTIuNDEsMi40OHYwLjA2QzU5LjY4LDExLjksNjAuNzUsMTMsNjIuMDgsMTNzMi40Mi0xLjEyLDIuNDItMi41MSAgICBTNjMuNDEsNy45OCw2Mi4wOCw3Ljk4eiBNNjIuMDgsMTEuNzZjLTAuNjMsMC0xLjE0LTAuNTYtMS4xNy0xLjI1di0wLjA0YzAuMDEtMC42OSwwLjU0LTEuMjUsMS4xNy0xLjI1ICAgIGMwLjYzLDAsMS4xNywwLjU3LDEuMTcsMS4yN0M2My4yNCwxMS4yLDYyLjczLDExLjc2LDYyLjA4LDExLjc2eiIvPiAgPHBhdGggY2xhc3M9InN0MSIgc3R5bGU9Im9wYWNpdHk6MC4zNTsgZW5hYmxlLWJhY2tncm91bmQ6bmV3OyIgZD0iTTcxLjY1LDcuOThjLTEuMzMsMC0yLjQyLDEuMTItMi40MiwyLjUxUzcwLjMyLDEzLDcxLjY1LDEzczIuNDItMS4xMiwyLjQyLTIuNTFTNzIuOTksNy45OCw3MS42NSw3Ljk4eiAgICAgTTcxLjY1LDExLjc2Yy0wLjY0LDAtMS4xNy0wLjU3LTEuMTctMS4yN2MwLTAuNywwLjUzLTEuMjYsMS4xNy0xLjI2czEuMTcsMC41NywxLjE3LDEuMjdDNzIuODIsMTEuMjEsNzIuMjksMTEuNzYsNzEuNjUsMTEuNzZ6IiAgICAvPiAgPHBhdGggY2xhc3M9InN0MCIgc3R5bGU9Im9wYWNpdHk6MC45OyBmaWxsOiAjRkZGRkZGOyBlbmFibGUtYmFja2dyb3VuZDogbmV3OyIgZD0iTTQ1Ljc0LDYuNTNoLTEuNGMtMC4xMywwLTAuMjMsMC4xMS0wLjIzLDAuMjN2MC43M2MtMC43MS0wLjc1LTEuNy0xLjE4LTIuNzMtMS4xOCAgICBjLTIuMTcsMC0zLjk0LDEuODctMy45NCw0LjE5czEuNzcsNC4xOSwzLjk0LDQuMTljMS4wNCwwLDIuMDMtMC40MywyLjczLTEuMTl2MC43M2MwLDAuMTMsMC4xLDAuMjMsMC4yMywwLjIzaDEuNCAgICBjMC4xMywwLDAuMjMtMC4xMSwwLjIzLTAuMjNWNi43NGMwLTAuMTItMC4wOS0wLjIyLTAuMjItMC4yMkM0NS43NSw2LjUzLDQ1Ljc1LDYuNTMsNDUuNzQsNi41M3ogTTQ0LjEyLDEwLjUzICAgIEM0NC4xMSwxMS45LDQzLjAzLDEzLDQxLjcxLDEzcy0yLjQyLTEuMTItMi40Mi0yLjUxczEuMDgtMi41MiwyLjQtMi41MmMxLjMzLDAsMi4zOSwxLjExLDIuNDEsMi40OEw0NC4xMiwxMC41M3oiLz4gIDxwYXRoIGNsYXNzPSJzdDEiIHN0eWxlPSJvcGFjaXR5OjAuMzU7IGVuYWJsZS1iYWNrZ3JvdW5kOm5ldzsiIGQ9Ik00MS43MSw3Ljk4Yy0xLjMzLDAtMi40MiwxLjEyLTIuNDIsMi41MVM0MC4zNywxMyw0MS43MSwxM3MyLjM5LTEuMTEsMi40MS0yLjQ4di0wLjA2ICAgIEM0NC4xLDkuMDksNDMuMDMsNy45OCw0MS43MSw3Ljk4eiBNNDAuNTUsMTAuNDljMC0wLjcsMC41Mi0xLjI3LDEuMTctMS4yN2MwLjY0LDAsMS4xNCwwLjU2LDEuMTcsMS4yNXYwLjA0ICAgIGMtMC4wMSwwLjY4LTAuNTMsMS4yNC0xLjE3LDEuMjRDNDEuMDgsMTEuNzUsNDAuNTUsMTEuMTksNDAuNTUsMTAuNDl6Ii8+ICA8cGF0aCBjbGFzcz0ic3QwIiBzdHlsZT0ib3BhY2l0eTowLjk7IGZpbGw6ICNGRkZGRkY7IGVuYWJsZS1iYWNrZ3JvdW5kOiBuZXc7IiBkPSJNNTIuNDEsNi4zMmMtMS4wMywwLTIuMDMsMC40Mi0yLjczLDEuMThWNi43NWMwLTAuMTMtMC4xLTAuMjMtMC4yMy0wLjIzaC0xLjRjLTAuMTMsMC0wLjIzLDAuMTEtMC4yMywwLjIzICAgIHYxMC43MmMwLDAuMTMsMC4xLDAuMjMsMC4yMywwLjIzaDEuNGMwLjEzLDAsMC4yMy0wLjEsMC4yMy0wLjIzVjEzLjVjMC43MSwwLjc1LDEuNywxLjE4LDIuNzQsMS4xOGMyLjE3LDAsMy45NC0xLjg3LDMuOTQtNC4xOSAgICBTNTQuNTgsNi4zMiw1Mi40MSw2LjMyeiBNNTIuMDgsMTMuMDFjLTEuMzIsMC0yLjM5LTEuMTEtMi40Mi0yLjQ4di0wLjA3YzAuMDItMS4zOCwxLjA5LTIuNDksMi40LTIuNDljMS4zMiwwLDIuNDEsMS4xMiwyLjQxLDIuNTEgICAgUzUzLjQsMTMsNTIuMDgsMTMuMDFMNTIuMDgsMTMuMDF6Ii8+ICA8cGF0aCBjbGFzcz0ic3QxIiBzdHlsZT0ib3BhY2l0eTowLjM1OyBlbmFibGUtYmFja2dyb3VuZDpuZXc7IiBkPSJNNTIuMDgsNy45OGMtMS4zMiwwLTIuMzksMS4xMS0yLjQyLDIuNDh2MC4wNmMwLjAzLDEuMzgsMS4xLDIuNDgsMi40MiwyLjQ4czIuNDEtMS4xMiwyLjQxLTIuNTEgICAgUzUzLjQsNy45OCw1Mi4wOCw3Ljk4eiBNNTIuMDgsMTEuNzZjLTAuNjMsMC0xLjE0LTAuNTYtMS4xNy0xLjI1di0wLjA0YzAuMDEtMC42OSwwLjU0LTEuMjUsMS4xNy0xLjI1YzAuNjMsMCwxLjE3LDAuNTgsMS4xNywxLjI3ICAgIFM1Mi43MiwxMS43Niw1Mi4wOCwxMS43NnoiLz4gIDxwYXRoIGNsYXNzPSJzdDAiIHN0eWxlPSJvcGFjaXR5OjAuOTsgZmlsbDogI0ZGRkZGRjsgZW5hYmxlLWJhY2tncm91bmQ6IG5ldzsiIGQ9Ik0zNi4wOCwxNC4yNGMwLDAuMTMtMC4xLDAuMjMtMC4yMywwLjIzaC0xLjQxYy0wLjEzLDAtMC4yMy0wLjExLTAuMjMtMC4yM1Y5LjY4YzAtMC45OC0wLjc0LTEuNzEtMS42Mi0xLjcxICAgIGMtMC44LDAtMS40NiwwLjctMS41OSwxLjYybDAuMDEsNC42NmMwLDAuMTMtMC4xMSwwLjIzLTAuMjMsMC4yM2gtMS40MWMtMC4xMywwLTAuMjMtMC4xMS0wLjIzLTAuMjNWOS42OCAgICBjMC0wLjk4LTAuNzQtMS43MS0xLjYyLTEuNzFjLTAuODUsMC0xLjU0LDAuNzktMS42LDEuOHY0LjQ4YzAsMC4xMy0wLjEsMC4yMy0wLjIzLDAuMjNoLTEuNGMtMC4xMywwLTAuMjMtMC4xMS0wLjIzLTAuMjNWNi43NCAgICBjMC4wMS0wLjEzLDAuMS0wLjIyLDAuMjMtMC4yMmgxLjRjMC4xMywwLDAuMjIsMC4xMSwwLjIzLDAuMjJWNy40YzAuNS0wLjY4LDEuMy0xLjA5LDIuMTYtMS4xaDAuMDNjMS4wOSwwLDIuMDksMC42LDIuNiwxLjU1ICAgIGMwLjQ1LTAuOTUsMS40LTEuNTUsMi40NC0xLjU2YzEuNjIsMCwyLjkzLDEuMjUsMi45LDIuNzhMMzYuMDgsMTQuMjR6Ii8+ICA8cGF0aCBjbGFzcz0ic3QxIiBzdHlsZT0ib3BhY2l0eTowLjM1OyBlbmFibGUtYmFja2dyb3VuZDpuZXc7IiBkPSJNODQuMzQsMTMuNTlsLTAuMDctMC4xM2wtMS45Ni0yLjk5bDEuOTQtMi45NWMwLjQ0LTAuNjcsMC4yNi0xLjU2LTAuNDEtMi4wMmMtMC4wMiwwLTAuMDMsMC0wLjA0LTAuMDEgICAgYy0wLjIzLTAuMTUtMC41LTAuMjItMC43OC0wLjIyaC0xLjYxYy0wLjU2LDAtMS4wOCwwLjI5LTEuMzcsMC43OEw3OS43Miw2LjZsLTAuMzQtMC41NkM3OS4wOSw1LjU2LDc4LjU3LDUuMjcsNzgsNS4yN2gtMS42ICAgIGMtMC42LDAtMS4xMywwLjM3LTEuMzUsMC45MmMtMi4xOS0xLjY2LTUuMjgtMS40Ny03LjI2LDAuNDVjLTAuMzUsMC4zNC0wLjY1LDAuNzItMC44OSwxLjE0Yy0wLjktMS42Mi0yLjU4LTIuNzItNC41LTIuNzIgICAgYy0wLjUsMC0xLjAxLDAuMDctMS40OCwwLjIzVjMuNTFjMC0wLjgyLTAuNjYtMS40OC0xLjQ3LTEuNDhoLTEuNGMtMC44MSwwLTEuNDcsMC42Ni0xLjQ3LDEuNDd2My43NSAgICBjLTAuOTUtMS4zNi0yLjUtMi4xOC00LjE3LTIuMTljLTAuNzQsMC0xLjQ2LDAuMTYtMi4xMiwwLjQ3Yy0wLjI0LTAuMTctMC41NC0wLjI2LTAuODQtMC4yNmgtMS40Yy0wLjQ1LDAtMC44NywwLjIxLTEuMTUsMC41NiAgICBjLTAuMDItMC4wMy0wLjA0LTAuMDUtMC4wNy0wLjA4Yy0wLjI4LTAuMy0wLjY4LTAuNDctMS4wOS0wLjQ3aC0xLjM5Yy0wLjMsMC0wLjYsMC4wOS0wLjg0LDAuMjZjLTAuNjctMC4zLTEuMzktMC40Ni0yLjEyLTAuNDYgICAgYy0xLjgzLDAtMy40MywxLTQuMzcsMi41Yy0wLjItMC40Ni0wLjQ4LTAuODktMC44My0xLjI1Yy0wLjgtMC44MS0xLjg5LTEuMjUtMy4wMi0xLjI1aC0wLjAxYy0wLjg5LDAuMDEtMS43NSwwLjMzLTIuNDYsMC44OCAgICBjLTAuNzQtMC41Ny0xLjY0LTAuODgtMi41Ny0wLjg4SDI4LjFjLTAuMjksMC0wLjU4LDAuMDMtMC44NiwwLjExYy0wLjI4LDAuMDYtMC41NiwwLjE2LTAuODIsMC4yOGMtMC4yMS0wLjEyLTAuNDUtMC4xOC0wLjctMC4xOCAgICBoLTEuNGMtMC44MiwwLTEuNDcsMC42Ni0xLjQ3LDEuNDd2Ny41YzAsMC44MiwwLjY2LDEuNDcsMS40NywxLjQ3aDEuNGMwLjgyLDAsMS40OC0wLjY2LDEuNDgtMS40OGwwLDBWOS43OSAgICBjMC4wMy0wLjM2LDAuMjMtMC41OSwwLjM2LTAuNTljMC4xOCwwLDAuMzgsMC4xOCwwLjM4LDAuNDd2NC41N2MwLDAuODIsMC42NiwxLjQ3LDEuNDcsMS40N2gxLjQxYzAuODIsMCwxLjQ3LTAuNjYsMS40Ny0xLjQ3ICAgIGwtMC4wMS00LjU3YzAuMDYtMC4zMiwwLjI1LTAuNDcsMC4zNS0wLjQ3YzAuMTgsMCwwLjM4LDAuMTgsMC4zOCwwLjQ3djQuNTdjMCwwLjgyLDAuNjYsMS40NywxLjQ3LDEuNDdoMS40MSAgICBjMC44MiwwLDEuNDctMC42NiwxLjQ3LTEuNDd2LTAuMzhjMC45NiwxLjI5LDIuNDYsMi4wNiw0LjA2LDIuMDZjMC43NCwwLDEuNDYtMC4xNiwyLjEyLTAuNDdjMC4yNCwwLjE3LDAuNTQsMC4yNiwwLjg0LDAuMjZoMS4zOSAgICBjMC4zLDAsMC42LTAuMDksMC44NC0wLjI2djIuMDFjMCwwLjgyLDAuNjYsMS40NywxLjQ3LDEuNDdoMS40YzAuODIsMCwxLjQ3LTAuNjYsMS40Ny0xLjQ3di0xLjc3YzAuNDgsMC4xNSwwLjk5LDAuMjMsMS40OSwwLjIyICAgIGMxLjcsMCwzLjIyLTAuODcsNC4xNy0yLjJ2MC41MmMwLDAuODIsMC42NiwxLjQ3LDEuNDcsMS40N2gxLjRjMC4zLDAsMC42LTAuMDksMC44NC0wLjI2YzAuNjYsMC4zMSwxLjM5LDAuNDcsMi4xMiwwLjQ3ICAgIGMxLjkyLDAsMy42LTEuMSw0LjQ5LTIuNzNjMS41NCwyLjY1LDQuOTUsMy41Myw3LjU4LDEuOThjMC4xOC0wLjExLDAuMzYtMC4yMiwwLjUzLTAuMzZjMC4yMiwwLjU1LDAuNzYsMC45MSwxLjM1LDAuOUg3OCAgICBjMC41NiwwLDEuMDgtMC4yOSwxLjM3LTAuNzhsMC4zNy0wLjYxbDAuMzcsMC42MWMwLjI5LDAuNDgsMC44MSwwLjc4LDEuMzgsMC43OGgxLjZjMC44MSwwLDEuNDYtMC42NiwxLjQ1LTEuNDYgICAgQzg0LjQ5LDE0LjAyLDg0LjQ0LDEzLjgsODQuMzQsMTMuNTlMODQuMzQsMTMuNTl6IE0zNS44NiwxNC40N2gtMS40MWMtMC4xMywwLTAuMjMtMC4xMS0wLjIzLTAuMjNWOS42OCAgICBjMC0wLjk4LTAuNzQtMS43MS0xLjYyLTEuNzFjLTAuOCwwLTEuNDYsMC43LTEuNTksMS42MmwwLjAxLDQuNjZjMCwwLjEzLTAuMSwwLjIzLTAuMjMsMC4yM2gtMS40MWMtMC4xMywwLTAuMjMtMC4xMS0wLjIzLTAuMjMgICAgVjkuNjhjMC0wLjk4LTAuNzQtMS43MS0xLjYyLTEuNzFjLTAuODUsMC0xLjU0LDAuNzktMS42LDEuOHY0LjQ4YzAsMC4xMy0wLjEsMC4yMy0wLjIzLDAuMjNoLTEuNGMtMC4xMywwLTAuMjMtMC4xMS0wLjIzLTAuMjMgICAgVjYuNzRjMC4wMS0wLjEzLDAuMTEtMC4yMiwwLjIzLTAuMjJoMS40YzAuMTMsMCwwLjIyLDAuMTEsMC4yMywwLjIyVjcuNGMwLjUtMC42OCwxLjMtMS4wOSwyLjE2LTEuMWgwLjAzICAgIGMxLjA5LDAsMi4wOSwwLjYsMi42LDEuNTVjMC40NS0wLjk1LDEuNC0xLjU1LDIuNDQtMS41NmMxLjYyLDAsMi45MywxLjI1LDIuOSwyLjc4bDAuMDEsNS4xNkMzNi4wOSwxNC4zNiwzNS45OCwxNC40NiwzNS44NiwxNC40NyAgICBMMzUuODYsMTQuNDd6IE00NS45NywxNC4yNGMwLDAuMTMtMC4xLDAuMjMtMC4yMywwLjIzaC0xLjRjLTAuMTMsMC0wLjIzLTAuMTEtMC4yMy0wLjIzVjEzLjVjLTAuNywwLjc2LTEuNjksMS4xOC0yLjcyLDEuMTggICAgYy0yLjE3LDAtMy45NC0xLjg3LTMuOTQtNC4xOXMxLjc3LTQuMTksMy45NC00LjE5YzEuMDMsMCwyLjAyLDAuNDMsMi43MywxLjE4VjYuNzRjMC0wLjEzLDAuMS0wLjIzLDAuMjMtMC4yM2gxLjQgICAgYzAuMTItMC4wMSwwLjIyLDAuMDgsMC4yMywwLjIxYzAsMC4wMSwwLDAuMDEsMCwwLjAydjcuNTFoLTAuMDFWMTQuMjR6IE01Mi40MSwxNC42N2MtMS4wMywwLTIuMDItMC40My0yLjczLTEuMTh2My45NyAgICBjMCwwLjEzLTAuMSwwLjIzLTAuMjMsMC4yM2gtMS40Yy0wLjEzLDAtMC4yMy0wLjEtMC4yMy0wLjIzVjYuNzVjMC0wLjEzLDAuMS0wLjIyLDAuMjMtMC4yMmgxLjRjMC4xMywwLDAuMjMsMC4xMSwwLjIzLDAuMjN2MC43MyAgICBjMC43MS0wLjc2LDEuNy0xLjE4LDIuNzMtMS4xOGMyLjE3LDAsMy45NCwxLjg2LDMuOTQsNC4xOFM1NC41OCwxNC42Nyw1Mi40MSwxNC42N3ogTTY2LjI0LDExLjM5Yy0wLjM5LDEuODctMS45NiwzLjI5LTMuODQsMy4yOSAgICBjLTEuMDMsMC0yLjAyLTAuNDMtMi43My0xLjE4djAuNzNjMCwwLjEzLTAuMSwwLjIzLTAuMjMsMC4yM2gtMS40Yy0wLjEzLDAtMC4yMy0wLjExLTAuMjMtMC4yM1YzLjUxYzAtMC4xMywwLjEtMC4yMywwLjIzLTAuMjMgICAgaDEuNGMwLjEzLDAsMC4yMywwLjExLDAuMjMsMC4yM3YzLjk3YzAuNzEtMC43NSwxLjctMS4xOCwyLjczLTEuMTdjMS44OCwwLDMuNDUsMS40LDMuODQsMy4yOEM2Ni4zNywxMC4xOSw2Ni4zNywxMC44LDY2LjI0LDExLjM5ICAgIEw2Ni4yNCwxMS4zOUw2Ni4yNCwxMS4zOXogTTcxLjY3LDE0LjY4Yy0yLDAuMDEtMy43My0xLjM1LTQuMTctMy4zYy0wLjEzLTAuNTktMC4xMy0xLjE5LDAtMS43N2MwLjQ0LTEuOTQsMi4xNy0zLjMxLDQuMTctMy4zICAgIGMyLjM2LDAsNC4yNiwxLjg3LDQuMjYsNC4xOVM3NC4wMywxNC42OCw3MS42NywxNC42OEw3MS42NywxNC42OHogTTgzLjA0LDE0LjQ3aC0xLjYxYy0wLjEzLDAtMC4yNC0wLjA2LTAuMy0wLjE3bC0xLjQ0LTIuMzkgICAgbC0xLjQ0LDIuMzljLTAuMDYsMC4xMS0wLjE4LDAuMTctMC4zLDAuMTdoLTEuNjFjLTAuMDQsMC0wLjA4LTAuMDEtMC4xMi0wLjAzYy0wLjA5LTAuMDYtMC4xMy0wLjE5LTAuMDYtMC4yOGwwLDBsMi40My0zLjY4ICAgIEw3Ni4yLDYuODRjLTAuMDItMC4wMy0wLjAzLTAuMDctMC4wMy0wLjEyYzAtMC4xMiwwLjA5LTAuMjEsMC4yMS0wLjIxaDEuNjFjMC4xMywwLDAuMjQsMC4wNiwwLjMsMC4xN2wxLjQxLDIuMzZsMS40MS0yLjM2ICAgIGMwLjA2LTAuMTEsMC4xOC0wLjE3LDAuMy0wLjE3aDEuNjFjMC4wNCwwLDAuMDgsMC4wMSwwLjEyLDAuMDNjMC4wOSwwLjA2LDAuMTMsMC4xOSwwLjA2LDAuMjhsMCwwbC0yLjM4LDMuNjRsMi40MywzLjY3ICAgIGMwLjAyLDAuMDMsMC4wMywwLjA3LDAuMDMsMC4xMkM4My4yNSwxNC4zOCw4My4xNiwxNC40Nyw4My4wNCwxNC40N0w4My4wNCwxNC40N0w4My4wNCwxNC40N3oiLz4gIDxwYXRoIGNsYXNzPSJzdDAiIHN0eWxlPSJvcGFjaXR5OjAuOTsgZmlsbDogI0ZGRkZGRjsgZW5hYmxlLWJhY2tncm91bmQ6IG5ldzsiIGQ9Ik0xMC41LDEuMjRjLTUuMTEsMC05LjI1LDQuMTUtOS4yNSw5LjI1czQuMTUsOS4yNSw5LjI1LDkuMjVzOS4yNS00LjE1LDkuMjUtOS4yNSAgICBDMTkuNzUsNS4zOCwxNS42MSwxLjI0LDEwLjUsMS4yNHogTTE0Ljg5LDEyLjc3Yy0xLjkzLDEuOTMtNC43OCwyLjMxLTYuNywyLjMxYy0wLjcsMC0xLjQxLTAuMDUtMi4xLTAuMTZjMCwwLTEuMDItNS42NCwyLjE0LTguODEgICAgYzAuODMtMC44MywxLjk1LTEuMjgsMy4xMy0xLjI4YzEuMjcsMCwyLjQ5LDAuNTEsMy4zOSwxLjQyQzE2LjU5LDguMDksMTYuNjQsMTEsMTQuODksMTIuNzd6Ii8+ICA8cGF0aCBjbGFzcz0ic3QxIiBzdHlsZT0ib3BhY2l0eTowLjM1OyBlbmFibGUtYmFja2dyb3VuZDpuZXc7IiBkPSJNMTAuNS0wLjAxQzQuNy0wLjAxLDAsNC43LDAsMTAuNDlzNC43LDEwLjUsMTAuNSwxMC41UzIxLDE2LjI5LDIxLDEwLjQ5QzIwLjk5LDQuNywxNi4zLTAuMDEsMTAuNS0wLjAxeiAgICAgTTEwLjUsMTkuNzRjLTUuMTEsMC05LjI1LTQuMTUtOS4yNS05LjI1czQuMTQtOS4yNiw5LjI1LTkuMjZzOS4yNSw0LjE1LDkuMjUsOS4yNUMxOS43NSwxNS42MSwxNS42MSwxOS43NCwxMC41LDE5Ljc0eiIvPiAgPHBhdGggY2xhc3M9InN0MSIgc3R5bGU9Im9wYWNpdHk6MC4zNTsgZW5hYmxlLWJhY2tncm91bmQ6bmV3OyIgZD0iTTE0Ljc0LDYuMjVDMTIuOSw0LjQxLDkuOTgsNC4zNSw4LjIzLDYuMWMtMy4xNiwzLjE3LTIuMTQsOC44MS0yLjE0LDguODFzNS42NCwxLjAyLDguODEtMi4xNCAgICBDMTYuNjQsMTEsMTYuNTksOC4wOSwxNC43NCw2LjI1eiBNMTIuNDcsMTAuMzRsLTAuOTEsMS44N2wtMC45LTEuODdMOC44LDkuNDNsMS44Ni0wLjlsMC45LTEuODdsMC45MSwxLjg3bDEuODYsMC45TDEyLjQ3LDEwLjM0eiIgICAgLz4gIDxwb2x5Z29uIGNsYXNzPSJzdDAiIHN0eWxlPSJvcGFjaXR5OjAuOTsgZmlsbDogI0ZGRkZGRjsgZW5hYmxlLWJhY2tncm91bmQ6IG5ldzsiIHBvaW50cz0iMTQuMzMsOS40MyAxMi40NywxMC4zNCAxMS41NiwxMi4yMSAxMC42NiwxMC4zNCA4LjgsOS40MyAxMC42Niw4LjUzIDExLjU2LDYuNjYgMTIuNDcsOC41MyAgICIvPjwvZz48L3N2Zz4=);
  122 +}
  123 +
  124 +.mapboxgl-ctrl.mapboxgl-ctrl-attrib {
  125 + padding: 0 5px;
  126 + background-color: rgba(255, 255, 255, .5);
  127 + margin: 0;
  128 +}
  129 +.mapboxgl-ctrl-attrib.mapboxgl-compact {
  130 + padding-top: 2px;
  131 + padding-bottom: 2px;
  132 + margin: 0 10px 10px 10px;
  133 + position: relative;
  134 + padding-right: 24px;
  135 + background-color: #fff;
  136 + border-radius: 3px 12px 12px 3px;
  137 + visibility: hidden;
  138 +}
  139 +.mapboxgl-ctrl-attrib.mapboxgl-compact:hover {
  140 + visibility: visible;
  141 +}
  142 +.mapboxgl-ctrl-attrib.mapboxgl-compact:after {
  143 + content: '';
  144 + cursor: pointer;
  145 + position: absolute;
  146 + bottom: 0;
  147 + right: 0;
  148 + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D%270%200%2020%2020%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%0D%0A%09%3Cpath%20fill%3D%27%23333333%27%20fill-rule%3D%27evenodd%27%20d%3D%27M4%2C10a6%2C6%200%201%2C0%2012%2C0a6%2C6%200%201%2C0%20-12%2C0%20M9%2C7a1%2C1%200%201%2C0%202%2C0a1%2C1%200%201%2C0%20-2%2C0%20M9%2C10a1%2C1%200%201%2C1%202%2C0l0%2C3a1%2C1%200%201%2C1%20-2%2C0%27%20%2F%3E%0D%0A%3C%2Fsvg%3E");
  149 + background-color: rgba(255, 255, 255, .5);
  150 + width: 24px;
  151 + height: 24px;
  152 + box-sizing: border-box;
  153 + visibility: visible;
  154 + border-radius: 12px;
  155 +}
  156 +.mapboxgl-ctrl-attrib a {
  157 + color: rgba(0,0,0,0.75);
  158 + text-decoration: none;
  159 +}
  160 +.mapboxgl-ctrl-attrib a:hover {
  161 + color: inherit;
  162 + text-decoration: underline;
  163 +}
  164 +/* stylelint-disable */
  165 +.mapboxgl-ctrl-attrib .mapbox-improve-map {
  166 + font-weight: bold;
  167 + margin-left: 2px;
  168 +}
  169 +/*stylelint-enable*/
  170 +.mapboxgl-ctrl-scale {
  171 + background-color: rgba(255,255,255,0.75);
  172 + font-size: 10px;
  173 + border-width: medium 2px 2px;
  174 + border-style: none solid solid;
  175 + border-color: #333;
  176 + padding: 0 5px;
  177 + color: #333;
  178 +}
  179 +
  180 +.mapboxgl-popup {
  181 + position: absolute;
  182 + top: 0;
  183 + left: 0;
  184 + display: -webkit-flex;
  185 + display: flex;
  186 + will-change: transform;
  187 + pointer-events: none;
  188 +}
  189 +.mapboxgl-popup-anchor-top,
  190 +.mapboxgl-popup-anchor-top-left,
  191 +.mapboxgl-popup-anchor-top-right {
  192 + -webkit-flex-direction: column;
  193 + flex-direction: column;
  194 +}
  195 +.mapboxgl-popup-anchor-bottom,
  196 +.mapboxgl-popup-anchor-bottom-left,
  197 +.mapboxgl-popup-anchor-bottom-right {
  198 + -webkit-flex-direction: column-reverse;
  199 + flex-direction: column-reverse;
  200 +}
  201 +.mapboxgl-popup-anchor-left {
  202 + -webkit-flex-direction: row;
  203 + flex-direction: row;
  204 +}
  205 +.mapboxgl-popup-anchor-right {
  206 + -webkit-flex-direction: row-reverse;
  207 + flex-direction: row-reverse;
  208 +}
  209 +.mapboxgl-popup-tip {
  210 + width: 0;
  211 + height: 0;
  212 + border: 10px solid transparent;
  213 + z-index: 1;
  214 +}
  215 +.mapboxgl-popup-anchor-top .mapboxgl-popup-tip {
  216 + -webkit-align-self: center;
  217 + align-self: center;
  218 + border-top: none;
  219 + border-bottom-color: #fff;
  220 +}
  221 +.mapboxgl-popup-anchor-top-left .mapboxgl-popup-tip {
  222 + -webkit-align-self: flex-start;
  223 + align-self: flex-start;
  224 + border-top: none;
  225 + border-left: none;
  226 + border-bottom-color: #fff;
  227 +}
  228 +.mapboxgl-popup-anchor-top-right .mapboxgl-popup-tip {
  229 + -webkit-align-self: flex-end;
  230 + align-self: flex-end;
  231 + border-top: none;
  232 + border-right: none;
  233 + border-bottom-color: #fff;
  234 +}
  235 +.mapboxgl-popup-anchor-bottom .mapboxgl-popup-tip {
  236 + -webkit-align-self: center;
  237 + align-self: center;
  238 + border-bottom: none;
  239 + border-top-color: #fff;
  240 +}
  241 +.mapboxgl-popup-anchor-bottom-left .mapboxgl-popup-tip {
  242 + -webkit-align-self: flex-start;
  243 + align-self: flex-start;
  244 + border-bottom: none;
  245 + border-left: none;
  246 + border-top-color: #fff;
  247 +}
  248 +.mapboxgl-popup-anchor-bottom-right .mapboxgl-popup-tip {
  249 + -webkit-align-self: flex-end;
  250 + align-self: flex-end;
  251 + border-bottom: none;
  252 + border-right: none;
  253 + border-top-color: #fff;
  254 +}
  255 +.mapboxgl-popup-anchor-left .mapboxgl-popup-tip {
  256 + -webkit-align-self: center;
  257 + align-self: center;
  258 + border-left: none;
  259 + border-right-color: #fff;
  260 +}
  261 +.mapboxgl-popup-anchor-right .mapboxgl-popup-tip {
  262 + -webkit-align-self: center;
  263 + align-self: center;
  264 + border-right: none;
  265 + border-left-color: #fff;
  266 +}
  267 +.mapboxgl-popup-close-button {
  268 + position: absolute;
  269 + right: 0;
  270 + top: 0;
  271 + border: none;
  272 + border-radius: 0 3px 0 0;
  273 + cursor: pointer;
  274 + background-color: rgba(0,0,0,0);
  275 +}
  276 +.mapboxgl-popup-close-button:hover {
  277 + background-color: rgba(0,0,0,0.05);
  278 +}
  279 +.mapboxgl-popup-content {
  280 + position: relative;
  281 + background: #fff;
  282 + border-radius: 3px;
  283 + box-shadow: 0 1px 2px rgba(0,0,0,0.10);
  284 + padding: 10px 10px 15px;
  285 + pointer-events: auto;
  286 +}
  287 +.mapboxgl-popup-anchor-top-left .mapboxgl-popup-content {
  288 + border-top-left-radius: 0;
  289 +}
  290 +.mapboxgl-popup-anchor-top-right .mapboxgl-popup-content {
  291 + border-top-right-radius: 0;
  292 +}
  293 +.mapboxgl-popup-anchor-bottom-left .mapboxgl-popup-content {
  294 + border-bottom-left-radius: 0;
  295 +}
  296 +.mapboxgl-popup-anchor-bottom-right .mapboxgl-popup-content {
  297 + border-bottom-right-radius: 0;
  298 +}
  299 +
  300 +.mapboxgl-marker {
  301 + position: absolute;
  302 + top: 0;
  303 + left: 0;
  304 + will-change: transform;
  305 +}
  306 +
  307 +.mapboxgl-crosshair,
  308 +.mapboxgl-crosshair .mapboxgl-interactive,
  309 +.mapboxgl-crosshair .mapboxgl-interactive:active {
  310 + cursor: crosshair;
  311 +}
  312 +.mapboxgl-boxzoom {
  313 + position: absolute;
  314 + top: 0;
  315 + left: 0;
  316 + width: 0;
  317 + height: 0;
  318 + background: #fff;
  319 + border: 2px dotted #202020;
  320 + opacity: 0.5;
  321 +}
  322 +
  323 +@media print {
  324 +/* stylelint-disable */
  325 + .mapbox-improve-map {
  326 + display:none;
  327 + }
  328 +/* stylelint-enable */
  329 +}
  1 +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.mapboxgl = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
  2 +!function(t,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):t.glMatrix=r()}(this,function(){"use strict";function t(){var t=new Float32Array(3);return t[0]=0,t[1]=0,t[2]=0,t}function r(t,r,n){var e=r[0],a=r[1],o=r[2];return t[0]=e*n[0]+a*n[3]+o*n[6],t[1]=e*n[1]+a*n[4]+o*n[7],t[2]=e*n[2]+a*n[5]+o*n[8],t}function n(){var t=new Float32Array(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=0,t}function e(t,r,n){var e=r[0],a=r[1],o=r[2],u=r[3];return t[0]=n[0]*e+n[4]*a+n[8]*o+n[12]*u,t[1]=n[1]*e+n[5]*a+n[9]*o+n[13]*u,t[2]=n[2]*e+n[6]*a+n[10]*o+n[14]*u,t[3]=n[3]*e+n[7]*a+n[11]*o+n[15]*u,t}function a(){var t=new Float32Array(4);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t}function o(t,r,n){var e=r[0],a=r[1],o=r[2],u=r[3],i=Math.sin(n),c=Math.cos(n);return t[0]=e*c+o*i,t[1]=a*c+u*i,t[2]=e*-i+o*c,t[3]=a*-i+u*c,t}function u(t,r,n){var e=r[0],a=r[1],o=r[2],u=r[3],i=n[0],c=n[1];return t[0]=e*i,t[1]=a*i,t[2]=o*c,t[3]=u*c,t}function i(){var t=new Float32Array(9);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t}function c(t,r){var n=Math.sin(r),e=Math.cos(r);return t[0]=e,t[1]=n,t[2]=0,t[3]=-n,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t}function f(){var t=new Float32Array(16);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t}function v(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t}function s(t,r){var n=r[0],e=r[1],a=r[2],o=r[3],u=r[4],i=r[5],c=r[6],f=r[7],v=r[8],s=r[9],l=r[10],M=r[11],h=r[12],m=r[13],y=r[14],d=r[15],p=n*i-e*u,w=n*c-a*u,A=n*f-o*u,F=e*c-a*i,x=e*f-o*i,b=a*f-o*c,g=v*m-s*h,j=v*y-l*h,R=v*d-M*h,X=s*y-l*m,Z=s*d-M*m,k=l*d-M*y,q=p*k-w*Z+A*X+F*R-x*j+b*g;return q?(q=1/q,t[0]=(i*k-c*Z+f*X)*q,t[1]=(a*Z-e*k-o*X)*q,t[2]=(m*b-y*x+d*F)*q,t[3]=(l*x-s*b-M*F)*q,t[4]=(c*R-u*k-f*j)*q,t[5]=(n*k-a*R+o*j)*q,t[6]=(y*A-h*b-d*w)*q,t[7]=(v*b-l*A+M*w)*q,t[8]=(u*Z-i*R+f*g)*q,t[9]=(e*R-n*Z-o*g)*q,t[10]=(h*x-m*A+d*p)*q,t[11]=(s*A-v*x-M*p)*q,t[12]=(i*j-u*X-c*g)*q,t[13]=(n*X-e*j+a*g)*q,t[14]=(m*w-h*F-y*p)*q,t[15]=(v*F-s*w+l*p)*q,t):null}function l(t,r,n){var e=r[0],a=r[1],o=r[2],u=r[3],i=r[4],c=r[5],f=r[6],v=r[7],s=r[8],l=r[9],M=r[10],h=r[11],m=r[12],y=r[13],d=r[14],p=r[15],w=n[0],A=n[1],F=n[2],x=n[3];return t[0]=w*e+A*i+F*s+x*m,t[1]=w*a+A*c+F*l+x*y,t[2]=w*o+A*f+F*M+x*d,t[3]=w*u+A*v+F*h+x*p,w=n[4],A=n[5],F=n[6],x=n[7],t[4]=w*e+A*i+F*s+x*m,t[5]=w*a+A*c+F*l+x*y,t[6]=w*o+A*f+F*M+x*d,t[7]=w*u+A*v+F*h+x*p,w=n[8],A=n[9],F=n[10],x=n[11],t[8]=w*e+A*i+F*s+x*m,t[9]=w*a+A*c+F*l+x*y,t[10]=w*o+A*f+F*M+x*d,t[11]=w*u+A*v+F*h+x*p,w=n[12],A=n[13],F=n[14],x=n[15],t[12]=w*e+A*i+F*s+x*m,t[13]=w*a+A*c+F*l+x*y,t[14]=w*o+A*f+F*M+x*d,t[15]=w*u+A*v+F*h+x*p,t}function M(t,r,n){var e,a,o,u,i,c,f,v,s,l,M,h,m=n[0],y=n[1],d=n[2];return r===t?(t[12]=r[0]*m+r[4]*y+r[8]*d+r[12],t[13]=r[1]*m+r[5]*y+r[9]*d+r[13],t[14]=r[2]*m+r[6]*y+r[10]*d+r[14],t[15]=r[3]*m+r[7]*y+r[11]*d+r[15]):(e=r[0],a=r[1],o=r[2],u=r[3],i=r[4],c=r[5],f=r[6],v=r[7],s=r[8],l=r[9],M=r[10],h=r[11],t[0]=e,t[1]=a,t[2]=o,t[3]=u,t[4]=i,t[5]=c,t[6]=f,t[7]=v,t[8]=s,t[9]=l,t[10]=M,t[11]=h,t[12]=e*m+i*y+s*d+r[12],t[13]=a*m+c*y+l*d+r[13],t[14]=o*m+f*y+M*d+r[14],t[15]=u*m+v*y+h*d+r[15]),t}function h(t,r,n){var e=n[0],a=n[1],o=n[2];return t[0]=r[0]*e,t[1]=r[1]*e,t[2]=r[2]*e,t[3]=r[3]*e,t[4]=r[4]*a,t[5]=r[5]*a,t[6]=r[6]*a,t[7]=r[7]*a,t[8]=r[8]*o,t[9]=r[9]*o,t[10]=r[10]*o,t[11]=r[11]*o,t[12]=r[12],t[13]=r[13],t[14]=r[14],t[15]=r[15],t}function m(t,r,n){var e=Math.sin(n),a=Math.cos(n),o=r[4],u=r[5],i=r[6],c=r[7],f=r[8],v=r[9],s=r[10],l=r[11];return r!==t&&(t[0]=r[0],t[1]=r[1],t[2]=r[2],t[3]=r[3],t[12]=r[12],t[13]=r[13],t[14]=r[14],t[15]=r[15]),t[4]=o*a+f*e,t[5]=u*a+v*e,t[6]=i*a+s*e,t[7]=c*a+l*e,t[8]=f*a-o*e,t[9]=v*a-u*e,t[10]=s*a-i*e,t[11]=l*a-c*e,t}function y(t,r,n){var e=Math.sin(n),a=Math.cos(n),o=r[0],u=r[1],i=r[2],c=r[3],f=r[4],v=r[5],s=r[6],l=r[7];return r!==t&&(t[8]=r[8],t[9]=r[9],t[10]=r[10],t[11]=r[11],t[12]=r[12],t[13]=r[13],t[14]=r[14],t[15]=r[15]),t[0]=o*a+f*e,t[1]=u*a+v*e,t[2]=i*a+s*e,t[3]=c*a+l*e,t[4]=f*a-o*e,t[5]=v*a-u*e,t[6]=s*a-i*e,t[7]=l*a-c*e,t}function d(t,r,n,e,a){var o=1/Math.tan(r/2),u=1/(e-a);return t[0]=o/n,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=o,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=(a+e)*u,t[11]=-1,t[12]=0,t[13]=0,t[14]=2*a*e*u,t[15]=0,t}function p(t,r,n,e,a,o,u){var i=1/(r-n),c=1/(e-a),f=1/(o-u);return t[0]=-2*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*c,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*f,t[11]=0,t[12]=(r+n)*i,t[13]=(a+e)*c,t[14]=(u+o)*f,t[15]=1,t}var w=(t(),n(),{vec3:{transformMat3:r},vec4:{transformMat4:e},mat2:{create:a,rotate:o,scale:u},mat3:{create:i,fromRotation:c},mat4:{create:f,identity:v,translate:M,scale:h,multiply:l,perspective:d,rotateX:m,rotateZ:y,invert:s,ortho:p}});return w});
  3 +},{}],2:[function(_dereq_,module,exports){
  4 +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.ShelfPack=e()}(this,function(){function t(t,e,i){i=i||{},this.w=t||64,this.h=e||64,this.autoResize=!!i.autoResize,this.shelves=[],this.freebins=[],this.stats={},this.bins={},this.maxId=0}function e(t,e,i){this.x=0,this.y=t,this.w=this.free=e,this.h=i}function i(t,e,i,s,h,n,r){this.id=t,this.x=e,this.y=i,this.w=s,this.h=h,this.maxw=n||s,this.maxh=r||h,this.refcount=0}return t.prototype.pack=function(t,e){t=[].concat(t),e=e||{};for(var i,s,h,n,r=[],f=0;f<t.length;f++)if(i=t[f].w||t[f].width,s=t[f].h||t[f].height,h=t[f].id,i&&s){if(n=this.packOne(i,s,h),!n)continue;e.inPlace&&(t[f].x=n.x,t[f].y=n.y,t[f].id=n.id),r.push(n)}if(this.shelves.length>0){for(var o=0,a=0,u=0;u<this.shelves.length;u++){var l=this.shelves[u];a+=l.h,o=Math.max(l.w-l.free,o)}this.resize(o,a)}return r},t.prototype.packOne=function(t,i,s){var h,n,r,f,o={freebin:-1,shelf:-1,waste:1/0},a=0;if("string"==typeof s||"number"==typeof s){if(h=this.getBin(s))return this.ref(h),h;"number"==typeof s&&(this.maxId=Math.max(s,this.maxId))}else s=++this.maxId;for(f=0;f<this.freebins.length;f++){if(h=this.freebins[f],i===h.maxh&&t===h.maxw)return this.allocFreebin(f,t,i,s);i>h.maxh||t>h.maxw||i<=h.maxh&&t<=h.maxw&&(r=h.maxw*h.maxh-t*i,r<o.waste&&(o.waste=r,o.freebin=f))}for(f=0;f<this.shelves.length;f++)if(n=this.shelves[f],a+=n.h,!(t>n.free)){if(i===n.h)return this.allocShelf(f,t,i,s);i>n.h||i<n.h&&(r=(n.h-i)*t,r<o.waste&&(o.freebin=-1,o.waste=r,o.shelf=f))}if(o.freebin!==-1)return this.allocFreebin(o.freebin,t,i,s);if(o.shelf!==-1)return this.allocShelf(o.shelf,t,i,s);if(i<=this.h-a&&t<=this.w)return n=new e(a,this.w,i),this.allocShelf(this.shelves.push(n)-1,t,i,s);if(this.autoResize){var u,l,c,p;return u=l=this.h,c=p=this.w,(c<=u||t>c)&&(p=2*Math.max(t,c)),(u<c||i>u)&&(l=2*Math.max(i,u)),this.resize(p,l),this.packOne(t,i,s)}return null},t.prototype.allocFreebin=function(t,e,i,s){var h=this.freebins.splice(t,1)[0];return h.id=s,h.w=e,h.h=i,h.refcount=0,this.bins[s]=h,this.ref(h),h},t.prototype.allocShelf=function(t,e,i,s){var h=this.shelves[t],n=h.alloc(e,i,s);return this.bins[s]=n,this.ref(n),n},t.prototype.getBin=function(t){return this.bins[t]},t.prototype.ref=function(t){if(1===++t.refcount){var e=t.h;this.stats[e]=(0|this.stats[e])+1}return t.refcount},t.prototype.unref=function(t){return 0===t.refcount?0:(0===--t.refcount&&(this.stats[t.h]--,delete this.bins[t.id],this.freebins.push(t)),t.refcount)},t.prototype.clear=function(){this.shelves=[],this.freebins=[],this.stats={},this.bins={},this.maxId=0},t.prototype.resize=function(t,e){this.w=t,this.h=e;for(var i=0;i<this.shelves.length;i++)this.shelves[i].resize(t);return!0},e.prototype.alloc=function(t,e,s){if(t>this.free||e>this.h)return null;var h=this.x;return this.x+=t,this.free-=t,new i(s,h,this.y,t,e,t,this.h)},e.prototype.resize=function(t){return this.free+=t-this.w,this.w=t,!0},t});
  5 +},{}],3:[function(_dereq_,module,exports){
  6 +function UnitBezier(t,i,e,r){this.cx=3*t,this.bx=3*(e-t)-this.cx,this.ax=1-this.cx-this.bx,this.cy=3*i,this.by=3*(r-i)-this.cy,this.ay=1-this.cy-this.by,this.p1x=t,this.p1y=r,this.p2x=e,this.p2y=r}module.exports=UnitBezier,UnitBezier.prototype.sampleCurveX=function(t){return((this.ax*t+this.bx)*t+this.cx)*t},UnitBezier.prototype.sampleCurveY=function(t){return((this.ay*t+this.by)*t+this.cy)*t},UnitBezier.prototype.sampleCurveDerivativeX=function(t){return(3*this.ax*t+2*this.bx)*t+this.cx},UnitBezier.prototype.solveCurveX=function(t,i){"undefined"==typeof i&&(i=1e-6);var e,r,s,h,n;for(s=t,n=0;n<8;n++){if(h=this.sampleCurveX(s)-t,Math.abs(h)<i)return s;var u=this.sampleCurveDerivativeX(s);if(Math.abs(u)<1e-6)break;s-=h/u}if(e=0,r=1,s=t,s<e)return e;if(s>r)return r;for(;e<r;){if(h=this.sampleCurveX(s),Math.abs(h-t)<i)return s;t>h?e=s:r=s,s=.5*(r-e)+e}return s},UnitBezier.prototype.solve=function(t,i){return this.sampleCurveY(this.solveCurveX(t,i))};
  7 +},{}],4:[function(_dereq_,module,exports){
  8 +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(e.WhooTS=e.WhooTS||{})}(this,function(e){function t(e,t,r,n,i,s){s=s||{};var f=e+"?"+["bbox="+o(r,n,i),"format="+(s.format||"image/png"),"service="+(s.service||"WMS"),"version="+(s.version||"1.1.1"),"request="+(s.request||"GetMap"),"srs="+(s.srs||"EPSG:3857"),"width="+(s.width||256),"height="+(s.height||256),"layers="+t].join("&");return f}function o(e,t,o){t=Math.pow(2,o)-t-1;var n=r(256*e,256*t,o),i=r(256*(e+1),256*(t+1),o);return n[0]+","+n[1]+","+i[0]+","+i[1]}function r(e,t,o){var r=2*Math.PI*6378137/256/Math.pow(2,o),n=e*r-2*Math.PI*6378137/2,i=t*r-2*Math.PI*6378137/2;return[n,i]}e.getURL=t,e.getTileBBox=o,e.getMercCoords=r,Object.defineProperty(e,"__esModule",{value:!0})});
  9 +},{}],5:[function(_dereq_,module,exports){
  10 +"use strict";function earcut(e,n,r){r=r||2;var t=n&&n.length,i=t?n[0]*r:e.length,x=linkedList(e,0,i,r,!0),a=[];if(!x)return a;var o,l,u,s,v,f,y;if(t&&(x=eliminateHoles(e,n,x,r)),e.length>80*r){o=u=e[0],l=s=e[1];for(var d=r;d<i;d+=r)v=e[d],f=e[d+1],v<o&&(o=v),f<l&&(l=f),v>u&&(u=v),f>s&&(s=f);y=Math.max(u-o,s-l)}return earcutLinked(x,a,r,o,l,y),a}function linkedList(e,n,r,t,i){var x,a;if(i===signedArea(e,n,r,t)>0)for(x=n;x<r;x+=t)a=insertNode(x,e[x],e[x+1],a);else for(x=r-t;x>=n;x-=t)a=insertNode(x,e[x],e[x+1],a);return a&&equals(a,a.next)&&(removeNode(a),a=a.next),a}function filterPoints(e,n){if(!e)return e;n||(n=e);var r,t=e;do if(r=!1,t.steiner||!equals(t,t.next)&&0!==area(t.prev,t,t.next))t=t.next;else{if(removeNode(t),t=n=t.prev,t===t.next)return null;r=!0}while(r||t!==n);return n}function earcutLinked(e,n,r,t,i,x,a){if(e){!a&&x&&indexCurve(e,t,i,x);for(var o,l,u=e;e.prev!==e.next;)if(o=e.prev,l=e.next,x?isEarHashed(e,t,i,x):isEar(e))n.push(o.i/r),n.push(e.i/r),n.push(l.i/r),removeNode(e),e=l.next,u=l.next;else if(e=l,e===u){a?1===a?(e=cureLocalIntersections(e,n,r),earcutLinked(e,n,r,t,i,x,2)):2===a&&splitEarcut(e,n,r,t,i,x):earcutLinked(filterPoints(e),n,r,t,i,x,1);break}}}function isEar(e){var n=e.prev,r=e,t=e.next;if(area(n,r,t)>=0)return!1;for(var i=e.next.next;i!==e.prev;){if(pointInTriangle(n.x,n.y,r.x,r.y,t.x,t.y,i.x,i.y)&&area(i.prev,i,i.next)>=0)return!1;i=i.next}return!0}function isEarHashed(e,n,r,t){var i=e.prev,x=e,a=e.next;if(area(i,x,a)>=0)return!1;for(var o=i.x<x.x?i.x<a.x?i.x:a.x:x.x<a.x?x.x:a.x,l=i.y<x.y?i.y<a.y?i.y:a.y:x.y<a.y?x.y:a.y,u=i.x>x.x?i.x>a.x?i.x:a.x:x.x>a.x?x.x:a.x,s=i.y>x.y?i.y>a.y?i.y:a.y:x.y>a.y?x.y:a.y,v=zOrder(o,l,n,r,t),f=zOrder(u,s,n,r,t),y=e.nextZ;y&&y.z<=f;){if(y!==e.prev&&y!==e.next&&pointInTriangle(i.x,i.y,x.x,x.y,a.x,a.y,y.x,y.y)&&area(y.prev,y,y.next)>=0)return!1;y=y.nextZ}for(y=e.prevZ;y&&y.z>=v;){if(y!==e.prev&&y!==e.next&&pointInTriangle(i.x,i.y,x.x,x.y,a.x,a.y,y.x,y.y)&&area(y.prev,y,y.next)>=0)return!1;y=y.prevZ}return!0}function cureLocalIntersections(e,n,r){var t=e;do{var i=t.prev,x=t.next.next;!equals(i,x)&&intersects(i,t,t.next,x)&&locallyInside(i,x)&&locallyInside(x,i)&&(n.push(i.i/r),n.push(t.i/r),n.push(x.i/r),removeNode(t),removeNode(t.next),t=e=x),t=t.next}while(t!==e);return t}function splitEarcut(e,n,r,t,i,x){var a=e;do{for(var o=a.next.next;o!==a.prev;){if(a.i!==o.i&&isValidDiagonal(a,o)){var l=splitPolygon(a,o);return a=filterPoints(a,a.next),l=filterPoints(l,l.next),earcutLinked(a,n,r,t,i,x),void earcutLinked(l,n,r,t,i,x)}o=o.next}a=a.next}while(a!==e)}function eliminateHoles(e,n,r,t){var i,x,a,o,l,u=[];for(i=0,x=n.length;i<x;i++)a=n[i]*t,o=i<x-1?n[i+1]*t:e.length,l=linkedList(e,a,o,t,!1),l===l.next&&(l.steiner=!0),u.push(getLeftmost(l));for(u.sort(compareX),i=0;i<u.length;i++)eliminateHole(u[i],r),r=filterPoints(r,r.next);return r}function compareX(e,n){return e.x-n.x}function eliminateHole(e,n){if(n=findHoleBridge(e,n)){var r=splitPolygon(n,e);filterPoints(r,r.next)}}function findHoleBridge(e,n){var r,t=n,i=e.x,x=e.y,a=-(1/0);do{if(x<=t.y&&x>=t.next.y){var o=t.x+(x-t.y)*(t.next.x-t.x)/(t.next.y-t.y);if(o<=i&&o>a){if(a=o,o===i){if(x===t.y)return t;if(x===t.next.y)return t.next}r=t.x<t.next.x?t:t.next}}t=t.next}while(t!==n);if(!r)return null;if(i===a)return r.prev;var l,u=r,s=r.x,v=r.y,f=1/0;for(t=r.next;t!==u;)i>=t.x&&t.x>=s&&pointInTriangle(x<v?i:a,x,s,v,x<v?a:i,x,t.x,t.y)&&(l=Math.abs(x-t.y)/(i-t.x),(l<f||l===f&&t.x>r.x)&&locallyInside(t,e)&&(r=t,f=l)),t=t.next;return r}function indexCurve(e,n,r,t){var i=e;do null===i.z&&(i.z=zOrder(i.x,i.y,n,r,t)),i.prevZ=i.prev,i.nextZ=i.next,i=i.next;while(i!==e);i.prevZ.nextZ=null,i.prevZ=null,sortLinked(i)}function sortLinked(e){var n,r,t,i,x,a,o,l,u=1;do{for(r=e,e=null,x=null,a=0;r;){for(a++,t=r,o=0,n=0;n<u&&(o++,t=t.nextZ,t);n++);for(l=u;o>0||l>0&&t;)0===o?(i=t,t=t.nextZ,l--):0!==l&&t?r.z<=t.z?(i=r,r=r.nextZ,o--):(i=t,t=t.nextZ,l--):(i=r,r=r.nextZ,o--),x?x.nextZ=i:e=i,i.prevZ=x,x=i;r=t}x.nextZ=null,u*=2}while(a>1);return e}function zOrder(e,n,r,t,i){return e=32767*(e-r)/i,n=32767*(n-t)/i,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),n=16711935&(n|n<<8),n=252645135&(n|n<<4),n=858993459&(n|n<<2),n=1431655765&(n|n<<1),e|n<<1}function getLeftmost(e){var n=e,r=e;do n.x<r.x&&(r=n),n=n.next;while(n!==e);return r}function pointInTriangle(e,n,r,t,i,x,a,o){return(i-a)*(n-o)-(e-a)*(x-o)>=0&&(e-a)*(t-o)-(r-a)*(n-o)>=0&&(r-a)*(x-o)-(i-a)*(t-o)>=0}function isValidDiagonal(e,n){return e.next.i!==n.i&&e.prev.i!==n.i&&!intersectsPolygon(e,n)&&locallyInside(e,n)&&locallyInside(n,e)&&middleInside(e,n)}function area(e,n,r){return(n.y-e.y)*(r.x-n.x)-(n.x-e.x)*(r.y-n.y)}function equals(e,n){return e.x===n.x&&e.y===n.y}function intersects(e,n,r,t){return!!(equals(e,n)&&equals(r,t)||equals(e,t)&&equals(r,n))||area(e,n,r)>0!=area(e,n,t)>0&&area(r,t,e)>0!=area(r,t,n)>0}function intersectsPolygon(e,n){var r=e;do{if(r.i!==e.i&&r.next.i!==e.i&&r.i!==n.i&&r.next.i!==n.i&&intersects(r,r.next,e,n))return!0;r=r.next}while(r!==e);return!1}function locallyInside(e,n){return area(e.prev,e,e.next)<0?area(e,n,e.next)>=0&&area(e,e.prev,n)>=0:area(e,n,e.prev)<0||area(e,e.next,n)<0}function middleInside(e,n){var r=e,t=!1,i=(e.x+n.x)/2,x=(e.y+n.y)/2;do r.y>x!=r.next.y>x&&i<(r.next.x-r.x)*(x-r.y)/(r.next.y-r.y)+r.x&&(t=!t),r=r.next;while(r!==e);return t}function splitPolygon(e,n){var r=new Node(e.i,e.x,e.y),t=new Node(n.i,n.x,n.y),i=e.next,x=n.prev;return e.next=n,n.prev=e,r.next=i,i.prev=r,t.next=r,r.prev=t,x.next=t,t.prev=x,t}function insertNode(e,n,r,t){var i=new Node(e,n,r);return t?(i.next=t.next,i.prev=t,t.next.prev=i,t.next=i):(i.prev=i,i.next=i),i}function removeNode(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function Node(e,n,r){this.i=e,this.x=n,this.y=r,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function signedArea(e,n,r,t){for(var i=0,x=n,a=r-t;x<r;x+=t)i+=(e[a]-e[x])*(e[x+1]+e[a+1]),a=x;return i}module.exports=earcut,earcut.deviation=function(e,n,r,t){var i=n&&n.length,x=i?n[0]*r:e.length,a=Math.abs(signedArea(e,0,x,r));if(i)for(var o=0,l=n.length;o<l;o++){var u=n[o]*r,s=o<l-1?n[o+1]*r:e.length;a-=Math.abs(signedArea(e,u,s,r))}var v=0;for(o=0;o<t.length;o+=3){var f=t[o]*r,y=t[o+1]*r,d=t[o+2]*r;v+=Math.abs((e[f]-e[d])*(e[y+1]-e[f+1])-(e[f]-e[y])*(e[d+1]-e[f+1]))}return 0===a&&0===v?0:Math.abs((v-a)/a)},earcut.flatten=function(e){for(var n=e[0][0].length,r={vertices:[],holes:[],dimensions:n},t=0,i=0;i<e.length;i++){for(var x=0;x<e[i].length;x++)for(var a=0;a<n;a++)r.vertices.push(e[i][x][a]);i>0&&(t+=e[i-1].length,r.holes.push(t))}return r};
  11 +},{}],6:[function(_dereq_,module,exports){
  12 +function geometry(r){if("Polygon"===r.type)return polygonArea(r.coordinates);if("MultiPolygon"===r.type){for(var e=0,n=0;n<r.coordinates.length;n++)e+=polygonArea(r.coordinates[n]);return e}return null}function polygonArea(r){var e=0;if(r&&r.length>0){e+=Math.abs(ringArea(r[0]));for(var n=1;n<r.length;n++)e-=Math.abs(ringArea(r[n]))}return e}function ringArea(r){var e=0;if(r.length>2){for(var n,t,o=0;o<r.length-1;o++)n=r[o],t=r[o+1],e+=rad(t[0]-n[0])*(2+Math.sin(rad(n[1]))+Math.sin(rad(t[1])));e=e*wgs84.RADIUS*wgs84.RADIUS/2}return e}function rad(r){return r*Math.PI/180}var wgs84=_dereq_("wgs84");module.exports.geometry=geometry,module.exports.ring=ringArea;
  13 +},{"wgs84":41}],7:[function(_dereq_,module,exports){
  14 +function rewind(r,e){switch(r&&r.type||null){case"FeatureCollection":return r.features=r.features.map(curryOuter(rewind,e)),r;case"Feature":return r.geometry=rewind(r.geometry,e),r;case"Polygon":case"MultiPolygon":return correct(r,e);default:return r}}function curryOuter(r,e){return function(n){return r(n,e)}}function correct(r,e){return"Polygon"===r.type?r.coordinates=correctRings(r.coordinates,e):"MultiPolygon"===r.type&&(r.coordinates=r.coordinates.map(curryOuter(correctRings,e))),r}function correctRings(r,e){e=!!e,r[0]=wind(r[0],!e);for(var n=1;n<r.length;n++)r[n]=wind(r[n],e);return r}function wind(r,e){return cw(r)===e?r:r.reverse()}function cw(r){return geojsonArea.ring(r)>=0}var geojsonArea=_dereq_("geojson-area");module.exports=rewind;
  15 +},{"geojson-area":6}],8:[function(_dereq_,module,exports){
  16 +"use strict";function clip(e,r,t,n,u,i,l,s){if(t/=r,n/=r,l>=t&&s<=n)return e;if(l>n||s<t)return null;for(var h=[],p=0;p<e.length;p++){var a,c,o=e[p],f=o.geometry,g=o.type;if(a=o.min[u],c=o.max[u],a>=t&&c<=n)h.push(o);else if(!(a>n||c<t)){var v=1===g?clipPoints(f,t,n,u):clipGeometry(f,t,n,u,i,3===g);v.length&&h.push(createFeature(o.tags,g,v,o.id))}}return h.length?h:null}function clipPoints(e,r,t,n){for(var u=[],i=0;i<e.length;i++){var l=e[i],s=l[n];s>=r&&s<=t&&u.push(l)}return u}function clipGeometry(e,r,t,n,u,i){for(var l=[],s=0;s<e.length;s++){var h,p,a,c=0,o=0,f=null,g=e[s],v=g.area,m=g.dist,w=g.outer,S=g.length,d=[];for(p=0;p<S-1;p++)h=f||g[p],f=g[p+1],c=o||h[n],o=f[n],c<r?o>t?(d.push(u(h,f,r),u(h,f,t)),i||(d=newSlice(l,d,v,m,w))):o>=r&&d.push(u(h,f,r)):c>t?o<r?(d.push(u(h,f,t),u(h,f,r)),i||(d=newSlice(l,d,v,m,w))):o<=t&&d.push(u(h,f,t)):(d.push(h),o<r?(d.push(u(h,f,r)),i||(d=newSlice(l,d,v,m,w))):o>t&&(d.push(u(h,f,t)),i||(d=newSlice(l,d,v,m,w))));h=g[S-1],c=h[n],c>=r&&c<=t&&d.push(h),a=d[d.length-1],i&&a&&(d[0][0]!==a[0]||d[0][1]!==a[1])&&d.push(d[0]),newSlice(l,d,v,m,w)}return l}function newSlice(e,r,t,n,u){return r.length&&(r.area=t,r.dist=n,void 0!==u&&(r.outer=u),e.push(r)),[]}module.exports=clip;var createFeature=_dereq_("./feature");
  17 +},{"./feature":10}],9:[function(_dereq_,module,exports){
  18 +"use strict";function convert(e,t){var r=[];if("FeatureCollection"===e.type)for(var o=0;o<e.features.length;o++)convertFeature(r,e.features[o],t);else"Feature"===e.type?convertFeature(r,e,t):convertFeature(r,{geometry:e},t);return r}function convertFeature(e,t,r){if(null!==t.geometry){var o,a,i,n,u=t.geometry,c=u.type,l=u.coordinates,s=t.properties,p=t.id;if("Point"===c)e.push(createFeature(s,1,[projectPoint(l)],p));else if("MultiPoint"===c)e.push(createFeature(s,1,project(l),p));else if("LineString"===c)e.push(createFeature(s,2,[project(l,r)],p));else if("MultiLineString"===c||"Polygon"===c){for(i=[],o=0;o<l.length;o++)n=project(l[o],r),"Polygon"===c&&(n.outer=0===o),i.push(n);e.push(createFeature(s,"Polygon"===c?3:2,i,p))}else if("MultiPolygon"===c){for(i=[],o=0;o<l.length;o++)for(a=0;a<l[o].length;a++)n=project(l[o][a],r),n.outer=0===a,i.push(n);e.push(createFeature(s,3,i,p))}else{if("GeometryCollection"!==c)throw new Error("Input data is not a valid GeoJSON object.");for(o=0;o<u.geometries.length;o++)convertFeature(e,{geometry:u.geometries[o],properties:s},r)}}}function project(e,t){for(var r=[],o=0;o<e.length;o++)r.push(projectPoint(e[o]));return t&&(simplify(r,t),calcSize(r)),r}function projectPoint(e){var t=Math.sin(e[1]*Math.PI/180),r=e[0]/360+.5,o=.5-.25*Math.log((1+t)/(1-t))/Math.PI;return o=o<0?0:o>1?1:o,[r,o,0]}function calcSize(e){for(var t,r,o=0,a=0,i=0;i<e.length-1;i++)t=r||e[i],r=e[i+1],o+=t[0]*r[1]-r[0]*t[1],a+=Math.abs(r[0]-t[0])+Math.abs(r[1]-t[1]);e.area=Math.abs(o/2),e.dist=a}module.exports=convert;var simplify=_dereq_("./simplify"),createFeature=_dereq_("./feature");
  19 +},{"./feature":10,"./simplify":12}],10:[function(_dereq_,module,exports){
  20 +"use strict";function createFeature(e,t,a,n){var r={id:n||null,type:t,geometry:a,tags:e||null,min:[1/0,1/0],max:[-(1/0),-(1/0)]};return calcBBox(r),r}function calcBBox(e){var t=e.geometry,a=e.min,n=e.max;if(1===e.type)calcRingBBox(a,n,t);else for(var r=0;r<t.length;r++)calcRingBBox(a,n,t[r]);return e}function calcRingBBox(e,t,a){for(var n,r=0;r<a.length;r++)n=a[r],e[0]=Math.min(n[0],e[0]),t[0]=Math.max(n[0],t[0]),e[1]=Math.min(n[1],e[1]),t[1]=Math.max(n[1],t[1])}module.exports=createFeature;
  21 +},{}],11:[function(_dereq_,module,exports){
  22 +"use strict";function geojsonvt(e,t){return new GeoJSONVT(e,t)}function GeoJSONVT(e,t){t=this.options=extend(Object.create(this.options),t);var i=t.debug;i&&console.time("preprocess data");var o=1<<t.maxZoom,n=convert(e,t.tolerance/(o*t.extent));this.tiles={},this.tileCoords=[],i&&(console.timeEnd("preprocess data"),console.log("index: maxZoom: %d, maxPoints: %d",t.indexMaxZoom,t.indexMaxPoints),console.time("generate tiles"),this.stats={},this.total=0),n=wrap(n,t.buffer/t.extent,intersectX),n.length&&this.splitTile(n,0,0,0),i&&(n.length&&console.log("features: %d, points: %d",this.tiles[0].numFeatures,this.tiles[0].numPoints),console.timeEnd("generate tiles"),console.log("tiles generated:",this.total,JSON.stringify(this.stats)))}function toID(e,t,i){return 32*((1<<e)*i+t)+e}function intersectX(e,t,i){return[i,(i-e[0])*(t[1]-e[1])/(t[0]-e[0])+e[1],1]}function intersectY(e,t,i){return[(i-e[1])*(t[0]-e[0])/(t[1]-e[1])+e[0],i,1]}function extend(e,t){for(var i in t)e[i]=t[i];return e}function isClippedSquare(e,t,i){var o=e.source;if(1!==o.length)return!1;var n=o[0];if(3!==n.type||n.geometry.length>1)return!1;var r=n.geometry[0].length;if(5!==r)return!1;for(var s=0;s<r;s++){var l=transform.point(n.geometry[0][s],t,e.z2,e.x,e.y);if(l[0]!==-i&&l[0]!==t+i||l[1]!==-i&&l[1]!==t+i)return!1}return!0}module.exports=geojsonvt;var convert=_dereq_("./convert"),transform=_dereq_("./transform"),clip=_dereq_("./clip"),wrap=_dereq_("./wrap"),createTile=_dereq_("./tile");GeoJSONVT.prototype.options={maxZoom:14,indexMaxZoom:5,indexMaxPoints:1e5,solidChildren:!1,tolerance:3,extent:4096,buffer:64,debug:0},GeoJSONVT.prototype.splitTile=function(e,t,i,o,n,r,s){for(var l=[e,t,i,o],a=this.options,u=a.debug,c=null;l.length;){o=l.pop(),i=l.pop(),t=l.pop(),e=l.pop();var p=1<<t,d=toID(t,i,o),m=this.tiles[d],f=t===a.maxZoom?0:a.tolerance/(p*a.extent);if(!m&&(u>1&&console.time("creation"),m=this.tiles[d]=createTile(e,p,i,o,f,t===a.maxZoom),this.tileCoords.push({z:t,x:i,y:o}),u)){u>1&&(console.log("tile z%d-%d-%d (features: %d, points: %d, simplified: %d)",t,i,o,m.numFeatures,m.numPoints,m.numSimplified),console.timeEnd("creation"));var h="z"+t;this.stats[h]=(this.stats[h]||0)+1,this.total++}if(m.source=e,n){if(t===a.maxZoom||t===n)continue;var x=1<<n-t;if(i!==Math.floor(r/x)||o!==Math.floor(s/x))continue}else if(t===a.indexMaxZoom||m.numPoints<=a.indexMaxPoints)continue;if(a.solidChildren||!isClippedSquare(m,a.extent,a.buffer)){m.source=null,u>1&&console.time("clipping");var g,v,M,T,b,y,S=.5*a.buffer/a.extent,Z=.5-S,q=.5+S,w=1+S;g=v=M=T=null,b=clip(e,p,i-S,i+q,0,intersectX,m.min[0],m.max[0]),y=clip(e,p,i+Z,i+w,0,intersectX,m.min[0],m.max[0]),b&&(g=clip(b,p,o-S,o+q,1,intersectY,m.min[1],m.max[1]),v=clip(b,p,o+Z,o+w,1,intersectY,m.min[1],m.max[1])),y&&(M=clip(y,p,o-S,o+q,1,intersectY,m.min[1],m.max[1]),T=clip(y,p,o+Z,o+w,1,intersectY,m.min[1],m.max[1])),u>1&&console.timeEnd("clipping"),e.length&&(l.push(g||[],t+1,2*i,2*o),l.push(v||[],t+1,2*i,2*o+1),l.push(M||[],t+1,2*i+1,2*o),l.push(T||[],t+1,2*i+1,2*o+1))}else n&&(c=t)}return c},GeoJSONVT.prototype.getTile=function(e,t,i){var o=this.options,n=o.extent,r=o.debug,s=1<<e;t=(t%s+s)%s;var l=toID(e,t,i);if(this.tiles[l])return transform.tile(this.tiles[l],n);r>1&&console.log("drilling down to z%d-%d-%d",e,t,i);for(var a,u=e,c=t,p=i;!a&&u>0;)u--,c=Math.floor(c/2),p=Math.floor(p/2),a=this.tiles[toID(u,c,p)];if(!a||!a.source)return null;if(r>1&&console.log("found parent tile z%d-%d-%d",u,c,p),isClippedSquare(a,n,o.buffer))return transform.tile(a,n);r>1&&console.time("drilling down");var d=this.splitTile(a.source,u,c,p,e,t,i);if(r>1&&console.timeEnd("drilling down"),null!==d){var m=1<<e-d;l=toID(d,Math.floor(t/m),Math.floor(i/m))}return this.tiles[l]?transform.tile(this.tiles[l],n):null};
  23 +},{"./clip":8,"./convert":9,"./tile":13,"./transform":14,"./wrap":15}],12:[function(_dereq_,module,exports){
  24 +"use strict";function simplify(t,i){var e,p,r,s,o=i*i,f=t.length,u=0,n=f-1,g=[];for(t[u][2]=1,t[n][2]=1;n;){for(p=0,e=u+1;e<n;e++)r=getSqSegDist(t[e],t[u],t[n]),r>p&&(s=e,p=r);p>o?(t[s][2]=p,g.push(u),g.push(s),u=s):(n=g.pop(),u=g.pop())}}function getSqSegDist(t,i,e){var p=i[0],r=i[1],s=e[0],o=e[1],f=t[0],u=t[1],n=s-p,g=o-r;if(0!==n||0!==g){var l=((f-p)*n+(u-r)*g)/(n*n+g*g);l>1?(p=s,r=o):l>0&&(p+=n*l,r+=g*l)}return n=f-p,g=u-r,n*n+g*g}module.exports=simplify;
  25 +},{}],13:[function(_dereq_,module,exports){
  26 +"use strict";function createTile(e,n,r,i,t,u){for(var a={features:[],numPoints:0,numSimplified:0,numFeatures:0,source:null,x:r,y:i,z2:n,transformed:!1,min:[2,1],max:[-1,0]},m=0;m<e.length;m++){a.numFeatures++,addFeature(a,e[m],t,u);var s=e[m].min,l=e[m].max;s[0]<a.min[0]&&(a.min[0]=s[0]),s[1]<a.min[1]&&(a.min[1]=s[1]),l[0]>a.max[0]&&(a.max[0]=l[0]),l[1]>a.max[1]&&(a.max[1]=l[1])}return a}function addFeature(e,n,r,i){var t,u,a,m,s=n.geometry,l=n.type,o=[],f=r*r;if(1===l)for(t=0;t<s.length;t++)o.push(s[t]),e.numPoints++,e.numSimplified++;else for(t=0;t<s.length;t++)if(a=s[t],i||!(2===l&&a.dist<r||3===l&&a.area<f)){var d=[];for(u=0;u<a.length;u++)m=a[u],(i||m[2]>f)&&(d.push(m),e.numSimplified++),e.numPoints++;3===l&&rewind(d,a.outer),o.push(d)}else e.numPoints+=a.length;if(o.length){var g={geometry:o,type:l,tags:n.tags||null};null!==n.id&&(g.id=n.id),e.features.push(g)}}function rewind(e,n){var r=signedArea(e);r<0===n&&e.reverse()}function signedArea(e){for(var n,r,i=0,t=0,u=e.length,a=u-1;t<u;a=t++)n=e[t],r=e[a],i+=(r[0]-n[0])*(n[1]+r[1]);return i}module.exports=createTile;
  27 +},{}],14:[function(_dereq_,module,exports){
  28 +"use strict";function transformTile(r,t){if(r.transformed)return r;var n,e,o,f=r.z2,a=r.x,s=r.y;for(n=0;n<r.features.length;n++){var i=r.features[n],u=i.geometry,m=i.type;if(1===m)for(e=0;e<u.length;e++)u[e]=transformPoint(u[e],t,f,a,s);else for(e=0;e<u.length;e++){var l=u[e];for(o=0;o<l.length;o++)l[o]=transformPoint(l[o],t,f,a,s)}}return r.transformed=!0,r}function transformPoint(r,t,n,e,o){var f=Math.round(t*(r[0]*n-e)),a=Math.round(t*(r[1]*n-o));return[f,a]}exports.tile=transformTile,exports.point=transformPoint;
  29 +},{}],15:[function(_dereq_,module,exports){
  30 +"use strict";function wrap(r,e,t){var o=r,a=clip(r,1,-1-e,e,0,t,-1,2),s=clip(r,1,1-e,2+e,0,t,-1,2);return(a||s)&&(o=clip(r,1,-e,1+e,0,t,-1,2)||[],a&&(o=shiftFeatureCoords(a,1).concat(o)),s&&(o=o.concat(shiftFeatureCoords(s,-1)))),o}function shiftFeatureCoords(r,e){for(var t=[],o=0;o<r.length;o++){var a,s=r[o],i=s.type;if(1===i)a=shiftCoords(s.geometry,e);else{a=[];for(var u=0;u<s.geometry.length;u++)a.push(shiftCoords(s.geometry[u],e))}t.push(createFeature(s.tags,i,a,s.id))}return t}function shiftCoords(r,e){var t=[];t.area=r.area,t.dist=r.dist;for(var o=0;o<r.length;o++)t.push([r[o][0]+e,r[o][1],r[o][2]]);return t}var clip=_dereq_("./clip"),createFeature=_dereq_("./feature");module.exports=wrap;
  31 +},{"./clip":8,"./feature":10}],16:[function(_dereq_,module,exports){
  32 +"use strict";function GridIndex(t,r,e){var s=this.cells=[];if(t instanceof ArrayBuffer){this.arrayBuffer=t;var i=new Int32Array(this.arrayBuffer);t=i[0],r=i[1],e=i[2],this.d=r+2*e;for(var h=0;h<this.d*this.d;h++){var n=i[NUM_PARAMS+h],o=i[NUM_PARAMS+h+1];s.push(n===o?null:i.subarray(n,o))}var l=i[NUM_PARAMS+s.length],a=i[NUM_PARAMS+s.length+1];this.keys=i.subarray(l,a),this.bboxes=i.subarray(a),this.insert=this._insertReadonly}else{this.d=r+2*e;for(var d=0;d<this.d*this.d;d++)s.push([]);this.keys=[],this.bboxes=[]}this.n=r,this.extent=t,this.padding=e,this.scale=r/t,this.uid=0;var f=e/r*t;this.min=-f,this.max=t+f}module.exports=GridIndex;var NUM_PARAMS=3;GridIndex.prototype.insert=function(t,r,e,s,i){this._forEachCell(r,e,s,i,this._insertCell,this.uid++),this.keys.push(t),this.bboxes.push(r),this.bboxes.push(e),this.bboxes.push(s),this.bboxes.push(i)},GridIndex.prototype._insertReadonly=function(){throw"Cannot insert into a GridIndex created from an ArrayBuffer."},GridIndex.prototype._insertCell=function(t,r,e,s,i,h){this.cells[i].push(h)},GridIndex.prototype.query=function(t,r,e,s){var i=this.min,h=this.max;if(t<=i&&r<=i&&h<=e&&h<=s)return Array.prototype.slice.call(this.keys);var n=[],o={};return this._forEachCell(t,r,e,s,this._queryCell,n,o),n},GridIndex.prototype._queryCell=function(t,r,e,s,i,h,n){var o=this.cells[i];if(null!==o)for(var l=this.keys,a=this.bboxes,d=0;d<o.length;d++){var f=o[d];if(void 0===n[f]){var u=4*f;t<=a[u+2]&&r<=a[u+3]&&e>=a[u+0]&&s>=a[u+1]?(n[f]=!0,h.push(l[f])):n[f]=!1}}},GridIndex.prototype._forEachCell=function(t,r,e,s,i,h,n){for(var o=this._convertToCellCoord(t),l=this._convertToCellCoord(r),a=this._convertToCellCoord(e),d=this._convertToCellCoord(s),f=o;f<=a;f++)for(var u=l;u<=d;u++){var y=this.d*u+f;if(i.call(this,t,r,e,s,y,h,n))return}},GridIndex.prototype._convertToCellCoord=function(t){return Math.max(0,Math.min(this.d-1,Math.floor(t*this.scale)+this.padding))},GridIndex.prototype.toArrayBuffer=function(){if(this.arrayBuffer)return this.arrayBuffer;for(var t=this.cells,r=NUM_PARAMS+this.cells.length+1+1,e=0,s=0;s<this.cells.length;s++)e+=this.cells[s].length;var i=new Int32Array(r+e+this.keys.length+this.bboxes.length);i[0]=this.extent,i[1]=this.n,i[2]=this.padding;for(var h=r,n=0;n<t.length;n++){var o=t[n];i[NUM_PARAMS+n]=h,i.set(o,h),h+=o.length}return i[NUM_PARAMS+t.length]=h,i.set(this.keys,h),h+=this.keys.length,i[NUM_PARAMS+t.length+1]=h,i.set(this.bboxes,h),h+=this.bboxes.length,i.buffer};
  33 +},{}],17:[function(_dereq_,module,exports){
  34 +exports.read=function(a,o,t,r,h){var M,p,w=8*h-r-1,f=(1<<w)-1,e=f>>1,i=-7,N=t?h-1:0,n=t?-1:1,s=a[o+N];for(N+=n,M=s&(1<<-i)-1,s>>=-i,i+=w;i>0;M=256*M+a[o+N],N+=n,i-=8);for(p=M&(1<<-i)-1,M>>=-i,i+=r;i>0;p=256*p+a[o+N],N+=n,i-=8);if(0===M)M=1-e;else{if(M===f)return p?NaN:(s?-1:1)*(1/0);p+=Math.pow(2,r),M-=e}return(s?-1:1)*p*Math.pow(2,M-r)},exports.write=function(a,o,t,r,h,M){var p,w,f,e=8*M-h-1,i=(1<<e)-1,N=i>>1,n=23===h?Math.pow(2,-24)-Math.pow(2,-77):0,s=r?0:M-1,u=r?1:-1,l=o<0||0===o&&1/o<0?1:0;for(o=Math.abs(o),isNaN(o)||o===1/0?(w=isNaN(o)?1:0,p=i):(p=Math.floor(Math.log(o)/Math.LN2),o*(f=Math.pow(2,-p))<1&&(p--,f*=2),o+=p+N>=1?n/f:n*Math.pow(2,1-N),o*f>=2&&(p++,f/=2),p+N>=i?(w=0,p=i):p+N>=1?(w=(o*f-1)*Math.pow(2,h),p+=N):(w=o*Math.pow(2,N-1)*Math.pow(2,h),p=0));h>=8;a[t+s]=255&w,s+=u,w/=256,h-=8);for(p=p<<h|w,e+=h;e>0;a[t+s]=255&p,s+=u,p/=256,e-=8);a[t+s-u]|=128*l};
  35 +},{}],18:[function(_dereq_,module,exports){
  36 +"use strict";function kdbush(t,i,e,s,n){return new KDBush(t,i,e,s,n)}function KDBush(t,i,e,s,n){i=i||defaultGetX,e=e||defaultGetY,n=n||Array,this.nodeSize=s||64,this.points=t,this.ids=new n(t.length),this.coords=new n(2*t.length);for(var r=0;r<t.length;r++)this.ids[r]=r,this.coords[2*r]=i(t[r]),this.coords[2*r+1]=e(t[r]);sort(this.ids,this.coords,this.nodeSize,0,this.ids.length-1,0)}function defaultGetX(t){return t[0]}function defaultGetY(t){return t[1]}var sort=_dereq_("./sort"),range=_dereq_("./range"),within=_dereq_("./within");module.exports=kdbush,KDBush.prototype={range:function(t,i,e,s){return range(this.ids,this.coords,t,i,e,s,this.nodeSize)},within:function(t,i,e){return within(this.ids,this.coords,t,i,e,this.nodeSize)}};
  37 +},{"./range":19,"./sort":20,"./within":21}],19:[function(_dereq_,module,exports){
  38 +"use strict";function range(p,r,s,u,h,e,o){for(var a,t,n=[0,p.length-1,0],f=[];n.length;){var l=n.pop(),v=n.pop(),g=n.pop();if(v-g<=o)for(var i=g;i<=v;i++)a=r[2*i],t=r[2*i+1],a>=s&&a<=h&&t>=u&&t<=e&&f.push(p[i]);else{var c=Math.floor((g+v)/2);a=r[2*c],t=r[2*c+1],a>=s&&a<=h&&t>=u&&t<=e&&f.push(p[c]);var d=(l+1)%2;(0===l?s<=a:u<=t)&&(n.push(g),n.push(c-1),n.push(d)),(0===l?h>=a:e>=t)&&(n.push(c+1),n.push(v),n.push(d))}}return f}module.exports=range;
  39 +},{}],20:[function(_dereq_,module,exports){
  40 +"use strict";function sortKD(t,a,o,s,r,e){if(!(r-s<=o)){var f=Math.floor((s+r)/2);select(t,a,f,s,r,e%2),sortKD(t,a,o,s,f-1,e+1),sortKD(t,a,o,f+1,r,e+1)}}function select(t,a,o,s,r,e){for(;r>s;){if(r-s>600){var f=r-s+1,p=o-s+1,w=Math.log(f),m=.5*Math.exp(2*w/3),n=.5*Math.sqrt(w*m*(f-m)/f)*(p-f/2<0?-1:1),c=Math.max(s,Math.floor(o-p*m/f+n)),h=Math.min(r,Math.floor(o+(f-p)*m/f+n));select(t,a,o,c,h,e)}var i=a[2*o+e],l=s,M=r;for(swapItem(t,a,s,o),a[2*r+e]>i&&swapItem(t,a,s,r);l<M;){for(swapItem(t,a,l,M),l++,M--;a[2*l+e]<i;)l++;for(;a[2*M+e]>i;)M--}a[2*s+e]===i?swapItem(t,a,s,M):(M++,swapItem(t,a,M,r)),M<=o&&(s=M+1),o<=M&&(r=M-1)}}function swapItem(t,a,o,s){swap(t,o,s),swap(a,2*o,2*s),swap(a,2*o+1,2*s+1)}function swap(t,a,o){var s=t[a];t[a]=t[o],t[o]=s}module.exports=sortKD;
  41 +},{}],21:[function(_dereq_,module,exports){
  42 +"use strict";function within(s,p,r,t,u,h){for(var i=[0,s.length-1,0],o=[],n=u*u;i.length;){var e=i.pop(),a=i.pop(),f=i.pop();if(a-f<=h)for(var v=f;v<=a;v++)sqDist(p[2*v],p[2*v+1],r,t)<=n&&o.push(s[v]);else{var l=Math.floor((f+a)/2),c=p[2*l],q=p[2*l+1];sqDist(c,q,r,t)<=n&&o.push(s[l]);var D=(e+1)%2;(0===e?r-u<=c:t-u<=q)&&(i.push(f),i.push(l-1),i.push(D)),(0===e?r+u>=c:t+u>=q)&&(i.push(l+1),i.push(a),i.push(D))}}return o}function sqDist(s,p,r,t){var u=s-r,h=p-t;return u*u+h*h}module.exports=within;
  43 +},{}],22:[function(_dereq_,module,exports){
  44 +"use strict";function isSupported(e){return!!(isBrowser()&&isArraySupported()&&isFunctionSupported()&&isObjectSupported()&&isJSONSupported()&&isWorkerSupported()&&isUint8ClampedArraySupported()&&isWebGLSupportedCached(e&&e.failIfMajorPerformanceCaveat))}function isBrowser(){return"undefined"!=typeof window&&"undefined"!=typeof document}function isArraySupported(){return Array.prototype&&Array.prototype.every&&Array.prototype.filter&&Array.prototype.forEach&&Array.prototype.indexOf&&Array.prototype.lastIndexOf&&Array.prototype.map&&Array.prototype.some&&Array.prototype.reduce&&Array.prototype.reduceRight&&Array.isArray}function isFunctionSupported(){return Function.prototype&&Function.prototype.bind}function isObjectSupported(){return Object.keys&&Object.create&&Object.getPrototypeOf&&Object.getOwnPropertyNames&&Object.isSealed&&Object.isFrozen&&Object.isExtensible&&Object.getOwnPropertyDescriptor&&Object.defineProperty&&Object.defineProperties&&Object.seal&&Object.freeze&&Object.preventExtensions}function isJSONSupported(){return"JSON"in window&&"parse"in JSON&&"stringify"in JSON}function isWorkerSupported(){return"Worker"in window}function isUint8ClampedArraySupported(){return"Uint8ClampedArray"in window}function isWebGLSupportedCached(e){return void 0===isWebGLSupportedCache[e]&&(isWebGLSupportedCache[e]=isWebGLSupported(e)),isWebGLSupportedCache[e]}function isWebGLSupported(e){var t=document.createElement("canvas"),r=Object.create(isSupported.webGLContextAttributes);return r.failIfMajorPerformanceCaveat=e,t.probablySupportsContext?t.probablySupportsContext("webgl",r)||t.probablySupportsContext("experimental-webgl",r):t.supportsContext?t.supportsContext("webgl",r)||t.supportsContext("experimental-webgl",r):t.getContext("webgl",r)||t.getContext("experimental-webgl",r)}"undefined"!=typeof module&&module.exports?module.exports=isSupported:window&&(window.mapboxgl=window.mapboxgl||{},window.mapboxgl.supported=isSupported);var isWebGLSupportedCache={};isSupported.webGLContextAttributes={antialias:!1,alpha:!0,stencil:!0,depth:!0};
  45 +},{}],23:[function(_dereq_,module,exports){
  46 +"use strict";function Buffer(t){var e;t&&t.length&&(e=t,t=e.length);var r=new Uint8Array(t||0);return e&&r.set(e),r.readUInt32LE=BufferMethods.readUInt32LE,r.writeUInt32LE=BufferMethods.writeUInt32LE,r.readInt32LE=BufferMethods.readInt32LE,r.writeInt32LE=BufferMethods.writeInt32LE,r.readFloatLE=BufferMethods.readFloatLE,r.writeFloatLE=BufferMethods.writeFloatLE,r.readDoubleLE=BufferMethods.readDoubleLE,r.writeDoubleLE=BufferMethods.writeDoubleLE,r.toString=BufferMethods.toString,r.write=BufferMethods.write,r.slice=BufferMethods.slice,r.copy=BufferMethods.copy,r._isBuffer=!0,r}function encodeString(t){for(var e,r,n=t.length,i=[],o=0;o<n;o++){if(e=t.charCodeAt(o),e>55295&&e<57344){if(!r){e>56319||o+1===n?i.push(239,191,189):r=e;continue}if(e<56320){i.push(239,191,189),r=e;continue}e=r-55296<<10|e-56320|65536,r=null}else r&&(i.push(239,191,189),r=null);e<128?i.push(e):e<2048?i.push(e>>6|192,63&e|128):e<65536?i.push(e>>12|224,e>>6&63|128,63&e|128):i.push(e>>18|240,e>>12&63|128,e>>6&63|128,63&e|128)}return i}module.exports=Buffer;var ieee754=_dereq_("ieee754"),BufferMethods,lastStr,lastStrEncoded;BufferMethods={readUInt32LE:function(t){return(this[t]|this[t+1]<<8|this[t+2]<<16)+16777216*this[t+3]},writeUInt32LE:function(t,e){this[e]=t,this[e+1]=t>>>8,this[e+2]=t>>>16,this[e+3]=t>>>24},readInt32LE:function(t){return(this[t]|this[t+1]<<8|this[t+2]<<16)+(this[t+3]<<24)},readFloatLE:function(t){return ieee754.read(this,t,!0,23,4)},readDoubleLE:function(t){return ieee754.read(this,t,!0,52,8)},writeFloatLE:function(t,e){return ieee754.write(this,t,e,!0,23,4)},writeDoubleLE:function(t,e){return ieee754.write(this,t,e,!0,52,8)},toString:function(t,e,r){var n="",i="";e=e||0,r=Math.min(this.length,r||this.length);for(var o=e;o<r;o++){var u=this[o];u<=127?(n+=decodeURIComponent(i)+String.fromCharCode(u),i=""):i+="%"+u.toString(16)}return n+=decodeURIComponent(i)},write:function(t,e){for(var r=t===lastStr?lastStrEncoded:encodeString(t),n=0;n<r.length;n++)this[e+n]=r[n]},slice:function(t,e){return this.subarray(t,e)},copy:function(t,e){e=e||0;for(var r=0;r<this.length;r++)t[e+r]=this[r]}},BufferMethods.writeInt32LE=BufferMethods.writeUInt32LE,Buffer.byteLength=function(t){return lastStr=t,lastStrEncoded=encodeString(t),lastStrEncoded.length},Buffer.isBuffer=function(t){return!(!t||!t._isBuffer)};
  47 +},{"ieee754":17}],24:[function(_dereq_,module,exports){
  48 +(function (global){
  49 +"use strict";function Pbf(t){this.buf=Buffer.isBuffer(t)?t:new Buffer(t||0),this.pos=0,this.length=this.buf.length}function readVarintRemainder(t,i){var e,r=i.buf;if(e=r[i.pos++],t+=268435456*(127&e),e<128)return t;if(e=r[i.pos++],t+=34359738368*(127&e),e<128)return t;if(e=r[i.pos++],t+=4398046511104*(127&e),e<128)return t;if(e=r[i.pos++],t+=562949953421312*(127&e),e<128)return t;if(e=r[i.pos++],t+=72057594037927940*(127&e),e<128)return t;if(e=r[i.pos++],t+=0x8000000000000000*(127&e),e<128)return t;throw new Error("Expected varint not more than 10 bytes")}function writeBigVarint(t,i){i.realloc(10);for(var e=i.pos+10;t>=1;){if(i.pos>=e)throw new Error("Given varint doesn't fit into 10 bytes");var r=255&t;i.buf[i.pos++]=r|(t>=128?128:0),t/=128}}function reallocForRawMessage(t,i,e){var r=i<=16383?1:i<=2097151?2:i<=268435455?3:Math.ceil(Math.log(i)/(7*Math.LN2));e.realloc(r);for(var s=e.pos-1;s>=t;s--)e.buf[s+r]=e.buf[s]}function writePackedVarint(t,i){for(var e=0;e<t.length;e++)i.writeVarint(t[e])}function writePackedSVarint(t,i){for(var e=0;e<t.length;e++)i.writeSVarint(t[e])}function writePackedFloat(t,i){for(var e=0;e<t.length;e++)i.writeFloat(t[e])}function writePackedDouble(t,i){for(var e=0;e<t.length;e++)i.writeDouble(t[e])}function writePackedBoolean(t,i){for(var e=0;e<t.length;e++)i.writeBoolean(t[e])}function writePackedFixed32(t,i){for(var e=0;e<t.length;e++)i.writeFixed32(t[e])}function writePackedSFixed32(t,i){for(var e=0;e<t.length;e++)i.writeSFixed32(t[e])}function writePackedFixed64(t,i){for(var e=0;e<t.length;e++)i.writeFixed64(t[e])}function writePackedSFixed64(t,i){for(var e=0;e<t.length;e++)i.writeSFixed64(t[e])}module.exports=Pbf;var Buffer=global.Buffer||_dereq_("./buffer");Pbf.Varint=0,Pbf.Fixed64=1,Pbf.Bytes=2,Pbf.Fixed32=5;var SHIFT_LEFT_32=4294967296,SHIFT_RIGHT_32=1/SHIFT_LEFT_32,POW_2_63=Math.pow(2,63);Pbf.prototype={destroy:function(){this.buf=null},readFields:function(t,i,e){for(e=e||this.length;this.pos<e;){var r=this.readVarint(),s=r>>3,n=this.pos;t(s,i,this),this.pos===n&&this.skip(r)}return i},readMessage:function(t,i){return this.readFields(t,i,this.readVarint()+this.pos)},readFixed32:function(){var t=this.buf.readUInt32LE(this.pos);return this.pos+=4,t},readSFixed32:function(){var t=this.buf.readInt32LE(this.pos);return this.pos+=4,t},readFixed64:function(){var t=this.buf.readUInt32LE(this.pos)+this.buf.readUInt32LE(this.pos+4)*SHIFT_LEFT_32;return this.pos+=8,t},readSFixed64:function(){var t=this.buf.readUInt32LE(this.pos)+this.buf.readInt32LE(this.pos+4)*SHIFT_LEFT_32;return this.pos+=8,t},readFloat:function(){var t=this.buf.readFloatLE(this.pos);return this.pos+=4,t},readDouble:function(){var t=this.buf.readDoubleLE(this.pos);return this.pos+=8,t},readVarint:function(){var t,i,e=this.buf;return i=e[this.pos++],t=127&i,i<128?t:(i=e[this.pos++],t|=(127&i)<<7,i<128?t:(i=e[this.pos++],t|=(127&i)<<14,i<128?t:(i=e[this.pos++],t|=(127&i)<<21,i<128?t:readVarintRemainder(t,this))))},readVarint64:function(){var t=this.pos,i=this.readVarint();if(i<POW_2_63)return i;for(var e=this.pos-2;255===this.buf[e];)e--;e<t&&(e=t),i=0;for(var r=0;r<e-t+1;r++){var s=127&~this.buf[t+r];i+=r<4?s<<7*r:s*Math.pow(2,7*r)}return-i-1},readSVarint:function(){var t=this.readVarint();return t%2===1?(t+1)/-2:t/2},readBoolean:function(){return Boolean(this.readVarint())},readString:function(){var t=this.readVarint()+this.pos,i=this.buf.toString("utf8",this.pos,t);return this.pos=t,i},readBytes:function(){var t=this.readVarint()+this.pos,i=this.buf.slice(this.pos,t);return this.pos=t,i},readPackedVarint:function(){for(var t=this.readVarint()+this.pos,i=[];this.pos<t;)i.push(this.readVarint());return i},readPackedSVarint:function(){for(var t=this.readVarint()+this.pos,i=[];this.pos<t;)i.push(this.readSVarint());return i},readPackedBoolean:function(){for(var t=this.readVarint()+this.pos,i=[];this.pos<t;)i.push(this.readBoolean());return i},readPackedFloat:function(){for(var t=this.readVarint()+this.pos,i=[];this.pos<t;)i.push(this.readFloat());return i},readPackedDouble:function(){for(var t=this.readVarint()+this.pos,i=[];this.pos<t;)i.push(this.readDouble());return i},readPackedFixed32:function(){for(var t=this.readVarint()+this.pos,i=[];this.pos<t;)i.push(this.readFixed32());return i},readPackedSFixed32:function(){for(var t=this.readVarint()+this.pos,i=[];this.pos<t;)i.push(this.readSFixed32());return i},readPackedFixed64:function(){for(var t=this.readVarint()+this.pos,i=[];this.pos<t;)i.push(this.readFixed64());return i},readPackedSFixed64:function(){for(var t=this.readVarint()+this.pos,i=[];this.pos<t;)i.push(this.readSFixed64());return i},skip:function(t){var i=7&t;if(i===Pbf.Varint)for(;this.buf[this.pos++]>127;);else if(i===Pbf.Bytes)this.pos=this.readVarint()+this.pos;else if(i===Pbf.Fixed32)this.pos+=4;else{if(i!==Pbf.Fixed64)throw new Error("Unimplemented type: "+i);this.pos+=8}},writeTag:function(t,i){this.writeVarint(t<<3|i)},realloc:function(t){for(var i=this.length||16;i<this.pos+t;)i*=2;if(i!==this.length){var e=new Buffer(i);this.buf.copy(e),this.buf=e,this.length=i}},finish:function(){return this.length=this.pos,this.pos=0,this.buf.slice(0,this.length)},writeFixed32:function(t){this.realloc(4),this.buf.writeUInt32LE(t,this.pos),this.pos+=4},writeSFixed32:function(t){this.realloc(4),this.buf.writeInt32LE(t,this.pos),this.pos+=4},writeFixed64:function(t){this.realloc(8),this.buf.writeInt32LE(t&-1,this.pos),this.buf.writeUInt32LE(Math.floor(t*SHIFT_RIGHT_32),this.pos+4),this.pos+=8},writeSFixed64:function(t){this.realloc(8),this.buf.writeInt32LE(t&-1,this.pos),this.buf.writeInt32LE(Math.floor(t*SHIFT_RIGHT_32),this.pos+4),this.pos+=8},writeVarint:function(t){return t=+t,t>268435455?void writeBigVarint(t,this):(this.realloc(4),this.buf[this.pos++]=127&t|(t>127?128:0),void(t<=127||(this.buf[this.pos++]=127&(t>>>=7)|(t>127?128:0),t<=127||(this.buf[this.pos++]=127&(t>>>=7)|(t>127?128:0),t<=127||(this.buf[this.pos++]=t>>>7&127)))))},writeSVarint:function(t){this.writeVarint(t<0?2*-t-1:2*t)},writeBoolean:function(t){this.writeVarint(Boolean(t))},writeString:function(t){t=String(t);var i=Buffer.byteLength(t);this.writeVarint(i),this.realloc(i),this.buf.write(t,this.pos),this.pos+=i},writeFloat:function(t){this.realloc(4),this.buf.writeFloatLE(t,this.pos),this.pos+=4},writeDouble:function(t){this.realloc(8),this.buf.writeDoubleLE(t,this.pos),this.pos+=8},writeBytes:function(t){var i=t.length;this.writeVarint(i),this.realloc(i);for(var e=0;e<i;e++)this.buf[this.pos++]=t[e]},writeRawMessage:function(t,i){this.pos++;var e=this.pos;t(i,this);var r=this.pos-e;r>=128&&reallocForRawMessage(e,r,this),this.pos=e-1,this.writeVarint(r),this.pos+=r},writeMessage:function(t,i,e){this.writeTag(t,Pbf.Bytes),this.writeRawMessage(i,e)},writePackedVarint:function(t,i){this.writeMessage(t,writePackedVarint,i)},writePackedSVarint:function(t,i){this.writeMessage(t,writePackedSVarint,i)},writePackedBoolean:function(t,i){this.writeMessage(t,writePackedBoolean,i)},writePackedFloat:function(t,i){this.writeMessage(t,writePackedFloat,i)},writePackedDouble:function(t,i){this.writeMessage(t,writePackedDouble,i)},writePackedFixed32:function(t,i){this.writeMessage(t,writePackedFixed32,i)},writePackedSFixed32:function(t,i){this.writeMessage(t,writePackedSFixed32,i)},writePackedFixed64:function(t,i){this.writeMessage(t,writePackedFixed64,i)},writePackedSFixed64:function(t,i){this.writeMessage(t,writePackedSFixed64,i)},writeBytesField:function(t,i){this.writeTag(t,Pbf.Bytes),this.writeBytes(i)},writeFixed32Field:function(t,i){this.writeTag(t,Pbf.Fixed32),this.writeFixed32(i)},writeSFixed32Field:function(t,i){this.writeTag(t,Pbf.Fixed32),this.writeSFixed32(i)},writeFixed64Field:function(t,i){this.writeTag(t,Pbf.Fixed64),this.writeFixed64(i)},writeSFixed64Field:function(t,i){this.writeTag(t,Pbf.Fixed64),this.writeSFixed64(i)},writeVarintField:function(t,i){this.writeTag(t,Pbf.Varint),this.writeVarint(i)},writeSVarintField:function(t,i){this.writeTag(t,Pbf.Varint),this.writeSVarint(i)},writeStringField:function(t,i){this.writeTag(t,Pbf.Bytes),this.writeString(i)},writeFloatField:function(t,i){this.writeTag(t,Pbf.Fixed32),this.writeFloat(i)},writeDoubleField:function(t,i){this.writeTag(t,Pbf.Fixed64),this.writeDouble(i)},writeBooleanField:function(t,i){this.writeVarintField(t,Boolean(i))}};
  50 +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  51 +
  52 +},{"./buffer":23}],25:[function(_dereq_,module,exports){
  53 +"use strict";function Point(t,n){this.x=t,this.y=n}module.exports=Point,Point.prototype={clone:function(){return new Point(this.x,this.y)},add:function(t){return this.clone()._add(t)},sub:function(t){return this.clone()._sub(t)},mult:function(t){return this.clone()._mult(t)},div:function(t){return this.clone()._div(t)},rotate:function(t){return this.clone()._rotate(t)},matMult:function(t){return this.clone()._matMult(t)},unit:function(){return this.clone()._unit()},perp:function(){return this.clone()._perp()},round:function(){return this.clone()._round()},mag:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},equals:function(t){return this.x===t.x&&this.y===t.y},dist:function(t){return Math.sqrt(this.distSqr(t))},distSqr:function(t){var n=t.x-this.x,i=t.y-this.y;return n*n+i*i},angle:function(){return Math.atan2(this.y,this.x)},angleTo:function(t){return Math.atan2(this.y-t.y,this.x-t.x)},angleWith:function(t){return this.angleWithSep(t.x,t.y)},angleWithSep:function(t,n){return Math.atan2(this.x*n-this.y*t,this.x*t+this.y*n)},_matMult:function(t){var n=t[0]*this.x+t[1]*this.y,i=t[2]*this.x+t[3]*this.y;return this.x=n,this.y=i,this},_add:function(t){return this.x+=t.x,this.y+=t.y,this},_sub:function(t){return this.x-=t.x,this.y-=t.y,this},_mult:function(t){return this.x*=t,this.y*=t,this},_div:function(t){return this.x/=t,this.y/=t,this},_unit:function(){return this._div(this.mag()),this},_perp:function(){var t=this.y;return this.y=this.x,this.x=-t,this},_rotate:function(t){var n=Math.cos(t),i=Math.sin(t),s=n*this.x-i*this.y,r=i*this.x+n*this.y;return this.x=s,this.y=r,this},_round:function(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this}},Point.convert=function(t){return t instanceof Point?t:Array.isArray(t)?new Point(t[0],t[1]):t};
  54 +},{}],26:[function(_dereq_,module,exports){
  55 +function defaultSetTimout(){throw new Error("setTimeout has not been defined")}function defaultClearTimeout(){throw new Error("clearTimeout has not been defined")}function runTimeout(e){if(cachedSetTimeout===setTimeout)return setTimeout(e,0);if((cachedSetTimeout===defaultSetTimout||!cachedSetTimeout)&&setTimeout)return cachedSetTimeout=setTimeout,setTimeout(e,0);try{return cachedSetTimeout(e,0)}catch(t){try{return cachedSetTimeout.call(null,e,0)}catch(t){return cachedSetTimeout.call(this,e,0)}}}function runClearTimeout(e){if(cachedClearTimeout===clearTimeout)return clearTimeout(e);if((cachedClearTimeout===defaultClearTimeout||!cachedClearTimeout)&&clearTimeout)return cachedClearTimeout=clearTimeout,clearTimeout(e);try{return cachedClearTimeout(e)}catch(t){try{return cachedClearTimeout.call(null,e)}catch(t){return cachedClearTimeout.call(this,e)}}}function cleanUpNextTick(){draining&&currentQueue&&(draining=!1,currentQueue.length?queue=currentQueue.concat(queue):queueIndex=-1,queue.length&&drainQueue())}function drainQueue(){if(!draining){var e=runTimeout(cleanUpNextTick);draining=!0;for(var t=queue.length;t;){for(currentQueue=queue,queue=[];++queueIndex<t;)currentQueue&&currentQueue[queueIndex].run();queueIndex=-1,t=queue.length}currentQueue=null,draining=!1,runClearTimeout(e)}}function Item(e,t){this.fun=e,this.array=t}function noop(){}var process=module.exports={},cachedSetTimeout,cachedClearTimeout;!function(){try{cachedSetTimeout="function"==typeof setTimeout?setTimeout:defaultSetTimout}catch(e){cachedSetTimeout=defaultSetTimout}try{cachedClearTimeout="function"==typeof clearTimeout?clearTimeout:defaultClearTimeout}catch(e){cachedClearTimeout=defaultClearTimeout}}();var queue=[],draining=!1,currentQueue,queueIndex=-1;process.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var u=1;u<arguments.length;u++)t[u-1]=arguments[u];queue.push(new Item(e,t)),1!==queue.length||draining||runTimeout(drainQueue)},Item.prototype.run=function(){this.fun.apply(null,this.array)},process.title="browser",process.browser=!0,process.env={},process.argv=[],process.version="",process.versions={},process.on=noop,process.addListener=noop,process.once=noop,process.off=noop,process.removeListener=noop,process.removeAllListeners=noop,process.emit=noop,process.binding=function(e){throw new Error("process.binding is not supported")},process.cwd=function(){return"/"},process.chdir=function(e){throw new Error("process.chdir is not supported")},process.umask=function(){return 0};
  56 +},{}],27:[function(_dereq_,module,exports){
  57 +"use strict";function partialSort(a,t,r,o,p){for(r=r||0,o=o||a.length-1,p=p||defaultCompare;o>r;){if(o-r>600){var f=o-r+1,e=t-r+1,l=Math.log(f),s=.5*Math.exp(2*l/3),i=.5*Math.sqrt(l*s*(f-s)/f)*(e-f/2<0?-1:1),n=Math.max(r,Math.floor(t-e*s/f+i)),h=Math.min(o,Math.floor(t+(f-e)*s/f+i));partialSort(a,t,n,h,p)}var u=a[t],M=r,w=o;for(swap(a,r,t),p(a[o],u)>0&&swap(a,r,o);M<w;){for(swap(a,M,w),M++,w--;p(a[M],u)<0;)M++;for(;p(a[w],u)>0;)w--}0===p(a[r],u)?swap(a,r,w):(w++,swap(a,w,o)),w<=t&&(r=w+1),t<=w&&(o=w-1)}}function swap(a,t,r){var o=a[t];a[t]=a[r],a[r]=o}function defaultCompare(a,t){return a<t?-1:a>t?1:0}module.exports=partialSort;
  58 +},{}],28:[function(_dereq_,module,exports){
  59 +"use strict";function supercluster(t){return new SuperCluster(t)}function SuperCluster(t){this.options=extend(Object.create(this.options),t),this.trees=new Array(this.options.maxZoom+1)}function createCluster(t,e,o,n){return{x:t,y:e,zoom:1/0,id:n,numPoints:o}}function createPointCluster(t,e){var o=t.geometry.coordinates;return createCluster(lngX(o[0]),latY(o[1]),1,e)}function getClusterJSON(t){return{type:"Feature",properties:getClusterProperties(t),geometry:{type:"Point",coordinates:[xLng(t.x),yLat(t.y)]}}}function getClusterProperties(t){var e=t.numPoints,o=e>=1e4?Math.round(e/1e3)+"k":e>=1e3?Math.round(e/100)/10+"k":e;return{cluster:!0,point_count:e,point_count_abbreviated:o}}function lngX(t){return t/360+.5}function latY(t){var e=Math.sin(t*Math.PI/180),o=.5-.25*Math.log((1+e)/(1-e))/Math.PI;return o<0?0:o>1?1:o}function xLng(t){return 360*(t-.5)}function yLat(t){var e=(180-360*t)*Math.PI/180;return 360*Math.atan(Math.exp(e))/Math.PI-90}function extend(t,e){for(var o in e)t[o]=e[o];return t}function getX(t){return t.x}function getY(t){return t.y}var kdbush=_dereq_("kdbush");module.exports=supercluster,SuperCluster.prototype={options:{minZoom:0,maxZoom:16,radius:40,extent:512,nodeSize:64,log:!1},load:function(t){var e=this.options.log;e&&console.time("total time");var o="prepare "+t.length+" points";e&&console.time(o),this.points=t;var n=t.map(createPointCluster);e&&console.timeEnd(o);for(var r=this.options.maxZoom;r>=this.options.minZoom;r--){var i=+Date.now();this.trees[r+1]=kdbush(n,getX,getY,this.options.nodeSize,Float32Array),n=this._cluster(n,r),e&&console.log("z%d: %d clusters in %dms",r,n.length,+Date.now()-i)}return this.trees[this.options.minZoom]=kdbush(n,getX,getY,this.options.nodeSize,Float32Array),e&&console.timeEnd("total time"),this},getClusters:function(t,e){for(var o=this.trees[this._limitZoom(e)],n=o.range(lngX(t[0]),latY(t[3]),lngX(t[2]),latY(t[1])),r=[],i=0;i<n.length;i++){var s=o.points[n[i]];r.push(s.id!==-1?this.points[s.id]:getClusterJSON(s))}return r},getTile:function(t,e,o){var n=this.trees[this._limitZoom(t)],r=Math.pow(2,t),i=this.options.extent,s=this.options.radius,u=s/i,a=(o-u)/r,h=(o+1+u)/r,l={features:[]};return this._addTileFeatures(n.range((e-u)/r,a,(e+1+u)/r,h),n.points,e,o,r,l),0===e&&this._addTileFeatures(n.range(1-u/r,a,1,h),n.points,r,o,r,l),e===r-1&&this._addTileFeatures(n.range(0,a,u/r,h),n.points,-1,o,r,l),l.features.length?l:null},_addTileFeatures:function(t,e,o,n,r,i){for(var s=0;s<t.length;s++){var u=e[t[s]];i.features.push({type:1,geometry:[[Math.round(this.options.extent*(u.x*r-o)),Math.round(this.options.extent*(u.y*r-n))]],tags:u.id!==-1?this.points[u.id].properties:getClusterProperties(u)})}},_limitZoom:function(t){return Math.max(this.options.minZoom,Math.min(t,this.options.maxZoom+1))},_cluster:function(t,e){for(var o=[],n=this.options.radius/(this.options.extent*Math.pow(2,e)),r=0;r<t.length;r++){var i=t[r];if(!(i.zoom<=e)){i.zoom=e;for(var s=this.trees[e+1],u=s.within(i.x,i.y,n),a=!1,h=i.numPoints,l=i.x*h,p=i.y*h,m=0;m<u.length;m++){var c=s.points[u[m]];e<c.zoom&&(a=!0,c.zoom=e,l+=c.x*c.numPoints,p+=c.y*c.numPoints,h+=c.numPoints)}o.push(a?createCluster(l/h,p/h,h,-1):i)}}return o}};
  60 +},{"kdbush":18}],29:[function(_dereq_,module,exports){
  61 +"use strict";function TinyQueue(t,i){if(!(this instanceof TinyQueue))return new TinyQueue(t,i);if(this.data=t||[],this.length=this.data.length,this.compare=i||defaultCompare,t)for(var a=Math.floor(this.length/2);a>=0;a--)this._down(a)}function defaultCompare(t,i){return t<i?-1:t>i?1:0}function swap(t,i,a){var n=t[i];t[i]=t[a],t[a]=n}module.exports=TinyQueue,TinyQueue.prototype={push:function(t){this.data.push(t),this.length++,this._up(this.length-1)},pop:function(){var t=this.data[0];return this.data[0]=this.data[this.length-1],this.length--,this.data.pop(),this._down(0),t},peek:function(){return this.data[0]},_up:function(t){for(var i=this.data,a=this.compare;t>0;){var n=Math.floor((t-1)/2);if(!(a(i[t],i[n])<0))break;swap(i,n,t),t=n}},_down:function(t){for(var i=this.data,a=this.compare,n=this.length;;){var e=2*t+1,h=e+1,s=t;if(e<n&&a(i[e],i[s])<0&&(s=e),h<n&&a(i[h],i[s])<0&&(s=h),s===t)return;swap(i,s,t),t=s}}};
  62 +},{}],30:[function(_dereq_,module,exports){
  63 +"function"==typeof Object.create?module.exports=function(t,e){t.super_=e,t.prototype=Object.create(e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}})}:module.exports=function(t,e){t.super_=e;var o=function(){};o.prototype=e.prototype,t.prototype=new o,t.prototype.constructor=t};
  64 +},{}],31:[function(_dereq_,module,exports){
  65 +module.exports=function(o){return o&&"object"==typeof o&&"function"==typeof o.copy&&"function"==typeof o.fill&&"function"==typeof o.readUInt8};
  66 +},{}],32:[function(_dereq_,module,exports){
  67 +(function (process,global){
  68 +function inspect(e,r){var t={seen:[],stylize:stylizeNoColor};return arguments.length>=3&&(t.depth=arguments[2]),arguments.length>=4&&(t.colors=arguments[3]),isBoolean(r)?t.showHidden=r:r&&exports._extend(t,r),isUndefined(t.showHidden)&&(t.showHidden=!1),isUndefined(t.depth)&&(t.depth=2),isUndefined(t.colors)&&(t.colors=!1),isUndefined(t.customInspect)&&(t.customInspect=!0),t.colors&&(t.stylize=stylizeWithColor),formatValue(t,e,t.depth)}function stylizeWithColor(e,r){var t=inspect.styles[r];return t?"["+inspect.colors[t][0]+"m"+e+"["+inspect.colors[t][1]+"m":e}function stylizeNoColor(e,r){return e}function arrayToHash(e){var r={};return e.forEach(function(e,t){r[e]=!0}),r}function formatValue(e,r,t){if(e.customInspect&&r&&isFunction(r.inspect)&&r.inspect!==exports.inspect&&(!r.constructor||r.constructor.prototype!==r)){var n=r.inspect(t,e);return isString(n)||(n=formatValue(e,n,t)),n}var i=formatPrimitive(e,r);if(i)return i;var o=Object.keys(r),s=arrayToHash(o);if(e.showHidden&&(o=Object.getOwnPropertyNames(r)),isError(r)&&(o.indexOf("message")>=0||o.indexOf("description")>=0))return formatError(r);if(0===o.length){if(isFunction(r)){var u=r.name?": "+r.name:"";return e.stylize("[Function"+u+"]","special")}if(isRegExp(r))return e.stylize(RegExp.prototype.toString.call(r),"regexp");if(isDate(r))return e.stylize(Date.prototype.toString.call(r),"date");if(isError(r))return formatError(r)}var c="",a=!1,l=["{","}"];if(isArray(r)&&(a=!0,l=["[","]"]),isFunction(r)){var p=r.name?": "+r.name:"";c=" [Function"+p+"]"}if(isRegExp(r)&&(c=" "+RegExp.prototype.toString.call(r)),isDate(r)&&(c=" "+Date.prototype.toUTCString.call(r)),isError(r)&&(c=" "+formatError(r)),0===o.length&&(!a||0==r.length))return l[0]+c+l[1];if(t<0)return isRegExp(r)?e.stylize(RegExp.prototype.toString.call(r),"regexp"):e.stylize("[Object]","special");e.seen.push(r);var f;return f=a?formatArray(e,r,t,s,o):o.map(function(n){return formatProperty(e,r,t,s,n,a)}),e.seen.pop(),reduceToSingleString(f,c,l)}function formatPrimitive(e,r){if(isUndefined(r))return e.stylize("undefined","undefined");if(isString(r)){var t="'"+JSON.stringify(r).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(t,"string")}return isNumber(r)?e.stylize(""+r,"number"):isBoolean(r)?e.stylize(""+r,"boolean"):isNull(r)?e.stylize("null","null"):void 0}function formatError(e){return"["+Error.prototype.toString.call(e)+"]"}function formatArray(e,r,t,n,i){for(var o=[],s=0,u=r.length;s<u;++s)hasOwnProperty(r,String(s))?o.push(formatProperty(e,r,t,n,String(s),!0)):o.push("");return i.forEach(function(i){i.match(/^\d+$/)||o.push(formatProperty(e,r,t,n,i,!0))}),o}function formatProperty(e,r,t,n,i,o){var s,u,c;if(c=Object.getOwnPropertyDescriptor(r,i)||{value:r[i]},c.get?u=c.set?e.stylize("[Getter/Setter]","special"):e.stylize("[Getter]","special"):c.set&&(u=e.stylize("[Setter]","special")),hasOwnProperty(n,i)||(s="["+i+"]"),u||(e.seen.indexOf(c.value)<0?(u=isNull(t)?formatValue(e,c.value,null):formatValue(e,c.value,t-1),u.indexOf("\n")>-1&&(u=o?u.split("\n").map(function(e){return" "+e}).join("\n").substr(2):"\n"+u.split("\n").map(function(e){return" "+e}).join("\n"))):u=e.stylize("[Circular]","special")),isUndefined(s)){if(o&&i.match(/^\d+$/))return u;s=JSON.stringify(""+i),s.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(s=s.substr(1,s.length-2),s=e.stylize(s,"name")):(s=s.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),s=e.stylize(s,"string"))}return s+": "+u}function reduceToSingleString(e,r,t){var n=0,i=e.reduce(function(e,r){return n++,r.indexOf("\n")>=0&&n++,e+r.replace(/\u001b\[\d\d?m/g,"").length+1},0);return i>60?t[0]+(""===r?"":r+"\n ")+" "+e.join(",\n ")+" "+t[1]:t[0]+r+" "+e.join(", ")+" "+t[1]}function isArray(e){return Array.isArray(e)}function isBoolean(e){return"boolean"==typeof e}function isNull(e){return null===e}function isNullOrUndefined(e){return null==e}function isNumber(e){return"number"==typeof e}function isString(e){return"string"==typeof e}function isSymbol(e){return"symbol"==typeof e}function isUndefined(e){return void 0===e}function isRegExp(e){return isObject(e)&&"[object RegExp]"===objectToString(e)}function isObject(e){return"object"==typeof e&&null!==e}function isDate(e){return isObject(e)&&"[object Date]"===objectToString(e)}function isError(e){return isObject(e)&&("[object Error]"===objectToString(e)||e instanceof Error)}function isFunction(e){return"function"==typeof e}function isPrimitive(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||"undefined"==typeof e}function objectToString(e){return Object.prototype.toString.call(e)}function pad(e){return e<10?"0"+e.toString(10):e.toString(10)}function timestamp(){var e=new Date,r=[pad(e.getHours()),pad(e.getMinutes()),pad(e.getSeconds())].join(":");return[e.getDate(),months[e.getMonth()],r].join(" ")}function hasOwnProperty(e,r){return Object.prototype.hasOwnProperty.call(e,r)}var formatRegExp=/%[sdj%]/g;exports.format=function(e){if(!isString(e)){for(var r=[],t=0;t<arguments.length;t++)r.push(inspect(arguments[t]));return r.join(" ")}for(var t=1,n=arguments,i=n.length,o=String(e).replace(formatRegExp,function(e){if("%%"===e)return"%";if(t>=i)return e;switch(e){case"%s":return String(n[t++]);case"%d":return Number(n[t++]);case"%j":try{return JSON.stringify(n[t++])}catch(e){return"[Circular]"}default:return e}}),s=n[t];t<i;s=n[++t])o+=isNull(s)||!isObject(s)?" "+s:" "+inspect(s);return o},exports.deprecate=function(e,r){function t(){if(!n){if(process.throwDeprecation)throw new Error(r);process.traceDeprecation?console.trace(r):console.error(r),n=!0}return e.apply(this,arguments)}if(isUndefined(global.process))return function(){return exports.deprecate(e,r).apply(this,arguments)};if(process.noDeprecation===!0)return e;var n=!1;return t};var debugs={},debugEnviron;exports.debuglog=function(e){if(isUndefined(debugEnviron)&&(debugEnviron=process.env.NODE_DEBUG||""),e=e.toUpperCase(),!debugs[e])if(new RegExp("\\b"+e+"\\b","i").test(debugEnviron)){var r=process.pid;debugs[e]=function(){var t=exports.format.apply(exports,arguments);console.error("%s %d: %s",e,r,t)}}else debugs[e]=function(){};return debugs[e]},exports.inspect=inspect,inspect.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},inspect.styles={special:"cyan",number:"yellow",boolean:"yellow",undefined:"grey",null:"bold",string:"green",date:"magenta",regexp:"red"},exports.isArray=isArray,exports.isBoolean=isBoolean,exports.isNull=isNull,exports.isNullOrUndefined=isNullOrUndefined,exports.isNumber=isNumber,exports.isString=isString,exports.isSymbol=isSymbol,exports.isUndefined=isUndefined,exports.isRegExp=isRegExp,exports.isObject=isObject,exports.isDate=isDate,exports.isError=isError,exports.isFunction=isFunction,exports.isPrimitive=isPrimitive,exports.isBuffer=_dereq_("./support/isBuffer");var months=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];exports.log=function(){console.log("%s - %s",timestamp(),exports.format.apply(exports,arguments))},exports.inherits=_dereq_("inherits"),exports._extend=function(e,r){if(!r||!isObject(r))return e;for(var t=Object.keys(r),n=t.length;n--;)e[t[n]]=r[t[n]];return e};
  69 +}).call(this,_dereq_('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  70 +
  71 +},{"./support/isBuffer":31,"_process":26,"inherits":30}],33:[function(_dereq_,module,exports){
  72 +module.exports.VectorTile=_dereq_("./lib/vectortile.js"),module.exports.VectorTileFeature=_dereq_("./lib/vectortilefeature.js"),module.exports.VectorTileLayer=_dereq_("./lib/vectortilelayer.js");
  73 +},{"./lib/vectortile.js":34,"./lib/vectortilefeature.js":35,"./lib/vectortilelayer.js":36}],34:[function(_dereq_,module,exports){
  74 +"use strict";function VectorTile(e,r){this.layers=e.readFields(readTile,{},r)}function readTile(e,r,i){if(3===e){var t=new VectorTileLayer(i,i.readVarint()+i.pos);t.length&&(r[t.name]=t)}}var VectorTileLayer=_dereq_("./vectortilelayer");module.exports=VectorTile;
  75 +},{"./vectortilelayer":36}],35:[function(_dereq_,module,exports){
  76 +"use strict";function VectorTileFeature(e,t,r,i,a){this.properties={},this.extent=r,this.type=0,this._pbf=e,this._geometry=-1,this._keys=i,this._values=a,e.readFields(readFeature,this,t)}function readFeature(e,t,r){1==e?t.id=r.readVarint():2==e?readTag(r,t):3==e?t.type=r.readVarint():4==e&&(t._geometry=r.pos)}function readTag(e,t){for(var r=e.readVarint()+e.pos;e.pos<r;){var i=t._keys[e.readVarint()],a=t._values[e.readVarint()];t.properties[i]=a}}function classifyRings(e){var t=e.length;if(t<=1)return[e];for(var r,i,a=[],o=0;o<t;o++){var n=signedArea(e[o]);0!==n&&(void 0===i&&(i=n<0),i===n<0?(r&&a.push(r),r=[e[o]]):r.push(e[o]))}return r&&a.push(r),a}function signedArea(e){for(var t,r,i=0,a=0,o=e.length,n=o-1;a<o;n=a++)t=e[a],r=e[n],i+=(r.x-t.x)*(t.y+r.y);return i}var Point=_dereq_("point-geometry");module.exports=VectorTileFeature,VectorTileFeature.types=["Unknown","Point","LineString","Polygon"],VectorTileFeature.prototype.loadGeometry=function(){var e=this._pbf;e.pos=this._geometry;for(var t,r=e.readVarint()+e.pos,i=1,a=0,o=0,n=0,s=[];e.pos<r;){if(!a){var p=e.readVarint();i=7&p,a=p>>3}if(a--,1===i||2===i)o+=e.readSVarint(),n+=e.readSVarint(),1===i&&(t&&s.push(t),t=[]),t.push(new Point(o,n));else{if(7!==i)throw new Error("unknown command "+i);t&&t.push(t[0].clone())}}return t&&s.push(t),s},VectorTileFeature.prototype.bbox=function(){var e=this._pbf;e.pos=this._geometry;for(var t=e.readVarint()+e.pos,r=1,i=0,a=0,o=0,n=1/0,s=-(1/0),p=1/0,h=-(1/0);e.pos<t;){if(!i){var u=e.readVarint();r=7&u,i=u>>3}if(i--,1===r||2===r)a+=e.readSVarint(),o+=e.readSVarint(),a<n&&(n=a),a>s&&(s=a),o<p&&(p=o),o>h&&(h=o);else if(7!==r)throw new Error("unknown command "+r)}return[n,p,s,h]},VectorTileFeature.prototype.toGeoJSON=function(e,t,r){function i(e){for(var t=0;t<e.length;t++){var r=e[t],i=180-360*(r.y+p)/n;e[t]=[360*(r.x+s)/n-180,360/Math.PI*Math.atan(Math.exp(i*Math.PI/180))-90]}}var a,o,n=this.extent*Math.pow(2,r),s=this.extent*e,p=this.extent*t,h=this.loadGeometry(),u=VectorTileFeature.types[this.type];switch(this.type){case 1:var d=[];for(a=0;a<h.length;a++)d[a]=h[a][0];h=d,i(h);break;case 2:for(a=0;a<h.length;a++)i(h[a]);break;case 3:for(h=classifyRings(h),a=0;a<h.length;a++)for(o=0;o<h[a].length;o++)i(h[a][o])}1===h.length?h=h[0]:u="Multi"+u;var f={type:"Feature",geometry:{type:u,coordinates:h},properties:this.properties};return"id"in this&&(f.id=this.id),f};
  77 +},{"point-geometry":25}],36:[function(_dereq_,module,exports){
  78 +"use strict";function VectorTileLayer(e,t){this.version=1,this.name=null,this.extent=4096,this.length=0,this._pbf=e,this._keys=[],this._values=[],this._features=[],e.readFields(readLayer,this,t),this.length=this._features.length}function readLayer(e,t,r){15===e?t.version=r.readVarint():1===e?t.name=r.readString():5===e?t.extent=r.readVarint():2===e?t._features.push(r.pos):3===e?t._keys.push(r.readString()):4===e&&t._values.push(readValueMessage(r))}function readValueMessage(e){for(var t=null,r=e.readVarint()+e.pos;e.pos<r;){var a=e.readVarint()>>3;t=1===a?e.readString():2===a?e.readFloat():3===a?e.readDouble():4===a?e.readVarint64():5===a?e.readVarint():6===a?e.readSVarint():7===a?e.readBoolean():null}return t}var VectorTileFeature=_dereq_("./vectortilefeature.js");module.exports=VectorTileLayer,VectorTileLayer.prototype.feature=function(e){if(e<0||e>=this._features.length)throw new Error("feature index out of bounds");this._pbf.pos=this._features[e];var t=this._pbf.readVarint()+this._pbf.pos;return new VectorTileFeature(this._pbf,t,this.extent,this._keys,this._values)};
  79 +},{"./vectortilefeature.js":35}],37:[function(_dereq_,module,exports){
  80 +function fromVectorTileJs(e){var r=[];for(var o in e.layers)r.push(prepareLayer(e.layers[o]));var t=new Pbf;return vtpb.tile.write({layers:r},t),t.finish()}function fromGeojsonVt(e){var r={};for(var o in e)r[o]=new GeoJSONWrapper(e[o].features),r[o].name=o;return fromVectorTileJs({layers:r})}function prepareLayer(e){for(var r={name:e.name||"",version:e.version||1,extent:e.extent||4096,keys:[],values:[],features:[]},o={},t={},n=0;n<e.length;n++){var a=e.feature(n);a.geometry=encodeGeometry(a.loadGeometry());var u=[];for(var s in a.properties){var i=o[s];"undefined"==typeof i&&(r.keys.push(s),i=r.keys.length-1,o[s]=i);var p=wrapValue(a.properties[s]),l=t[p.key];"undefined"==typeof l&&(r.values.push(p),l=r.values.length-1,t[p.key]=l),u.push(i),u.push(l)}a.tags=u,r.features.push(a)}return r}function command(e,r){return(r<<3)+(7&e)}function zigzag(e){return e<<1^e>>31}function encodeGeometry(e){for(var r=[],o=0,t=0,n=e.length,a=0;a<n;a++){var u=e[a];r.push(command(1,1));for(var s=0;s<u.length;s++){1===s&&r.push(command(2,u.length-1));var i=u[s].x-o,p=u[s].y-t;r.push(zigzag(i),zigzag(p)),o+=i,t+=p}}return r}function wrapValue(e){var r,o=typeof e;return"string"===o?r={string_value:e}:"boolean"===o?r={bool_value:e}:"number"===o?r=e%1!==0?{double_value:e}:e<0?{sint_value:e}:{uint_value:e}:(e=JSON.stringify(e),r={string_value:e}),r.key=o+":"+e,r}var Pbf=_dereq_("pbf"),vtpb=_dereq_("./vector-tile-pb"),GeoJSONWrapper=_dereq_("./lib/geojson_wrapper");module.exports=fromVectorTileJs,module.exports.fromVectorTileJs=fromVectorTileJs,module.exports.fromGeojsonVt=fromGeojsonVt,module.exports.GeoJSONWrapper=GeoJSONWrapper;
  81 +},{"./lib/geojson_wrapper":38,"./vector-tile-pb":39,"pbf":24}],38:[function(_dereq_,module,exports){
  82 +"use strict";function GeoJSONWrapper(e){this.features=e,this.length=e.length}function FeatureWrapper(e){this.id="number"==typeof e.id?e.id:void 0,this.type=e.type,this.rawGeometry=1===e.type?[e.geometry]:e.geometry,this.properties=e.tags,this.extent=4096}var Point=_dereq_("point-geometry"),VectorTileFeature=_dereq_("vector-tile").VectorTileFeature;module.exports=GeoJSONWrapper,GeoJSONWrapper.prototype.feature=function(e){return new FeatureWrapper(this.features[e])},FeatureWrapper.prototype.loadGeometry=function(){var e=this.rawGeometry;this.geometry=[];for(var t=0;t<e.length;t++){for(var r=e[t],o=[],a=0;a<r.length;a++)o.push(new Point(r[a][0],r[a][1]));this.geometry.push(o)}return this.geometry},FeatureWrapper.prototype.bbox=function(){this.geometry||this.loadGeometry();for(var e=this.geometry,t=1/0,r=-(1/0),o=1/0,a=-(1/0),i=0;i<e.length;i++)for(var p=e[i],n=0;n<p.length;n++){var h=p[n];t=Math.min(t,h.x),r=Math.max(r,h.x),o=Math.min(o,h.y),a=Math.max(a,h.y)}return[t,o,r,a]},FeatureWrapper.prototype.toGeoJSON=VectorTileFeature.prototype.toGeoJSON;
  83 +},{"point-geometry":25,"vector-tile":33}],39:[function(_dereq_,module,exports){
  84 +"use strict";function readTile(e,r){return e.readFields(readTileField,{layers:[]},r)}function readTileField(e,r,i){3===e&&r.layers.push(readLayer(i,i.readVarint()+i.pos))}function writeTile(e,r){var i;if(void 0!==e.layers)for(i=0;i<e.layers.length;i++)r.writeMessage(3,writeLayer,e.layers[i])}function readValue(e,r){return e.readFields(readValueField,{},r)}function readValueField(e,r,i){1===e?r.string_value=i.readString():2===e?r.float_value=i.readFloat():3===e?r.double_value=i.readDouble():4===e?r.int_value=i.readVarint():5===e?r.uint_value=i.readVarint():6===e?r.sint_value=i.readSVarint():7===e&&(r.bool_value=i.readBoolean())}function writeValue(e,r){void 0!==e.string_value&&r.writeStringField(1,e.string_value),void 0!==e.float_value&&r.writeFloatField(2,e.float_value),void 0!==e.double_value&&r.writeDoubleField(3,e.double_value),void 0!==e.int_value&&r.writeVarintField(4,e.int_value),void 0!==e.uint_value&&r.writeVarintField(5,e.uint_value),void 0!==e.sint_value&&r.writeSVarintField(6,e.sint_value),void 0!==e.bool_value&&r.writeBooleanField(7,e.bool_value)}function readFeature(e,r){var i=e.readFields(readFeatureField,{},r);return void 0===i.type&&(i.type="Unknown"),i}function readFeatureField(e,r,i){1===e?r.id=i.readVarint():2===e?r.tags=i.readPackedVarint():3===e?r.type=i.readVarint():4===e&&(r.geometry=i.readPackedVarint())}function writeFeature(e,r){void 0!==e.id&&r.writeVarintField(1,e.id),void 0!==e.tags&&r.writePackedVarint(2,e.tags),void 0!==e.type&&r.writeVarintField(3,e.type),void 0!==e.geometry&&r.writePackedVarint(4,e.geometry)}function readLayer(e,r){return e.readFields(readLayerField,{features:[],keys:[],values:[]},r)}function readLayerField(e,r,i){15===e?r.version=i.readVarint():1===e?r.name=i.readString():2===e?r.features.push(readFeature(i,i.readVarint()+i.pos)):3===e?r.keys.push(i.readString()):4===e?r.values.push(readValue(i,i.readVarint()+i.pos)):5===e&&(r.extent=i.readVarint())}function writeLayer(e,r){void 0!==e.version&&r.writeVarintField(15,e.version),void 0!==e.name&&r.writeStringField(1,e.name);var i;if(void 0!==e.features)for(i=0;i<e.features.length;i++)r.writeMessage(2,writeFeature,e.features[i]);if(void 0!==e.keys)for(i=0;i<e.keys.length;i++)r.writeStringField(3,e.keys[i]);if(void 0!==e.values)for(i=0;i<e.values.length;i++)r.writeMessage(4,writeValue,e.values[i]);void 0!==e.extent&&r.writeVarintField(5,e.extent)}var tile=exports.tile={read:readTile,write:writeTile};tile.GeomType={Unknown:0,Point:1,LineString:2,Polygon:3},tile.value={read:readValue,write:writeValue},tile.feature={read:readFeature,write:writeFeature},tile.layer={read:readLayer,write:writeLayer};
  85 +},{}],40:[function(_dereq_,module,exports){
  86 +var bundleFn=arguments[3],sources=arguments[4],cache=arguments[5],stringify=JSON.stringify;module.exports=function(r,e){function t(r){d[r]=!0;for(var e in sources[r][1]){var n=sources[r][1][e];d[n]||t(n)}}for(var n,o=Object.keys(cache),a=0,i=o.length;a<i;a++){var s=o[a],u=cache[s].exports;if(u===r||u&&u.default===r){n=s;break}}if(!n){n=Math.floor(Math.pow(16,8)*Math.random()).toString(16);for(var f={},a=0,i=o.length;a<i;a++){var s=o[a];f[s]=s}sources[n]=[Function(["require","module","exports"],"("+r+")(self)"),f]}var c=Math.floor(Math.pow(16,8)*Math.random()).toString(16),l={};l[n]=n,sources[c]=[Function(["require"],"var f = require("+stringify(n)+");(f.default ? f.default : f)(self);"),l];var d={};t(c);var g="("+bundleFn+")({"+Object.keys(d).map(function(r){return stringify(r)+":["+sources[r][0]+","+stringify(sources[r][1])+"]"}).join(",")+"},{},["+stringify(c)+"])",v=window.URL||window.webkitURL||window.mozURL||window.msURL,w=new Blob([g],{type:"text/javascript"});if(e&&e.bare)return w;var h=v.createObjectURL(w),b=new Worker(h);return b.objectURL=h,b};
  87 +},{}],41:[function(_dereq_,module,exports){
  88 +module.exports.RADIUS=6378137,module.exports.FLATTENING=1/298.257223563,module.exports.POLAR_RADIUS=6356752.3142;
  89 +},{}],42:[function(_dereq_,module,exports){
  90 +module.exports={"version":"0.38.0"}
  91 +},{}],43:[function(_dereq_,module,exports){
  92 +"use strict";function serializePaintVertexArrays(r,e){var t={};for(var a in r){var i=r[a].paintVertexArray;if(0!==i.length){var n=i.serialize(e),s=i.constructor.serialize();t[a]={array:n,type:s}}}return t}var ProgramConfiguration=_dereq_("./program_configuration"),createVertexArrayType=_dereq_("./vertex_array_type"),Segment=function(r,e){this.vertexOffset=r,this.primitiveOffset=e,this.vertexLength=0,this.primitiveLength=0},ArrayGroup=function(r,e,t){var a=this;this.globalProperties={zoom:t};var i=createVertexArrayType(r.layoutAttributes);this.layoutVertexArray=new i;var n=r.elementArrayType;n&&(this.elementArray=new n);var s=r.elementArrayType2;s&&(this.elementArray2=new s),this.layerData={};for(var y=0,o=e;y<o.length;y+=1){var p=o[y],l=ProgramConfiguration.createDynamic(r,p,t);a.layerData[p.id]={layer:p,programConfiguration:l,paintVertexArray:new l.PaintVertexArray,paintPropertyStatistics:l.createPaintPropertyStatistics()}}this.segments=[],this.segments2=[]};ArrayGroup.prototype.prepareSegment=function(r){var e=this.segments[this.segments.length-1];return(!e||e.vertexLength+r>ArrayGroup.MAX_VERTEX_ARRAY_LENGTH)&&(e=new Segment(this.layoutVertexArray.length,this.elementArray.length),this.segments.push(e)),e},ArrayGroup.prototype.prepareSegment2=function(r){var e=this.segments2[this.segments2.length-1];return(!e||e.vertexLength+r>ArrayGroup.MAX_VERTEX_ARRAY_LENGTH)&&(e=new Segment(this.layoutVertexArray.length,this.elementArray2.length),this.segments2.push(e)),e},ArrayGroup.prototype.populatePaintArrays=function(r){var e=this;for(var t in e.layerData){var a=e.layerData[t];0!==a.paintVertexArray.bytesPerElement&&a.programConfiguration.populatePaintArray(a.layer,a.paintVertexArray,a.paintPropertyStatistics,e.layoutVertexArray.length,e.globalProperties,r)}},ArrayGroup.prototype.isEmpty=function(){return 0===this.layoutVertexArray.length},ArrayGroup.prototype.serialize=function(r){return{layoutVertexArray:this.layoutVertexArray.serialize(r),elementArray:this.elementArray&&this.elementArray.serialize(r),elementArray2:this.elementArray2&&this.elementArray2.serialize(r),paintVertexArrays:serializePaintVertexArrays(this.layerData,r),segments:this.segments,segments2:this.segments2}},ArrayGroup.MAX_VERTEX_ARRAY_LENGTH=Math.pow(2,16)-1,module.exports=ArrayGroup;
  93 +},{"./program_configuration":57,"./vertex_array_type":59}],44:[function(_dereq_,module,exports){
  94 +"use strict";var ArrayGroup=_dereq_("./array_group"),BufferGroup=_dereq_("./buffer_group"),util=_dereq_("../util/util"),Bucket=function(r,t){this.zoom=r.zoom,this.overscaling=r.overscaling,this.layers=r.layers,this.index=r.index,r.arrays?this.buffers=new BufferGroup(t,r.layers,r.zoom,r.arrays):this.arrays=new ArrayGroup(t,r.layers,r.zoom)};Bucket.prototype.populate=function(r,t){for(var e=this,i=0,a=r;i<a.length;i+=1){var u=a[i];e.layers[0].filter(u)&&(e.addFeature(u),t.featureIndex.insert(u,e.index))}},Bucket.prototype.getPaintPropertyStatistics=function(){return util.mapObject(this.arrays.layerData,function(r){return r.paintPropertyStatistics})},Bucket.prototype.isEmpty=function(){return this.arrays.isEmpty()},Bucket.prototype.serialize=function(r){return{zoom:this.zoom,layerIds:this.layers.map(function(r){return r.id}),arrays:this.arrays.serialize(r)}},Bucket.prototype.destroy=function(){this.buffers&&(this.buffers.destroy(),this.buffers=null)},module.exports=Bucket,Bucket.deserialize=function(r,t){if(t){for(var e={},i=0,a=r;i<a.length;i+=1){var u=a[i],o=u.layerIds.map(function(r){return t.getLayer(r)}).filter(Boolean);if(0!==o.length)for(var s=o[0].createBucket(util.extend({layers:o},u)),n=0,f=o;n<f.length;n+=1){var y=f[n];e[y.id]=s}}return e}};
  95 +},{"../util/util":215,"./array_group":43,"./buffer_group":51}],45:[function(_dereq_,module,exports){
  96 +"use strict";function addCircleVertex(e,r,t,c,i){e.emplaceBack(2*r+(c+1)/2,2*t+(i+1)/2)}var Bucket=_dereq_("../bucket"),createElementArrayType=_dereq_("../element_array_type"),loadGeometry=_dereq_("../load_geometry"),EXTENT=_dereq_("../extent"),circleInterface={layoutAttributes:[{name:"a_pos",components:2,type:"Int16"}],elementArrayType:createElementArrayType(),paintAttributes:[{property:"circle-color",type:"Uint8"},{property:"circle-radius",type:"Uint16",multiplier:10},{property:"circle-blur",type:"Uint16",multiplier:10},{property:"circle-opacity",type:"Uint8",multiplier:255},{property:"circle-stroke-color",type:"Uint8"},{property:"circle-stroke-width",type:"Uint16",multiplier:10},{property:"circle-stroke-opacity",type:"Uint8",multiplier:255}]},CircleBucket=function(e){function r(r){e.call(this,r,circleInterface)}return e&&(r.__proto__=e),r.prototype=Object.create(e&&e.prototype),r.prototype.constructor=r,r.prototype.addFeature=function(e){for(var r=this.arrays,t=0,c=loadGeometry(e);t<c.length;t+=1)for(var i=c[t],a=0,p=i;a<p.length;a+=1){var l=p[a],o=l.x,y=l.y;if(!(o<0||o>=EXTENT||y<0||y>=EXTENT)){var n=r.prepareSegment(4),u=n.vertexLength;addCircleVertex(r.layoutVertexArray,o,y,-1,-1),addCircleVertex(r.layoutVertexArray,o,y,1,-1),addCircleVertex(r.layoutVertexArray,o,y,1,1),addCircleVertex(r.layoutVertexArray,o,y,-1,1),r.elementArray.emplaceBack(u,u+1,u+2),r.elementArray.emplaceBack(u,u+3,u+2),n.vertexLength+=4,n.primitiveLength+=2}}r.populatePaintArrays(e.properties)},r}(Bucket);CircleBucket.programInterface=circleInterface,module.exports=CircleBucket;
  97 +},{"../bucket":44,"../element_array_type":52,"../extent":53,"../load_geometry":55}],46:[function(_dereq_,module,exports){
  98 +"use strict";var Bucket=_dereq_("../bucket"),createElementArrayType=_dereq_("../element_array_type"),loadGeometry=_dereq_("../load_geometry"),earcut=_dereq_("earcut"),classifyRings=_dereq_("../../util/classify_rings"),EARCUT_MAX_RINGS=500,fillInterface={layoutAttributes:[{name:"a_pos",components:2,type:"Int16"}],elementArrayType:createElementArrayType(3),elementArrayType2:createElementArrayType(2),paintAttributes:[{property:"fill-color",type:"Uint8"},{property:"fill-outline-color",type:"Uint8"},{property:"fill-opacity",type:"Uint8",multiplier:255}]},FillBucket=function(e){function t(t){e.call(this,t,fillInterface)}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype.addFeature=function(e){for(var t=this.arrays,r=0,a=classifyRings(loadGeometry(e),EARCUT_MAX_RINGS);r<a.length;r+=1){for(var l=a[r],n=0,p=0,i=l;p<i.length;p+=1){var o=i[p];n+=o.length}for(var y=t.prepareSegment(n),c=y.vertexLength,u=[],s=[],g=0,h=l;g<h.length;g+=1){var m=h[g];if(0!==m.length){m!==l[0]&&s.push(u.length/2);var f=t.prepareSegment2(m.length),A=f.vertexLength;t.layoutVertexArray.emplaceBack(m[0].x,m[0].y),t.elementArray2.emplaceBack(A+m.length-1,A),u.push(m[0].x),u.push(m[0].y);for(var v=1;v<m.length;v++)t.layoutVertexArray.emplaceBack(m[v].x,m[v].y),t.elementArray2.emplaceBack(A+v-1,A+v),u.push(m[v].x),u.push(m[v].y);f.vertexLength+=m.length,f.primitiveLength+=m.length}}for(var _=earcut(u,s),k=0;k<_.length;k+=3)t.elementArray.emplaceBack(c+_[k],c+_[k+1],c+_[k+2]);y.vertexLength+=n,y.primitiveLength+=_.length/3}t.populatePaintArrays(e.properties)},t}(Bucket);FillBucket.programInterface=fillInterface,module.exports=FillBucket;
  99 +},{"../../util/classify_rings":197,"../bucket":44,"../element_array_type":52,"../load_geometry":55,"earcut":5}],47:[function(_dereq_,module,exports){
  100 +"use strict";function addVertex(e,t,r,a,n,o,i,y){e.emplaceBack(t,r,2*Math.floor(a*FACTOR)+i,n*FACTOR*2,o*FACTOR*2,Math.round(y))}function isBoundaryEdge(e,t){return e.x===t.x&&(e.x<0||e.x>EXTENT)||e.y===t.y&&(e.y<0||e.y>EXTENT)}var Bucket=_dereq_("../bucket"),createElementArrayType=_dereq_("../element_array_type"),loadGeometry=_dereq_("../load_geometry"),EXTENT=_dereq_("../extent"),earcut=_dereq_("earcut"),classifyRings=_dereq_("../../util/classify_rings"),EARCUT_MAX_RINGS=500,fillExtrusionInterface={layoutAttributes:[{name:"a_pos",components:2,type:"Int16"},{name:"a_normal",components:3,type:"Int16"},{name:"a_edgedistance",components:1,type:"Int16"}],elementArrayType:createElementArrayType(3),paintAttributes:[{property:"fill-extrusion-base",type:"Uint16"},{property:"fill-extrusion-height",type:"Uint16"},{property:"fill-extrusion-color",type:"Uint8"}]},FACTOR=Math.pow(2,13),FillExtrusionBucket=function(e){function t(t){e.call(this,t,fillExtrusionInterface)}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype.addFeature=function(e){for(var t=this.arrays,r=0,a=classifyRings(loadGeometry(e),EARCUT_MAX_RINGS);r<a.length;r+=1){for(var n=a[r],o=0,i=0,y=n;i<y.length;i+=1){var l=y[i];o+=l.length}for(var u=t.prepareSegment(5*o),p=[],s=[],c=[],x=0,f=n;x<f.length;x+=1){var d=f[x];if(0!==d.length){d!==n[0]&&s.push(p.length/2);for(var m=0,h=0;h<d.length;h++){var g=d[h];if(addVertex(t.layoutVertexArray,g.x,g.y,0,0,1,1,0),c.push(u.vertexLength++),h>=1){var A=d[h-1];if(!isBoundaryEdge(g,A)){var E=g.sub(A)._perp()._unit();addVertex(t.layoutVertexArray,g.x,g.y,E.x,E.y,0,0,m),addVertex(t.layoutVertexArray,g.x,g.y,E.x,E.y,0,1,m),m+=A.dist(g),addVertex(t.layoutVertexArray,A.x,A.y,E.x,E.y,0,0,m),addVertex(t.layoutVertexArray,A.x,A.y,E.x,E.y,0,1,m);var v=u.vertexLength;t.elementArray.emplaceBack(v,v+1,v+2),t.elementArray.emplaceBack(v+1,v+2,v+3),u.vertexLength+=4,u.primitiveLength+=2}}p.push(g.x),p.push(g.y)}}}for(var _=earcut(p,s),T=0;T<_.length;T+=3)t.elementArray.emplaceBack(c[_[T]],c[_[T+1]],c[_[T+2]]);u.primitiveLength+=_.length/3}t.populatePaintArrays(e.properties)},t}(Bucket);FillExtrusionBucket.programInterface=fillExtrusionInterface,module.exports=FillExtrusionBucket;
  101 +},{"../../util/classify_rings":197,"../bucket":44,"../element_array_type":52,"../extent":53,"../load_geometry":55,"earcut":5}],48:[function(_dereq_,module,exports){
  102 +"use strict";function addLineVertex(e,t,r,i,a,n,d){e.emplaceBack(t.x<<1|i,t.y<<1|a,Math.round(EXTRUDE_SCALE*r.x)+128,Math.round(EXTRUDE_SCALE*r.y)+128,(0===n?0:n<0?-1:1)+1|(d*LINE_DISTANCE_SCALE&63)<<2,d*LINE_DISTANCE_SCALE>>6)}var Bucket=_dereq_("../bucket"),createElementArrayType=_dereq_("../element_array_type"),loadGeometry=_dereq_("../load_geometry"),EXTENT=_dereq_("../extent"),VectorTileFeature=_dereq_("vector-tile").VectorTileFeature,EXTRUDE_SCALE=63,COS_HALF_SHARP_CORNER=Math.cos(37.5*(Math.PI/180)),SHARP_CORNER_OFFSET=15,LINE_DISTANCE_BUFFER_BITS=15,LINE_DISTANCE_SCALE=.5,MAX_LINE_DISTANCE=Math.pow(2,LINE_DISTANCE_BUFFER_BITS-1)/LINE_DISTANCE_SCALE,lineInterface={layoutAttributes:[{name:"a_pos",components:2,type:"Int16"},{name:"a_data",components:4,type:"Uint8"}],paintAttributes:[{property:"line-color",type:"Uint8"},{property:"line-blur",multiplier:10,type:"Uint8"},{property:"line-opacity",multiplier:10,type:"Uint8"},{property:"line-gap-width",multiplier:10,type:"Uint8",name:"a_gapwidth"},{property:"line-offset",multiplier:1,type:"Int8"}],elementArrayType:createElementArrayType()},LineBucket=function(e){function t(t){e.call(this,t,lineInterface)}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype.addFeature=function(e){for(var t=this,r=this.layers[0].layout,i=r["line-join"],a=r["line-cap"],n=r["line-miter-limit"],d=r["line-round-limit"],s=0,u=loadGeometry(e,LINE_DISTANCE_BUFFER_BITS);s<u.length;s+=1){var l=u[s];t.addLine(l,e,i,a,n,d)}},t.prototype.addLine=function(e,t,r,i,a,n){for(var d=this,s=t.properties,u="Polygon"===VectorTileFeature.types[t.type],l=e.length;l>=2&&e[l-1].equals(e[l-2]);)l--;for(var o=0;o<l-1&&e[o].equals(e[o+1]);)o++;if(!(l<(u?3:2))){"bevel"===r&&(a=1.05);var p=SHARP_CORNER_OFFSET*(EXTENT/(512*this.overscaling)),c=e[o],_=this.arrays,h=_.prepareSegment(10*l);this.distance=0;var y,m,E,x,C,v,f,A=i,L=u?"butt":i,S=!0;this.e1=this.e2=this.e3=-1,u&&(y=e[l-2],C=c.sub(y)._unit()._perp());for(var V=o;V<l;V++)if(E=u&&V===l-1?e[o+1]:e[V+1],!E||!e[V].equals(E)){C&&(x=C),y&&(m=y),y=e[V],C=E?E.sub(y)._unit()._perp():x,x=x||C;var I=x.add(C);0===I.x&&0===I.y||I._unit();var T=I.x*C.x+I.y*C.y,N=0!==T?1/T:1/0,b=T<COS_HALF_SHARP_CORNER&&m&&E;if(b&&V>o){var R=y.dist(m);if(R>2*p){var g=y.sub(y.sub(m)._mult(p/R)._round());d.distance+=g.dist(m),d.addCurrentVertex(g,d.distance,x.mult(1),0,0,!1,h),m=g}}var F=m&&E,B=F?r:E?A:L;if(F&&"round"===B&&(N<n?B="miter":N<=2&&(B="fakeround")),"miter"===B&&N>a&&(B="bevel"),"bevel"===B&&(N>2&&(B="flipbevel"),N<a&&(B="miter")),m&&(d.distance+=y.dist(m)),"miter"===B)I._mult(N),d.addCurrentVertex(y,d.distance,I,0,0,!1,h);else if("flipbevel"===B){if(N>100)I=C.clone().mult(-1);else{var k=x.x*C.y-x.y*C.x>0?-1:1,D=N*x.add(C).mag()/x.sub(C).mag();I._perp()._mult(D*k)}d.addCurrentVertex(y,d.distance,I,0,0,!1,h),d.addCurrentVertex(y,d.distance,I.mult(-1),0,0,!1,h)}else if("bevel"===B||"fakeround"===B){var P=x.x*C.y-x.y*C.x>0,U=-Math.sqrt(N*N-1);if(P?(f=0,v=U):(v=0,f=U),S||d.addCurrentVertex(y,d.distance,x,v,f,!1,h),"fakeround"===B){for(var q=Math.floor(8*(.5-(T-.5))),M=void 0,O=0;O<q;O++)M=C.mult((O+1)/(q+1))._add(x)._unit(),d.addPieSliceVertex(y,d.distance,M,P,h);d.addPieSliceVertex(y,d.distance,I,P,h);for(var X=q-1;X>=0;X--)M=x.mult((X+1)/(q+1))._add(C)._unit(),d.addPieSliceVertex(y,d.distance,M,P,h)}E&&d.addCurrentVertex(y,d.distance,C,-v,-f,!1,h)}else"butt"===B?(S||d.addCurrentVertex(y,d.distance,x,0,0,!1,h),E&&d.addCurrentVertex(y,d.distance,C,0,0,!1,h)):"square"===B?(S||(d.addCurrentVertex(y,d.distance,x,1,1,!1,h),d.e1=d.e2=-1),E&&d.addCurrentVertex(y,d.distance,C,-1,-1,!1,h)):"round"===B&&(S||(d.addCurrentVertex(y,d.distance,x,0,0,!1,h),d.addCurrentVertex(y,d.distance,x,1,1,!0,h),d.e1=d.e2=-1),E&&(d.addCurrentVertex(y,d.distance,C,-1,-1,!0,h),d.addCurrentVertex(y,d.distance,C,0,0,!1,h)));if(b&&V<l-1){var H=y.dist(E);if(H>2*p){var w=y.add(E.sub(y)._mult(p/H)._round());d.distance+=w.dist(y),d.addCurrentVertex(w,d.distance,C.mult(1),0,0,!1,h),y=w}}S=!1}_.populatePaintArrays(s)}},t.prototype.addCurrentVertex=function(e,t,r,i,a,n,d){var s,u=n?1:0,l=this.arrays,o=l.layoutVertexArray,p=l.elementArray;s=r.clone(),i&&s._sub(r.perp()._mult(i)),addLineVertex(o,e,s,u,0,i,t),this.e3=d.vertexLength++,this.e1>=0&&this.e2>=0&&(p.emplaceBack(this.e1,this.e2,this.e3),d.primitiveLength++),this.e1=this.e2,this.e2=this.e3,s=r.mult(-1),a&&s._sub(r.perp()._mult(a)),addLineVertex(o,e,s,u,1,-a,t),this.e3=d.vertexLength++,this.e1>=0&&this.e2>=0&&(p.emplaceBack(this.e1,this.e2,this.e3),d.primitiveLength++),this.e1=this.e2,this.e2=this.e3,t>MAX_LINE_DISTANCE/2&&(this.distance=0,this.addCurrentVertex(e,this.distance,r,i,a,n,d))},t.prototype.addPieSliceVertex=function(e,t,r,i,a){var n=i?1:0;r=r.mult(i?-1:1);var d=this.arrays,s=d.layoutVertexArray,u=d.elementArray;addLineVertex(s,e,r,0,n,0,t),this.e3=a.vertexLength++,this.e1>=0&&this.e2>=0&&(u.emplaceBack(this.e1,this.e2,this.e3),a.primitiveLength++),i?this.e2=this.e3:this.e1=this.e3},t}(Bucket);LineBucket.programInterface=lineInterface,module.exports=LineBucket;
  103 +},{"../bucket":44,"../element_array_type":52,"../extent":53,"../load_geometry":55,"vector-tile":33}],49:[function(_dereq_,module,exports){
  104 +"use strict";function addVertex(e,t,o,a,i,r,n,s,l,c,y,u,p,h){e.emplaceBack(t,o,Math.round(64*a),Math.round(64*i),r,n,s,l,packUint8ToFloat(10*(p||0),h%256),packUint8ToFloat(10*(y||0),10*Math.min(u||25,25)),c?c[0]:void 0,c?c[1]:void 0,c?c[2]:void 0)}function addCollisionBoxVertex(e,t,o,a,i,r){return e.emplaceBack(t.x,t.y,o.x,o.y,Math.round(a.x),Math.round(a.y),10*i,10*r)}function getSizeData(e,t,o){var a={isFeatureConstant:t.isLayoutValueFeatureConstant(o),isZoomConstant:t.isLayoutValueZoomConstant(o)};if(a.isFeatureConstant&&(a.layoutSize=t.getLayoutValue(o,{zoom:e+1})),!a.isZoomConstant){for(var i=t.getLayoutValueStopZoomLevels(o),r=0;r<i.length&&i[r]<=e;)r++;r=Math.max(0,r-1);for(var n=r;n<i.length&&i[n]<e+1;)n++;n=Math.min(i.length-1,n),a.coveringZoomRange=[i[r],i[n]],t.isLayoutValueFeatureConstant(o)&&(a.coveringStopValues=[t.getLayoutValue(o,{zoom:i[r]}),t.getLayoutValue(o,{zoom:i[n]})]),a.functionBase=t.getLayoutProperty(o).base,"undefined"==typeof a.functionBase&&(a.functionBase=1),a.functionType=t.getLayoutProperty(o).type||"exponential"}return a}function getSizeAttributeDeclarations(e,t){return e.isLayoutValueZoomConstant(t)&&!e.isLayoutValueFeatureConstant(t)?[{name:"a_size",components:1,type:"Uint16"}]:e.isLayoutValueZoomConstant(t)||e.isLayoutValueFeatureConstant(t)?[]:[{name:"a_size",components:3,type:"Uint16"}]}function getSizeVertexData(e,t,o,a,i){return e.isLayoutValueZoomConstant(a)&&!e.isLayoutValueFeatureConstant(a)?[10*e.getLayoutValue(a,{},i)]:e.isLayoutValueZoomConstant(a)||e.isLayoutValueFeatureConstant(a)?null:[10*e.getLayoutValue(a,{zoom:o[0]},i),10*e.getLayoutValue(a,{zoom:o[1]},i),10*e.getLayoutValue(a,{zoom:1+t},i)]}var Point=_dereq_("point-geometry"),ArrayGroup=_dereq_("../array_group"),BufferGroup=_dereq_("../buffer_group"),createElementArrayType=_dereq_("../element_array_type"),EXTENT=_dereq_("../extent"),packUint8ToFloat=_dereq_("../../shaders/encode_attribute").packUint8ToFloat,Anchor=_dereq_("../../symbol/anchor"),getAnchors=_dereq_("../../symbol/get_anchors"),resolveTokens=_dereq_("../../util/token"),Quads=_dereq_("../../symbol/quads"),Shaping=_dereq_("../../symbol/shaping"),transformText=_dereq_("../../symbol/transform_text"),mergeLines=_dereq_("../../symbol/mergelines"),clipLine=_dereq_("../../symbol/clip_line"),util=_dereq_("../../util/util"),scriptDetection=_dereq_("../../util/script_detection"),loadGeometry=_dereq_("../load_geometry"),CollisionFeature=_dereq_("../../symbol/collision_feature"),findPoleOfInaccessibility=_dereq_("../../util/find_pole_of_inaccessibility"),classifyRings=_dereq_("../../util/classify_rings"),VectorTileFeature=_dereq_("vector-tile").VectorTileFeature,shapeText=Shaping.shapeText,shapeIcon=Shaping.shapeIcon,WritingMode=Shaping.WritingMode,getGlyphQuads=Quads.getGlyphQuads,getIconQuads=Quads.getIconQuads,elementArrayType=createElementArrayType(),layoutAttributes=[{name:"a_pos_offset",components:4,type:"Int16"},{name:"a_label_pos",components:2,type:"Int16"},{name:"a_data",components:4,type:"Uint16"}],symbolInterfaces={glyph:{layoutAttributes:layoutAttributes,elementArrayType:elementArrayType,paintAttributes:[{name:"a_fill_color",property:"text-color",type:"Uint8"},{name:"a_halo_color",property:"text-halo-color",type:"Uint8"},{name:"a_halo_width",property:"text-halo-width",type:"Uint16",multiplier:10},{name:"a_halo_blur",property:"text-halo-blur",type:"Uint16",multiplier:10},{name:"a_opacity",property:"text-opacity",type:"Uint8",multiplier:255}]},icon:{layoutAttributes:layoutAttributes,elementArrayType:elementArrayType,paintAttributes:[{name:"a_fill_color",property:"icon-color",type:"Uint8"},{name:"a_halo_color",property:"icon-halo-color",type:"Uint8"},{name:"a_halo_width",property:"icon-halo-width",type:"Uint16",multiplier:10},{name:"a_halo_blur",property:"icon-halo-blur",type:"Uint16",multiplier:10},{name:"a_opacity",property:"icon-opacity",type:"Uint8",multiplier:255}]},collisionBox:{layoutAttributes:[{name:"a_pos",components:2,type:"Int16"},{name:"a_anchor_pos",components:2,type:"Int16"},{name:"a_extrude",components:2,type:"Int16"},{name:"a_data",components:2,type:"Uint8"}],elementArrayType:createElementArrayType(2)}},SymbolBucket=function(e){var t=this;this.collisionBoxArray=e.collisionBoxArray,this.zoom=e.zoom,this.overscaling=e.overscaling,this.layers=e.layers,this.index=e.index,this.sdfIcons=e.sdfIcons,this.iconsNeedLinear=e.iconsNeedLinear,this.fontstack=e.fontstack;var o=this.layers[0];if(this.symbolInterfaces={glyph:util.extend({},symbolInterfaces.glyph,{layoutAttributes:[].concat(symbolInterfaces.glyph.layoutAttributes,getSizeAttributeDeclarations(o,"text-size"))}),icon:util.extend({},symbolInterfaces.icon,{layoutAttributes:[].concat(symbolInterfaces.icon.layoutAttributes,getSizeAttributeDeclarations(o,"icon-size"))}),collisionBox:util.extend({},symbolInterfaces.collisionBox,{layoutAttributes:[].concat(symbolInterfaces.collisionBox.layoutAttributes)})},e.arrays){this.buffers={};for(var a in e.arrays)e.arrays[a]&&(t.buffers[a]=new BufferGroup(t.symbolInterfaces[a],e.layers,e.zoom,e.arrays[a]));this.textSizeData=e.textSizeData,this.iconSizeData=e.iconSizeData}else this.textSizeData=getSizeData(this.zoom,o,"text-size"),this.iconSizeData=getSizeData(this.zoom,o,"icon-size")};SymbolBucket.prototype.populate=function(e,t){var o=this,a=this.layers[0],i=a.layout,r=i["text-font"],n=(!a.isLayoutValueFeatureConstant("text-field")||i["text-field"])&&r,s=!a.isLayoutValueFeatureConstant("icon-image")||i["icon-image"];if(this.features=[],n||s){for(var l=t.iconDependencies,c=t.glyphDependencies,y=c[r]=c[r]||{},u={zoom:this.zoom},p=0;p<e.length;p++){var h=e[p];if(a.filter(h)){var m=void 0;n&&(m=a.getLayoutValue("text-field",u,h.properties),a.isLayoutValueFeatureConstant("text-field")&&(m=resolveTokens(h.properties,m)),m=transformText(m,a,u,h.properties));var x=void 0;if(s&&(x=a.getLayoutValue("icon-image",u,h.properties),a.isLayoutValueFeatureConstant("icon-image")&&(x=resolveTokens(h.properties,x))),(m||x)&&(o.features.push({text:m,icon:x,index:p,sourceLayerIndex:h.sourceLayerIndex,geometry:loadGeometry(h),properties:h.properties,type:VectorTileFeature.types[h.type]}),x&&(l[x]=!0),m))for(var d=0;d<m.length;d++)y[m.charCodeAt(d)]=!0}}"line"===i["symbol-placement"]&&(this.features=mergeLines(this.features))}},SymbolBucket.prototype.isEmpty=function(){return this.arrays.icon.isEmpty()&&this.arrays.glyph.isEmpty()&&this.arrays.collisionBox.isEmpty()},SymbolBucket.prototype.getPaintPropertyStatistics=function(){for(var e=this,t={},o=0,a=e.layers;o<a.length;o+=1){var i=a[o];t[i.id]=util.extend({},e.arrays.icon.layerData[i.id].paintPropertyStatistics,e.arrays.glyph.layerData[i.id].paintPropertyStatistics)}return t},SymbolBucket.prototype.serialize=function(e){return{zoom:this.zoom,layerIds:this.layers.map(function(e){return e.id}),sdfIcons:this.sdfIcons,iconsNeedLinear:this.iconsNeedLinear,textSizeData:this.textSizeData,iconSizeData:this.iconSizeData,fontstack:this.fontstack,arrays:util.mapObject(this.arrays,function(t){return t.isEmpty()?null:t.serialize(e)})}},SymbolBucket.prototype.destroy=function(){this.buffers&&(this.buffers.icon&&this.buffers.icon.destroy(),this.buffers.glyph&&this.buffers.glyph.destroy(),this.buffers.collisionBox&&this.buffers.collisionBox.destroy(),this.buffers=null)},SymbolBucket.prototype.createArrays=function(){var e=this;this.arrays=util.mapObject(this.symbolInterfaces,function(t){return new ArrayGroup(t,e.layers,e.zoom)})},SymbolBucket.prototype.prepare=function(e,t){var o=this;this.symbolInstances=[];var a=512*this.overscaling;this.tilePixelRatio=EXTENT/a,this.compareText={},this.iconsNeedLinear=!1;var i=this.layers[0].layout,r=.5,n=.5;switch(i["text-anchor"]){case"right":case"top-right":case"bottom-right":r=1;break;case"left":case"top-left":case"bottom-left":r=0}switch(i["text-anchor"]){case"bottom":case"bottom-right":case"bottom-left":n=1;break;case"top":case"top-right":case"top-left":n=0}for(var s="right"===i["text-justify"]?1:"left"===i["text-justify"]?0:.5,l=24,c=i["text-line-height"]*l,y="line"!==i["symbol-placement"]?i["text-max-width"]*l:0,u=i["text-letter-spacing"]*l,p=this.fontstack=i["text-font"].join(","),h="map"===i["text-rotation-alignment"]&&"line"===i["symbol-placement"],m=0,x=o.features;m<x.length;m+=1){var d=x[m],g=void 0;if(d.text){var f=scriptDetection.allowsVerticalWritingMode(d.text),b=o.layers[0].getLayoutValue("text-offset",{zoom:o.zoom},d.properties).map(function(e){return e*l}),v=scriptDetection.allowsLetterSpacing(d.text)?u:0;g={},g[WritingMode.horizontal]=shapeText(d.text,e[p],y,c,r,n,s,v,b,l,WritingMode.horizontal),g[WritingMode.vertical]=f&&h&&shapeText(d.text,e[p],y,c,r,n,s,v,b,l,WritingMode.vertical)}else g={};var S=void 0;if(d.icon){var I=t[d.icon];I&&(S=shapeIcon(I,o.layers[0].getLayoutValue("icon-offset",{zoom:o.zoom},d.properties)),void 0===o.sdfIcons?o.sdfIcons=I.sdf:o.sdfIcons!==I.sdf&&util.warnOnce("Style sheet warning: Cannot mix SDF and non-SDF icons in one buffer"),I.isNativePixelRatio?0===i["icon-rotate"]&&o.layers[0].isLayoutValueFeatureConstant("icon-rotate")||(o.iconsNeedLinear=!0):o.iconsNeedLinear=!0)}(g[WritingMode.horizontal]||S)&&o.addFeature(d,g,S)}},SymbolBucket.prototype.addFeature=function(e,t,o){var a=this,i=this.layers[0].getLayoutValue("text-size",{zoom:this.zoom+1},e.properties),r=this.layers[0].getLayoutValue("icon-size",{zoom:this.zoom+1},e.properties),n=this.layers[0].getLayoutValue("text-size",{zoom:18},e.properties);void 0===n&&(n=i);var s=this.layers[0].layout,l=24,c=i/l,y=this.tilePixelRatio*c,u=this.tilePixelRatio*n/l,p=this.tilePixelRatio*r,h=this.tilePixelRatio*s["symbol-spacing"],m=s["symbol-avoid-edges"],x=s["text-padding"]*this.tilePixelRatio,d=s["icon-padding"]*this.tilePixelRatio,g=s["text-max-angle"]/180*Math.PI,f="map"===s["text-rotation-alignment"]&&"line"===s["symbol-placement"],b="map"===s["icon-rotation-alignment"]&&"line"===s["symbol-placement"],v=s["text-allow-overlap"]||s["icon-allow-overlap"]||s["text-ignore-placement"]||s["icon-ignore-placement"],S=s["symbol-placement"],I=h/2,z=function(i,r){var n=!(r.x<0||r.x>EXTENT||r.y<0||r.y>EXTENT);if(!m||n){var s=n||v;a.addSymbolInstance(r,i,t,o,a.layers[0],s,a.collisionBoxArray,e.index,e.sourceLayerIndex,a.index,y,x,f,p,d,b,{zoom:a.zoom},e.properties)}};if("line"===S)for(var B=0,M=clipLine(e.geometry,0,0,EXTENT,EXTENT);B<M.length;B+=1)for(var L=M[B],A=getAnchors(L,h,g,t[WritingMode.vertical]||t[WritingMode.horizontal],o,l,u,a.overscaling,EXTENT),_=0,T=A;_<T.length;_+=1){var V=T[_],k=t[WritingMode.horizontal];k&&a.anchorIsTooClose(k.text,I,V)||z(L,V)}else if("Polygon"===e.type)for(var C=0,P=classifyRings(e.geometry,0);C<P.length;C+=1){var E=P[C],w=findPoleOfInaccessibility(E,16);z(E[0],new Anchor(w.x,w.y,0))}else if("LineString"===e.type)for(var F=0,D=e.geometry;F<D.length;F+=1){var N=D[F];z(N,new Anchor(N[0].x,N[0].y,0))}else if("Point"===e.type)for(var q=0,U=e.geometry;q<U.length;q+=1)for(var W=U[q],R=0,Q=W;R<Q.length;R+=1){var Z=Q[R];z([Z],new Anchor(Z.x,Z.y,0))}},SymbolBucket.prototype.anchorIsTooClose=function(e,t,o){var a=this.compareText;if(e in a){for(var i=a[e],r=i.length-1;r>=0;r--)if(o.dist(i[r])<t)return!0}else a[e]=[];return a[e].push(o),!1},SymbolBucket.prototype.place=function(e,t){var o=this;this.createArrays();var a=this.layers[0],i=a.layout,r=e.maxScale,n="map"===i["text-rotation-alignment"]&&"line"===i["symbol-placement"],s="map"===i["icon-rotation-alignment"]&&"line"===i["symbol-placement"],l=i["text-allow-overlap"]||i["icon-allow-overlap"]||i["text-ignore-placement"]||i["icon-ignore-placement"];if(l){var c=e.angle,y=Math.sin(c),u=Math.cos(c);this.symbolInstances.sort(function(e,t){var o=y*e.anchor.x+u*e.anchor.y|0,a=y*t.anchor.x+u*t.anchor.y|0;return o-a||t.featureIndex-e.featureIndex})}for(var p=0,h=o.symbolInstances;p<h.length;p+=1){var m=h[p],x={boxStartIndex:m.textBoxStartIndex,boxEndIndex:m.textBoxEndIndex},d={boxStartIndex:m.iconBoxStartIndex,boxEndIndex:m.iconBoxEndIndex},g=!(m.textBoxStartIndex===m.textBoxEndIndex),f=!(m.iconBoxStartIndex===m.iconBoxEndIndex),b=i["text-optional"]||!g,v=i["icon-optional"]||!f,S=g?e.placeCollisionFeature(x,i["text-allow-overlap"],i["symbol-avoid-edges"]):e.minScale,I=f?e.placeCollisionFeature(d,i["icon-allow-overlap"],i["symbol-avoid-edges"]):e.minScale;if(b||v?!v&&S?S=Math.max(I,S):!b&&I&&(I=Math.max(I,S)):I=S=Math.max(I,S),g&&(e.insertCollisionFeature(x,S,i["text-ignore-placement"]),S<=r)){var z=getSizeVertexData(a,o.zoom,o.textSizeData.coveringZoomRange,"text-size",m.featureProperties);o.addSymbols(o.arrays.glyph,m.glyphQuads,S,z,i["text-keep-upright"],n,e.angle,m.featureProperties,m.writingModes,m.anchor)}if(f&&(e.insertCollisionFeature(d,I,i["icon-ignore-placement"]),I<=r)){var B=getSizeVertexData(a,o.zoom,o.iconSizeData.coveringZoomRange,"icon-size",m.featureProperties);o.addSymbols(o.arrays.icon,m.iconQuads,I,B,i["icon-keep-upright"],s,e.angle,m.featureProperties,null,m.anchor)}}t&&this.addToDebugBuffers(e)},SymbolBucket.prototype.addSymbols=function(e,t,o,a,i,r,n,s,l,c){for(var y=e.elementArray,u=e.layoutVertexArray,p=this.zoom,h=Math.max(Math.log(o)/Math.LN2+p,0),m=0,x=t;m<x.length;m+=1){var d=x[m],g=(d.anchorAngle+n+Math.PI)%(2*Math.PI);if(l&WritingMode.vertical){if(r&&d.writingMode===WritingMode.vertical){if(i&&r&&g<=5*Math.PI/4||g>7*Math.PI/4)continue}else if(i&&r&&g<=3*Math.PI/4||g>5*Math.PI/4)continue}else if(i&&r&&(g<=Math.PI/2||g>3*Math.PI/2))continue;var f=d.tl,b=d.tr,v=d.bl,S=d.br,I=d.tex,z=d.anchorPoint,B=Math.max(p+Math.log(d.minScale)/Math.LN2,h),M=Math.min(p+Math.log(d.maxScale)/Math.LN2,25);if(!(M<=B)){B===h&&(B=0);var L=Math.round(d.glyphAngle/(2*Math.PI)*256),A=e.prepareSegment(4),_=A.vertexLength;addVertex(u,z.x,z.y,f.x,f.y,c.x,c.y,I.x,I.y,a,B,M,h,L),addVertex(u,z.x,z.y,b.x,b.y,c.x,c.y,I.x+I.w,I.y,a,B,M,h,L),addVertex(u,z.x,z.y,v.x,v.y,c.x,c.y,I.x,I.y+I.h,a,B,M,h,L),addVertex(u,z.x,z.y,S.x,S.y,c.x,c.y,I.x+I.w,I.y+I.h,a,B,M,h,L),y.emplaceBack(_,_+1,_+2),y.emplaceBack(_+1,_+2,_+3),A.vertexLength+=4,A.primitiveLength+=2}}e.populatePaintArrays(s)},SymbolBucket.prototype.addToDebugBuffers=function(e){for(var t=this,o=this.arrays.collisionBox,a=o.layoutVertexArray,i=o.elementArray,r=-e.angle,n=e.yStretch,s=0,l=t.symbolInstances;s<l.length;s+=1){var c=l[s];c.textCollisionFeature={boxStartIndex:c.textBoxStartIndex,boxEndIndex:c.textBoxEndIndex},c.iconCollisionFeature={boxStartIndex:c.iconBoxStartIndex,boxEndIndex:c.iconBoxEndIndex};for(var y=0;y<2;y++){var u=c[0===y?"textCollisionFeature":"iconCollisionFeature"];if(u)for(var p=u.boxStartIndex;p<u.boxEndIndex;p++){var h=t.collisionBoxArray.get(p);if(!(1===e.perspectiveRatio&&h.maxScale<1)){var m=h.anchorPoint,x=new Point(h.x1,h.y1*n)._rotate(r),d=new Point(h.x2,h.y1*n)._rotate(r),g=new Point(h.x1,h.y2*n)._rotate(r),f=new Point(h.x2,h.y2*n)._rotate(r),b=Math.max(0,Math.min(25,t.zoom+Math.log(h.maxScale)/Math.LN2)),v=Math.max(0,Math.min(25,t.zoom+Math.log(h.placementScale)/Math.LN2)),S=o.prepareSegment(4),I=S.vertexLength;addCollisionBoxVertex(a,m,c.anchor,x,b,v),addCollisionBoxVertex(a,m,c.anchor,d,b,v),addCollisionBoxVertex(a,m,c.anchor,f,b,v),addCollisionBoxVertex(a,m,c.anchor,g,b,v),i.emplaceBack(I,I+1),i.emplaceBack(I+1,I+2),i.emplaceBack(I+2,I+3),i.emplaceBack(I+3,I),S.vertexLength+=4,S.primitiveLength+=4}}}}},SymbolBucket.prototype.addSymbolInstance=function(e,t,o,a,i,r,n,s,l,c,y,u,p,h,m,x,d,g){var f,b,v=[],S=[];for(var I in o){var z=parseInt(I,10);o[z]&&(S=S.concat(r?getGlyphQuads(e,o[z],y,t,i,p,d,g):[]),f=new CollisionFeature(n,t,e,s,l,c,o[z],y,u,p,!1))}var B=f?f.boxStartIndex:this.collisionBoxArray.length,M=f?f.boxEndIndex:this.collisionBoxArray.length;a&&(v=r?getIconQuads(e,a,h,t,i,x,o[WritingMode.horizontal],d,g):[],b=new CollisionFeature(n,t,e,s,l,c,a,h,m,x,!0));var L=b?b.boxStartIndex:this.collisionBoxArray.length,A=b?b.boxEndIndex:this.collisionBoxArray.length;M>SymbolBucket.MAX_INSTANCES&&util.warnOnce("Too many symbols being rendered in a tile. See https://github.com/mapbox/mapbox-gl-js/issues/2907"),A>SymbolBucket.MAX_INSTANCES&&util.warnOnce("Too many glyphs being rendered in a tile. See https://github.com/mapbox/mapbox-gl-js/issues/2907");var _=(o[WritingMode.vertical]?WritingMode.vertical:0)|(o[WritingMode.horizontal]?WritingMode.horizontal:0);this.symbolInstances.push({textBoxStartIndex:B,textBoxEndIndex:M,iconBoxStartIndex:L,iconBoxEndIndex:A,glyphQuads:S,iconQuads:v,anchor:e,featureIndex:s,featureProperties:g,writingModes:_})},SymbolBucket.programInterfaces=symbolInterfaces,SymbolBucket.MAX_INSTANCES=65535,module.exports=SymbolBucket;
  105 +},{"../../shaders/encode_attribute":80,"../../symbol/anchor":159,"../../symbol/clip_line":161,"../../symbol/collision_feature":163,"../../symbol/get_anchors":165,"../../symbol/mergelines":168,"../../symbol/quads":169,"../../symbol/shaping":170,"../../symbol/transform_text":172,"../../util/classify_rings":197,"../../util/find_pole_of_inaccessibility":203,"../../util/script_detection":210,"../../util/token":214,"../../util/util":215,"../array_group":43,"../buffer_group":51,"../element_array_type":52,"../extent":53,"../load_geometry":55,"point-geometry":25,"vector-tile":33}],50:[function(_dereq_,module,exports){
  106 +"use strict";var AttributeType={Int8:"BYTE",Uint8:"UNSIGNED_BYTE",Int16:"SHORT",Uint16:"UNSIGNED_SHORT"},Buffer=function(t,e,r){this.arrayBuffer=t.arrayBuffer,this.length=t.length,this.attributes=e.members,this.itemSize=e.bytesPerElement,this.type=r,this.arrayType=e};Buffer.fromStructArray=function(t,e){return new Buffer(t.serialize(),t.constructor.serialize(),e)},Buffer.prototype.bind=function(t){var e=t[this.type];this.buffer?t.bindBuffer(e,this.buffer):(this.gl=t,this.buffer=t.createBuffer(),t.bindBuffer(e,this.buffer),t.bufferData(e,this.arrayBuffer,t.STATIC_DRAW),this.arrayBuffer=null)},Buffer.prototype.enableAttributes=function(t,e){for(var r=this,f=0;f<this.attributes.length;f++){var i=r.attributes[f],u=e[i.name];void 0!==u&&t.enableVertexAttribArray(u)}},Buffer.prototype.setVertexAttribPointers=function(t,e,r){for(var f=this,i=0;i<this.attributes.length;i++){var u=f.attributes[i],s=e[u.name];void 0!==s&&t.vertexAttribPointer(s,u.components,t[AttributeType[u.type]],!1,f.arrayType.bytesPerElement,u.offset+(f.arrayType.bytesPerElement*r||0))}},Buffer.prototype.destroy=function(){this.buffer&&this.gl.deleteBuffer(this.buffer)},Buffer.BufferType={VERTEX:"ARRAY_BUFFER",ELEMENT:"ELEMENT_ARRAY_BUFFER"},module.exports=Buffer;
  107 +},{}],51:[function(_dereq_,module,exports){
  108 +"use strict";var util=_dereq_("../util/util"),Buffer=_dereq_("./buffer"),ProgramConfiguration=_dereq_("./program_configuration"),createVertexArrayType=_dereq_("./vertex_array_type"),VertexArrayObject=_dereq_("../render/vertex_array_object"),BufferGroup=function(e,r,t,a){var f=this,u=createVertexArrayType(e.layoutAttributes);this.layoutVertexBuffer=new Buffer(a.layoutVertexArray,u.serialize(),Buffer.BufferType.VERTEX),a.elementArray&&(this.elementBuffer=new Buffer(a.elementArray,e.elementArrayType.serialize(),Buffer.BufferType.ELEMENT)),a.elementArray2&&(this.elementBuffer2=new Buffer(a.elementArray2,e.elementArrayType2.serialize(),Buffer.BufferType.ELEMENT)),this.layerData={};for(var n=0,i=r;n<i.length;n+=1){var s=i[n],o=a.paintVertexArrays&&a.paintVertexArrays[s.id],y=ProgramConfiguration.createDynamic(e,s,t),l=o?new Buffer(o.array,o.type,Buffer.BufferType.VERTEX):null;f.layerData[s.id]={programConfiguration:y,paintVertexBuffer:l}}this.segments=a.segments,this.segments2=a.segments2;for(var m=0,B=[f.segments,f.segments2];m<B.length;m+=1)for(var p=B[m],g=0,v=p||[];g<v.length;g+=1){var h=v[g];h.vaos=util.mapObject(f.layerData,function(){return new VertexArrayObject})}};BufferGroup.prototype.destroy=function(){var e=this;this.layoutVertexBuffer.destroy(),this.elementBuffer&&this.elementBuffer.destroy(),this.elementBuffer2&&this.elementBuffer2.destroy();for(var r in e.layerData){var t=e.layerData[r].paintVertexBuffer;t&&t.destroy()}for(var a=0,f=[e.segments,e.segments2];a<f.length;a+=1)for(var u=f[a],n=0,i=u||[];n<i.length;n+=1){var s=i[n];for(var o in s.vaos)s.vaos[o].destroy()}},module.exports=BufferGroup;
  109 +},{"../render/vertex_array_object":79,"../util/util":215,"./buffer":50,"./program_configuration":57,"./vertex_array_type":59}],52:[function(_dereq_,module,exports){
  110 +"use strict";function createElementArrayType(e){return createStructArrayType({members:[{type:"Uint16",name:"vertices",components:e||3}]})}var createStructArrayType=_dereq_("../util/struct_array");module.exports=createElementArrayType;
  111 +},{"../util/struct_array":212}],53:[function(_dereq_,module,exports){
  112 +"use strict";module.exports=8192;
  113 +},{}],54:[function(_dereq_,module,exports){
  114 +"use strict";function translateDistance(e){return Math.sqrt(e[0]*e[0]+e[1]*e[1])}function topDownFeatureComparator(e,t){return t-e}function getLineWidth(e,t){return t>0?t+2*e:e}function translate(e,t,r,i,a){if(!t[0]&&!t[1])return e;t=Point.convert(t),"viewport"===r&&t._rotate(-i);for(var n=[],s=0;s<e.length;s++){for(var o=e[s],l=[],u=0;u<o.length;u++)l.push(o[u].sub(t._mult(a)));n.push(l)}return n}function offsetLine(e,t){for(var r=[],i=new Point(0,0),a=0;a<e.length;a++){for(var n=e[a],s=[],o=0;o<n.length;o++){var l=n[o-1],u=n[o],c=n[o+1],y=0===o?i:u.sub(l)._unit()._perp(),f=o===n.length-1?i:c.sub(u)._unit()._perp(),h=y._add(f)._unit(),d=h.x*f.x+h.y*f.y;h._mult(1/d),s.push(h._mult(t)._add(u))}r.push(s)}return r}var Point=_dereq_("point-geometry"),loadGeometry=_dereq_("./load_geometry"),EXTENT=_dereq_("./extent"),featureFilter=_dereq_("../style-spec/feature_filter"),createStructArrayType=_dereq_("../util/struct_array"),Grid=_dereq_("grid-index"),DictionaryCoder=_dereq_("../util/dictionary_coder"),vt=_dereq_("vector-tile"),Protobuf=_dereq_("pbf"),GeoJSONFeature=_dereq_("../util/vectortile_to_geojson"),arraysIntersect=_dereq_("../util/util").arraysIntersect,intersection=_dereq_("../util/intersection_tests"),multiPolygonIntersectsBufferedMultiPoint=intersection.multiPolygonIntersectsBufferedMultiPoint,multiPolygonIntersectsMultiPolygon=intersection.multiPolygonIntersectsMultiPolygon,multiPolygonIntersectsBufferedMultiLine=intersection.multiPolygonIntersectsBufferedMultiLine,FeatureIndexArray=createStructArrayType({members:[{type:"Uint32",name:"featureIndex"},{type:"Uint16",name:"sourceLayerIndex"},{type:"Uint16",name:"bucketIndex"}]}),FeatureIndex=function(e,t,r){if(e.grid){var i=e,a=t;e=i.coord,t=i.overscaling,this.grid=new Grid(i.grid),this.featureIndexArray=new FeatureIndexArray(i.featureIndexArray),this.rawTileData=a,this.bucketLayerIDs=i.bucketLayerIDs,this.paintPropertyStatistics=i.paintPropertyStatistics}else this.grid=new Grid(EXTENT,16,0),this.featureIndexArray=new FeatureIndexArray;this.coord=e,this.overscaling=t,this.x=e.x,this.y=e.y,this.z=e.z-Math.log(t)/Math.LN2,this.setCollisionTile(r)};FeatureIndex.prototype.insert=function(e,t){var r=this,i=this.featureIndexArray.length;this.featureIndexArray.emplaceBack(e.index,e.sourceLayerIndex,t);for(var a=loadGeometry(e),n=0;n<a.length;n++){for(var s=a[n],o=[1/0,1/0,-(1/0),-(1/0)],l=0;l<s.length;l++){var u=s[l];o[0]=Math.min(o[0],u.x),o[1]=Math.min(o[1],u.y),o[2]=Math.max(o[2],u.x),o[3]=Math.max(o[3],u.y)}r.grid.insert(i,o[0],o[1],o[2],o[3])}},FeatureIndex.prototype.setCollisionTile=function(e){this.collisionTile=e},FeatureIndex.prototype.serialize=function(e){var t=this.grid.toArrayBuffer();return e&&e.push(t),{coord:this.coord,overscaling:this.overscaling,grid:t,featureIndexArray:this.featureIndexArray.serialize(e),bucketLayerIDs:this.bucketLayerIDs,paintPropertyStatistics:this.paintPropertyStatistics}},FeatureIndex.prototype.query=function(e,t){var r=this;this.vtLayers||(this.vtLayers=new vt.VectorTile(new Protobuf(this.rawTileData)).layers,this.sourceLayerCoder=new DictionaryCoder(this.vtLayers?Object.keys(this.vtLayers).sort():["_geojsonTileLayer"]));var i={},a=e.params||{},n=EXTENT/e.tileSize/e.scale,s=featureFilter(a.filter),o=0;for(var l in t)if(r.hasLayer(l)){var u=t[l],c=0;if("line"===u.type){var y=getLineWidth(r.getPaintValue("line-width",u),r.getPaintValue("line-gap-width",u)),f=r.getPaintValue("line-offset",u),h=r.getPaintValue("line-translate",u);c=y/2+Math.abs(f)+translateDistance(h)}else"fill"===u.type?c=translateDistance(r.getPaintValue("fill-translate",u)):"fill-extrusion"===u.type?c=translateDistance(r.getPaintValue("fill-extrusion-translate",u)):"circle"===u.type&&(c=r.getPaintValue("circle-radius",u)+translateDistance(r.getPaintValue("circle-translate",u)));o=Math.max(o,c*n)}for(var d=e.queryGeometry.map(function(e){return e.map(function(e){return new Point(e.x,e.y)})}),g=1/0,p=1/0,v=-(1/0),x=-(1/0),I=0;I<d.length;I++)for(var P=d[I],m=0;m<P.length;m++){var L=P[m];g=Math.min(g,L.x),p=Math.min(p,L.y),v=Math.max(v,L.x),x=Math.max(x,L.y)}var M=this.grid.query(g-o,p-o,v+o,x+o);M.sort(topDownFeatureComparator),this.filterMatching(i,M,this.featureIndexArray,d,s,a.layers,t,e.bearing,n);var b=this.collisionTile.queryRenderedSymbols(d,e.scale);return b.sort(),this.filterMatching(i,b,this.collisionTile.collisionBoxArray,d,s,a.layers,t,e.bearing,n),i},FeatureIndex.prototype.filterMatching=function(e,t,r,i,a,n,s,o,l){for(var u,c=this,y=0;y<t.length;y++){var f=t[y];if(f!==u){u=f;var h=r.get(f),d=c.bucketLayerIDs[h.bucketIndex];if(!n||arraysIntersect(n,d)){var g=c.sourceLayerCoder.decode(h.sourceLayerIndex),p=c.vtLayers[g],v=p.feature(h.featureIndex);if(a(v))for(var x=null,I=0;I<d.length;I++){var P=d[I];if(!(n&&n.indexOf(P)<0)){var m=s[P];if(m){var L=void 0;if("symbol"!==m.type)if(x||(x=loadGeometry(v)),"line"===m.type){L=translate(i,c.getPaintValue("line-translate",m,v),c.getPaintValue("line-translate-anchor",m,v),o,l);var M=l/2*getLineWidth(c.getPaintValue("line-width",m,v),c.getPaintValue("line-gap-width",m,v)),b=c.getPaintValue("line-offset",m,v);if(b&&(x=offsetLine(x,b*l)),!multiPolygonIntersectsBufferedMultiLine(L,x,M))continue}else if("fill"===m.type||"fill-extrusion"===m.type){var V=m.type;if(L=translate(i,c.getPaintValue(V+"-translate",m,v),c.getPaintValue(V+"-translate-anchor",m,v),o,l),!multiPolygonIntersectsMultiPolygon(L,x))continue}else if("circle"===m.type){L=translate(i,c.getPaintValue("circle-translate",m,v),c.getPaintValue("circle-translate-anchor",m,v),o,l);var w=c.getPaintValue("circle-radius",m,v)*l;if(!multiPolygonIntersectsBufferedMultiPoint(L,x,w))continue}var F=new GeoJSONFeature(v,c.z,c.x,c.y);F.layer=m.serialize();var _=e[P];void 0===_&&(_=e[P]=[]),_.push({featureIndex:f,feature:F})}}}}}}},FeatureIndex.prototype.hasLayer=function(e){var t=this;for(var r in t.bucketLayerIDs)for(var i=0,a=t.bucketLayerIDs[r];i<a.length;i+=1){var n=a[i];if(e===n)return!0}return!1},FeatureIndex.prototype.getPaintValue=function(e,t,r){var i=t.isPaintValueFeatureConstant(e);if(i||r){var a=r?r.properties:{};return t.getPaintValue(e,{zoom:this.z},a)}return this.paintPropertyStatistics[t.id][e].max},module.exports=FeatureIndex;
  115 +},{"../style-spec/feature_filter":104,"../util/dictionary_coder":199,"../util/intersection_tests":206,"../util/struct_array":212,"../util/util":215,"../util/vectortile_to_geojson":216,"./extent":53,"./load_geometry":55,"grid-index":16,"pbf":24,"point-geometry":25,"vector-tile":33}],55:[function(_dereq_,module,exports){
  116 +"use strict";function createBounds(e){return{min:-1*Math.pow(2,e-1),max:Math.pow(2,e-1)-1}}var util=_dereq_("../util/util"),EXTENT=_dereq_("./extent"),boundsLookup={15:createBounds(15),16:createBounds(16)};module.exports=function(e,t){for(var r=boundsLookup[t||16],o=EXTENT/e.extent,u=e.loadGeometry(),n=0;n<u.length;n++)for(var a=u[n],i=0;i<a.length;i++){var d=a[i];d.x=Math.round(d.x*o),d.y=Math.round(d.y*o),(d.x<r.min||d.x>r.max||d.y<r.min||d.y>r.max)&&util.warnOnce("Geometry exceeds allowed extent, reduce your vector tile buffer size")}return u};
  117 +},{"../util/util":215,"./extent":53}],56:[function(_dereq_,module,exports){
  118 +"use strict";var createStructArrayType=_dereq_("../util/struct_array"),PosArray=createStructArrayType({members:[{name:"a_pos",type:"Int16",components:2}]});module.exports=PosArray;
  119 +},{"../util/struct_array":212}],57:[function(_dereq_,module,exports){
  120 +"use strict";function getPaintAttributeValue(t,r,e,i){if(!t.zoomStops)return r.getPaintValue(t.property,e,i);var a=t.zoomStops.map(function(a){return r.getPaintValue(t.property,util.extend({},e,{zoom:a}),i)});return 1===a.length?a[0]:a}function normalizePaintAttribute(t,r){var e=t.name;e||(e=t.property.replace(r.type+"-","").replace(/-/g,"_"));var i="color"===r._paintSpecifications[t.property].type;return util.extend({name:"a_"+e,components:i?4:1,multiplier:i?255:1,dimensions:i?4:1},t)}var createVertexArrayType=_dereq_("./vertex_array_type"),util=_dereq_("../util/util"),ProgramConfiguration=function(){this.attributes=[],this.uniforms=[],this.interpolationUniforms=[],this.pragmas={vertex:{},fragment:{}},this.cacheKey="",this.interface={}};ProgramConfiguration.createDynamic=function(t,r,e){for(var i=new ProgramConfiguration,a=0,n=t.paintAttributes||[];a<n.length;a+=1){var o=n[a],p=normalizePaintAttribute(o,r),u=p.name.slice(2);r.isPaintValueFeatureConstant(p.property)?i.addZoomAttribute(u,p):r.isPaintValueZoomConstant(p.property)?i.addPropertyAttribute(u,p):i.addZoomAndPropertyAttribute(u,p,r,e)}return i.PaintVertexArray=createVertexArrayType(i.attributes),i.interface=t,i},ProgramConfiguration.createStatic=function(t){for(var r=new ProgramConfiguration,e=0,i=t;e<i.length;e+=1){var a=i[e];r.addUniform(a,"u_"+a)}return r},ProgramConfiguration.prototype.addUniform=function(t,r){var e=this.getPragmas(t);e.define.push("uniform {precision} {type} "+r+";"),e.initialize.push("{precision} {type} "+t+" = "+r+";"),this.cacheKey+="/u_"+t},ProgramConfiguration.prototype.addZoomAttribute=function(t,r){this.uniforms.push(r),this.addUniform(t,r.name)},ProgramConfiguration.prototype.addPropertyAttribute=function(t,r){var e=this.getPragmas(t);this.attributes.push(r),e.define.push("varying {precision} {type} "+t+";"),e.vertex.define.push("attribute {precision} {type} "+r.name+";"),e.vertex.initialize.push(t+" = "+r.name+" / "+r.multiplier+".0;"),this.cacheKey+="/a_"+t},ProgramConfiguration.prototype.addZoomAndPropertyAttribute=function(t,r,e,i){var a=this,n=this.getPragmas(t);n.define.push("varying {precision} {type} "+t+";");var o=e.getPaintValueStopZoomLevels(r.property),p=0;if(o.length>4)for(;p<o.length-2&&o[p]<i;)p++;var u="u_"+t+"_t";n.vertex.define.push("uniform lowp float "+u+";"),this.interpolationUniforms.push({name:u,property:r.property,stopOffset:p});for(var s=[],m=0;m<4;m++)s.push(o[Math.min(p+m,o.length-1)]);var f=[];if(1===r.components)this.attributes.push(util.extend({},r,{components:4,zoomStops:s})),n.vertex.define.push("attribute {precision} vec4 "+r.name+";"),f.push(r.name);else for(var g=0;g<4;g++){var h=r.name+g;f.push(h),a.attributes.push(util.extend({},r,{name:h,zoomStops:[s[g]]})),n.vertex.define.push("attribute {precision} {type} "+h+";")}n.vertex.initialize.push(t+" = evaluate_zoom_function_"+r.components+"( "+f.join(", ")+", "+u+") / "+r.multiplier+".0;"),this.cacheKey+="/z_"+t},ProgramConfiguration.prototype.getPragmas=function(t){return this.pragmas[t]||(this.pragmas[t]={define:[],initialize:[]},this.pragmas[t].fragment={define:[],initialize:[]},this.pragmas[t].vertex={define:[],initialize:[]}),this.pragmas[t]},ProgramConfiguration.prototype.applyPragmas=function(t,r){var e=this;return t.replace(/#pragma mapbox: ([\w]+) ([\w]+) ([\w]+) ([\w]+)/g,function(t,i,a,n,o){return e.pragmas[o][i].concat(e.pragmas[o][r][i]).join("\n").replace(/{type}/g,n).replace(/{precision}/g,a)})},ProgramConfiguration.prototype.createPaintPropertyStatistics=function(){for(var t=this,r={},e=0,i=t.attributes;e<i.length;e+=1){var a=i[e];1===a.dimensions&&(r[a.property]={max:-(1/0)})}return r},ProgramConfiguration.prototype.populatePaintArray=function(t,r,e,i,a,n){var o=this,p=r.length;r.resize(i);for(var u=0,s=o.attributes;u<s.length;u+=1)for(var m=s[u],f=getPaintAttributeValue(m,t,a,n),g=p;g<i;g++){var h=r.get(g);if(4===m.components)for(var l=0;l<4;l++)h[m.name+l]=f[l]*m.multiplier;else h[m.name]=f*m.multiplier;if(1===m.dimensions){var c=e[m.property];c.max=Math.max(c.max,1===m.components?f:Math.max.apply(Math,f))}}},ProgramConfiguration.prototype.setUniforms=function(t,r,e,i){for(var a=this,n=0,o=a.uniforms;n<o.length;n+=1){var p=o[n],u=e.getPaintValue(p.property,i);4===p.components?t.uniform4fv(r[p.name],u):t.uniform1f(r[p.name],u)}for(var s=0,m=a.interpolationUniforms;s<m.length;s+=1){var f=m[s],g=e.getPaintInterpolationT(f.property,i);t.uniform1f(r[f.name],Math.max(0,Math.min(3,g-f.stopOffset)))}},module.exports=ProgramConfiguration;
  121 +},{"../util/util":215,"./vertex_array_type":59}],58:[function(_dereq_,module,exports){
  122 +"use strict";var createStructArrayType=_dereq_("../util/struct_array"),RasterBoundsArray=createStructArrayType({members:[{name:"a_pos",type:"Int16",components:2},{name:"a_texture_pos",type:"Int16",components:2}]});module.exports=RasterBoundsArray;
  123 +},{"../util/struct_array":212}],59:[function(_dereq_,module,exports){
  124 +"use strict";function createVertexArrayType(r){return createStructArrayType({members:r,alignment:4})}var createStructArrayType=_dereq_("../util/struct_array");module.exports=createVertexArrayType;
  125 +},{"../util/struct_array":212}],60:[function(_dereq_,module,exports){
  126 +"use strict";var Coordinate=function(o,t,n){this.column=o,this.row=t,this.zoom=n};Coordinate.prototype.clone=function(){return new Coordinate(this.column,this.row,this.zoom)},Coordinate.prototype.zoomTo=function(o){return this.clone()._zoomTo(o)},Coordinate.prototype.sub=function(o){return this.clone()._sub(o)},Coordinate.prototype._zoomTo=function(o){var t=Math.pow(2,o-this.zoom);return this.column*=t,this.row*=t,this.zoom=o,this},Coordinate.prototype._sub=function(o){return o=o.zoomTo(this.zoom),this.column-=o.column,this.row-=o.row,this},module.exports=Coordinate;
  127 +},{}],61:[function(_dereq_,module,exports){
  128 +"use strict";var wrap=_dereq_("../util/util").wrap,LngLat=function(t,n){if(isNaN(t)||isNaN(n))throw new Error("Invalid LngLat object: ("+t+", "+n+")");if(this.lng=+t,this.lat=+n,this.lat>90||this.lat<-90)throw new Error("Invalid LngLat latitude value: must be between -90 and 90")};LngLat.prototype.wrap=function(){return new LngLat(wrap(this.lng,-180,180),this.lat)},LngLat.prototype.toArray=function(){return[this.lng,this.lat]},LngLat.prototype.toString=function(){return"LngLat("+this.lng+", "+this.lat+")"},LngLat.convert=function(t){if(t instanceof LngLat)return t;if(Array.isArray(t)&&2===t.length)return new LngLat(Number(t[0]),Number(t[1]));if(!Array.isArray(t)&&"object"==typeof t&&null!==t)return new LngLat(Number(t.lng),Number(t.lat));throw new Error("`LngLatLike` argument must be specified as a LngLat instance, an object {lng: <lng>, lat: <lat>}, or an array of [<lng>, <lat>]")},module.exports=LngLat;
  129 +},{"../util/util":215}],62:[function(_dereq_,module,exports){
  130 +"use strict";var LngLat=_dereq_("./lng_lat"),LngLatBounds=function(t,n){t&&(n?this.setSouthWest(t).setNorthEast(n):4===t.length?this.setSouthWest([t[0],t[1]]).setNorthEast([t[2],t[3]]):this.setSouthWest(t[0]).setNorthEast(t[1]))};LngLatBounds.prototype.setNorthEast=function(t){return this._ne=t instanceof LngLat?new LngLat(t.lng,t.lat):LngLat.convert(t),this},LngLatBounds.prototype.setSouthWest=function(t){return this._sw=t instanceof LngLat?new LngLat(t.lng,t.lat):LngLat.convert(t),this},LngLatBounds.prototype.extend=function(t){var n,e,s=this._sw,o=this._ne;if(t instanceof LngLat)n=t,e=t;else{if(!(t instanceof LngLatBounds))return Array.isArray(t)?t.every(Array.isArray)?this.extend(LngLatBounds.convert(t)):this.extend(LngLat.convert(t)):this;if(n=t._sw,e=t._ne,!n||!e)return this}return s||o?(s.lng=Math.min(n.lng,s.lng),s.lat=Math.min(n.lat,s.lat),o.lng=Math.max(e.lng,o.lng),o.lat=Math.max(e.lat,o.lat)):(this._sw=new LngLat(n.lng,n.lat),this._ne=new LngLat(e.lng,e.lat)),this},LngLatBounds.prototype.getCenter=function(){return new LngLat((this._sw.lng+this._ne.lng)/2,(this._sw.lat+this._ne.lat)/2)},LngLatBounds.prototype.getSouthWest=function(){return this._sw},LngLatBounds.prototype.getNorthEast=function(){return this._ne},LngLatBounds.prototype.getNorthWest=function(){return new LngLat(this.getWest(),this.getNorth())},LngLatBounds.prototype.getSouthEast=function(){return new LngLat(this.getEast(),this.getSouth())},LngLatBounds.prototype.getWest=function(){return this._sw.lng},LngLatBounds.prototype.getSouth=function(){return this._sw.lat},LngLatBounds.prototype.getEast=function(){return this._ne.lng},LngLatBounds.prototype.getNorth=function(){return this._ne.lat},LngLatBounds.prototype.toArray=function(){return[this._sw.toArray(),this._ne.toArray()]},LngLatBounds.prototype.toString=function(){return"LngLatBounds("+this._sw.toString()+", "+this._ne.toString()+")"},LngLatBounds.convert=function(t){return!t||t instanceof LngLatBounds?t:new LngLatBounds(t)},module.exports=LngLatBounds;
  131 +},{"./lng_lat":61}],63:[function(_dereq_,module,exports){
  132 +"use strict";var LngLat=_dereq_("./lng_lat"),Point=_dereq_("point-geometry"),Coordinate=_dereq_("./coordinate"),util=_dereq_("../util/util"),interp=_dereq_("../style-spec/util/interpolate"),TileCoord=_dereq_("../source/tile_coord"),EXTENT=_dereq_("../data/extent"),glmatrix=_dereq_("@mapbox/gl-matrix"),vec4=glmatrix.vec4,mat4=glmatrix.mat4,mat2=glmatrix.mat2,Transform=function(t,o,i){this.tileSize=512,this._renderWorldCopies=void 0===i||i,this._minZoom=t||0,this._maxZoom=o||22,this.latRange=[-85.05113,85.05113],this.width=0,this.height=0,this._center=new LngLat(0,0),this.zoom=0,this.angle=0,this._fov=.6435011087932844,this._pitch=0,this._unmodified=!0},prototypeAccessors={minZoom:{},maxZoom:{},renderWorldCopies:{},worldSize:{},centerPoint:{},size:{},bearing:{},pitch:{},fov:{},zoom:{},center:{},unmodified:{},x:{},y:{},point:{}};prototypeAccessors.minZoom.get=function(){return this._minZoom},prototypeAccessors.minZoom.set=function(t){this._minZoom!==t&&(this._minZoom=t,this.zoom=Math.max(this.zoom,t))},prototypeAccessors.maxZoom.get=function(){return this._maxZoom},prototypeAccessors.maxZoom.set=function(t){this._maxZoom!==t&&(this._maxZoom=t,this.zoom=Math.min(this.zoom,t))},prototypeAccessors.renderWorldCopies.get=function(){return this._renderWorldCopies},prototypeAccessors.worldSize.get=function(){return this.tileSize*this.scale},prototypeAccessors.centerPoint.get=function(){return this.size._div(2)},prototypeAccessors.size.get=function(){return new Point(this.width,this.height)},prototypeAccessors.bearing.get=function(){return-this.angle/Math.PI*180},prototypeAccessors.bearing.set=function(t){var o=-util.wrap(t,-180,180)*Math.PI/180;this.angle!==o&&(this._unmodified=!1,this.angle=o,this._calcMatrices(),this.rotationMatrix=mat2.create(),mat2.rotate(this.rotationMatrix,this.rotationMatrix,this.angle))},prototypeAccessors.pitch.get=function(){return this._pitch/Math.PI*180},prototypeAccessors.pitch.set=function(t){var o=util.clamp(t,0,60)/180*Math.PI;this._pitch!==o&&(this._unmodified=!1,this._pitch=o,this._calcMatrices())},prototypeAccessors.fov.get=function(){return this._fov/Math.PI*180},prototypeAccessors.fov.set=function(t){t=Math.max(.01,Math.min(60,t)),this._fov!==t&&(this._unmodified=!1,this._fov=t/180*Math.PI,this._calcMatrices())},prototypeAccessors.zoom.get=function(){return this._zoom},prototypeAccessors.zoom.set=function(t){var o=Math.min(Math.max(t,this.minZoom),this.maxZoom);this._zoom!==o&&(this._unmodified=!1,this._zoom=o,this.scale=this.zoomScale(o),this.tileZoom=Math.floor(o),this.zoomFraction=o-this.tileZoom,this._constrain(),this._calcMatrices())},prototypeAccessors.center.get=function(){return this._center},prototypeAccessors.center.set=function(t){t.lat===this._center.lat&&t.lng===this._center.lng||(this._unmodified=!1,this._center=t,this._constrain(),this._calcMatrices())},Transform.prototype.coveringZoomLevel=function(t){return(t.roundZoom?Math.round:Math.floor)(this.zoom+this.scaleZoom(this.tileSize/t.tileSize))},Transform.prototype.getVisibleWrappedCoordinates=function(t){for(var o=this.pointCoordinate(new Point(0,0),0),i=this.pointCoordinate(new Point(this.width,0),0),e=Math.floor(o.column),r=Math.floor(i.column),n=[t],s=e;s<=r;s++)0!==s&&n.push(new TileCoord(t.z,t.x,t.y,s));return n},Transform.prototype.coveringTiles=function(t){var o=this.coveringZoomLevel(t),i=o;if(o<t.minzoom)return[];o>t.maxzoom&&(o=t.maxzoom);var e=this.pointCoordinate(this.centerPoint,o),r=new Point(e.column-.5,e.row-.5),n=[this.pointCoordinate(new Point(0,0),o),this.pointCoordinate(new Point(this.width,0),o),this.pointCoordinate(new Point(this.width,this.height),o),this.pointCoordinate(new Point(0,this.height),o)];return TileCoord.cover(o,n,t.reparseOverscaled?i:o,this._renderWorldCopies).sort(function(t,o){return r.dist(t)-r.dist(o)})},Transform.prototype.resize=function(t,o){this.width=t,this.height=o,this.pixelsToGLUnits=[2/t,-2/o],this._constrain(),this._calcMatrices()},prototypeAccessors.unmodified.get=function(){return this._unmodified},Transform.prototype.zoomScale=function(t){return Math.pow(2,t)},Transform.prototype.scaleZoom=function(t){return Math.log(t)/Math.LN2},Transform.prototype.project=function(t){return new Point(this.lngX(t.lng),this.latY(t.lat))},Transform.prototype.unproject=function(t){return new LngLat(this.xLng(t.x),this.yLat(t.y))},prototypeAccessors.x.get=function(){return this.lngX(this.center.lng)},prototypeAccessors.y.get=function(){return this.latY(this.center.lat)},prototypeAccessors.point.get=function(){return new Point(this.x,this.y)},Transform.prototype.lngX=function(t){return(180+t)*this.worldSize/360},Transform.prototype.latY=function(t){var o=180/Math.PI*Math.log(Math.tan(Math.PI/4+t*Math.PI/360));return(180-o)*this.worldSize/360},Transform.prototype.xLng=function(t){return 360*t/this.worldSize-180},Transform.prototype.yLat=function(t){var o=180-360*t/this.worldSize;return 360/Math.PI*Math.atan(Math.exp(o*Math.PI/180))-90},Transform.prototype.setLocationAtPoint=function(t,o){var i=this.pointCoordinate(o)._sub(this.pointCoordinate(this.centerPoint));this.center=this.coordinateLocation(this.locationCoordinate(t)._sub(i)),this._renderWorldCopies&&(this.center=this.center.wrap())},Transform.prototype.locationPoint=function(t){return this.coordinatePoint(this.locationCoordinate(t))},Transform.prototype.pointLocation=function(t){return this.coordinateLocation(this.pointCoordinate(t))},Transform.prototype.locationCoordinate=function(t){return new Coordinate(this.lngX(t.lng)/this.tileSize,this.latY(t.lat)/this.tileSize,this.zoom).zoomTo(this.tileZoom)},Transform.prototype.coordinateLocation=function(t){var o=t.zoomTo(this.zoom);return new LngLat(this.xLng(o.column*this.tileSize),this.yLat(o.row*this.tileSize))},Transform.prototype.pointCoordinate=function(t,o){void 0===o&&(o=this.tileZoom);var i=0,e=[t.x,t.y,0,1],r=[t.x,t.y,1,1];vec4.transformMat4(e,e,this.pixelMatrixInverse),vec4.transformMat4(r,r,this.pixelMatrixInverse);var n=e[3],s=r[3],a=e[0]/n,h=r[0]/s,c=e[1]/n,m=r[1]/s,p=e[2]/n,l=r[2]/s,u=p===l?0:(i-p)/(l-p);return new Coordinate(interp(a,h,u)/this.tileSize,interp(c,m,u)/this.tileSize,this.zoom)._zoomTo(o)},Transform.prototype.coordinatePoint=function(t){var o=t.zoomTo(this.zoom),i=[o.column*this.tileSize,o.row*this.tileSize,0,1];return vec4.transformMat4(i,i,this.pixelMatrix),new Point(i[0]/i[3],i[1]/i[3])},Transform.prototype.calculatePosMatrix=function(t,o){var i=t.toCoordinate(o),e=this.worldSize/this.zoomScale(i.zoom),r=mat4.identity(new Float64Array(16));return mat4.translate(r,r,[i.column*e,i.row*e,0]),mat4.scale(r,r,[e/EXTENT,e/EXTENT,1]),mat4.multiply(r,this.projMatrix,r),new Float32Array(r)},Transform.prototype.cameraToTileDistance=function(t){var o=this.calculatePosMatrix(t.coord,t.sourceMaxZoom),i=[t.tileSize/2,t.tileSize/2,0,1];return vec4.transformMat4(i,i,o),i[3]},Transform.prototype._constrain=function(){if(this.center&&this.width&&this.height&&!this._constraining){this._constraining=!0;var t,o,i,e,r=-90,n=90,s=-180,a=180,h=this.size,c=this._unmodified;if(this.latRange){var m=this.latRange;r=this.latY(m[1]),n=this.latY(m[0]),t=n-r<h.y?h.y/(n-r):0}if(this.lngRange){var p=this.lngRange;s=this.lngX(p[0]),a=this.lngX(p[1]),o=a-s<h.x?h.x/(a-s):0}var l=Math.max(o||0,t||0);if(l)return this.center=this.unproject(new Point(o?(a+s)/2:this.x,t?(n+r)/2:this.y)),this.zoom+=this.scaleZoom(l),this._unmodified=c,void(this._constraining=!1);if(this.latRange){var u=this.y,f=h.y/2;u-f<r&&(e=r+f),u+f>n&&(e=n-f)}if(this.lngRange){var d=this.x,g=h.x/2;d-g<s&&(i=s+g),d+g>a&&(i=a-g)}void 0===i&&void 0===e||(this.center=this.unproject(new Point(void 0!==i?i:this.x,void 0!==e?e:this.y))),this._unmodified=c,this._constraining=!1}},Transform.prototype._calcMatrices=function(){if(this.height){this.cameraToCenterDistance=.5/Math.tan(this._fov/2)*this.height;var t=this._fov/2,o=Math.PI/2+this._pitch,i=Math.sin(t)*this.cameraToCenterDistance/Math.sin(Math.PI-o-t),e=Math.cos(Math.PI/2-this._pitch)*i+this.cameraToCenterDistance,r=1.01*e,n=new Float64Array(16);mat4.perspective(n,this._fov,this.width/this.height,1,r),mat4.scale(n,n,[1,-1,1]),mat4.translate(n,n,[0,0,-this.cameraToCenterDistance]),mat4.rotateX(n,n,this._pitch),mat4.rotateZ(n,n,this.angle),mat4.translate(n,n,[-this.x,-this.y,0]);var s=this.worldSize/(2*Math.PI*6378137*Math.abs(Math.cos(this.center.lat*(Math.PI/180))));if(mat4.scale(n,n,[1,1,s,1]),this.projMatrix=n,n=mat4.create(),mat4.scale(n,n,[this.width/2,-this.height/2,1]),mat4.translate(n,n,[1,-1,0]),this.pixelMatrix=mat4.multiply(new Float64Array(16),n,this.projMatrix),n=mat4.invert(new Float64Array(16),this.pixelMatrix),!n)throw new Error("failed to invert matrix");this.pixelMatrixInverse=n}},Object.defineProperties(Transform.prototype,prototypeAccessors),module.exports=Transform;
  133 +},{"../data/extent":53,"../source/tile_coord":95,"../style-spec/util/interpolate":122,"../util/util":215,"./coordinate":60,"./lng_lat":61,"@mapbox/gl-matrix":1,"point-geometry":25}],64:[function(_dereq_,module,exports){
  134 +"use strict";var browser=_dereq_("./util/browser"),mapboxgl=module.exports={};mapboxgl.version=_dereq_("../package.json").version,mapboxgl.workerCount=Math.max(Math.floor(browser.hardwareConcurrency/2),1),mapboxgl.Map=_dereq_("./ui/map"),mapboxgl.NavigationControl=_dereq_("./ui/control/navigation_control"),mapboxgl.GeolocateControl=_dereq_("./ui/control/geolocate_control"),mapboxgl.AttributionControl=_dereq_("./ui/control/attribution_control"),mapboxgl.ScaleControl=_dereq_("./ui/control/scale_control"),mapboxgl.FullscreenControl=_dereq_("./ui/control/fullscreen_control"),mapboxgl.Popup=_dereq_("./ui/popup"),mapboxgl.Marker=_dereq_("./ui/marker"),mapboxgl.Style=_dereq_("./style/style"),mapboxgl.LngLat=_dereq_("./geo/lng_lat"),mapboxgl.LngLatBounds=_dereq_("./geo/lng_lat_bounds"),mapboxgl.Point=_dereq_("point-geometry"),mapboxgl.Evented=_dereq_("./util/evented"),mapboxgl.supported=_dereq_("./util/browser").supported;var config=_dereq_("./util/config");mapboxgl.config=config;var rtlTextPlugin=_dereq_("./source/rtl_text_plugin");mapboxgl.setRTLTextPlugin=rtlTextPlugin.setRTLTextPlugin,Object.defineProperty(mapboxgl,"accessToken",{get:function(){return config.ACCESS_TOKEN},set:function(o){config.ACCESS_TOKEN=o}});
  135 +},{"../package.json":42,"./geo/lng_lat":61,"./geo/lng_lat_bounds":62,"./source/rtl_text_plugin":90,"./style/style":148,"./ui/control/attribution_control":175,"./ui/control/fullscreen_control":176,"./ui/control/geolocate_control":177,"./ui/control/navigation_control":179,"./ui/control/scale_control":180,"./ui/map":189,"./ui/marker":190,"./ui/popup":191,"./util/browser":194,"./util/config":198,"./util/evented":202,"point-geometry":25}],65:[function(_dereq_,module,exports){
  136 +"use strict";function drawBackground(r,t,e){var a=r.gl,i=r.transform,n=i.tileSize,o=e.paint["background-color"],l=e.paint["background-pattern"],u=e.paint["background-opacity"],f=!l&&1===o[3]&&1===u;if(r.isOpaquePass===f){a.disable(a.STENCIL_TEST),r.setDepthSublayer(0);var s;if(l){if(pattern.isPatternMissing(l,r))return;s=r.useProgram("fillPattern",r.basicFillProgramConfiguration),pattern.prepare(l,r,s),r.tileExtentPatternVAO.bind(a,s,r.tileExtentBuffer)}else s=r.useProgram("fill",r.basicFillProgramConfiguration),a.uniform4fv(s.u_color,o),r.tileExtentVAO.bind(a,s,r.tileExtentBuffer);a.uniform1f(s.u_opacity,u);for(var c=i.coveringTiles({tileSize:n}),g=0,p=c;g<p.length;g+=1){var d=p[g];l&&pattern.setTile({coord:d,tileSize:n},r,s),a.uniformMatrix4fv(s.u_matrix,!1,r.transform.calculatePosMatrix(d)),a.drawArrays(a.TRIANGLE_STRIP,0,r.tileExtentBuffer.length)}}}var pattern=_dereq_("./pattern");module.exports=drawBackground;
  137 +},{"./pattern":77}],66:[function(_dereq_,module,exports){
  138 +"use strict";function drawCircles(e,r,t,a){if(!e.isOpaquePass){var i=e.gl;e.setDepthSublayer(0),e.depthMask(!1),i.disable(i.STENCIL_TEST);for(var s=0;s<a.length;s++){var o=a[s],n=r.getTile(o),f=n.getBucket(t);if(f){var l=f.buffers,m=l.layerData[t.id],u=m.programConfiguration,c=e.useProgram("circle",u);u.setUniforms(i,c,t,{zoom:e.transform.zoom}),"map"===t.paint["circle-pitch-scale"]?(i.uniform1i(c.u_scale_with_map,!0),i.uniform2f(c.u_extrude_scale,e.transform.pixelsToGLUnits[0]*e.transform.cameraToCenterDistance,e.transform.pixelsToGLUnits[1]*e.transform.cameraToCenterDistance)):(i.uniform1i(c.u_scale_with_map,!1),i.uniform2fv(c.u_extrude_scale,e.transform.pixelsToGLUnits)),i.uniform1f(c.u_devicepixelratio,browser.devicePixelRatio),i.uniformMatrix4fv(c.u_matrix,!1,e.translatePosMatrix(o.posMatrix,n,t.paint["circle-translate"],t.paint["circle-translate-anchor"]));for(var p=0,v=l.segments;p<v.length;p+=1){var x=v[p];x.vaos[t.id].bind(i,c,l.layoutVertexBuffer,l.elementBuffer,m.paintVertexBuffer,x.vertexOffset),i.drawElements(i.TRIANGLES,3*x.primitiveLength,i.UNSIGNED_SHORT,3*x.primitiveOffset*2)}}}}}var browser=_dereq_("../util/browser");module.exports=drawCircles;
  139 +},{"../util/browser":194}],67:[function(_dereq_,module,exports){
  140 +"use strict";function drawCollisionDebug(e,r,i,o){var t=e.gl;t.enable(t.STENCIL_TEST);var a=e.useProgram("collisionBox");t.activeTexture(t.TEXTURE1),e.frameHistory.bind(t),t.uniform1i(a.u_fadetexture,1);for(var n=0;n<o.length;n++){var f=o[n],l=r.getTile(f),m=l.getBucket(i);if(m){var u=m.buffers.collisionBox;if(u){t.uniformMatrix4fv(a.u_matrix,!1,f.posMatrix),e.enableTileClippingMask(f),e.lineWidth(1),t.uniform1f(a.u_scale,Math.pow(2,e.transform.zoom-l.coord.z)),t.uniform1f(a.u_zoom,10*e.transform.zoom);var s=Math.max(0,Math.min(25,l.coord.z+Math.log(l.collisionTile.maxScale)/Math.LN2));t.uniform1f(a.u_maxzoom,10*s),t.uniform1f(a.u_collision_y_stretch,l.collisionTile.yStretch),t.uniform1f(a.u_pitch,e.transform.pitch/360*2*Math.PI),t.uniform1f(a.u_camera_to_center_distance,e.transform.cameraToCenterDistance);for(var c=0,_=u.segments;c<_.length;c+=1){var h=_[c];h.vaos[i.id].bind(t,a,u.layoutVertexBuffer,u.elementBuffer,null,h.vertexOffset),t.drawElements(t.LINES,2*h.primitiveLength,t.UNSIGNED_SHORT,2*h.primitiveOffset*2)}}}}}module.exports=drawCollisionDebug;
  141 +},{}],68:[function(_dereq_,module,exports){
  142 +"use strict";function drawDebug(r,e,a){for(var t=0;t<a.length;t++)drawDebugTile(r,e,a[t])}function drawDebugTile(r,e,a){var t=r.gl;t.disable(t.STENCIL_TEST),r.lineWidth(1*browser.devicePixelRatio);var i=a.posMatrix,u=r.useProgram("debug");t.uniformMatrix4fv(u.u_matrix,!1,i),t.uniform4f(u.u_color,1,0,0,1),r.debugVAO.bind(t,u,r.debugBuffer),t.drawArrays(t.LINE_STRIP,0,r.debugBuffer.length);for(var o=createTextVerticies(a.toString(),50,200,5),f=new PosArray,n=0;n<o.length;n+=2)f.emplaceBack(o[n],o[n+1]);var l=Buffer.fromStructArray(f,Buffer.BufferType.VERTEX),m=new VertexArrayObject;m.bind(t,u,l),t.uniform4f(u.u_color,1,1,1,1);for(var s=e.getTile(a).tileSize,g=EXTENT/(Math.pow(2,r.transform.zoom-a.z)*s),x=[[-1,-1],[-1,1],[1,-1],[1,1]],d=0;d<x.length;d++){var b=x[d];t.uniformMatrix4fv(u.u_matrix,!1,mat4.translate([],i,[g*b[0],g*b[1],0])),t.drawArrays(t.LINES,0,l.length)}t.uniform4f(u.u_color,0,0,0,1),t.uniformMatrix4fv(u.u_matrix,!1,i),t.drawArrays(t.LINES,0,l.length)}function createTextVerticies(r,e,a,t){t=t||1;var i,u,o,f,n,l,m,s,g=[];for(i=0,u=r.length;i<u;i++)if(n=simplexFont[r[i]]){for(s=null,o=0,f=n[1].length;o<f;o+=2)n[1][o]===-1&&n[1][o+1]===-1?s=null:(l=e+n[1][o]*t,m=a-n[1][o+1]*t,s&&g.push(s.x,s.y,l,m),s={x:l,y:m});e+=n[0]*t}return g}var browser=_dereq_("../util/browser"),mat4=_dereq_("@mapbox/gl-matrix").mat4,EXTENT=_dereq_("../data/extent"),Buffer=_dereq_("../data/buffer"),VertexArrayObject=_dereq_("./vertex_array_object"),PosArray=_dereq_("../data/pos_array");module.exports=drawDebug;var simplexFont={" ":[16,[]],"!":[10,[5,21,5,7,-1,-1,5,2,4,1,5,0,6,1,5,2]],'"':[16,[4,21,4,14,-1,-1,12,21,12,14]],"#":[21,[11,25,4,-7,-1,-1,17,25,10,-7,-1,-1,4,12,18,12,-1,-1,3,6,17,6]],$:[20,[8,25,8,-4,-1,-1,12,25,12,-4,-1,-1,17,18,15,20,12,21,8,21,5,20,3,18,3,16,4,14,5,13,7,12,13,10,15,9,16,8,17,6,17,3,15,1,12,0,8,0,5,1,3,3]],"%":[24,[21,21,3,0,-1,-1,8,21,10,19,10,17,9,15,7,14,5,14,3,16,3,18,4,20,6,21,8,21,10,20,13,19,16,19,19,20,21,21,-1,-1,17,7,15,6,14,4,14,2,16,0,18,0,20,1,21,3,21,5,19,7,17,7]],"&":[26,[23,12,23,13,22,14,21,14,20,13,19,11,17,6,15,3,13,1,11,0,7,0,5,1,4,2,3,4,3,6,4,8,5,9,12,13,13,14,14,16,14,18,13,20,11,21,9,20,8,18,8,16,9,13,11,10,16,3,18,1,20,0,22,0,23,1,23,2]],"'":[10,[5,19,4,20,5,21,6,20,6,18,5,16,4,15]],"(":[14,[11,25,9,23,7,20,5,16,4,11,4,7,5,2,7,-2,9,-5,11,-7]],")":[14,[3,25,5,23,7,20,9,16,10,11,10,7,9,2,7,-2,5,-5,3,-7]],"*":[16,[8,21,8,9,-1,-1,3,18,13,12,-1,-1,13,18,3,12]],"+":[26,[13,18,13,0,-1,-1,4,9,22,9]],",":[10,[6,1,5,0,4,1,5,2,6,1,6,-1,5,-3,4,-4]],"-":[26,[4,9,22,9]],".":[10,[5,2,4,1,5,0,6,1,5,2]],"/":[22,[20,25,2,-7]],0:[20,[9,21,6,20,4,17,3,12,3,9,4,4,6,1,9,0,11,0,14,1,16,4,17,9,17,12,16,17,14,20,11,21,9,21]],1:[20,[6,17,8,18,11,21,11,0]],2:[20,[4,16,4,17,5,19,6,20,8,21,12,21,14,20,15,19,16,17,16,15,15,13,13,10,3,0,17,0]],3:[20,[5,21,16,21,10,13,13,13,15,12,16,11,17,8,17,6,16,3,14,1,11,0,8,0,5,1,4,2,3,4]],4:[20,[13,21,3,7,18,7,-1,-1,13,21,13,0]],5:[20,[15,21,5,21,4,12,5,13,8,14,11,14,14,13,16,11,17,8,17,6,16,3,14,1,11,0,8,0,5,1,4,2,3,4]],6:[20,[16,18,15,20,12,21,10,21,7,20,5,17,4,12,4,7,5,3,7,1,10,0,11,0,14,1,16,3,17,6,17,7,16,10,14,12,11,13,10,13,7,12,5,10,4,7]],7:[20,[17,21,7,0,-1,-1,3,21,17,21]],8:[20,[8,21,5,20,4,18,4,16,5,14,7,13,11,12,14,11,16,9,17,7,17,4,16,2,15,1,12,0,8,0,5,1,4,2,3,4,3,7,4,9,6,11,9,12,13,13,15,14,16,16,16,18,15,20,12,21,8,21]],9:[20,[16,14,15,11,13,9,10,8,9,8,6,9,4,11,3,14,3,15,4,18,6,20,9,21,10,21,13,20,15,18,16,14,16,9,15,4,13,1,10,0,8,0,5,1,4,3]],":":[10,[5,14,4,13,5,12,6,13,5,14,-1,-1,5,2,4,1,5,0,6,1,5,2]],";":[10,[5,14,4,13,5,12,6,13,5,14,-1,-1,6,1,5,0,4,1,5,2,6,1,6,-1,5,-3,4,-4]],"<":[24,[20,18,4,9,20,0]],"=":[26,[4,12,22,12,-1,-1,4,6,22,6]],">":[24,[4,18,20,9,4,0]],"?":[18,[3,16,3,17,4,19,5,20,7,21,11,21,13,20,14,19,15,17,15,15,14,13,13,12,9,10,9,7,-1,-1,9,2,8,1,9,0,10,1,9,2]],"@":[27,[18,13,17,15,15,16,12,16,10,15,9,14,8,11,8,8,9,6,11,5,14,5,16,6,17,8,-1,-1,12,16,10,14,9,11,9,8,10,6,11,5,-1,-1,18,16,17,8,17,6,19,5,21,5,23,7,24,10,24,12,23,15,22,17,20,19,18,20,15,21,12,21,9,20,7,19,5,17,4,15,3,12,3,9,4,6,5,4,7,2,9,1,12,0,15,0,18,1,20,2,21,3,-1,-1,19,16,18,8,18,6,19,5]],A:[18,[9,21,1,0,-1,-1,9,21,17,0,-1,-1,4,7,14,7]],B:[21,[4,21,4,0,-1,-1,4,21,13,21,16,20,17,19,18,17,18,15,17,13,16,12,13,11,-1,-1,4,11,13,11,16,10,17,9,18,7,18,4,17,2,16,1,13,0,4,0]],C:[21,[18,16,17,18,15,20,13,21,9,21,7,20,5,18,4,16,3,13,3,8,4,5,5,3,7,1,9,0,13,0,15,1,17,3,18,5]],D:[21,[4,21,4,0,-1,-1,4,21,11,21,14,20,16,18,17,16,18,13,18,8,17,5,16,3,14,1,11,0,4,0]],E:[19,[4,21,4,0,-1,-1,4,21,17,21,-1,-1,4,11,12,11,-1,-1,4,0,17,0]],F:[18,[4,21,4,0,-1,-1,4,21,17,21,-1,-1,4,11,12,11]],G:[21,[18,16,17,18,15,20,13,21,9,21,7,20,5,18,4,16,3,13,3,8,4,5,5,3,7,1,9,0,13,0,15,1,17,3,18,5,18,8,-1,-1,13,8,18,8]],H:[22,[4,21,4,0,-1,-1,18,21,18,0,-1,-1,4,11,18,11]],I:[8,[4,21,4,0]],J:[16,[12,21,12,5,11,2,10,1,8,0,6,0,4,1,3,2,2,5,2,7]],K:[21,[4,21,4,0,-1,-1,18,21,4,7,-1,-1,9,12,18,0]],L:[17,[4,21,4,0,-1,-1,4,0,16,0]],M:[24,[4,21,4,0,-1,-1,4,21,12,0,-1,-1,20,21,12,0,-1,-1,20,21,20,0]],N:[22,[4,21,4,0,-1,-1,4,21,18,0,-1,-1,18,21,18,0]],O:[22,[9,21,7,20,5,18,4,16,3,13,3,8,4,5,5,3,7,1,9,0,13,0,15,1,17,3,18,5,19,8,19,13,18,16,17,18,15,20,13,21,9,21]],P:[21,[4,21,4,0,-1,-1,4,21,13,21,16,20,17,19,18,17,18,14,17,12,16,11,13,10,4,10]],Q:[22,[9,21,7,20,5,18,4,16,3,13,3,8,4,5,5,3,7,1,9,0,13,0,15,1,17,3,18,5,19,8,19,13,18,16,17,18,15,20,13,21,9,21,-1,-1,12,4,18,-2]],R:[21,[4,21,4,0,-1,-1,4,21,13,21,16,20,17,19,18,17,18,15,17,13,16,12,13,11,4,11,-1,-1,11,11,18,0]],S:[20,[17,18,15,20,12,21,8,21,5,20,3,18,3,16,4,14,5,13,7,12,13,10,15,9,16,8,17,6,17,3,15,1,12,0,8,0,5,1,3,3]],T:[16,[8,21,8,0,-1,-1,1,21,15,21]],U:[22,[4,21,4,6,5,3,7,1,10,0,12,0,15,1,17,3,18,6,18,21]],V:[18,[1,21,9,0,-1,-1,17,21,9,0]],W:[24,[2,21,7,0,-1,-1,12,21,7,0,-1,-1,12,21,17,0,-1,-1,22,21,17,0]],X:[20,[3,21,17,0,-1,-1,17,21,3,0]],Y:[18,[1,21,9,11,9,0,-1,-1,17,21,9,11]],Z:[20,[17,21,3,0,-1,-1,3,21,17,21,-1,-1,3,0,17,0]],"[":[14,[4,25,4,-7,-1,-1,5,25,5,-7,-1,-1,4,25,11,25,-1,-1,4,-7,11,-7]],"\\":[14,[0,21,14,-3]],"]":[14,[9,25,9,-7,-1,-1,10,25,10,-7,-1,-1,3,25,10,25,-1,-1,3,-7,10,-7]],"^":[16,[6,15,8,18,10,15,-1,-1,3,12,8,17,13,12,-1,-1,8,17,8,0]],_:[16,[0,-2,16,-2]],"`":[10,[6,21,5,20,4,18,4,16,5,15,6,16,5,17]],a:[19,[15,14,15,0,-1,-1,15,11,13,13,11,14,8,14,6,13,4,11,3,8,3,6,4,3,6,1,8,0,11,0,13,1,15,3]],b:[19,[4,21,4,0,-1,-1,4,11,6,13,8,14,11,14,13,13,15,11,16,8,16,6,15,3,13,1,11,0,8,0,6,1,4,3]],c:[18,[15,11,13,13,11,14,8,14,6,13,4,11,3,8,3,6,4,3,6,1,8,0,11,0,13,1,15,3]],d:[19,[15,21,15,0,-1,-1,15,11,13,13,11,14,8,14,6,13,4,11,3,8,3,6,4,3,6,1,8,0,11,0,13,1,15,3]],e:[18,[3,8,15,8,15,10,14,12,13,13,11,14,8,14,6,13,4,11,3,8,3,6,4,3,6,1,8,0,11,0,13,1,15,3]],f:[12,[10,21,8,21,6,20,5,17,5,0,-1,-1,2,14,9,14]],g:[19,[15,14,15,-2,14,-5,13,-6,11,-7,8,-7,6,-6,-1,-1,15,11,13,13,11,14,8,14,6,13,4,11,3,8,3,6,4,3,6,1,8,0,11,0,13,1,15,3]],h:[19,[4,21,4,0,-1,-1,4,10,7,13,9,14,12,14,14,13,15,10,15,0]],i:[8,[3,21,4,20,5,21,4,22,3,21,-1,-1,4,14,4,0]],j:[10,[5,21,6,20,7,21,6,22,5,21,-1,-1,6,14,6,-3,5,-6,3,-7,1,-7]],k:[17,[4,21,4,0,-1,-1,14,14,4,4,-1,-1,8,8,15,0]],l:[8,[4,21,4,0]],m:[30,[4,14,4,0,-1,-1,4,10,7,13,9,14,12,14,14,13,15,10,15,0,-1,-1,15,10,18,13,20,14,23,14,25,13,26,10,26,0]],n:[19,[4,14,4,0,-1,-1,4,10,7,13,9,14,12,14,14,13,15,10,15,0]],o:[19,[8,14,6,13,4,11,3,8,3,6,4,3,6,1,8,0,11,0,13,1,15,3,16,6,16,8,15,11,13,13,11,14,8,14]],p:[19,[4,14,4,-7,-1,-1,4,11,6,13,8,14,11,14,13,13,15,11,16,8,16,6,15,3,13,1,11,0,8,0,6,1,4,3]],q:[19,[15,14,15,-7,-1,-1,15,11,13,13,11,14,8,14,6,13,4,11,3,8,3,6,4,3,6,1,8,0,11,0,13,1,15,3]],r:[13,[4,14,4,0,-1,-1,4,8,5,11,7,13,9,14,12,14]],s:[17,[14,11,13,13,10,14,7,14,4,13,3,11,4,9,6,8,11,7,13,6,14,4,14,3,13,1,10,0,7,0,4,1,3,3]],t:[12,[5,21,5,4,6,1,8,0,10,0,-1,-1,2,14,9,14]],u:[19,[4,14,4,4,5,1,7,0,10,0,12,1,15,4,-1,-1,15,14,15,0]],v:[16,[2,14,8,0,-1,-1,14,14,8,0]],w:[22,[3,14,7,0,-1,-1,11,14,7,0,-1,-1,11,14,15,0,-1,-1,19,14,15,0]],x:[17,[3,14,14,0,-1,-1,14,14,3,0]],y:[16,[2,14,8,0,-1,-1,14,14,8,0,6,-4,4,-6,2,-7,1,-7]],z:[17,[14,14,3,0,-1,-1,3,14,14,14,-1,-1,3,0,14,0]],"{":[14,[9,25,7,24,6,23,5,21,5,19,6,17,7,16,8,14,8,12,6,10,-1,-1,7,24,6,22,6,20,7,18,8,17,9,15,9,13,8,11,4,9,8,7,9,5,9,3,8,1,7,0,6,-2,6,-4,7,-6,-1,-1,6,8,8,6,8,4,7,2,6,1,5,-1,5,-3,6,-5,7,-6,9,-7]],"|":[8,[4,25,4,-7]],"}":[14,[5,25,7,24,8,23,9,21,9,19,8,17,7,16,6,14,6,12,8,10,-1,-1,7,24,8,22,8,20,7,18,6,17,5,15,5,13,6,11,10,9,6,7,5,5,5,3,6,1,7,0,8,-2,8,-4,7,-6,-1,-1,8,8,6,6,6,4,7,2,8,1,9,-1,9,-3,8,-5,7,-6,5,-7]],"~":[24,[3,6,3,8,4,11,6,12,8,12,10,11,14,8,16,7,18,7,20,8,21,10,-1,-1,3,8,4,10,6,11,8,11,10,10,14,7,16,6,18,6,20,7,21,10,21,12]]};
  143 +},{"../data/buffer":50,"../data/extent":53,"../data/pos_array":56,"../util/browser":194,"./vertex_array_object":79,"@mapbox/gl-matrix":1}],69:[function(_dereq_,module,exports){
  144 +"use strict";function drawFill(t,e,r,i){var a=t.gl;a.enable(a.STENCIL_TEST);var l=!r.paint["fill-pattern"]&&r.isPaintValueFeatureConstant("fill-color")&&r.isPaintValueFeatureConstant("fill-opacity")&&1===r.paint["fill-color"][3]&&1===r.paint["fill-opacity"];t.isOpaquePass===l&&(t.setDepthSublayer(1),drawFillTiles(t,e,r,i,drawFillTile)),!t.isOpaquePass&&r.paint["fill-antialias"]&&(t.lineWidth(2),t.depthMask(!1),t.setDepthSublayer(r.getPaintProperty("fill-outline-color")?2:0),drawFillTiles(t,e,r,i,drawStrokeTile))}function drawFillTiles(t,e,r,i,a){if(!pattern.isPatternMissing(r.paint["fill-pattern"],t))for(var l=!0,n=0,o=i;n<o.length;n+=1){var f=o[n],s=e.getTile(f),p=s.getBucket(r);p&&(t.enableTileClippingMask(f),a(t,e,r,s,f,p.buffers,l),l=!1)}}function drawFillTile(t,e,r,i,a,l,n){for(var o=t.gl,f=l.layerData[r.id],s=setFillProgram("fill",r.paint["fill-pattern"],t,f,r,i,a,n),p=0,u=l.segments;p<u.length;p+=1){var g=u[p];g.vaos[r.id].bind(o,s,l.layoutVertexBuffer,l.elementBuffer,f.paintVertexBuffer,g.vertexOffset),o.drawElements(o.TRIANGLES,3*g.primitiveLength,o.UNSIGNED_SHORT,3*g.primitiveOffset*2)}}function drawStrokeTile(t,e,r,i,a,l,n){var o=t.gl,f=l.layerData[r.id],s=r.paint["fill-pattern"]&&!r.getPaintProperty("fill-outline-color"),p=setFillProgram("fillOutline",s,t,f,r,i,a,n);o.uniform2f(p.u_world,o.drawingBufferWidth,o.drawingBufferHeight);for(var u=0,g=l.segments2;u<g.length;u+=1){var m=g[u];m.vaos[r.id].bind(o,p,l.layoutVertexBuffer,l.elementBuffer2,f.paintVertexBuffer,m.vertexOffset),o.drawElements(o.LINES,2*m.primitiveLength,o.UNSIGNED_SHORT,2*m.primitiveOffset*2)}}function setFillProgram(t,e,r,i,a,l,n,o){var f,s=r.currentProgram;return e?(f=r.useProgram(t+"Pattern",i.programConfiguration),(o||f!==s)&&(i.programConfiguration.setUniforms(r.gl,f,a,{zoom:r.transform.zoom}),pattern.prepare(a.paint["fill-pattern"],r,f)),pattern.setTile(l,r,f)):(f=r.useProgram(t,i.programConfiguration),(o||f!==s)&&i.programConfiguration.setUniforms(r.gl,f,a,{zoom:r.transform.zoom})),r.gl.uniformMatrix4fv(f.u_matrix,!1,r.translatePosMatrix(n.posMatrix,l,a.paint["fill-translate"],a.paint["fill-translate-anchor"])),f}var pattern=_dereq_("./pattern");module.exports=drawFill;
  145 +},{"./pattern":77}],70:[function(_dereq_,module,exports){
  146 +"use strict";function draw(e,r,t,a){if(0!==t.paint["fill-extrusion-opacity"]){var i=e.gl;i.disable(i.STENCIL_TEST),i.enable(i.DEPTH_TEST),e.depthMask(!0);var n=renderToTexture(i,e);i.clearColor(0,0,0,0),i.clear(i.COLOR_BUFFER_BIT|i.DEPTH_BUFFER_BIT);for(var f=0;f<a.length;f++)drawExtrusion(e,r,t,a[f]);i.bindFramebuffer(i.FRAMEBUFFER,null),renderTextureToMap(i,e,t,n)}}function renderToTexture(e,r){e.activeTexture(e.TEXTURE1);var t=r.viewportTexture;t?e.bindTexture(e.TEXTURE_2D,t):(t=e.createTexture(),e.bindTexture(e.TEXTURE_2D,t),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,r.width,r.height,0,e.RGBA,e.UNSIGNED_BYTE,null),r.viewportTexture=t);var a=r.viewportFbo;if(a)e.bindFramebuffer(e.FRAMEBUFFER,a);else{a=e.createFramebuffer(),e.bindFramebuffer(e.FRAMEBUFFER,a);var i=e.createRenderbuffer();e.bindRenderbuffer(e.RENDERBUFFER,i),e.renderbufferStorage(e.RENDERBUFFER,e.DEPTH_COMPONENT16,r.width,r.height),e.framebufferRenderbuffer(e.FRAMEBUFFER,e.DEPTH_ATTACHMENT,e.RENDERBUFFER,i),r.viewportFbo=a}return e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,t,0),t}function renderTextureToMap(e,r,t,a){var i=r.useProgram("extrusionTexture");e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,a),e.uniform1f(i.u_opacity,t.paint["fill-extrusion-opacity"]),e.uniform1i(i.u_image,1);var n=mat4.create();mat4.ortho(n,0,r.width,r.height,0,0,1),e.uniformMatrix4fv(i.u_matrix,!1,n),e.disable(e.DEPTH_TEST),e.uniform2f(i.u_world,e.drawingBufferWidth,e.drawingBufferHeight);var f=new PosArray;f.emplaceBack(0,0),f.emplaceBack(1,0),f.emplaceBack(0,1),f.emplaceBack(1,1);var u=Buffer.fromStructArray(f,Buffer.BufferType.VERTEX),T=new VertexArrayObject;T.bind(e,i,u),e.drawArrays(e.TRIANGLE_STRIP,0,4),e.enable(e.DEPTH_TEST)}function drawExtrusion(e,r,t,a){if(!e.isOpaquePass){var i=r.getTile(a),n=i.getBucket(t);if(n){var f=n.buffers,u=e.gl,T=t.paint["fill-extrusion-pattern"],o=f.layerData[t.id],E=o.programConfiguration,l=e.useProgram(T?"fillExtrusionPattern":"fillExtrusion",E);if(E.setUniforms(u,l,t,{zoom:e.transform.zoom}),T){if(pattern.isPatternMissing(T,e))return;pattern.prepare(T,e,l),pattern.setTile(i,e,l),u.uniform1f(l.u_height_factor,-Math.pow(2,a.z)/i.tileSize/8)}e.gl.uniformMatrix4fv(l.u_matrix,!1,e.translatePosMatrix(a.posMatrix,i,t.paint["fill-extrusion-translate"],t.paint["fill-extrusion-translate-anchor"])),setLight(l,e);for(var s=0,R=f.segments;s<R.length;s+=1){var m=R[s];m.vaos[t.id].bind(u,l,f.layoutVertexBuffer,f.elementBuffer,o.paintVertexBuffer,m.vertexOffset),u.drawElements(u.TRIANGLES,3*m.primitiveLength,u.UNSIGNED_SHORT,3*m.primitiveOffset*2)}}}}function setLight(e,r){var t=r.gl,a=r.style.light,i=a.calculated.position,n=[i.x,i.y,i.z],f=mat3.create();"viewport"===a.calculated.anchor&&mat3.fromRotation(f,-r.transform.angle),vec3.transformMat3(n,n,f),t.uniform3fv(e.u_lightpos,n),t.uniform1f(e.u_lightintensity,a.calculated.intensity),t.uniform3fv(e.u_lightcolor,a.calculated.color.slice(0,3))}var glMatrix=_dereq_("@mapbox/gl-matrix"),Buffer=_dereq_("../data/buffer"),VertexArrayObject=_dereq_("./vertex_array_object"),PosArray=_dereq_("../data/pos_array"),pattern=_dereq_("./pattern"),mat3=glMatrix.mat3,mat4=glMatrix.mat4,vec3=glMatrix.vec3;module.exports=draw;
  147 +},{"../data/buffer":50,"../data/pos_array":56,"./pattern":77,"./vertex_array_object":79,"@mapbox/gl-matrix":1}],71:[function(_dereq_,module,exports){
  148 +"use strict";function drawLineTile(e,i,t,r,a,n,o,l,f){var s,u,m,p,_=i.gl,d=a.paint["line-dasharray"],g=a.paint["line-pattern"];if(l||f){var v=1/pixelsToTileUnits(t,1,i.transform.tileZoom);if(d){s=i.lineAtlas.getDash(d.from,"round"===a.layout["line-cap"]),u=i.lineAtlas.getDash(d.to,"round"===a.layout["line-cap"]);var x=s.width*d.fromScale,T=u.width*d.toScale;_.uniform2f(e.u_patternscale_a,v/x,-s.height/2),_.uniform2f(e.u_patternscale_b,v/T,-u.height/2),_.uniform1f(e.u_sdfgamma,i.lineAtlas.width/(256*Math.min(x,T)*browser.devicePixelRatio)/2)}else if(g){if(m=i.spriteAtlas.getPattern(g.from),p=i.spriteAtlas.getPattern(g.to),!m||!p)return;_.uniform2f(e.u_pattern_size_a,m.displaySize[0]*g.fromScale/v,p.displaySize[1]),_.uniform2f(e.u_pattern_size_b,p.displaySize[0]*g.toScale/v,p.displaySize[1]),_.uniform2fv(e.u_texsize,i.spriteAtlas.getPixelSize())}_.uniform2f(e.u_gl_units_to_pixels,1/i.transform.pixelsToGLUnits[0],1/i.transform.pixelsToGLUnits[1])}l&&(d?(_.uniform1i(e.u_image,0),_.activeTexture(_.TEXTURE0),i.lineAtlas.bind(_),_.uniform1f(e.u_tex_y_a,s.y),_.uniform1f(e.u_tex_y_b,u.y),_.uniform1f(e.u_mix,d.t)):g&&(_.uniform1i(e.u_image,0),_.activeTexture(_.TEXTURE0),i.spriteAtlas.bind(_,!0),_.uniform2fv(e.u_pattern_tl_a,m.tl),_.uniform2fv(e.u_pattern_br_a,m.br),_.uniform2fv(e.u_pattern_tl_b,p.tl),_.uniform2fv(e.u_pattern_br_b,p.br),_.uniform1f(e.u_fade,g.t)),_.uniform1f(e.u_width,a.paint["line-width"])),i.enableTileClippingMask(n);var h=i.translatePosMatrix(n.posMatrix,t,a.paint["line-translate"],a.paint["line-translate-anchor"]);_.uniformMatrix4fv(e.u_matrix,!1,h),_.uniform1f(e.u_ratio,1/pixelsToTileUnits(t,1,i.transform.zoom));for(var b=0,c=r.segments;b<c.length;b+=1){var S=c[b];S.vaos[a.id].bind(_,e,r.layoutVertexBuffer,r.elementBuffer,o.paintVertexBuffer,S.vertexOffset),_.drawElements(_.TRIANGLES,3*S.primitiveLength,_.UNSIGNED_SHORT,3*S.primitiveOffset*2)}}var browser=_dereq_("../util/browser"),pixelsToTileUnits=_dereq_("../source/pixels_to_tile_units");module.exports=function(e,i,t,r){if(!e.isOpaquePass){e.setDepthSublayer(0),e.depthMask(!1);var a=e.gl;if(a.enable(a.STENCIL_TEST),!(t.paint["line-width"]<=0))for(var n,o=t.paint["line-dasharray"]?"lineSDF":t.paint["line-pattern"]?"linePattern":"line",l=!0,f=0,s=r;f<s.length;f+=1){var u=s[f],m=i.getTile(u),p=m.getBucket(t);if(p){var _=p.buffers.layerData[t.id],d=e.currentProgram,g=e.useProgram(o,_.programConfiguration),v=l||g!==d,x=n!==m.coord.z;v&&_.programConfiguration.setUniforms(e.gl,g,t,{zoom:e.transform.zoom}),drawLineTile(g,e,m,p.buffers,t,u,_,v,x),n=m.coord.z,l=!1}}}};
  149 +},{"../source/pixels_to_tile_units":87,"../util/browser":194}],72:[function(_dereq_,module,exports){
  150 +"use strict";function drawRaster(r,t,e,a){if(!r.isOpaquePass){var i=r.gl;i.enable(i.DEPTH_TEST),r.depthMask(!0),i.depthFunc(i.LESS);for(var o=a.length&&a[0].z,n=0;n<a.length;n++){var u=a[n];r.setDepthSublayer(u.z-o),drawRasterTile(r,t,e,u)}i.depthFunc(i.LEQUAL)}}function drawRasterTile(r,t,e,a){var i=r.gl;i.disable(i.STENCIL_TEST);var o=t.getTile(a),n=r.transform.calculatePosMatrix(a,t.getSource().maxzoom);o.registerFadeDuration(r.style.animationLoop,e.paint["raster-fade-duration"]);var u=r.useProgram("raster");i.uniformMatrix4fv(u.u_matrix,!1,n),i.uniform1f(u.u_brightness_low,e.paint["raster-brightness-min"]),i.uniform1f(u.u_brightness_high,e.paint["raster-brightness-max"]),i.uniform1f(u.u_saturation_factor,saturationFactor(e.paint["raster-saturation"])),i.uniform1f(u.u_contrast_factor,contrastFactor(e.paint["raster-contrast"])),i.uniform3fv(u.u_spin_weights,spinWeights(e.paint["raster-hue-rotate"]));var s,c,f=o.sourceCache&&o.sourceCache.findLoadedParent(a,0,{}),d=getFadeValues(o,f,e,r.transform);i.activeTexture(i.TEXTURE0),i.bindTexture(i.TEXTURE_2D,o.texture),i.activeTexture(i.TEXTURE1),f?(i.bindTexture(i.TEXTURE_2D,f.texture),s=Math.pow(2,f.coord.z-o.coord.z),c=[o.coord.x*s%1,o.coord.y*s%1]):i.bindTexture(i.TEXTURE_2D,o.texture),i.uniform2fv(u.u_tl_parent,c||[0,0]),i.uniform1f(u.u_scale_parent,s||1),i.uniform1f(u.u_buffer_scale,1),i.uniform1f(u.u_fade_t,d.mix),i.uniform1f(u.u_opacity,d.opacity*e.paint["raster-opacity"]),i.uniform1i(u.u_image0,0),i.uniform1i(u.u_image1,1);var m=o.boundsBuffer||r.rasterBoundsBuffer,p=o.boundsVAO||r.rasterBoundsVAO;p.bind(i,u,m),i.drawArrays(i.TRIANGLE_STRIP,0,m.length)}function spinWeights(r){r*=Math.PI/180;var t=Math.sin(r),e=Math.cos(r);return[(2*e+1)/3,(-Math.sqrt(3)*t-e+1)/3,(Math.sqrt(3)*t-e+1)/3]}function contrastFactor(r){return r>0?1/(1-r):1+r}function saturationFactor(r){return r>0?1-1/(1.001-r):-r}function getFadeValues(r,t,e,a){var i=e.paint["raster-fade-duration"];if(r.sourceCache&&i>0){var o=Date.now(),n=(o-r.timeAdded)/i,u=t?(o-t.timeAdded)/i:-1,s=r.sourceCache.getSource(),c=a.coveringZoomLevel({tileSize:s.tileSize,roundZoom:s.roundZoom}),f=!t||Math.abs(t.coord.z-c)>Math.abs(r.coord.z-c),d=f&&r.refreshedUponExpiration?1:util.clamp(f?n:1-u,0,1);return r.refreshedUponExpiration&&n>=1&&(r.refreshedUponExpiration=!1),t?{opacity:1,mix:1-d}:{opacity:d,mix:0}}return{opacity:1,mix:0}}var util=_dereq_("../util/util");module.exports=drawRaster;
  151 +},{"../util/util":215}],73:[function(_dereq_,module,exports){
  152 +"use strict";function drawSymbols(t,e,i,o){if(!t.isOpaquePass){var a=!(i.layout["text-allow-overlap"]||i.layout["icon-allow-overlap"]||i.layout["text-ignore-placement"]||i.layout["icon-ignore-placement"]),n=t.gl;a?n.disable(n.STENCIL_TEST):n.enable(n.STENCIL_TEST),t.setDepthSublayer(0),t.depthMask(!1),drawLayerSymbols(t,e,i,o,!1,i.paint["icon-translate"],i.paint["icon-translate-anchor"],i.layout["icon-rotation-alignment"],i.layout["icon-rotation-alignment"]),drawLayerSymbols(t,e,i,o,!0,i.paint["text-translate"],i.paint["text-translate-anchor"],i.layout["text-rotation-alignment"],i.layout["text-pitch-alignment"]),e.map.showCollisionBoxes&&drawCollisionDebug(t,e,i,o)}}function drawLayerSymbols(t,e,i,o,a,n,r,s,l){if(a||!t.style.sprite||t.style.sprite.loaded()){var u=t.gl,m="map"===s,f="map"===l,c=f;c?u.enable(u.DEPTH_TEST):u.disable(u.DEPTH_TEST);for(var _,p,y=0,g=o;y<g.length;y+=1){var d=g[y],T=e.getTile(d),x=T.getBucket(i);if(x){var v=a?x.buffers.glyph:x.buffers.icon;if(v&&v.segments.length){var h=v.layerData[i.id],S=h.programConfiguration,b=a||x.sdfIcons,z=a?x.textSizeData:x.iconSizeData;_&&x.fontstack===p||(_=t.useProgram(b?"symbolSDF":"symbolIcon",S),S.setUniforms(u,_,i,{zoom:t.transform.zoom}),setSymbolDrawState(_,t,i,d.z,a,b,m,f,x.fontstack,x.iconsNeedLinear,z)),t.enableTileClippingMask(d),u.uniformMatrix4fv(_.u_matrix,!1,t.translatePosMatrix(d.posMatrix,T,n,r)),u.uniform1f(_.u_collision_y_stretch,T.collisionTile.yStretch),drawTileSymbols(_,S,t,i,T,v,a,b,f),p=x.fontstack}}}c||u.enable(u.DEPTH_TEST)}}function setSymbolDrawState(t,e,i,o,a,n,r,s,l,u,m){var f=e.gl,c=e.transform;if(f.uniform1i(t.u_rotate_with_map,r),f.uniform1i(t.u_pitch_with_map,s),f.activeTexture(f.TEXTURE0),f.uniform1i(t.u_texture,0),f.uniform1f(t.u_is_text,a?1:0),a){var _=l&&e.glyphSource.getGlyphAtlas(l);if(!_)return;_.updateTexture(f),f.uniform2f(t.u_texsize,_.width,_.height)}else{var p=e.options.rotating||e.options.zooming,y=!i.isLayoutValueFeatureConstant("icon-size")||!i.isLayoutValueZoomConstant("icon-size")||1!==i.getLayoutValue("icon-size",{zoom:c.zoom}),g=y||u,d=s||c.pitch;e.spriteAtlas.bind(f,n||p||g||d),f.uniform2fv(t.u_texsize,e.spriteAtlas.getPixelSize())}if(f.activeTexture(f.TEXTURE1),e.frameHistory.bind(f),f.uniform1i(t.u_fadetexture,1),f.uniform1f(t.u_zoom,c.zoom),f.uniform1f(t.u_pitch,c.pitch/360*2*Math.PI),f.uniform1f(t.u_bearing,c.bearing/360*2*Math.PI),f.uniform1f(t.u_aspect_ratio,c.width/c.height),f.uniform1i(t.u_is_size_zoom_constant,m.isZoomConstant?1:0),f.uniform1i(t.u_is_size_feature_constant,m.isFeatureConstant?1:0),m.isZoomConstant||m.isFeatureConstant)if(m.isFeatureConstant&&!m.isZoomConstant){var T;if("interval"===m.functionType)T=i.getLayoutValue(a?"text-size":"icon-size",{zoom:c.zoom});else{var x="interval"===m.functionType?0:interpolationFactor(c.zoom,m.functionBase,m.coveringZoomRange[0],m.coveringZoomRange[1]),v=m.coveringStopValues[0],h=m.coveringStopValues[1];T=v+(h-v)*util.clamp(x,0,1)}f.uniform1f(t.u_size,T),f.uniform1f(t.u_layout_size,m.layoutSize)}else m.isFeatureConstant&&m.isZoomConstant&&f.uniform1f(t.u_size,m.layoutSize);else{var S=interpolationFactor(c.zoom,m.functionBase,m.coveringZoomRange[0],m.coveringZoomRange[1]);f.uniform1f(t.u_size_t,util.clamp(S,0,1))}f.uniform1f(t.u_camera_to_center_distance,c.cameraToCenterDistance),"line"===i.layout["symbol-placement"]&&"map"===i.layout["text-rotation-alignment"]&&"viewport"===i.layout["text-pitch-alignment"]&&i.layout["text-field"]?f.uniform1f(t.u_max_camera_distance,1.5):f.uniform1f(t.u_max_camera_distance,10)}function drawTileSymbols(t,e,i,o,a,n,r,s,l){var u=i.gl,m=i.transform;if(l){var f=pixelsToTileUnits(a,1,m.zoom);u.uniform2f(t.u_extrude_scale,f,f)}else{var c=m.cameraToCenterDistance;u.uniform2f(t.u_extrude_scale,m.pixelsToGLUnits[0]*c,m.pixelsToGLUnits[1]*c)}if(s){var _=(r?"text":"icon")+"-halo-width",p=!o.isPaintValueFeatureConstant(_)||o.paint[_],y=(l?Math.cos(m._pitch):1)*m.cameraToCenterDistance;u.uniform1f(t.u_gamma_scale,y),p&&(u.uniform1f(t.u_is_halo,1),drawSymbolElements(n,o,u,t)),u.uniform1f(t.u_is_halo,0)}drawSymbolElements(n,o,u,t)}function drawSymbolElements(t,e,i,o){for(var a=t.layerData[e.id],n=a&&a.paintVertexBuffer,r=0,s=t.segments;r<s.length;r+=1){var l=s[r];l.vaos[e.id].bind(i,o,t.layoutVertexBuffer,t.elementBuffer,n,l.vertexOffset),i.drawElements(i.TRIANGLES,3*l.primitiveLength,i.UNSIGNED_SHORT,3*l.primitiveOffset*2)}}var util=_dereq_("../util/util"),drawCollisionDebug=_dereq_("./draw_collision_debug"),pixelsToTileUnits=_dereq_("../source/pixels_to_tile_units"),interpolationFactor=_dereq_("../style-spec/function").interpolationFactor;module.exports=drawSymbols;
  153 +},{"../source/pixels_to_tile_units":87,"../style-spec/function":106,"../util/util":215,"./draw_collision_debug":67}],74:[function(_dereq_,module,exports){
  154 +"use strict";var FrameHistory=function(){this.changeTimes=new Float64Array(256),this.changeOpacities=new Uint8Array(256),this.opacities=new Uint8ClampedArray(256),this.array=new Uint8Array(this.opacities.buffer),this.previousZoom=0,this.firstFrame=!0};FrameHistory.prototype.record=function(e,t,i){var r=this;this.firstFrame&&(e=0,this.firstFrame=!1),t=Math.floor(10*t);var a;if(t<this.previousZoom)for(a=t+1;a<=this.previousZoom;a++)r.changeTimes[a]=e,r.changeOpacities[a]=r.opacities[a];else for(a=t;a>this.previousZoom;a--)r.changeTimes[a]=e,r.changeOpacities[a]=r.opacities[a];for(a=0;a<256;a++){var s=e-r.changeTimes[a],o=255*(i?s/i:1);a<=t?r.opacities[a]=r.changeOpacities[a]+o:r.opacities[a]=r.changeOpacities[a]-o}this.changed=!0,this.previousZoom=t},FrameHistory.prototype.bind=function(e){this.texture?(e.bindTexture(e.TEXTURE_2D,this.texture),this.changed&&(e.texSubImage2D(e.TEXTURE_2D,0,0,0,256,1,e.ALPHA,e.UNSIGNED_BYTE,this.array),this.changed=!1)):(this.texture=e.createTexture(),e.bindTexture(e.TEXTURE_2D,this.texture),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texImage2D(e.TEXTURE_2D,0,e.ALPHA,256,1,0,e.ALPHA,e.UNSIGNED_BYTE,this.array))},module.exports=FrameHistory;
  155 +},{}],75:[function(_dereq_,module,exports){
  156 +"use strict";var util=_dereq_("../util/util"),LineAtlas=function(t,i){this.width=t,this.height=i,this.nextRow=0,this.bytes=4,this.data=new Uint8Array(this.width*this.height*this.bytes),this.positions={}};LineAtlas.prototype.setSprite=function(t){this.sprite=t},LineAtlas.prototype.getDash=function(t,i){var e=t.join(",")+i;return this.positions[e]||(this.positions[e]=this.addDash(t,i)),this.positions[e]},LineAtlas.prototype.addDash=function(t,i){var e=this,h=i?7:0,s=2*h+1,a=128;if(this.nextRow+s>this.height)return util.warnOnce("LineAtlas out of space"),null;for(var r=0,n=0;n<t.length;n++)r+=t[n];for(var o=this.width/r,E=o/2,T=t.length%2===1,R=-h;R<=h;R++)for(var u=e.nextRow+h+R,d=e.width*u,l=T?-t[t.length-1]:0,x=t[0],A=1,_=0;_<this.width;_++){for(;x<_/o;)l=x,x+=t[A],T&&A===t.length-1&&(x+=t[0]),A++;var p=Math.abs(_-l*o),g=Math.abs(_-x*o),w=Math.min(p,g),D=A%2===1,U=void 0;if(i){var f=h?R/h*(E+1):0;if(D){var X=E-Math.abs(f);U=Math.sqrt(w*w+X*X)}else U=E-Math.sqrt(w*w+f*f)}else U=(D?1:-1)*w;e.data[3+4*(d+_)]=Math.max(0,Math.min(255,U+a))}var v={y:(this.nextRow+h+.5)/this.height,height:2*h/this.height,width:r};return this.nextRow+=s,this.dirty=!0,v},LineAtlas.prototype.bind=function(t){this.texture?(t.bindTexture(t.TEXTURE_2D,this.texture),this.dirty&&(this.dirty=!1,t.texSubImage2D(t.TEXTURE_2D,0,0,0,this.width,this.height,t.RGBA,t.UNSIGNED_BYTE,this.data))):(this.texture=t.createTexture(),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.REPEAT),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.REPEAT),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.LINEAR),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.width,this.height,0,t.RGBA,t.UNSIGNED_BYTE,this.data))},module.exports=LineAtlas;
  157 +},{"../util/util":215}],76:[function(_dereq_,module,exports){
  158 +"use strict";var browser=_dereq_("../util/browser"),mat4=_dereq_("@mapbox/gl-matrix").mat4,FrameHistory=_dereq_("./frame_history"),SourceCache=_dereq_("../source/source_cache"),EXTENT=_dereq_("../data/extent"),pixelsToTileUnits=_dereq_("../source/pixels_to_tile_units"),util=_dereq_("../util/util"),Buffer=_dereq_("../data/buffer"),VertexArrayObject=_dereq_("./vertex_array_object"),RasterBoundsArray=_dereq_("../data/raster_bounds_array"),PosArray=_dereq_("../data/pos_array"),ProgramConfiguration=_dereq_("../data/program_configuration"),shaders=_dereq_("./shaders"),draw={symbol:_dereq_("./draw_symbol"),circle:_dereq_("./draw_circle"),line:_dereq_("./draw_line"),fill:_dereq_("./draw_fill"),"fill-extrusion":_dereq_("./draw_fill_extrusion"),raster:_dereq_("./draw_raster"),background:_dereq_("./draw_background"),debug:_dereq_("./draw_debug")},Painter=function(e,r){this.gl=e,this.transform=r,this._tileTextures={},this.frameHistory=new FrameHistory,this.setup(),this.numSublayers=SourceCache.maxUnderzooming+SourceCache.maxOverzooming+1,this.depthEpsilon=1/Math.pow(2,16),this.lineWidthRange=e.getParameter(e.ALIASED_LINE_WIDTH_RANGE),this.basicFillProgramConfiguration=ProgramConfiguration.createStatic(["color","opacity"]),this.emptyProgramConfiguration=new ProgramConfiguration};Painter.prototype.resize=function(e,r){var t=this.gl;this.width=e*browser.devicePixelRatio,this.height=r*browser.devicePixelRatio,t.viewport(0,0,this.width,this.height),this.viewportTexture&&(this.gl.deleteTexture(this.viewportTexture),this.viewportTexture=null),this.viewportFbo&&(this.gl.deleteFramebuffer(this.viewportFbo),this.viewportFbo=null)},Painter.prototype.setup=function(){var e=this.gl;e.verbose=!0,e.enable(e.BLEND),e.blendFunc(e.ONE,e.ONE_MINUS_SRC_ALPHA),e.enable(e.STENCIL_TEST),e.enable(e.DEPTH_TEST),e.depthFunc(e.LEQUAL),this._depthMask=!1,e.depthMask(!1);var r=new PosArray;r.emplaceBack(0,0),r.emplaceBack(EXTENT,0),r.emplaceBack(0,EXTENT),r.emplaceBack(EXTENT,EXTENT),this.tileExtentBuffer=Buffer.fromStructArray(r,Buffer.BufferType.VERTEX),this.tileExtentVAO=new VertexArrayObject,this.tileExtentPatternVAO=new VertexArrayObject;var t=new PosArray;t.emplaceBack(0,0),t.emplaceBack(EXTENT,0),t.emplaceBack(EXTENT,EXTENT),t.emplaceBack(0,EXTENT),t.emplaceBack(0,0),this.debugBuffer=Buffer.fromStructArray(t,Buffer.BufferType.VERTEX),this.debugVAO=new VertexArrayObject;var i=new RasterBoundsArray;i.emplaceBack(0,0,0,0),i.emplaceBack(EXTENT,0,32767,0),i.emplaceBack(0,EXTENT,0,32767),i.emplaceBack(EXTENT,EXTENT,32767,32767),this.rasterBoundsBuffer=Buffer.fromStructArray(i,Buffer.BufferType.VERTEX),this.rasterBoundsVAO=new VertexArrayObject,this.extTextureFilterAnisotropic=e.getExtension("EXT_texture_filter_anisotropic")||e.getExtension("MOZ_EXT_texture_filter_anisotropic")||e.getExtension("WEBKIT_EXT_texture_filter_anisotropic"),this.extTextureFilterAnisotropic&&(this.extTextureFilterAnisotropicMax=e.getParameter(this.extTextureFilterAnisotropic.MAX_TEXTURE_MAX_ANISOTROPY_EXT))},Painter.prototype.clearColor=function(){var e=this.gl;e.clearColor(0,0,0,0),e.clear(e.COLOR_BUFFER_BIT)},Painter.prototype.clearStencil=function(){var e=this.gl;e.clearStencil(0),e.stencilMask(255),e.clear(e.STENCIL_BUFFER_BIT)},Painter.prototype.clearDepth=function(){var e=this.gl;e.clearDepth(1),this.depthMask(!0),e.clear(e.DEPTH_BUFFER_BIT)},Painter.prototype._renderTileClippingMasks=function(e){var r=this,t=this.gl;t.colorMask(!1,!1,!1,!1),this.depthMask(!1),t.disable(t.DEPTH_TEST),t.enable(t.STENCIL_TEST),t.stencilMask(255),t.stencilOp(t.KEEP,t.KEEP,t.REPLACE);var i=1;this._tileClippingMaskIDs={};for(var a=0,s=e;a<s.length;a+=1){var o=s[a],n=r._tileClippingMaskIDs[o.id]=i++;t.stencilFunc(t.ALWAYS,n,255);var l=r.useProgram("fill",r.basicFillProgramConfiguration);t.uniformMatrix4fv(l.u_matrix,!1,o.posMatrix),r.tileExtentVAO.bind(t,l,r.tileExtentBuffer),t.drawArrays(t.TRIANGLE_STRIP,0,r.tileExtentBuffer.length)}t.stencilMask(0),t.colorMask(!0,!0,!0,!0),this.depthMask(!0),t.enable(t.DEPTH_TEST)},Painter.prototype.enableTileClippingMask=function(e){var r=this.gl;r.stencilFunc(r.EQUAL,this._tileClippingMaskIDs[e.id],255)},Painter.prototype.prepareBuffers=function(){},Painter.prototype.render=function(e,r){if(this.style=e,this.options=r,this.lineAtlas=e.lineAtlas,this.spriteAtlas=e.spriteAtlas,this.spriteAtlas.setSprite(e.sprite),this.glyphSource=e.glyphSource,this.frameHistory.record(Date.now(),this.transform.zoom,e.getTransition().duration),this.prepareBuffers(),this.clearColor(),this.clearDepth(),this.showOverdrawInspector(r.showOverdrawInspector),this.depthRange=(e._order.length+2)*this.numSublayers*this.depthEpsilon,this.isOpaquePass=!0,this.renderPass(),this.isOpaquePass=!1,this.renderPass(),this.options.showTileBoundaries){var t=this.style.sourceCaches[Object.keys(this.style.sourceCaches)[0]];t&&draw.debug(this,t,t.getVisibleCoordinates())}},Painter.prototype.renderPass=function(){var e,r,t=this,i=this.style._order;this.currentLayer=this.isOpaquePass?i.length-1:0,this.isOpaquePass?this._showOverdrawInspector||this.gl.disable(this.gl.BLEND):this.gl.enable(this.gl.BLEND);for(var a=0;a<i.length;a++){var s=t.style._layers[i[t.currentLayer]];s.source!==(e&&e.id)&&(e=t.style.sourceCaches[s.source],r=[],e&&(e.prepare&&e.prepare(),t.clearStencil(),r=e.getVisibleCoordinates(),e.getSource().isTileClipped&&t._renderTileClippingMasks(r)),t.isOpaquePass||r.reverse()),t.renderLayer(t,e,s,r),t.currentLayer+=t.isOpaquePass?-1:1}},Painter.prototype.depthMask=function(e){e!==this._depthMask&&(this._depthMask=e,this.gl.depthMask(e))},Painter.prototype.renderLayer=function(e,r,t,i){t.isHidden(this.transform.zoom)||("background"===t.type||i.length)&&(this.id=t.id,draw[t.type](e,r,t,i))},Painter.prototype.setDepthSublayer=function(e){var r=1-((1+this.currentLayer)*this.numSublayers+e)*this.depthEpsilon,t=r-1+this.depthRange;this.gl.depthRange(t,r)},Painter.prototype.translatePosMatrix=function(e,r,t,i){if(!t[0]&&!t[1])return e;if("viewport"===i){var a=Math.sin(-this.transform.angle),s=Math.cos(-this.transform.angle);t=[t[0]*s-t[1]*a,t[0]*a+t[1]*s]}var o=[pixelsToTileUnits(r,t[0],this.transform.zoom),pixelsToTileUnits(r,t[1],this.transform.zoom),0],n=new Float32Array(16);return mat4.translate(n,e,o),n},Painter.prototype.saveTileTexture=function(e){var r=this._tileTextures[e.size];r?r.push(e):this._tileTextures[e.size]=[e]},Painter.prototype.getTileTexture=function(e){var r=this._tileTextures[e];return r&&r.length>0?r.pop():null},Painter.prototype.lineWidth=function(e){this.gl.lineWidth(util.clamp(e,this.lineWidthRange[0],this.lineWidthRange[1]))},Painter.prototype.showOverdrawInspector=function(e){if(e||this._showOverdrawInspector){this._showOverdrawInspector=e;var r=this.gl;if(e){r.blendFunc(r.CONSTANT_COLOR,r.ONE);var t=8,i=1/t;r.blendColor(i,i,i,0),r.clearColor(0,0,0,1),r.clear(r.COLOR_BUFFER_BIT)}else r.blendFunc(r.ONE,r.ONE_MINUS_SRC_ALPHA)}},Painter.prototype.createProgram=function(e,r){var t=this.gl,i=t.createProgram(),a=shaders[e],s="#define MAPBOX_GL_JS\n#define DEVICE_PIXEL_RATIO "+browser.devicePixelRatio.toFixed(1)+"\n";this._showOverdrawInspector&&(s+="#define OVERDRAW_INSPECTOR;\n");var o=r.applyPragmas(s+shaders.prelude.fragmentSource+a.fragmentSource,"fragment"),n=r.applyPragmas(s+shaders.prelude.vertexSource+a.vertexSource,"vertex"),l=t.createShader(t.FRAGMENT_SHADER);t.shaderSource(l,o),t.compileShader(l),t.attachShader(i,l);var h=t.createShader(t.VERTEX_SHADER);t.shaderSource(h,n),t.compileShader(h),t.attachShader(i,h);for(var c=r.interface.layoutAttributes||[],u=0;u<c.length;u++)t.bindAttribLocation(i,u,c[u].name);t.linkProgram(i);for(var p=t.getProgramParameter(i,t.ACTIVE_ATTRIBUTES),d={program:i,numAttributes:p},f=0;f<p;f++){var g=t.getActiveAttrib(i,f);d[g.name]=t.getAttribLocation(i,g.name)}for(var T=t.getProgramParameter(i,t.ACTIVE_UNIFORMS),E=0;E<T;E++){var m=t.getActiveUniform(i,E);d[m.name]=t.getUniformLocation(i,m.name)}return d},Painter.prototype._createProgramCached=function(e,r){this.cache=this.cache||{};var t=""+e+(r.cacheKey||"")+(this._showOverdrawInspector?"/overdraw":"");return this.cache[t]||(this.cache[t]=this.createProgram(e,r)),this.cache[t]},Painter.prototype.useProgram=function(e,r){var t=this.gl,i=this._createProgramCached(e,r||this.emptyProgramConfiguration);return this.currentProgram!==i&&(t.useProgram(i.program),this.currentProgram=i),i},module.exports=Painter;
  159 +},{"../data/buffer":50,"../data/extent":53,"../data/pos_array":56,"../data/program_configuration":57,"../data/raster_bounds_array":58,"../source/pixels_to_tile_units":87,"../source/source_cache":92,"../util/browser":194,"../util/util":215,"./draw_background":65,"./draw_circle":66,"./draw_debug":68,"./draw_fill":69,"./draw_fill_extrusion":70,"./draw_line":71,"./draw_raster":72,"./draw_symbol":73,"./frame_history":74,"./shaders":78,"./vertex_array_object":79,"@mapbox/gl-matrix":1}],77:[function(_dereq_,module,exports){
  160 +"use strict";var pixelsToTileUnits=_dereq_("../source/pixels_to_tile_units");exports.isPatternMissing=function(t,r){if(!t)return!1;var e=r.spriteAtlas.getPattern(t.from),i=r.spriteAtlas.getPattern(t.to);return!e||!i},exports.prepare=function(t,r,e){var i=r.gl,o=r.spriteAtlas.getPattern(t.from),n=r.spriteAtlas.getPattern(t.to);i.uniform1i(e.u_image,0),i.uniform2fv(e.u_pattern_tl_a,o.tl),i.uniform2fv(e.u_pattern_br_a,o.br),i.uniform2fv(e.u_pattern_tl_b,n.tl),i.uniform2fv(e.u_pattern_br_b,n.br),i.uniform2fv(e.u_texsize,r.spriteAtlas.getPixelSize()),i.uniform1f(e.u_mix,t.t),i.uniform2fv(e.u_pattern_size_a,o.displaySize),i.uniform2fv(e.u_pattern_size_b,n.displaySize),i.uniform1f(e.u_scale_a,t.fromScale),i.uniform1f(e.u_scale_b,t.toScale),i.activeTexture(i.TEXTURE0),r.spriteAtlas.bind(i,!0)},exports.setTile=function(t,r,e){var i=r.gl;i.uniform1f(e.u_tile_units_to_pixels,1/pixelsToTileUnits(t,1,r.transform.tileZoom));var o=Math.pow(2,t.coord.z),n=t.tileSize*Math.pow(2,r.transform.tileZoom)/o,u=n*(t.coord.x+t.coord.w*o),a=n*t.coord.y;i.uniform2f(e.u_pixel_coord_upper,u>>16,a>>16),i.uniform2f(e.u_pixel_coord_lower,65535&u,65535&a)};
  161 +},{"../source/pixels_to_tile_units":87}],78:[function(_dereq_,module,exports){
  162 +"use strict";module.exports={prelude:{fragmentSource:"#ifdef GL_ES\nprecision mediump float;\n#else\n\n#if !defined(lowp)\n#define lowp\n#endif\n\n#if !defined(mediump)\n#define mediump\n#endif\n\n#if !defined(highp)\n#define highp\n#endif\n\n#endif\n",vertexSource:"#ifdef GL_ES\nprecision highp float;\n#else\n\n#if !defined(lowp)\n#define lowp\n#endif\n\n#if !defined(mediump)\n#define mediump\n#endif\n\n#if !defined(highp)\n#define highp\n#endif\n\n#endif\n\nfloat evaluate_zoom_function_1(const vec4 values, const float t) {\n if (t < 1.0) {\n return mix(values[0], values[1], t);\n } else if (t < 2.0) {\n return mix(values[1], values[2], t - 1.0);\n } else {\n return mix(values[2], values[3], t - 2.0);\n }\n}\nvec4 evaluate_zoom_function_4(const vec4 value0, const vec4 value1, const vec4 value2, const vec4 value3, const float t) {\n if (t < 1.0) {\n return mix(value0, value1, t);\n } else if (t < 2.0) {\n return mix(value1, value2, t - 1.0);\n } else {\n return mix(value2, value3, t - 2.0);\n }\n}\n\n// Unpack a pair of values that have been packed into a single float.\n// The packed values are assumed to be 8-bit unsigned integers, and are\n// packed like so:\n// packedValue = floor(input[0]) * 256 + input[1],\nvec2 unpack_float(const float packedValue) {\n int packedIntValue = int(packedValue);\n int v0 = packedIntValue / 256;\n return vec2(v0, packedIntValue - v0 * 256);\n}\n\n\n// To minimize the number of attributes needed in the mapbox-gl-native shaders,\n// we encode a 4-component color into a pair of floats (i.e. a vec2) as follows:\n// [ floor(color.r * 255) * 256 + color.g * 255,\n// floor(color.b * 255) * 256 + color.g * 255 ]\nvec4 decode_color(const vec2 encodedColor) {\n return vec4(\n unpack_float(encodedColor[0]) / 255.0,\n unpack_float(encodedColor[1]) / 255.0\n );\n}\n\n// Unpack a pair of paint values and interpolate between them.\nfloat unpack_mix_vec2(const vec2 packedValue, const float t) {\n return mix(packedValue[0], packedValue[1], t);\n}\n\n// Unpack a pair of paint values and interpolate between them.\nvec4 unpack_mix_vec4(const vec4 packedColors, const float t) {\n vec4 minColor = decode_color(vec2(packedColors[0], packedColors[1]));\n vec4 maxColor = decode_color(vec2(packedColors[2], packedColors[3]));\n return mix(minColor, maxColor, t);\n}\n\n// The offset depends on how many pixels are between the world origin and the edge of the tile:\n// vec2 offset = mod(pixel_coord, size)\n//\n// At high zoom levels there are a ton of pixels between the world origin and the edge of the tile.\n// The glsl spec only guarantees 16 bits of precision for highp floats. We need more than that.\n//\n// The pixel_coord is passed in as two 16 bit values:\n// pixel_coord_upper = floor(pixel_coord / 2^16)\n// pixel_coord_lower = mod(pixel_coord, 2^16)\n//\n// The offset is calculated in a series of steps that should preserve this precision:\nvec2 get_pattern_pos(const vec2 pixel_coord_upper, const vec2 pixel_coord_lower,\n const vec2 pattern_size, const float tile_units_to_pixels, const vec2 pos) {\n\n vec2 offset = mod(mod(mod(pixel_coord_upper, pattern_size) * 256.0, pattern_size) * 256.0 + pixel_coord_lower, pattern_size);\n return (tile_units_to_pixels * pos + offset) / pattern_size;\n}\n"},circle:{fragmentSource:"#pragma mapbox: define highp vec4 color\n#pragma mapbox: define mediump float radius\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define highp vec4 stroke_color\n#pragma mapbox: define mediump float stroke_width\n#pragma mapbox: define lowp float stroke_opacity\n\nvarying vec2 v_extrude;\nvarying lowp float v_antialiasblur;\n\nvoid main() {\n #pragma mapbox: initialize highp vec4 color\n #pragma mapbox: initialize mediump float radius\n #pragma mapbox: initialize lowp float blur\n #pragma mapbox: initialize lowp float opacity\n #pragma mapbox: initialize highp vec4 stroke_color\n #pragma mapbox: initialize mediump float stroke_width\n #pragma mapbox: initialize lowp float stroke_opacity\n\n float extrude_length = length(v_extrude);\n float antialiased_blur = -max(blur, v_antialiasblur);\n\n float opacity_t = smoothstep(0.0, antialiased_blur, extrude_length - 1.0);\n\n float color_t = stroke_width < 0.01 ? 0.0 : smoothstep(\n antialiased_blur,\n 0.0,\n extrude_length - radius / (radius + stroke_width)\n );\n\n gl_FragColor = opacity_t * mix(color * opacity, stroke_color * stroke_opacity, color_t);\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:"uniform mat4 u_matrix;\nuniform bool u_scale_with_map;\nuniform vec2 u_extrude_scale;\n\nattribute vec2 a_pos;\n\n#pragma mapbox: define highp vec4 color\n#pragma mapbox: define mediump float radius\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define highp vec4 stroke_color\n#pragma mapbox: define mediump float stroke_width\n#pragma mapbox: define lowp float stroke_opacity\n\nvarying vec2 v_extrude;\nvarying lowp float v_antialiasblur;\n\nvoid main(void) {\n #pragma mapbox: initialize highp vec4 color\n #pragma mapbox: initialize mediump float radius\n #pragma mapbox: initialize lowp float blur\n #pragma mapbox: initialize lowp float opacity\n #pragma mapbox: initialize highp vec4 stroke_color\n #pragma mapbox: initialize mediump float stroke_width\n #pragma mapbox: initialize lowp float stroke_opacity\n\n // unencode the extrusion vector that we snuck into the a_pos vector\n v_extrude = vec2(mod(a_pos, 2.0) * 2.0 - 1.0);\n\n vec2 extrude = v_extrude * (radius + stroke_width) * u_extrude_scale;\n // multiply a_pos by 0.5, since we had it * 2 in order to sneak\n // in extrusion data\n gl_Position = u_matrix * vec4(floor(a_pos * 0.5), 0, 1);\n\n if (u_scale_with_map) {\n gl_Position.xy += extrude;\n } else {\n gl_Position.xy += extrude * gl_Position.w;\n }\n\n // This is a minimum blur distance that serves as a faux-antialiasing for\n // the circle. since blur is a ratio of the circle's size and the intent is\n // to keep the blur at roughly 1px, the two are inversely related.\n v_antialiasblur = 1.0 / DEVICE_PIXEL_RATIO / (radius + stroke_width);\n}\n"},collisionBox:{fragmentSource:"uniform float u_zoom;\n// u_maxzoom is derived from the maximum scale considered by the CollisionTile\n// Labels with placement zoom greater than this value will not be placed,\n// regardless of perspective effects.\nuniform float u_maxzoom;\nuniform sampler2D u_fadetexture;\n\n// v_max_zoom is a collision-box-specific value that controls when line-following\n// collision boxes are used.\nvarying float v_max_zoom;\nvarying float v_placement_zoom;\nvarying float v_perspective_zoom_adjust;\nvarying vec2 v_fade_tex;\n\nvoid main() {\n\n float alpha = 0.5;\n\n // Green = no collisions, label is showing\n gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0) * alpha;\n\n // Red = collision, label hidden\n if (texture2D(u_fadetexture, v_fade_tex).a < 1.0) {\n gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0) * alpha;\n }\n\n // Faded black = this collision box is not used at this zoom (for curved labels)\n if (u_zoom >= v_max_zoom + v_perspective_zoom_adjust) {\n gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0) * alpha * 0.25;\n }\n\n // Faded blue = the placement scale for this label is beyond the CollisionTile\n // max scale, so it's impossible for this label to show without collision detection\n // being run again (the label's glyphs haven't even been added to the symbol bucket)\n if (v_placement_zoom >= u_maxzoom) {\n gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0) * alpha * 0.2;\n }\n}\n",vertexSource:"attribute vec2 a_pos;\nattribute vec2 a_anchor_pos;\nattribute vec2 a_extrude;\nattribute vec2 a_data;\n\nuniform mat4 u_matrix;\nuniform float u_scale;\nuniform float u_pitch;\nuniform float u_collision_y_stretch;\nuniform float u_camera_to_center_distance;\n\nvarying float v_max_zoom;\nvarying float v_placement_zoom;\nvarying float v_perspective_zoom_adjust;\nvarying vec2 v_fade_tex;\n\nvoid main() {\n vec4 projectedPoint = u_matrix * vec4(a_anchor_pos, 0, 1);\n highp float camera_to_anchor_distance = projectedPoint.w;\n highp float collision_perspective_ratio = 1.0 + 0.5 * ((camera_to_anchor_distance / u_camera_to_center_distance) - 1.0);\n\n highp float incidence_stretch = camera_to_anchor_distance / (u_camera_to_center_distance * cos(u_pitch));\n highp float collision_adjustment = max(1.0, incidence_stretch / u_collision_y_stretch);\n\n gl_Position = u_matrix * vec4(a_pos + a_extrude * collision_perspective_ratio * collision_adjustment / u_scale, 0.0, 1.0);\n\n v_max_zoom = a_data.x;\n v_placement_zoom = a_data.y;\n\n v_perspective_zoom_adjust = floor(log2(collision_perspective_ratio * collision_adjustment) * 10.0);\n v_fade_tex = vec2((v_placement_zoom + v_perspective_zoom_adjust) / 255.0, 0.0);\n}\n"},debug:{fragmentSource:"uniform highp vec4 u_color;\n\nvoid main() {\n gl_FragColor = u_color;\n}\n",vertexSource:"attribute vec2 a_pos;\n\nuniform mat4 u_matrix;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, step(32767.0, a_pos.x), 1);\n}\n"},fill:{fragmentSource:"#pragma mapbox: define highp vec4 color\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n #pragma mapbox: initialize highp vec4 color\n #pragma mapbox: initialize lowp float opacity\n\n gl_FragColor = color * opacity;\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:"attribute vec2 a_pos;\n\nuniform mat4 u_matrix;\n\n#pragma mapbox: define highp vec4 color\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n #pragma mapbox: initialize highp vec4 color\n #pragma mapbox: initialize lowp float opacity\n\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n}\n"},fillOutline:{fragmentSource:"#pragma mapbox: define highp vec4 outline_color\n#pragma mapbox: define lowp float opacity\n\nvarying vec2 v_pos;\n\nvoid main() {\n #pragma mapbox: initialize highp vec4 outline_color\n #pragma mapbox: initialize lowp float opacity\n\n float dist = length(v_pos - gl_FragCoord.xy);\n float alpha = 1.0 - smoothstep(0.0, 1.0, dist);\n gl_FragColor = outline_color * (alpha * opacity);\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:"attribute vec2 a_pos;\n\nuniform mat4 u_matrix;\nuniform vec2 u_world;\n\nvarying vec2 v_pos;\n\n#pragma mapbox: define highp vec4 outline_color\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n #pragma mapbox: initialize highp vec4 outline_color\n #pragma mapbox: initialize lowp float opacity\n\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n v_pos = (gl_Position.xy / gl_Position.w + 1.0) / 2.0 * u_world;\n}\n"},fillOutlinePattern:{fragmentSource:"uniform vec2 u_pattern_tl_a;\nuniform vec2 u_pattern_br_a;\nuniform vec2 u_pattern_tl_b;\nuniform vec2 u_pattern_br_b;\nuniform vec2 u_texsize;\nuniform float u_mix;\n\nuniform sampler2D u_image;\n\nvarying vec2 v_pos_a;\nvarying vec2 v_pos_b;\nvarying vec2 v_pos;\n\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n #pragma mapbox: initialize lowp float opacity\n\n vec2 imagecoord = mod(v_pos_a, 1.0);\n vec2 pos = mix(u_pattern_tl_a / u_texsize, u_pattern_br_a / u_texsize, imagecoord);\n vec4 color1 = texture2D(u_image, pos);\n\n vec2 imagecoord_b = mod(v_pos_b, 1.0);\n vec2 pos2 = mix(u_pattern_tl_b / u_texsize, u_pattern_br_b / u_texsize, imagecoord_b);\n vec4 color2 = texture2D(u_image, pos2);\n\n // find distance to outline for alpha interpolation\n\n float dist = length(v_pos - gl_FragCoord.xy);\n float alpha = 1.0 - smoothstep(0.0, 1.0, dist);\n\n\n gl_FragColor = mix(color1, color2, u_mix) * alpha * opacity;\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:"uniform mat4 u_matrix;\nuniform vec2 u_world;\nuniform vec2 u_pattern_size_a;\nuniform vec2 u_pattern_size_b;\nuniform vec2 u_pixel_coord_upper;\nuniform vec2 u_pixel_coord_lower;\nuniform float u_scale_a;\nuniform float u_scale_b;\nuniform float u_tile_units_to_pixels;\n\nattribute vec2 a_pos;\n\nvarying vec2 v_pos_a;\nvarying vec2 v_pos_b;\nvarying vec2 v_pos;\n\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n #pragma mapbox: initialize lowp float opacity\n\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n\n v_pos_a = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, u_scale_a * u_pattern_size_a, u_tile_units_to_pixels, a_pos);\n v_pos_b = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, u_scale_b * u_pattern_size_b, u_tile_units_to_pixels, a_pos);\n\n v_pos = (gl_Position.xy / gl_Position.w + 1.0) / 2.0 * u_world;\n}\n"},fillPattern:{fragmentSource:"uniform vec2 u_pattern_tl_a;\nuniform vec2 u_pattern_br_a;\nuniform vec2 u_pattern_tl_b;\nuniform vec2 u_pattern_br_b;\nuniform vec2 u_texsize;\nuniform float u_mix;\n\nuniform sampler2D u_image;\n\nvarying vec2 v_pos_a;\nvarying vec2 v_pos_b;\n\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n #pragma mapbox: initialize lowp float opacity\n\n vec2 imagecoord = mod(v_pos_a, 1.0);\n vec2 pos = mix(u_pattern_tl_a / u_texsize, u_pattern_br_a / u_texsize, imagecoord);\n vec4 color1 = texture2D(u_image, pos);\n\n vec2 imagecoord_b = mod(v_pos_b, 1.0);\n vec2 pos2 = mix(u_pattern_tl_b / u_texsize, u_pattern_br_b / u_texsize, imagecoord_b);\n vec4 color2 = texture2D(u_image, pos2);\n\n gl_FragColor = mix(color1, color2, u_mix) * opacity;\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:"uniform mat4 u_matrix;\nuniform vec2 u_pattern_size_a;\nuniform vec2 u_pattern_size_b;\nuniform vec2 u_pixel_coord_upper;\nuniform vec2 u_pixel_coord_lower;\nuniform float u_scale_a;\nuniform float u_scale_b;\nuniform float u_tile_units_to_pixels;\n\nattribute vec2 a_pos;\n\nvarying vec2 v_pos_a;\nvarying vec2 v_pos_b;\n\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n #pragma mapbox: initialize lowp float opacity\n\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n\n v_pos_a = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, u_scale_a * u_pattern_size_a, u_tile_units_to_pixels, a_pos);\n v_pos_b = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, u_scale_b * u_pattern_size_b, u_tile_units_to_pixels, a_pos);\n}\n"},fillExtrusion:{fragmentSource:"varying vec4 v_color;\n#pragma mapbox: define lowp float base\n#pragma mapbox: define lowp float height\n#pragma mapbox: define highp vec4 color\n\nvoid main() {\n #pragma mapbox: initialize lowp float base\n #pragma mapbox: initialize lowp float height\n #pragma mapbox: initialize highp vec4 color\n\n gl_FragColor = v_color;\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:"uniform mat4 u_matrix;\nuniform vec3 u_lightcolor;\nuniform lowp vec3 u_lightpos;\nuniform lowp float u_lightintensity;\n\nattribute vec2 a_pos;\nattribute vec3 a_normal;\nattribute float a_edgedistance;\n\nvarying vec4 v_color;\n\n#pragma mapbox: define lowp float base\n#pragma mapbox: define lowp float height\n\n#pragma mapbox: define highp vec4 color\n\nvoid main() {\n #pragma mapbox: initialize lowp float base\n #pragma mapbox: initialize lowp float height\n #pragma mapbox: initialize highp vec4 color\n\n base = max(0.0, base);\n height = max(0.0, height);\n\n float ed = a_edgedistance; // use each attrib in order to not trip a VAO assert\n float t = mod(a_normal.x, 2.0);\n\n gl_Position = u_matrix * vec4(a_pos, t > 0.0 ? height : base, 1);\n\n // Relative luminance (how dark/bright is the surface color?)\n float colorvalue = color.r * 0.2126 + color.g * 0.7152 + color.b * 0.0722;\n\n v_color = vec4(0.0, 0.0, 0.0, 1.0);\n\n // Add slight ambient lighting so no extrusions are totally black\n vec4 ambientlight = vec4(0.03, 0.03, 0.03, 1.0);\n color += ambientlight;\n\n // Calculate cos(theta), where theta is the angle between surface normal and diffuse light ray\n float directional = clamp(dot(a_normal / 16384.0, u_lightpos), 0.0, 1.0);\n\n // Adjust directional so that\n // the range of values for highlight/shading is narrower\n // with lower light intensity\n // and with lighter/brighter surface colors\n directional = mix((1.0 - u_lightintensity), max((1.0 - colorvalue + u_lightintensity), 1.0), directional);\n\n // Add gradient along z axis of side surfaces\n if (a_normal.y != 0.0) {\n directional *= clamp((t + base) * pow(height / 150.0, 0.5), mix(0.7, 0.98, 1.0 - u_lightintensity), 1.0);\n }\n\n // Assign final color based on surface + ambient light color, diffuse light directional, and light color\n // with lower bounds adjusted to hue of light\n // so that shading is tinted with the complementary (opposite) color to the light color\n v_color.r += clamp(color.r * directional * u_lightcolor.r, mix(0.0, 0.3, 1.0 - u_lightcolor.r), 1.0);\n v_color.g += clamp(color.g * directional * u_lightcolor.g, mix(0.0, 0.3, 1.0 - u_lightcolor.g), 1.0);\n v_color.b += clamp(color.b * directional * u_lightcolor.b, mix(0.0, 0.3, 1.0 - u_lightcolor.b), 1.0);\n}\n"},fillExtrusionPattern:{fragmentSource:"uniform vec2 u_pattern_tl_a;\nuniform vec2 u_pattern_br_a;\nuniform vec2 u_pattern_tl_b;\nuniform vec2 u_pattern_br_b;\nuniform vec2 u_texsize;\nuniform float u_mix;\n\nuniform sampler2D u_image;\n\nvarying vec2 v_pos_a;\nvarying vec2 v_pos_b;\nvarying vec4 v_lighting;\n\n#pragma mapbox: define lowp float base\n#pragma mapbox: define lowp float height\n\nvoid main() {\n #pragma mapbox: initialize lowp float base\n #pragma mapbox: initialize lowp float height\n\n vec2 imagecoord = mod(v_pos_a, 1.0);\n vec2 pos = mix(u_pattern_tl_a / u_texsize, u_pattern_br_a / u_texsize, imagecoord);\n vec4 color1 = texture2D(u_image, pos);\n\n vec2 imagecoord_b = mod(v_pos_b, 1.0);\n vec2 pos2 = mix(u_pattern_tl_b / u_texsize, u_pattern_br_b / u_texsize, imagecoord_b);\n vec4 color2 = texture2D(u_image, pos2);\n\n vec4 mixedColor = mix(color1, color2, u_mix);\n\n gl_FragColor = mixedColor * v_lighting;\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:"uniform mat4 u_matrix;\nuniform vec2 u_pattern_size_a;\nuniform vec2 u_pattern_size_b;\nuniform vec2 u_pixel_coord_upper;\nuniform vec2 u_pixel_coord_lower;\nuniform float u_scale_a;\nuniform float u_scale_b;\nuniform float u_tile_units_to_pixels;\nuniform float u_height_factor;\n\nuniform vec3 u_lightcolor;\nuniform lowp vec3 u_lightpos;\nuniform lowp float u_lightintensity;\n\nattribute vec2 a_pos;\nattribute vec3 a_normal;\nattribute float a_edgedistance;\n\nvarying vec2 v_pos_a;\nvarying vec2 v_pos_b;\nvarying vec4 v_lighting;\nvarying float v_directional;\n\n#pragma mapbox: define lowp float base\n#pragma mapbox: define lowp float height\n\nvoid main() {\n #pragma mapbox: initialize lowp float base\n #pragma mapbox: initialize lowp float height\n\n base = max(0.0, base);\n height = max(0.0, height);\n\n float t = mod(a_normal.x, 2.0);\n float z = t > 0.0 ? height : base;\n\n gl_Position = u_matrix * vec4(a_pos, z, 1);\n\n vec2 pos = a_normal.x == 1.0 && a_normal.y == 0.0 && a_normal.z == 16384.0\n ? a_pos // extrusion top\n : vec2(a_edgedistance, z * u_height_factor); // extrusion side\n\n v_pos_a = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, u_scale_a * u_pattern_size_a, u_tile_units_to_pixels, pos);\n v_pos_b = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, u_scale_b * u_pattern_size_b, u_tile_units_to_pixels, pos);\n\n v_lighting = vec4(0.0, 0.0, 0.0, 1.0);\n float directional = clamp(dot(a_normal / 16383.0, u_lightpos), 0.0, 1.0);\n directional = mix((1.0 - u_lightintensity), max((0.5 + u_lightintensity), 1.0), directional);\n\n if (a_normal.y != 0.0) {\n directional *= clamp((t + base) * pow(height / 150.0, 0.5), mix(0.7, 0.98, 1.0 - u_lightintensity), 1.0);\n }\n\n v_lighting.rgb += clamp(directional * u_lightcolor, mix(vec3(0.0), vec3(0.3), 1.0 - u_lightcolor), vec3(1.0));\n}\n"},extrusionTexture:{fragmentSource:"uniform sampler2D u_image;\nuniform float u_opacity;\nvarying vec2 v_pos;\n\nvoid main() {\n gl_FragColor = texture2D(u_image, v_pos) * u_opacity;\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(0.0);\n#endif\n}\n",vertexSource:"uniform mat4 u_matrix;\nuniform vec2 u_world;\nattribute vec2 a_pos;\nvarying vec2 v_pos;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos * u_world, 0, 1);\n\n v_pos.x = a_pos.x;\n v_pos.y = 1.0 - a_pos.y;\n}\n"},line:{fragmentSource:"#pragma mapbox: define highp vec4 color\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n\nvarying vec2 v_width2;\nvarying vec2 v_normal;\nvarying float v_gamma_scale;\n\nvoid main() {\n #pragma mapbox: initialize highp vec4 color\n #pragma mapbox: initialize lowp float blur\n #pragma mapbox: initialize lowp float opacity\n\n // Calculate the distance of the pixel from the line in pixels.\n float dist = length(v_normal) * v_width2.s;\n\n // Calculate the antialiasing fade factor. This is either when fading in\n // the line in case of an offset line (v_width2.t) or when fading out\n // (v_width2.s)\n float blur2 = (blur + 1.0 / DEVICE_PIXEL_RATIO) * v_gamma_scale;\n float alpha = clamp(min(dist - (v_width2.t - blur2), v_width2.s - dist) / blur2, 0.0, 1.0);\n\n gl_FragColor = color * (alpha * opacity);\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:"\n\n// the distance over which the line edge fades out.\n// Retina devices need a smaller distance to avoid aliasing.\n#define ANTIALIASING 1.0 / DEVICE_PIXEL_RATIO / 2.0\n\n// floor(127 / 2) == 63.0\n// the maximum allowed miter limit is 2.0 at the moment. the extrude normal is\n// stored in a byte (-128..127). we scale regular normals up to length 63, but\n// there are also \"special\" normals that have a bigger length (of up to 126 in\n// this case).\n// #define scale 63.0\n#define scale 0.015873016\n\nattribute vec2 a_pos;\nattribute vec4 a_data;\n\nuniform mat4 u_matrix;\nuniform mediump float u_ratio;\nuniform mediump float u_width;\nuniform vec2 u_gl_units_to_pixels;\n\nvarying vec2 v_normal;\nvarying vec2 v_width2;\nvarying float v_gamma_scale;\n\n#pragma mapbox: define highp vec4 color\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define mediump float gapwidth\n#pragma mapbox: define lowp float offset\n\nvoid main() {\n #pragma mapbox: initialize highp vec4 color\n #pragma mapbox: initialize lowp float blur\n #pragma mapbox: initialize lowp float opacity\n #pragma mapbox: initialize mediump float gapwidth\n #pragma mapbox: initialize lowp float offset\n\n vec2 a_extrude = a_data.xy - 128.0;\n float a_direction = mod(a_data.z, 4.0) - 1.0;\n\n // We store the texture normals in the most insignificant bit\n // transform y so that 0 => -1 and 1 => 1\n // In the texture normal, x is 0 if the normal points straight up/down and 1 if it's a round cap\n // y is 1 if the normal points up, and -1 if it points down\n mediump vec2 normal = mod(a_pos, 2.0);\n normal.y = sign(normal.y - 0.5);\n v_normal = normal;\n\n\n // these transformations used to be applied in the JS and native code bases. \n // moved them into the shader for clarity and simplicity. \n gapwidth = gapwidth / 2.0;\n float width = u_width / 2.0;\n offset = -1.0 * offset; \n\n float inset = gapwidth + (gapwidth > 0.0 ? ANTIALIASING : 0.0);\n float outset = gapwidth + width * (gapwidth > 0.0 ? 2.0 : 1.0) + ANTIALIASING;\n\n // Scale the extrusion vector down to a normal and then up by the line width\n // of this vertex.\n mediump vec2 dist = outset * a_extrude * scale;\n\n // Calculate the offset when drawing a line that is to the side of the actual line.\n // We do this by creating a vector that points towards the extrude, but rotate\n // it when we're drawing round end points (a_direction = -1 or 1) since their\n // extrude vector points in another direction.\n mediump float u = 0.5 * a_direction;\n mediump float t = 1.0 - abs(u);\n mediump vec2 offset2 = offset * a_extrude * scale * normal.y * mat2(t, -u, u, t);\n\n // Remove the texture normal bit to get the position\n vec2 pos = floor(a_pos * 0.5);\n\n vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0);\n gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude;\n\n // calculate how much the perspective view squishes or stretches the extrude\n float extrude_length_without_perspective = length(dist);\n float extrude_length_with_perspective = length(projected_extrude.xy / gl_Position.w * u_gl_units_to_pixels);\n v_gamma_scale = extrude_length_without_perspective / extrude_length_with_perspective;\n\n v_width2 = vec2(outset, inset);\n}\n"},linePattern:{fragmentSource:"uniform vec2 u_pattern_size_a;\nuniform vec2 u_pattern_size_b;\nuniform vec2 u_pattern_tl_a;\nuniform vec2 u_pattern_br_a;\nuniform vec2 u_pattern_tl_b;\nuniform vec2 u_pattern_br_b;\nuniform vec2 u_texsize;\nuniform float u_fade;\n\nuniform sampler2D u_image;\n\nvarying vec2 v_normal;\nvarying vec2 v_width2;\nvarying float v_linesofar;\nvarying float v_gamma_scale;\n\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n #pragma mapbox: initialize lowp float blur\n #pragma mapbox: initialize lowp float opacity\n\n // Calculate the distance of the pixel from the line in pixels.\n float dist = length(v_normal) * v_width2.s;\n\n // Calculate the antialiasing fade factor. This is either when fading in\n // the line in case of an offset line (v_width2.t) or when fading out\n // (v_width2.s)\n float blur2 = (blur + 1.0 / DEVICE_PIXEL_RATIO) * v_gamma_scale;\n float alpha = clamp(min(dist - (v_width2.t - blur2), v_width2.s - dist) / blur2, 0.0, 1.0);\n\n float x_a = mod(v_linesofar / u_pattern_size_a.x, 1.0);\n float x_b = mod(v_linesofar / u_pattern_size_b.x, 1.0);\n float y_a = 0.5 + (v_normal.y * v_width2.s / u_pattern_size_a.y);\n float y_b = 0.5 + (v_normal.y * v_width2.s / u_pattern_size_b.y);\n vec2 pos_a = mix(u_pattern_tl_a / u_texsize, u_pattern_br_a / u_texsize, vec2(x_a, y_a));\n vec2 pos_b = mix(u_pattern_tl_b / u_texsize, u_pattern_br_b / u_texsize, vec2(x_b, y_b));\n\n vec4 color = mix(texture2D(u_image, pos_a), texture2D(u_image, pos_b), u_fade);\n\n gl_FragColor = color * alpha * opacity;\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:"// floor(127 / 2) == 63.0\n// the maximum allowed miter limit is 2.0 at the moment. the extrude normal is\n// stored in a byte (-128..127). we scale regular normals up to length 63, but\n// there are also \"special\" normals that have a bigger length (of up to 126 in\n// this case).\n// #define scale 63.0\n#define scale 0.015873016\n\n// We scale the distance before adding it to the buffers so that we can store\n// long distances for long segments. Use this value to unscale the distance.\n#define LINE_DISTANCE_SCALE 2.0\n\n// the distance over which the line edge fades out.\n// Retina devices need a smaller distance to avoid aliasing.\n#define ANTIALIASING 1.0 / DEVICE_PIXEL_RATIO / 2.0\n\nattribute vec2 a_pos;\nattribute vec4 a_data;\n\nuniform mat4 u_matrix;\nuniform mediump float u_ratio;\nuniform mediump float u_width;\nuniform vec2 u_gl_units_to_pixels;\n\nvarying vec2 v_normal;\nvarying vec2 v_width2;\nvarying float v_linesofar;\nvarying float v_gamma_scale;\n\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define lowp float offset\n#pragma mapbox: define mediump float gapwidth\n\nvoid main() {\n #pragma mapbox: initialize lowp float blur\n #pragma mapbox: initialize lowp float opacity\n #pragma mapbox: initialize lowp float offset\n #pragma mapbox: initialize mediump float gapwidth\n\n vec2 a_extrude = a_data.xy - 128.0;\n float a_direction = mod(a_data.z, 4.0) - 1.0;\n float a_linesofar = (floor(a_data.z / 4.0) + a_data.w * 64.0) * LINE_DISTANCE_SCALE;\n\n // We store the texture normals in the most insignificant bit\n // transform y so that 0 => -1 and 1 => 1\n // In the texture normal, x is 0 if the normal points straight up/down and 1 if it's a round cap\n // y is 1 if the normal points up, and -1 if it points down\n mediump vec2 normal = mod(a_pos, 2.0);\n normal.y = sign(normal.y - 0.5);\n v_normal = normal;\n\n // these transformations used to be applied in the JS and native code bases. \n // moved them into the shader for clarity and simplicity. \n gapwidth = gapwidth / 2.0;\n float width = u_width / 2.0;\n offset = -1.0 * offset; \n\n float inset = gapwidth + (gapwidth > 0.0 ? ANTIALIASING : 0.0);\n float outset = gapwidth + width * (gapwidth > 0.0 ? 2.0 : 1.0) + ANTIALIASING;\n\n // Scale the extrusion vector down to a normal and then up by the line width\n // of this vertex.\n mediump vec2 dist = outset * a_extrude * scale;\n\n // Calculate the offset when drawing a line that is to the side of the actual line.\n // We do this by creating a vector that points towards the extrude, but rotate\n // it when we're drawing round end points (a_direction = -1 or 1) since their\n // extrude vector points in another direction.\n mediump float u = 0.5 * a_direction;\n mediump float t = 1.0 - abs(u);\n mediump vec2 offset2 = offset * a_extrude * scale * normal.y * mat2(t, -u, u, t);\n\n // Remove the texture normal bit to get the position\n vec2 pos = floor(a_pos * 0.5);\n\n vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0);\n gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude;\n\n // calculate how much the perspective view squishes or stretches the extrude\n float extrude_length_without_perspective = length(dist);\n float extrude_length_with_perspective = length(projected_extrude.xy / gl_Position.w * u_gl_units_to_pixels);\n v_gamma_scale = extrude_length_without_perspective / extrude_length_with_perspective;\n\n v_linesofar = a_linesofar;\n v_width2 = vec2(outset, inset);\n}\n"},lineSDF:{fragmentSource:"\nuniform sampler2D u_image;\nuniform float u_sdfgamma;\nuniform float u_mix;\n\nvarying vec2 v_normal;\nvarying vec2 v_width2;\nvarying vec2 v_tex_a;\nvarying vec2 v_tex_b;\nvarying float v_gamma_scale;\n\n#pragma mapbox: define highp vec4 color\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n #pragma mapbox: initialize highp vec4 color\n #pragma mapbox: initialize lowp float blur\n #pragma mapbox: initialize lowp float opacity\n\n // Calculate the distance of the pixel from the line in pixels.\n float dist = length(v_normal) * v_width2.s;\n\n // Calculate the antialiasing fade factor. This is either when fading in\n // the line in case of an offset line (v_width2.t) or when fading out\n // (v_width2.s)\n float blur2 = (blur + 1.0 / DEVICE_PIXEL_RATIO) * v_gamma_scale;\n float alpha = clamp(min(dist - (v_width2.t - blur2), v_width2.s - dist) / blur2, 0.0, 1.0);\n\n float sdfdist_a = texture2D(u_image, v_tex_a).a;\n float sdfdist_b = texture2D(u_image, v_tex_b).a;\n float sdfdist = mix(sdfdist_a, sdfdist_b, u_mix);\n alpha *= smoothstep(0.5 - u_sdfgamma, 0.5 + u_sdfgamma, sdfdist);\n\n gl_FragColor = color * (alpha * opacity);\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",
  163 +vertexSource:"// floor(127 / 2) == 63.0\n// the maximum allowed miter limit is 2.0 at the moment. the extrude normal is\n// stored in a byte (-128..127). we scale regular normals up to length 63, but\n// there are also \"special\" normals that have a bigger length (of up to 126 in\n// this case).\n// #define scale 63.0\n#define scale 0.015873016\n\n// We scale the distance before adding it to the buffers so that we can store\n// long distances for long segments. Use this value to unscale the distance.\n#define LINE_DISTANCE_SCALE 2.0\n\n// the distance over which the line edge fades out.\n// Retina devices need a smaller distance to avoid aliasing.\n#define ANTIALIASING 1.0 / DEVICE_PIXEL_RATIO / 2.0\n\nattribute vec2 a_pos;\nattribute vec4 a_data;\n\nuniform mat4 u_matrix;\nuniform mediump float u_ratio;\nuniform vec2 u_patternscale_a;\nuniform float u_tex_y_a;\nuniform vec2 u_patternscale_b;\nuniform float u_tex_y_b;\nuniform vec2 u_gl_units_to_pixels;\nuniform mediump float u_width;\n\nvarying vec2 v_normal;\nvarying vec2 v_width2;\nvarying vec2 v_tex_a;\nvarying vec2 v_tex_b;\nvarying float v_gamma_scale;\n\n#pragma mapbox: define highp vec4 color\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define mediump float gapwidth\n#pragma mapbox: define lowp float offset\n\nvoid main() {\n #pragma mapbox: initialize highp vec4 color\n #pragma mapbox: initialize lowp float blur\n #pragma mapbox: initialize lowp float opacity\n #pragma mapbox: initialize mediump float gapwidth\n #pragma mapbox: initialize lowp float offset\n\n vec2 a_extrude = a_data.xy - 128.0;\n float a_direction = mod(a_data.z, 4.0) - 1.0;\n float a_linesofar = (floor(a_data.z / 4.0) + a_data.w * 64.0) * LINE_DISTANCE_SCALE;\n\n // We store the texture normals in the most insignificant bit\n // transform y so that 0 => -1 and 1 => 1\n // In the texture normal, x is 0 if the normal points straight up/down and 1 if it's a round cap\n // y is 1 if the normal points up, and -1 if it points down\n mediump vec2 normal = mod(a_pos, 2.0);\n normal.y = sign(normal.y - 0.5);\n v_normal = normal;\n\n // these transformations used to be applied in the JS and native code bases. \n // moved them into the shader for clarity and simplicity. \n gapwidth = gapwidth / 2.0;\n float width = u_width / 2.0;\n offset = -1.0 * offset;\n \n float inset = gapwidth + (gapwidth > 0.0 ? ANTIALIASING : 0.0);\n float outset = gapwidth + width * (gapwidth > 0.0 ? 2.0 : 1.0) + ANTIALIASING;\n\n // Scale the extrusion vector down to a normal and then up by the line width\n // of this vertex.\n mediump vec2 dist =outset * a_extrude * scale;\n\n // Calculate the offset when drawing a line that is to the side of the actual line.\n // We do this by creating a vector that points towards the extrude, but rotate\n // it when we're drawing round end points (a_direction = -1 or 1) since their\n // extrude vector points in another direction.\n mediump float u = 0.5 * a_direction;\n mediump float t = 1.0 - abs(u);\n mediump vec2 offset2 = offset * a_extrude * scale * normal.y * mat2(t, -u, u, t);\n\n // Remove the texture normal bit to get the position\n vec2 pos = floor(a_pos * 0.5);\n\n vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0);\n gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude;\n\n // calculate how much the perspective view squishes or stretches the extrude\n float extrude_length_without_perspective = length(dist);\n float extrude_length_with_perspective = length(projected_extrude.xy / gl_Position.w * u_gl_units_to_pixels);\n v_gamma_scale = extrude_length_without_perspective / extrude_length_with_perspective;\n\n v_tex_a = vec2(a_linesofar * u_patternscale_a.x, normal.y * u_patternscale_a.y + u_tex_y_a);\n v_tex_b = vec2(a_linesofar * u_patternscale_b.x, normal.y * u_patternscale_b.y + u_tex_y_b);\n\n v_width2 = vec2(outset, inset);\n}\n"},raster:{fragmentSource:"uniform float u_fade_t;\nuniform float u_opacity;\nuniform sampler2D u_image0;\nuniform sampler2D u_image1;\nvarying vec2 v_pos0;\nvarying vec2 v_pos1;\n\nuniform float u_brightness_low;\nuniform float u_brightness_high;\n\nuniform float u_saturation_factor;\nuniform float u_contrast_factor;\nuniform vec3 u_spin_weights;\n\nvoid main() {\n\n // read and cross-fade colors from the main and parent tiles\n vec4 color0 = texture2D(u_image0, v_pos0);\n vec4 color1 = texture2D(u_image1, v_pos1);\n vec4 color = mix(color0, color1, u_fade_t);\n color.a *= u_opacity;\n vec3 rgb = color.rgb;\n\n // spin\n rgb = vec3(\n dot(rgb, u_spin_weights.xyz),\n dot(rgb, u_spin_weights.zxy),\n dot(rgb, u_spin_weights.yzx));\n\n // saturation\n float average = (color.r + color.g + color.b) / 3.0;\n rgb += (average - rgb) * u_saturation_factor;\n\n // contrast\n rgb = (rgb - 0.5) * u_contrast_factor + 0.5;\n\n // brightness\n vec3 u_high_vec = vec3(u_brightness_low, u_brightness_low, u_brightness_low);\n vec3 u_low_vec = vec3(u_brightness_high, u_brightness_high, u_brightness_high);\n\n gl_FragColor = vec4(mix(u_high_vec, u_low_vec, rgb) * color.a, color.a);\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:"uniform mat4 u_matrix;\nuniform vec2 u_tl_parent;\nuniform float u_scale_parent;\nuniform float u_buffer_scale;\n\nattribute vec2 a_pos;\nattribute vec2 a_texture_pos;\n\nvarying vec2 v_pos0;\nvarying vec2 v_pos1;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n v_pos0 = (((a_texture_pos / 32767.0) - 0.5) / u_buffer_scale ) + 0.5;\n v_pos1 = (v_pos0 * u_scale_parent) + u_tl_parent;\n}\n"},symbolIcon:{fragmentSource:"uniform sampler2D u_texture;\nuniform sampler2D u_fadetexture;\n\n#pragma mapbox: define lowp float opacity\n\nvarying vec2 v_tex;\nvarying vec2 v_fade_tex;\n\nvoid main() {\n #pragma mapbox: initialize lowp float opacity\n\n lowp float alpha = texture2D(u_fadetexture, v_fade_tex).a * opacity;\n gl_FragColor = texture2D(u_texture, v_tex) * alpha;\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:'attribute vec4 a_pos_offset;\nattribute vec2 a_label_pos;\nattribute vec4 a_data;\n\n// icon-size data (see symbol_sdf.vertex.glsl for more)\nattribute vec3 a_size;\nuniform bool u_is_size_zoom_constant;\nuniform bool u_is_size_feature_constant;\nuniform highp float u_size_t; // used to interpolate between zoom stops when size is a composite function\nuniform highp float u_size; // used when size is both zoom and feature constant\nuniform highp float u_layout_size; // used when size is feature constant\nuniform highp float u_camera_to_center_distance;\nuniform highp float u_pitch;\nuniform highp float u_collision_y_stretch;\n\n#pragma mapbox: define lowp float opacity\n\n// matrix is for the vertex position.\nuniform mat4 u_matrix;\n\nuniform bool u_is_text;\nuniform highp float u_zoom;\nuniform bool u_rotate_with_map;\nuniform vec2 u_extrude_scale;\n\nuniform vec2 u_texsize;\n\nvarying vec2 v_tex;\nvarying vec2 v_fade_tex;\n\nvoid main() {\n #pragma mapbox: initialize lowp float opacity\n\n vec2 a_pos = a_pos_offset.xy;\n vec2 a_offset = a_pos_offset.zw;\n\n vec2 a_tex = a_data.xy;\n highp vec2 label_data = unpack_float(a_data[2]);\n highp float a_labelminzoom = label_data[0];\n highp vec2 a_zoom = unpack_float(a_data[3]);\n highp float a_minzoom = a_zoom[0];\n highp float a_maxzoom = a_zoom[1];\n\n float size;\n // In order to accommodate placing labels around corners in\n // symbol-placement: line, each glyph in a label could have multiple\n // "quad"s only one of which should be shown at a given zoom level.\n // The min/max zoom assigned to each quad is based on the font size at\n // the vector tile\'s zoom level, which might be different than at the\n // currently rendered zoom level if text-size is zoom-dependent.\n // Thus, we compensate for this difference by calculating an adjustment\n // based on the scale of rendered text size relative to layout text size.\n highp float layoutSize;\n if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {\n size = mix(a_size[0], a_size[1], u_size_t) / 10.0;\n layoutSize = a_size[2] / 10.0;\n } else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {\n size = a_size[0] / 10.0;\n layoutSize = size;\n } else if (!u_is_size_zoom_constant && u_is_size_feature_constant) {\n size = u_size;\n layoutSize = u_layout_size;\n } else {\n size = u_size;\n layoutSize = u_size;\n }\n\n float fontScale = u_is_text ? size / 24.0 : size;\n\n highp float zoomAdjust = log2(size / layoutSize);\n highp float adjustedZoom = (u_zoom - zoomAdjust) * 10.0;\n // result: z = 0 if a_minzoom <= adjustedZoom < a_maxzoom, and 1 otherwise\n highp float z = 2.0 - step(a_minzoom, adjustedZoom) - (1.0 - step(a_maxzoom, adjustedZoom));\n\n vec4 projectedPoint = u_matrix * vec4(a_label_pos, 0, 1);\n highp float camera_to_anchor_distance = projectedPoint.w;\n highp float perspective_ratio = 1.0 + 0.5*((camera_to_anchor_distance / u_camera_to_center_distance) - 1.0);\n\n vec2 extrude = fontScale * u_extrude_scale * perspective_ratio * (a_offset / 64.0);\n if (u_rotate_with_map) {\n gl_Position = u_matrix * vec4(a_pos + extrude, 0, 1);\n gl_Position.z += z * gl_Position.w;\n } else {\n gl_Position = u_matrix * vec4(a_pos, 0, 1) + vec4(extrude, 0, 0);\n }\n\n v_tex = a_tex / u_texsize;\n // See comments in symbol_sdf.vertex\n highp float incidence_stretch = camera_to_anchor_distance / (u_camera_to_center_distance * cos(u_pitch));\n highp float collision_adjustment = max(1.0, incidence_stretch / u_collision_y_stretch);\n\n highp float perspective_zoom_adjust = floor(log2(perspective_ratio * collision_adjustment) * 10.0);\n v_fade_tex = vec2((a_labelminzoom + perspective_zoom_adjust) / 255.0, 0.0);\n}\n'},symbolSDF:{fragmentSource:"#define SDF_PX 8.0\n#define EDGE_GAMMA 0.105/DEVICE_PIXEL_RATIO\n\nuniform bool u_is_halo;\n#pragma mapbox: define highp vec4 fill_color\n#pragma mapbox: define highp vec4 halo_color\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define lowp float halo_width\n#pragma mapbox: define lowp float halo_blur\n\nuniform sampler2D u_texture;\nuniform sampler2D u_fadetexture;\nuniform highp float u_gamma_scale;\nuniform bool u_is_text;\n\nvarying vec2 v_tex;\nvarying vec2 v_fade_tex;\nvarying float v_gamma_scale;\nvarying float v_size;\n\nvoid main() {\n #pragma mapbox: initialize highp vec4 fill_color\n #pragma mapbox: initialize highp vec4 halo_color\n #pragma mapbox: initialize lowp float opacity\n #pragma mapbox: initialize lowp float halo_width\n #pragma mapbox: initialize lowp float halo_blur\n\n float fontScale = u_is_text ? v_size / 24.0 : v_size;\n\n lowp vec4 color = fill_color;\n highp float gamma = EDGE_GAMMA / (fontScale * u_gamma_scale);\n lowp float buff = (256.0 - 64.0) / 256.0;\n if (u_is_halo) {\n color = halo_color;\n gamma = (halo_blur * 1.19 / SDF_PX + EDGE_GAMMA) / (fontScale * u_gamma_scale);\n buff = (6.0 - halo_width / fontScale) / SDF_PX;\n }\n\n lowp float dist = texture2D(u_texture, v_tex).a;\n lowp float fade_alpha = texture2D(u_fadetexture, v_fade_tex).a;\n highp float gamma_scaled = gamma * v_gamma_scale;\n highp float alpha = smoothstep(buff - gamma_scaled, buff + gamma_scaled, dist) * fade_alpha;\n\n gl_FragColor = color * (alpha * opacity);\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:"const float PI = 3.141592653589793;\n\nattribute vec4 a_pos_offset;\nattribute vec2 a_label_pos;\nattribute vec4 a_data;\n\n// contents of a_size vary based on the type of property value\n// used for {text,icon}-size.\n// For constants, a_size is disabled.\n// For source functions, we bind only one value per vertex: the value of {text,icon}-size evaluated for the current feature.\n// For composite functions:\n// [ text-size(lowerZoomStop, feature),\n// text-size(upperZoomStop, feature),\n// layoutSize == text-size(layoutZoomLevel, feature) ]\nattribute vec3 a_size;\nuniform bool u_is_size_zoom_constant;\nuniform bool u_is_size_feature_constant;\nuniform highp float u_size_t; // used to interpolate between zoom stops when size is a composite function\nuniform highp float u_size; // used when size is both zoom and feature constant\nuniform highp float u_layout_size; // used when size is feature constant\n\n#pragma mapbox: define highp vec4 fill_color\n#pragma mapbox: define highp vec4 halo_color\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define lowp float halo_width\n#pragma mapbox: define lowp float halo_blur\n\n// matrix is for the vertex position.\nuniform mat4 u_matrix;\n\nuniform bool u_is_text;\nuniform highp float u_zoom;\nuniform bool u_rotate_with_map;\nuniform bool u_pitch_with_map;\nuniform highp float u_pitch;\nuniform highp float u_bearing;\nuniform highp float u_aspect_ratio;\nuniform highp float u_camera_to_center_distance;\nuniform highp float u_max_camera_distance;\nuniform highp float u_collision_y_stretch;\nuniform vec2 u_extrude_scale;\n\nuniform vec2 u_texsize;\n\nvarying vec2 v_tex;\nvarying vec2 v_fade_tex;\nvarying float v_gamma_scale;\nvarying float v_size;\n\n// Used below to move the vertex out of the clip space for when the current\n// zoom is out of the glyph's zoom range.\nhighp float clipUnusedGlyphAngles(const highp float render_size,\n const highp float layout_size,\n const highp float min_zoom,\n const highp float max_zoom) {\n highp float zoom_adjust = log2(render_size / layout_size);\n highp float adjusted_zoom = (u_zoom - zoom_adjust) * 10.0;\n // result: 0 if min_zoom <= adjusted_zoom < max_zoom, and 1 otherwise\n return 2.0 - step(min_zoom, adjusted_zoom) - (1.0 - step(max_zoom, adjusted_zoom));\n}\n\nvoid main() {\n #pragma mapbox: initialize highp vec4 fill_color\n #pragma mapbox: initialize highp vec4 halo_color\n #pragma mapbox: initialize lowp float opacity\n #pragma mapbox: initialize lowp float halo_width\n #pragma mapbox: initialize lowp float halo_blur\n\n vec2 a_pos = a_pos_offset.xy;\n vec2 a_offset = a_pos_offset.zw;\n\n vec2 a_tex = a_data.xy;\n\n highp vec2 label_data = unpack_float(a_data[2]);\n highp float a_labelminzoom = label_data[0];\n highp float a_lineangle = (label_data[1] / 256.0 * 2.0 * PI);\n highp vec2 a_zoom = unpack_float(a_data[3]);\n highp float a_minzoom = a_zoom[0];\n highp float a_maxzoom = a_zoom[1];\n\n // In order to accommodate placing labels around corners in\n // symbol-placement: line, each glyph in a label could have multiple\n // \"quad\"s only one of which should be shown at a given zoom level.\n // The min/max zoom assigned to each quad is based on the font size at\n // the vector tile's zoom level, which might be different than at the\n // currently rendered zoom level if text-size is zoom-dependent.\n // Thus, we compensate for this difference by calculating an adjustment\n // based on the scale of rendered text size relative to layout text size.\n highp float layoutSize;\n if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {\n v_size = mix(a_size[0], a_size[1], u_size_t) / 10.0;\n layoutSize = a_size[2] / 10.0;\n } else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {\n v_size = a_size[0] / 10.0;\n layoutSize = v_size;\n } else if (!u_is_size_zoom_constant && u_is_size_feature_constant) {\n v_size = u_size;\n layoutSize = u_layout_size;\n } else {\n v_size = u_size;\n layoutSize = u_size;\n }\n\n float fontScale = u_is_text ? v_size / 24.0 : v_size;\n\n vec4 projectedPoint = u_matrix * vec4(a_label_pos, 0, 1);\n highp float camera_to_anchor_distance = projectedPoint.w;\n highp float perspective_ratio = 1.0 + 0.5*((camera_to_anchor_distance / u_camera_to_center_distance) - 1.0);\n\n // pitch-alignment: map\n // rotation-alignment: map | viewport\n if (u_pitch_with_map) {\n highp float angle = u_rotate_with_map ? a_lineangle : u_bearing;\n highp float asin = sin(angle);\n highp float acos = cos(angle);\n mat2 RotationMatrix = mat2(acos, asin, -1.0 * asin, acos);\n vec2 offset = RotationMatrix * a_offset;\n vec2 extrude = fontScale * u_extrude_scale * perspective_ratio * (offset / 64.0);\n\n gl_Position = u_matrix * vec4(a_pos + extrude, 0, 1);\n gl_Position.z += clipUnusedGlyphAngles(v_size*perspective_ratio, layoutSize, a_minzoom, a_maxzoom) * gl_Position.w;\n // pitch-alignment: viewport\n // rotation-alignment: map\n } else if (u_rotate_with_map) {\n // foreshortening factor to apply on pitched maps\n // as a label goes from horizontal <=> vertical in angle\n // it goes from 0% foreshortening to up to around 70% foreshortening\n highp float pitchfactor = 1.0 - cos(u_pitch * sin(u_pitch * 0.75));\n\n // use the lineangle to position points a,b along the line\n // project the points and calculate the label angle in projected space\n // this calculation allows labels to be rendered unskewed on pitched maps\n vec4 a = u_matrix * vec4(a_pos, 0, 1);\n vec4 b = u_matrix * vec4(a_pos + vec2(cos(a_lineangle), sin(a_lineangle)), 0, 1);\n highp float angle = atan((b[1] / b[3] - a[1] / a[3]) / u_aspect_ratio, b[0] / b[3] - a[0] / a[3]);\n highp float asin = sin(angle);\n highp float acos = cos(angle);\n mat2 RotationMatrix = mat2(acos, -1.0 * asin, asin, acos);\n highp float foreshortening = (1.0 - pitchfactor) + (pitchfactor * cos(angle * 2.0));\n\n vec2 offset = RotationMatrix * (vec2(foreshortening, 1.0) * a_offset);\n vec2 extrude = fontScale * u_extrude_scale * perspective_ratio * (offset / 64.0);\n\n gl_Position = u_matrix * vec4(a_pos, 0, 1) + vec4(extrude, 0, 0);\n gl_Position.z += clipUnusedGlyphAngles(v_size * perspective_ratio, layoutSize, a_minzoom, a_maxzoom) * gl_Position.w;\n // pitch-alignment: viewport\n // rotation-alignment: viewport\n } else {\n vec2 extrude = fontScale * u_extrude_scale * perspective_ratio * (a_offset / 64.0);\n gl_Position = u_matrix * vec4(a_pos, 0, 1) + vec4(extrude, 0, 0);\n }\n\n gl_Position.z +=\n step(u_max_camera_distance * u_camera_to_center_distance, camera_to_anchor_distance) * gl_Position.w;\n\n v_gamma_scale = gl_Position.w / perspective_ratio;\n\n v_tex = a_tex / u_texsize;\n // incidence_stretch is the ratio of how much y space a label takes up on a tile while drawn perpendicular to the viewport vs\n // how much space it would take up if it were drawn flat on the tile\n // Using law of sines, camera_to_anchor/sin(ground_angle) = camera_to_center/sin(incidence_angle)\n // sin(incidence_angle) = 1/incidence_stretch\n // Incidence angle 90 -> head on, sin(incidence_angle) = 1, no incidence stretch\n // Incidence angle 1 -> very oblique, sin(incidence_angle) =~ 0, lots of incidence stretch\n // ground_angle = u_pitch + PI/2 -> sin(ground_angle) = cos(u_pitch)\n // This 2D calculation is only exactly correct when gl_Position.x is in the center of the viewport,\n // but it's a close enough approximation for our purposes\n highp float incidence_stretch = camera_to_anchor_distance / (u_camera_to_center_distance * cos(u_pitch));\n // incidence_stretch only applies to the y-axis, but without re-calculating the collision tile, we can't\n // adjust the size of only one axis. So, we do a crude approximation at placement time to get the aspect ratio\n // about right, and then do the rest of the adjustment here: there will be some extra padding on the x-axis,\n // but hopefully not too much.\n // Never make the adjustment less than 1.0: instead of allowing collisions on the x-axis, be conservative on\n // the y-axis.\n highp float collision_adjustment = max(1.0, incidence_stretch / u_collision_y_stretch);\n\n // Floor to 1/10th zoom to dodge precision issues that can cause partially hidden labels\n highp float perspective_zoom_adjust = floor(log2(perspective_ratio * collision_adjustment) * 10.0);\n v_fade_tex = vec2((a_labelminzoom + perspective_zoom_adjust) / 255.0, 0.0);\n}\n"}};
  164 +},{}],79:[function(_dereq_,module,exports){
  165 +"use strict";var VertexArrayObject=function(){this.boundProgram=null,this.boundVertexBuffer=null,this.boundVertexBuffer2=null,this.boundElementBuffer=null,this.boundVertexOffset=null,this.vao=null};VertexArrayObject.prototype.bind=function(e,t,r,i,n,s){void 0===e.extVertexArrayObject&&(e.extVertexArrayObject=e.getExtension("OES_vertex_array_object"));var o=!this.vao||this.boundProgram!==t||this.boundVertexBuffer!==r||this.boundVertexBuffer2!==n||this.boundElementBuffer!==i||this.boundVertexOffset!==s;!e.extVertexArrayObject||o?(this.freshBind(e,t,r,i,n,s),this.gl=e):e.extVertexArrayObject.bindVertexArrayOES(this.vao)},VertexArrayObject.prototype.freshBind=function(e,t,r,i,n,s){var o,u=t.numAttributes;if(e.extVertexArrayObject)this.vao&&this.destroy(),this.vao=e.extVertexArrayObject.createVertexArrayOES(),e.extVertexArrayObject.bindVertexArrayOES(this.vao),o=0,this.boundProgram=t,this.boundVertexBuffer=r,this.boundVertexBuffer2=n,this.boundElementBuffer=i,this.boundVertexOffset=s;else{o=e.currentNumAttributes||0;for(var b=u;b<o;b++)e.disableVertexAttribArray(b)}r.enableAttributes(e,t),n&&n.enableAttributes(e,t),r.bind(e),r.setVertexAttribPointers(e,t,s),n&&(n.bind(e),n.setVertexAttribPointers(e,t,s)),i&&i.bind(e),e.currentNumAttributes=u},VertexArrayObject.prototype.destroy=function(){this.vao&&(this.gl.extVertexArrayObject.deleteVertexArrayOES(this.vao),this.vao=null)},module.exports=VertexArrayObject;
  166 +},{}],80:[function(_dereq_,module,exports){
  167 +"use strict";var util=_dereq_("../util/util");exports.packUint8ToFloat=function(t,l){return t=util.clamp(Math.floor(t),0,255),l=util.clamp(Math.floor(l),0,255),256*t+l};
  168 +},{"../util/util":215}],81:[function(_dereq_,module,exports){
  169 +"use strict";var ImageSource=_dereq_("./image_source"),window=_dereq_("../util/window"),CanvasSource=function(t){function i(i,a,s,n){t.call(this,i,a,s,n),this.options=a,this.animate=!a.hasOwnProperty("animate")||a.animate}return t&&(i.__proto__=t),i.prototype=Object.create(t&&t.prototype),i.prototype.constructor=i,i.prototype.load=function(){if(this.canvas=this.canvas||window.document.getElementById(this.options.canvas),this.width=this.canvas.width,this.height=this.canvas.height,this._hasInvalidDimensions())return this.fire("error",new Error("Canvas dimensions cannot be less than or equal to zero."));var t;this.play=function(){t=this.map.style.animationLoop.set(1/0),this.map._rerender()},this.pause=function(){this.map.style.animationLoop.cancel(t)},this._finishLoading()},i.prototype.getCanvas=function(){return this.canvas},i.prototype.onAdd=function(t){this.map||(this.map=t,this.load(),this.canvas&&this.animate&&this.play())},i.prototype.prepare=function(){var t=!1;this.canvas.width!==this.width&&(this.width=this.canvas.width,t=!0),this.canvas.height!==this.height&&(this.height=this.canvas.height,t=!0),this._hasInvalidDimensions()||0!==Object.keys(this.tiles).length&&this._prepareImage(this.map.painter.gl,this.canvas,t)},i.prototype.serialize=function(){return{type:"canvas",canvas:this.canvas,coordinates:this.coordinates}},i.prototype._hasInvalidDimensions=function(){for(var t=this,i=0,a=[t.canvas.width,t.canvas.height];i<a.length;i+=1){var s=a[i];if(isNaN(s)||s<=0)return!0}return!1},i}(ImageSource);module.exports=CanvasSource;
  170 +},{"../util/window":196,"./image_source":85}],82:[function(_dereq_,module,exports){
  171 +"use strict";function resolveURL(t){var e=window.document.createElement("a");return e.href=t,e.href}var Evented=_dereq_("../util/evented"),util=_dereq_("../util/util"),window=_dereq_("../util/window"),EXTENT=_dereq_("../data/extent"),GeoJSONSource=function(t){function e(e,o,i,r){t.call(this),o=o||{},this.id=e,this.type="geojson",this.minzoom=0,this.maxzoom=18,this.tileSize=512,this.isTileClipped=!0,this.reparseOverscaled=!0,this.dispatcher=i,this.setEventedParent(r),this._data=o.data,void 0!==o.maxzoom&&(this.maxzoom=o.maxzoom),o.type&&(this.type=o.type);var a=EXTENT/this.tileSize;this.workerOptions=util.extend({source:this.id,cluster:o.cluster||!1,geojsonVtOptions:{buffer:(void 0!==o.buffer?o.buffer:128)*a,tolerance:(void 0!==o.tolerance?o.tolerance:.375)*a,extent:EXTENT,maxZoom:this.maxzoom},superclusterOptions:{maxZoom:Math.min(o.clusterMaxZoom,this.maxzoom-1)||this.maxzoom-1,extent:EXTENT,radius:(o.clusterRadius||50)*a,log:!1}},o.workerOptions)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.load=function(){var t=this;this.fire("dataloading",{dataType:"source"}),this._updateWorkerData(function(e){return e?void t.fire("error",{error:e}):void t.fire("data",{dataType:"source",sourceDataType:"metadata"})})},e.prototype.onAdd=function(t){this.load(),this.map=t},e.prototype.setData=function(t){var e=this;return this._data=t,this.fire("dataloading",{dataType:"source"}),this._updateWorkerData(function(t){return t?e.fire("error",{error:t}):void e.fire("data",{dataType:"source",sourceDataType:"content"})}),this},e.prototype._updateWorkerData=function(t){var e=this,o=util.extend({},this.workerOptions),i=this._data;"string"==typeof i?o.url=resolveURL(i):o.data=JSON.stringify(i),this.workerID=this.dispatcher.send(this.type+".loadData",o,function(o){e._loaded=!0,t(o)})},e.prototype.loadTile=function(t,e){var o=this,i=t.coord.z>this.maxzoom?Math.pow(2,t.coord.z-this.maxzoom):1,r={type:this.type,uid:t.uid,coord:t.coord,zoom:t.coord.z,maxZoom:this.maxzoom,tileSize:this.tileSize,source:this.id,overscaling:i,angle:this.map.transform.angle,pitch:this.map.transform.pitch,cameraToCenterDistance:this.map.transform.cameraToCenterDistance,cameraToTileDistance:this.map.transform.cameraToTileDistance(t),showCollisionBoxes:this.map.showCollisionBoxes};t.workerID=this.dispatcher.send("loadTile",r,function(i,r){if(t.unloadVectorData(),!t.aborted)return i?e(i):(t.loadVectorData(r,o.map.painter),t.redoWhenDone&&(t.redoWhenDone=!1,t.redoPlacement(o)),e(null))},this.workerID)},e.prototype.abortTile=function(t){t.aborted=!0},e.prototype.unloadTile=function(t){t.unloadVectorData(),this.dispatcher.send("removeTile",{uid:t.uid,type:this.type,source:this.id},function(){},t.workerID)},e.prototype.onRemove=function(){this.dispatcher.broadcast("removeSource",{type:this.type,source:this.id},function(){})},e.prototype.serialize=function(){return{type:this.type,data:this._data}},e}(Evented);module.exports=GeoJSONSource;
  172 +},{"../data/extent":53,"../util/evented":202,"../util/util":215,"../util/window":196}],83:[function(_dereq_,module,exports){
  173 +"use strict";var ajax=_dereq_("../util/ajax"),rewind=_dereq_("geojson-rewind"),GeoJSONWrapper=_dereq_("./geojson_wrapper"),vtpbf=_dereq_("vt-pbf"),supercluster=_dereq_("supercluster"),geojsonvt=_dereq_("geojson-vt"),VectorTileWorkerSource=_dereq_("./vector_tile_worker_source"),GeoJSONWorkerSource=function(e){function r(r,t,o){e.call(this,r,t),o&&(this.loadGeoJSON=o),this._geoJSONIndexes={}}return e&&(r.__proto__=e),r.prototype=Object.create(e&&e.prototype),r.prototype.constructor=r,r.prototype.loadVectorData=function(e,r){var t=e.source,o=e.coord;if(!this._geoJSONIndexes[t])return r(null,null);var n=this._geoJSONIndexes[t].getTile(Math.min(o.z,e.maxZoom),o.x,o.y);if(!n)return r(null,null);var u=new GeoJSONWrapper(n.features);u.name="_geojsonTileLayer";var a=vtpbf({layers:{_geojsonTileLayer:u}});0===a.byteOffset&&a.byteLength===a.buffer.byteLength||(a=new Uint8Array(a)),u.rawData=a.buffer,r(null,u)},r.prototype.loadData=function(e,r){var t=function(t,o){var n=this;return t?r(t):"object"!=typeof o?r(new Error("Input data is not a valid GeoJSON object.")):(rewind(o,!0),void this._indexData(o,e,function(t,o){return t?r(t):(n._geoJSONIndexes[e.source]=o,void r(null))}))}.bind(this);this.loadGeoJSON(e,t)},r.prototype.loadGeoJSON=function(e,r){if(e.url)ajax.getJSON(e.url,r);else{if("string"!=typeof e.data)return r(new Error("Input data is not a valid GeoJSON object."));try{return r(null,JSON.parse(e.data))}catch(e){return r(new Error("Input data is not a valid GeoJSON object."))}}},r.prototype.removeSource=function(e){this._geoJSONIndexes[e.source]&&delete this._geoJSONIndexes[e.source]},r.prototype._indexData=function(e,r,t){try{r.cluster?t(null,supercluster(r.superclusterOptions).load(e.features)):t(null,geojsonvt(e,r.geojsonVtOptions))}catch(e){return t(e)}},r}(VectorTileWorkerSource);module.exports=GeoJSONWorkerSource;
  174 +},{"../util/ajax":193,"./geojson_wrapper":84,"./vector_tile_worker_source":97,"geojson-rewind":7,"geojson-vt":11,"supercluster":28,"vt-pbf":37}],84:[function(_dereq_,module,exports){
  175 +"use strict";var Point=_dereq_("point-geometry"),VectorTileFeature=_dereq_("vector-tile").VectorTileFeature,EXTENT=_dereq_("../data/extent"),FeatureWrapper=function(e){var t=this;if(this.type=e.type,1===e.type){this.rawGeometry=[];for(var r=0;r<e.geometry.length;r++)t.rawGeometry.push([e.geometry[r]])}else this.rawGeometry=e.geometry;this.properties=e.tags,"id"in e&&!isNaN(e.id)&&(this.id=parseInt(e.id,10)),this.extent=EXTENT};FeatureWrapper.prototype.loadGeometry=function(){var e=this,t=this.rawGeometry;this.geometry=[];for(var r=0;r<t.length;r++){for(var o=t[r],a=[],i=0;i<o.length;i++)a.push(new Point(o[i][0],o[i][1]));e.geometry.push(a)}return this.geometry},FeatureWrapper.prototype.bbox=function(){this.geometry||this.loadGeometry();for(var e=this.geometry,t=1/0,r=-(1/0),o=1/0,a=-(1/0),i=0;i<e.length;i++)for(var p=e[i],n=0;n<p.length;n++){var h=p[n];t=Math.min(t,h.x),r=Math.max(r,h.x),o=Math.min(o,h.y),a=Math.max(a,h.y)}return[t,o,r,a]},FeatureWrapper.prototype.toGeoJSON=function(){VectorTileFeature.prototype.toGeoJSON.call(this)};var GeoJSONWrapper=function(e){this.features=e,this.length=e.length,this.extent=EXTENT};GeoJSONWrapper.prototype.feature=function(e){return new FeatureWrapper(this.features[e])},module.exports=GeoJSONWrapper;
  176 +},{"../data/extent":53,"point-geometry":25,"vector-tile":33}],85:[function(_dereq_,module,exports){
  177 +"use strict";var util=_dereq_("../util/util"),window=_dereq_("../util/window"),TileCoord=_dereq_("./tile_coord"),LngLat=_dereq_("../geo/lng_lat"),Point=_dereq_("point-geometry"),Evented=_dereq_("../util/evented"),ajax=_dereq_("../util/ajax"),EXTENT=_dereq_("../data/extent"),RasterBoundsArray=_dereq_("../data/raster_bounds_array"),Buffer=_dereq_("../data/buffer"),VertexArrayObject=_dereq_("../render/vertex_array_object"),ImageSource=function(t){function e(e,o,r,i){t.call(this),this.id=e,this.dispatcher=r,this.coordinates=o.coordinates,this.type="upload_file.py",this.minzoom=0,this.maxzoom=22,this.tileSize=512,this.tiles={},this.setEventedParent(i),this.options=o,this.textureLoaded=!1}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.load=function(){var t=this;this.fire("dataloading",{dataType:"source"}),this.url=this.options.url,ajax.getImage(this.options.url,function(e, o){return e?t.fire("error",{error:e}):(t.image=o,void t._finishLoading())})},e.prototype._finishLoading=function(){this.map&&(this.setCoordinates(this.coordinates),this.fire("data",{dataType:"source",sourceDataType:"metadata"}))},e.prototype.onAdd=function(t){this.load(),this.map=t,this.image&&this.setCoordinates(this.coordinates)},e.prototype.setCoordinates=function(t){this.coordinates=t;var e=this.map,o=t.map(function(t){return e.transform.locationCoordinate(LngLat.convert(t)).zoomTo(0)}),r=this.centerCoord=util.getCoordinatesCenter(o);return r.column=Math.floor(r.column),r.row=Math.floor(r.row),this.coord=new TileCoord(r.zoom,r.column,r.row),this.minzoom=this.maxzoom=r.zoom,this._tileCoords=o.map(function(t){var e=t.zoomTo(r.zoom);return new Point(Math.round((e.column-r.column)*EXTENT),Math.round((e.row-r.row)*EXTENT))}),this.fire("data",{dataType:"source",sourceDataType:"content"}),this},e.prototype._setTile=function(t){this.tiles[t.coord.w]=t;var e=32767,o=new RasterBoundsArray;o.emplaceBack(this._tileCoords[0].x,this._tileCoords[0].y,0,0),o.emplaceBack(this._tileCoords[1].x,this._tileCoords[1].y,e,0),o.emplaceBack(this._tileCoords[3].x,this._tileCoords[3].y,0,e),o.emplaceBack(this._tileCoords[2].x,this._tileCoords[2].y,e,e),t.buckets={},t.boundsBuffer=Buffer.fromStructArray(o,Buffer.BufferType.VERTEX),t.boundsVAO=new VertexArrayObject},e.prototype.prepare=function(){0===Object.keys(this.tiles).length!==0&&this.image&&this._prepareImage(this.map.painter.gl,this.image)},e.prototype._prepareImage=function(t,e,o){var r=this;this.textureLoaded?o?t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,e):(e instanceof window.HTMLVideoElement||e instanceof window.ImageData||e instanceof window.HTMLCanvasElement)&&(t.bindTexture(t.TEXTURE_2D,this.texture),t.texSubImage2D(t.TEXTURE_2D,0,0,0,t.RGBA,t.UNSIGNED_BYTE,e)):(this.textureLoaded=!0,this.texture=t.createTexture(),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.LINEAR),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,e));for(var i in r.tiles){var a=r.tiles[i];"loaded"!==a.state&&(a.state="loaded",a.texture=r.texture)}},e.prototype.loadTile=function(t, e){this.coord&&this.coord.toString()===t.coord.toString()?(this._setTile(t),e(null)):(t.state="errored",e(null))},e.prototype.serialize=function(){return{type:"upload_file.py",urls:this.url,coordinates:this.coordinates}},e}(Evented);module.exports=ImageSource;
  178 +},{"../data/buffer":50,"../data/extent":53,"../data/raster_bounds_array":58,"../geo/lng_lat":61,"../render/vertex_array_object":79,"../util/ajax":193,"../util/evented":202,"../util/util":215,"../util/window":196,"./tile_coord":95,"point-geometry":25}],86:[function(_dereq_,module,exports){
  179 +"use strict";var util=_dereq_("../util/util"),ajax=_dereq_("../util/ajax"),browser=_dereq_("../util/browser"),normalizeURL=_dereq_("../util/mapbox").normalizeSourceURL;module.exports=function(r,e){var o=function(r,o){if(r)return e(r);var i=util.pick(o,["tiles","minzoom","maxzoom","attribution","mapbox_logo","bounds"]);o.vector_layers&&(i.vectorLayers=o.vector_layers,i.vectorLayerIds=i.vectorLayers.map(function(r){return r.id})),e(null,i)};r.url?ajax.getJSON(normalizeURL(r.url),o):browser.frame(o.bind(null,null,r))};
  180 +},{"../util/ajax":193,"../util/browser":194,"../util/mapbox":209,"../util/util":215}],87:[function(_dereq_,module,exports){
  181 +"use strict";var EXTENT=_dereq_("../data/extent");module.exports=function(e,t,r){return t*(EXTENT/(e.tileSize*Math.pow(2,r-e.coord.z)))};
  182 +},{"../data/extent":53}],88:[function(_dereq_,module,exports){
  183 +"use strict";function sortTilesIn(e,r){var t=e.coord,o=r.coord;return t.z-o.z||t.y-o.y||t.w-o.w||t.x-o.x}function mergeRenderedFeatureLayers(e){for(var r={},t={},o=0,a=e;o<a.length;o+=1){var n=a[o],u=n.queryResults,i=n.wrappedTileID,d=t[i]=t[i]||{};for(var s in u)for(var l=u[s],c=d[s]=d[s]||{},f=r[s]=r[s]||[],y=0,p=l;y<p.length;y+=1){var v=p[y];c[v.featureIndex]||(c[v.featureIndex]=!0,f.push(v.feature))}}return r}var TileCoord=_dereq_("./tile_coord");exports.rendered=function(e,r,t,o,a,n){var u=e.tilesIn(t);u.sort(sortTilesIn);for(var i=[],d=0;d<u.length;d++){var s=u[d];s.tile.featureIndex&&i.push({wrappedTileID:s.coord.wrapped().id,queryResults:s.tile.featureIndex.query({queryGeometry:s.queryGeometry,scale:s.scale,tileSize:s.tile.tileSize,bearing:n,params:o},r)})}return mergeRenderedFeatureLayers(i)},exports.source=function(e,r){for(var t=e.getRenderableIds().map(function(r){return e.getTileByID(r)}),o=[],a={},n=0;n<t.length;n++){var u=t[n],i=new TileCoord(Math.min(u.sourceMaxZoom,u.coord.z),u.coord.x,u.coord.y,0).id;a[i]||(a[i]=!0,u.querySourceFeatures(o,r))}return o};
  184 +},{"./tile_coord":95}],89:[function(_dereq_,module,exports){
  185 +"use strict";var util=_dereq_("../util/util"),ajax=_dereq_("../util/ajax"),Evented=_dereq_("../util/evented"),loadTileJSON=_dereq_("./load_tilejson"),normalizeURL=_dereq_("../util/mapbox").normalizeTileURL,TileBounds=_dereq_("./tile_bounds"),RasterTileSource=function(e){function t(t,i,r,o){e.call(this),this.id=t,this.dispatcher=r,this.setEventedParent(o),this.type="raster",this.minzoom=0,this.maxzoom=22,this.roundZoom=!0,this.scheme="xyz",this.tileSize=512,this._loaded=!1,this.options=i,util.extend(this,util.pick(i,["url","scheme","tileSize"]))}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype.load=function(){var e=this;this.fire("dataloading",{dataType:"source"}),loadTileJSON(this.options,function(t,i){return t?e.fire("error",t):(util.extend(e,i),e.setBounds(i.bounds),e.fire("data",{dataType:"source",sourceDataType:"metadata"}),void e.fire("data",{dataType:"source",sourceDataType:"content"}))})},t.prototype.onAdd=function(e){this.load(),this.map=e},t.prototype.setBounds=function(e){this.bounds=e,e&&(this.tileBounds=new TileBounds(e,this.minzoom,this.maxzoom))},t.prototype.serialize=function(){return{type:"raster",url:this.url,tileSize:this.tileSize,tiles:this.tiles,bounds:this.bounds}},t.prototype.hasTile=function(e){return!this.tileBounds||this.tileBounds.contains(e,this.maxzoom)},t.prototype.loadTile=function(e,t){function i(i,r){if(delete e.request,e.aborted)return this.state="unloaded",t(null);if(i)return this.state="errored",t(i);this.map._refreshExpiredTiles&&e.setExpiryData(r),delete r.cacheControl,delete r.expires;var o=this.map.painter.gl;e.texture=this.map.painter.getTileTexture(r.width),e.texture?(o.bindTexture(o.TEXTURE_2D,e.texture),o.texSubImage2D(o.TEXTURE_2D,0,0,0,o.RGBA,o.UNSIGNED_BYTE,r)):(e.texture=o.createTexture(),o.bindTexture(o.TEXTURE_2D,e.texture),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_MIN_FILTER,o.LINEAR_MIPMAP_NEAREST),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_MAG_FILTER,o.LINEAR),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_WRAP_S,o.CLAMP_TO_EDGE),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_WRAP_T,o.CLAMP_TO_EDGE),this.map.painter.extTextureFilterAnisotropic&&o.texParameterf(o.TEXTURE_2D,this.map.painter.extTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT,this.map.painter.extTextureFilterAnisotropicMax),o.texImage2D(o.TEXTURE_2D,0,o.RGBA,o.RGBA,o.UNSIGNED_BYTE,r),e.texture.size=r.width),o.generateMipmap(o.TEXTURE_2D),e.state="loaded",t(null)}var r=normalizeURL(e.coord.url(this.tiles,null,this.scheme),this.url,this.tileSize);e.request=ajax.getImage(r,i.bind(this))},t.prototype.abortTile=function(e){e.request&&(e.request.abort(),delete e.request)},t.prototype.unloadTile=function(e){e.texture&&this.map.painter.saveTileTexture(e.texture)},t}(Evented);module.exports=RasterTileSource;
  186 +},{"../util/ajax":193,"../util/evented":202,"../util/mapbox":209,"../util/util":215,"./load_tilejson":86,"./tile_bounds":94}],90:[function(_dereq_,module,exports){
  187 +"use strict";var ajax=_dereq_("../util/ajax"),Evented=_dereq_("../util/evented"),window=_dereq_("../util/window"),pluginRequested=!1,pluginBlobURL=null;module.exports.evented=new Evented,module.exports.registerForPluginAvailability=function(e){return pluginBlobURL?e(pluginBlobURL,module.exports.errorCallback):module.exports.evented.once("pluginAvailable",e),e},module.exports.setRTLTextPlugin=function(e,l){if(pluginRequested)throw new Error("setRTLTextPlugin cannot be called multiple times.");pluginRequested=!0,module.exports.errorCallback=l,ajax.getArrayBuffer(e,function(e,t){e?l(e):(pluginBlobURL=window.URL.createObjectURL(new window.Blob([t.data]),{type:"text/javascript"}),module.exports.evented.fire("pluginAvailable",{pluginBlobURL:pluginBlobURL,errorCallback:l}))})};
  188 +},{"../util/ajax":193,"../util/evented":202,"../util/window":196}],91:[function(_dereq_,module,exports){
  189 +"use strict";var util=_dereq_("../util/util"),sourceTypes={vector:_dereq_("../source/vector_tile_source"),raster:_dereq_("../source/raster_tile_source"),geojson:_dereq_("../source/geojson_source"),video:_dereq_("../source/video_source"),image:_dereq_("../source/image_source"),canvas:_dereq_("../source/canvas_source")};exports.create=function(e,r,o,u){if(r=new sourceTypes[r.type](e,r,o,u),r.id!==e)throw new Error("Expected Source id to be "+e+" instead of "+r.id);return util.bindAll(["load","abort","unload","serialize","prepare"],r),r},exports.getType=function(e){return sourceTypes[e]},exports.setType=function(e,r){sourceTypes[e]=r};
  190 +},{"../source/canvas_source":81,"../source/geojson_source":82,"../source/image_source":85,"../source/raster_tile_source":89,"../source/vector_tile_source":96,"../source/video_source":98,"../util/util":215}],92:[function(_dereq_,module,exports){
  191 +"use strict";function coordinateToTilePoint(e,t,o){var i=o.zoomTo(Math.min(e.z,t));return{x:(i.column-(e.x+e.w*Math.pow(2,e.z)))*EXTENT,y:(i.row-e.y)*EXTENT}}function compareKeyZoom(e,t){return e%32-t%32}function isRasterType(e){return"raster"===e||"upload_file.py"===e||"video"===e}var Source=_dereq_("./source"),Tile=_dereq_("./tile"),Evented=_dereq_("../util/evented"),TileCoord=_dereq_("./tile_coord"),Cache=_dereq_("../util/lru_cache"),Coordinate=_dereq_("../geo/coordinate"),util=_dereq_("../util/util"),EXTENT=_dereq_("../data/extent"),SourceCache=function(e){function t(t, o, i){e.call(this),this.id=t,this.dispatcher=i,this.on("data",function(e){"source"===e.dataType&&"metadata"===e.sourceDataType&&(this._sourceLoaded=!0),this._sourceLoaded&&"source"===e.dataType&&"content"===e.sourceDataType&&(this.reload(),this.transform&&this.update(this.transform))}),this.on("error",function(){this._sourceErrored=!0}),this._source=Source.create(t,o,i,this),this._tiles={},this._cache=new Cache(0,this.unloadTile.bind(this)),this._timers={},this._cacheTimers={},this._isIdRenderable=this._isIdRenderable.bind(this)}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype.onAdd=function(e){this.map=e,this._source&&this._source.onAdd&&this._source.onAdd(e)},t.prototype.onRemove=function(e){this._source&&this._source.onRemove&&this._source.onRemove(e)},t.prototype.loaded=function(){var e=this;if(this._sourceErrored)return!0;if(!this._sourceLoaded)return!1;for(var t in e._tiles){var o=e._tiles[t];if("loaded"!==o.state&&"errored"!==o.state)return!1}return!0},t.prototype.getSource=function(){return this._source},t.prototype.loadTile=function(e,t){return this._source.loadTile(e,t)},t.prototype.unloadTile=function(e){if(this._source.unloadTile)return this._source.unloadTile(e)},t.prototype.abortTile=function(e){if(this._source.abortTile)return this._source.abortTile(e)},t.prototype.serialize=function(){return this._source.serialize()},t.prototype.prepare=function(){if(this._sourceLoaded&&this._source.prepare)return this._source.prepare()},t.prototype.getIds=function(){return Object.keys(this._tiles).map(Number).sort(compareKeyZoom)},t.prototype.getRenderableIds=function(){return this.getIds().filter(this._isIdRenderable)},t.prototype._isIdRenderable=function(e){return this._tiles[e].hasData()&&!this._coveredTiles[e]},t.prototype.reload=function(){var e=this;this._cache.reset();for(var t in e._tiles)e.reloadTile(t,"reloading")},t.prototype.reloadTile=function(e,t){var o=this._tiles[e];o&&("loading"!==o.state&&(o.state=t),this.loadTile(o,this._tileLoaded.bind(this,o,e,t)))},t.prototype._tileLoaded=function(e,t,o,i){return i?(e.state="errored",void(404!==i.status&&this._source.fire("error",{tile:e,error:i}))):(e.sourceCache=this,e.timeAdded=(new Date).getTime(),"expired"===o&&(e.refreshedUponExpiration=!0),this._setTileReloadTimer(t,e),this._source.fire("data",{dataType:"source",tile:e,coord:e.coord}),void(this.map&&(this.map.painter.tileExtentVAO.vao=null)))},t.prototype.getTile=function(e){return this.getTileByID(e.id)},t.prototype.getTileByID=function(e){return this._tiles[e]},t.prototype.getZoom=function(e){return e.zoom+e.scaleZoom(e.tileSize/this._source.tileSize)},t.prototype.findLoadedChildren=function(e,t,o){var i=this,r=!1;for(var s in i._tiles){var a=i._tiles[s];if(!(o[s]||!a.hasData()||a.coord.z<=e.z||a.coord.z>t)){var n=Math.pow(2,Math.min(a.coord.z,i._source.maxzoom)-Math.min(e.z,i._source.maxzoom));if(Math.floor(a.coord.x/n)===e.x&&Math.floor(a.coord.y/n)===e.y)for(o[s]=!0,r=!0;a&&a.coord.z-1>e.z;){var c=a.coord.parent(i._source.maxzoom).id;a=i._tiles[c],a&&a.hasData()&&(delete o[s],o[c]=!0)}}}return r},t.prototype.findLoadedParent=function(e,t,o){for(var i=this,r=e.z-1;r>=t;r--){e=e.parent(i._source.maxzoom);var s=i._tiles[e.id];if(s&&s.hasData())return o[e.id]=!0,s;if(i._cache.has(e.id))return o[e.id]=!0,i._cache.getWithoutRemoving(e.id)}},t.prototype.updateCacheSize=function(e){var t=Math.ceil(e.width/e.tileSize)+1,o=Math.ceil(e.height/e.tileSize)+1,i=t*o,r=5;this._cache.setMaxSize(Math.floor(i*r))},t.prototype.update=function(e){var o=this;if(this.transform=e,this._sourceLoaded){var i,r,s,a;this.updateCacheSize(e);var n=(this._source.roundZoom?Math.round:Math.floor)(this.getZoom(e)),c=Math.max(n-t.maxOverzooming,this._source.minzoom),d=Math.max(n+t.maxUnderzooming,this._source.minzoom),h={};this._coveredTiles={};var u;for(this.used?this._source.coord?u=e.getVisibleWrappedCoordinates(this._source.coord):(u=e.coveringTiles({tileSize:this._source.tileSize,minzoom:this._source.minzoom,maxzoom:this._source.maxzoom,roundZoom:this._source.roundZoom,reparseOverscaled:this._source.reparseOverscaled}),this._source.hasTile&&(u=u.filter(function(e){return o._source.hasTile(e)}))):u=[],i=0;i<u.length;i++)r=u[i],s=o.addTile(r),h[r.id]=!0,s.hasData()||o.findLoadedChildren(r,d,h)||(a=o.findLoadedParent(r,c,h),a&&o.addTile(a.coord));var l={};if(isRasterType(this._source.type))for(var m=Object.keys(h),p=0;p<m.length;p++){var _=m[p];r=TileCoord.fromID(_),s=o._tiles[_],s&&("undefined"==typeof s.fadeEndTime||s.fadeEndTime>=Date.now())&&(o.findLoadedChildren(r,d,h)&&(h[_]=!0),a=o.findLoadedParent(r,c,l),a&&o.addTile(a.coord))}var f;for(f in l)h[f]||(o._coveredTiles[f]=!0);for(f in l)h[f]=!0;var T=util.keysDifference(this._tiles,h);for(i=0;i<T.length;i++)o.removeTile(+T[i])}},t.prototype.addTile=function(e){var t=this._tiles[e.id];if(t)return t;t=this._cache.get(e.id),t&&(t.redoPlacement(this._source),this._cacheTimers[e.id]&&(clearTimeout(this._cacheTimers[e.id]),this._cacheTimers[e.id]=void 0,this._setTileReloadTimer(e.id,t)));var o=Boolean(t);if(!o){var i=e.z,r=i>this._source.maxzoom?Math.pow(2,i-this._source.maxzoom):1;t=new Tile(e,this._source.tileSize*r,this._source.maxzoom),this.loadTile(t,this._tileLoaded.bind(this,t,e.id,t.state))}return t.uses++,this._tiles[e.id]=t,o||this._source.fire("dataloading",{tile:t,coord:t.coord,dataType:"source"}),t},t.prototype._setTileReloadTimer=function(e,t){var o=this,i=t.getExpiryTimeout();i&&(this._timers[e]=setTimeout(function(){o.reloadTile(e,"expired"),o._timers[e]=void 0},i))},t.prototype._setCacheInvalidationTimer=function(e,t){var o=this,i=t.getExpiryTimeout();i&&(this._cacheTimers[e]=setTimeout(function(){o._cache.remove(e),o._cacheTimers[e]=void 0},i))},t.prototype.removeTile=function(e){var t=this._tiles[e];if(t&&(t.uses--,delete this._tiles[e],this._timers[e]&&(clearTimeout(this._timers[e]),this._timers[e]=void 0),!(t.uses>0)))if(t.stopPlacementThrottler(),t.hasData()){var o=t.coord.wrapped().id;this._cache.add(o,t),this._setCacheInvalidationTimer(o,t)}else t.aborted=!0,this.abortTile(t),this.unloadTile(t)},t.prototype.clearTiles=function(){var e=this;for(var t in e._tiles)e.removeTile(t);this._cache.reset()},t.prototype.tilesIn=function(e){for(var t=this,o=[],i=this.getIds(),r=1/0,s=1/0,a=-(1/0),n=-(1/0),c=e[0].zoom,d=0;d<e.length;d++){var h=e[d];r=Math.min(r,h.column),s=Math.min(s,h.row),a=Math.max(a,h.column),n=Math.max(n,h.row)}for(var u=0;u<i.length;u++){var l=t._tiles[i[u]],m=TileCoord.fromID(i[u]),p=[coordinateToTilePoint(m,l.sourceMaxZoom,new Coordinate(r,s,c)),coordinateToTilePoint(m,l.sourceMaxZoom,new Coordinate(a,n,c))];if(p[0].x<EXTENT&&p[0].y<EXTENT&&p[1].x>=0&&p[1].y>=0){for(var _=[],f=0;f<e.length;f++)_.push(coordinateToTilePoint(m,l.sourceMaxZoom,e[f]));o.push({tile:l,coord:m,queryGeometry:[_],scale:Math.pow(2,t.transform.zoom-l.coord.z)})}}return o},t.prototype.redoPlacement=function(){for(var e=this,t=this.getIds(),o=0;o<t.length;o++){var i=e.getTileByID(t[o]);i.redoPlacement(e._source)}},t.prototype.getVisibleCoordinates=function(){for(var e=this,t=this.getRenderableIds().map(TileCoord.fromID),o=0,i=t;o<i.length;o+=1){var r=i[o];r.posMatrix=e.transform.calculatePosMatrix(r,e._source.maxzoom)}return t},t}(Evented);SourceCache.maxOverzooming=10,SourceCache.maxUnderzooming=3,module.exports=SourceCache;
  192 +},{"../data/extent":53,"../geo/coordinate":60,"../util/evented":202,"../util/lru_cache":208,"../util/util":215,"./source":91,"./tile":93,"./tile_coord":95}],93:[function(_dereq_,module,exports){
  193 +"use strict";var util=_dereq_("../util/util"),Bucket=_dereq_("../data/bucket"),FeatureIndex=_dereq_("../data/feature_index"),vt=_dereq_("vector-tile"),Protobuf=_dereq_("pbf"),GeoJSONFeature=_dereq_("../util/vectortile_to_geojson"),featureFilter=_dereq_("../style-spec/feature_filter"),CollisionTile=_dereq_("../symbol/collision_tile"),CollisionBoxArray=_dereq_("../symbol/collision_box"),Throttler=_dereq_("../util/throttler"),CLOCK_SKEW_RETRY_TIMEOUT=3e4,Tile=function(e,t,i){this.coord=e,this.uid=util.uniqueId(),this.uses=0,this.tileSize=t,this.sourceMaxZoom=i,this.buckets={},this.expirationTime=null,this.expiredRequestCount=0,this.state="loading",this.placementThrottler=new Throttler(300,this._immediateRedoPlacement.bind(this))};Tile.prototype.registerFadeDuration=function(e,t){var i=t+this.timeAdded;i<Date.now()||this.fadeEndTime&&i<this.fadeEndTime||(this.fadeEndTime=i,e.set(this.fadeEndTime-Date.now()))},Tile.prototype.loadVectorData=function(e,t){this.hasData()&&this.unloadVectorData(),this.state="loaded",e&&(e.rawTileData&&(this.rawTileData=e.rawTileData),this.collisionBoxArray=new CollisionBoxArray(e.collisionBoxArray),this.collisionTile=new CollisionTile(e.collisionTile,this.collisionBoxArray),this.featureIndex=new FeatureIndex(e.featureIndex,this.rawTileData,this.collisionTile),this.buckets=Bucket.deserialize(e.buckets,t.style))},Tile.prototype.reloadSymbolData=function(e,t){var i=this;if("unloaded"!==this.state){this.collisionTile=new CollisionTile(e.collisionTile,this.collisionBoxArray),this.featureIndex.setCollisionTile(this.collisionTile);for(var o in i.buckets){var a=i.buckets[o];"symbol"===a.layers[0].type&&(a.destroy(),delete i.buckets[o])}util.extend(this.buckets,Bucket.deserialize(e.buckets,t))}},Tile.prototype.unloadVectorData=function(){var e=this;for(var t in e.buckets)e.buckets[t].destroy();this.buckets={},this.collisionBoxArray=null,this.collisionTile=null,this.featureIndex=null,this.state="unloaded"},Tile.prototype.redoPlacement=function(e){if("vector"===e.type||"geojson"===e.type){if("loaded"!==this.state)return void(this.redoWhenDone=!0);if(this.collisionTile){var t=e.map.transform.cameraToTileDistance(this);if(this.angle===e.map.transform.angle&&this.pitch===e.map.transform.pitch&&this.cameraToCenterDistance===e.map.transform.cameraToCenterDistance&&this.showCollisionBoxes===e.map.showCollisionBoxes){if(this.cameraToTileDistance===t)return;if(this.pitch<25)return void(this.cameraToTileDistance=t)}this.angle=e.map.transform.angle,this.pitch=e.map.transform.pitch,this.cameraToCenterDistance=e.map.transform.cameraToCenterDistance,this.cameraToTileDistance=t,this.showCollisionBoxes=e.map.showCollisionBoxes,this.placementSource=e,this.state="reloading",this.placementThrottler.invoke()}}},Tile.prototype._immediateRedoPlacement=function(){var e=this;this.placementSource.dispatcher.send("redoPlacement",{type:this.placementSource.type,uid:this.uid,source:this.placementSource.id,angle:this.angle,pitch:this.pitch,cameraToCenterDistance:this.cameraToCenterDistance,cameraToTileDistance:this.cameraToTileDistance,showCollisionBoxes:this.showCollisionBoxes},function(t,i){e.reloadSymbolData(i,e.placementSource.map.style),e.placementSource.map.showCollisionBoxes&&e.placementSource.fire("data",{tile:e,coord:e.coord,dataType:"source"}),e.placementSource.map&&(e.placementSource.map.painter.tileExtentVAO.vao=null),e.state="loaded",e.redoWhenDone&&(e.redoWhenDone=!1,e._immediateRedoPlacement())},this.workerID)},Tile.prototype.getBucket=function(e){return this.buckets[e.id]},Tile.prototype.querySourceFeatures=function(e,t){var i=this;if(this.rawTileData){this.vtLayers||(this.vtLayers=new vt.VectorTile(new Protobuf(this.rawTileData)).layers);var o=t?t.sourceLayer:void 0,a=this.vtLayers._geojsonTileLayer||this.vtLayers[o];if(a)for(var s=featureFilter(t&&t.filter),r={z:this.coord.z,x:this.coord.x,y:this.coord.y},l=0;l<a.length;l++){var n=a.feature(l);if(s(n)){var h=new GeoJSONFeature(n,i.coord.z,i.coord.x,i.coord.y);h.tile=r,e.push(h)}}}},Tile.prototype.hasData=function(){return"loaded"===this.state||"reloading"===this.state||"expired"===this.state},Tile.prototype.setExpiryData=function(e){var t=this.expirationTime;if(e.cacheControl){var i=util.parseCacheControl(e.cacheControl);i["max-age"]&&(this.expirationTime=Date.now()+1e3*i["max-age"])}else e.expires&&(this.expirationTime=new Date(e.expires).getTime());if(this.expirationTime){var o=Date.now(),a=!1;if(this.expirationTime>o)a=!1;else if(t)if(this.expirationTime<t)a=!0;else{var s=this.expirationTime-t;s?this.expirationTime=o+Math.max(s,CLOCK_SKEW_RETRY_TIMEOUT):a=!0}else a=!0;a?(this.expiredRequestCount++,this.state="expired"):this.expiredRequestCount=0}},Tile.prototype.getExpiryTimeout=function(){if(this.expirationTime)return this.expiredRequestCount?1e3*(1<<Math.min(this.expiredRequestCount-1,31)):Math.min(this.expirationTime-(new Date).getTime(),Math.pow(2,31)-1)},Tile.prototype.stopPlacementThrottler=function(){this.placementThrottler.stop(),"reloading"===this.state&&(this.state="loaded")},module.exports=Tile;
  194 +},{"../data/bucket":44,"../data/feature_index":54,"../style-spec/feature_filter":104,"../symbol/collision_box":162,"../symbol/collision_tile":164,"../util/throttler":213,"../util/util":215,"../util/vectortile_to_geojson":216,"pbf":24,"vector-tile":33}],94:[function(_dereq_,module,exports){
  195 +"use strict";var LngLatBounds=_dereq_("../geo/lng_lat_bounds"),clamp=_dereq_("../util/util").clamp,TileBounds=function(t,n,o){this.bounds=LngLatBounds.convert(this.validateBounds(t)),this.minzoom=n||0,this.maxzoom=o||24};TileBounds.prototype.validateBounds=function(t){return Array.isArray(t)&&4===t.length?[Math.max(-180,t[0]),Math.max(-90,t[1]),Math.min(180,t[2]),Math.min(90,t[3])]:[-180,-90,180,90]},TileBounds.prototype.contains=function(t,n){var o=n?Math.min(t.z,n):t.z,a={minX:Math.floor(this.lngX(this.bounds.getWest(),o)),minY:Math.floor(this.latY(this.bounds.getNorth(),o)),maxX:Math.ceil(this.lngX(this.bounds.getEast(),o)),maxY:Math.ceil(this.latY(this.bounds.getSouth(),o))},i=t.x>=a.minX&&t.x<a.maxX&&t.y>=a.minY&&t.y<a.maxY;return i},TileBounds.prototype.lngX=function(t,n){return(t+180)*(Math.pow(2,n)/360)},TileBounds.prototype.latY=function(t,n){var o=clamp(Math.sin(Math.PI/180*t),-.9999,.9999),a=Math.pow(2,n)/(2*Math.PI);return Math.pow(2,n-1)+.5*Math.log((1+o)/(1-o))*-a},module.exports=TileBounds;
  196 +},{"../geo/lng_lat_bounds":62,"../util/util":215}],95:[function(_dereq_,module,exports){
  197 +"use strict";function edge(t,i){if(t.row>i.row){var o=t;t=i,i=o}return{x0:t.column,y0:t.row,x1:i.column,y1:i.row,dx:i.column-t.column,dy:i.row-t.row}}function scanSpans(t,i,o,r,e){var n=Math.max(o,Math.floor(i.y0)),h=Math.min(r,Math.ceil(i.y1));if(t.x0===i.x0&&t.y0===i.y0?t.x0+i.dy/t.dy*t.dx<i.x1:t.x1-i.dy/t.dy*t.dx<i.x0){var s=t;t=i,i=s}for(var a=t.dx/t.dy,d=i.dx/i.dy,y=t.dx>0,l=i.dx<0,u=n;u<h;u++){var x=a*Math.max(0,Math.min(t.dy,u+y-t.y0))+t.x0,c=d*Math.max(0,Math.min(i.dy,u+l-i.y0))+i.x0;e(Math.floor(c),Math.ceil(x),u)}}function scanTriangle(t,i,o,r,e,n){var h,s=edge(t,i),a=edge(i,o),d=edge(o,t);s.dy>a.dy&&(h=s,s=a,a=h),s.dy>d.dy&&(h=s,s=d,d=h),a.dy>d.dy&&(h=a,a=d,d=h),s.dy&&scanSpans(d,s,r,e,n),a.dy&&scanSpans(d,a,r,e,n)}function getQuadkey(t,i,o){for(var r,e="",n=t;n>0;n--)r=1<<n-1,e+=(i&r?1:0)+(o&r?2:0);return e}var WhooTS=_dereq_("@mapbox/whoots-js"),Coordinate=_dereq_("../geo/coordinate"),TileCoord=function(t,i,o,r){isNaN(r)&&(r=0),this.z=+t,this.x=+i,this.y=+o,this.w=+r,r*=2,r<0&&(r=r*-1-1);var e=1<<this.z;this.id=32*(e*e*r+e*this.y+this.x)+this.z,this.posMatrix=null};TileCoord.prototype.toString=function(){return this.z+"/"+this.x+"/"+this.y},TileCoord.prototype.toCoordinate=function(t){var i=Math.min(this.z,void 0===t?this.z:t),o=Math.pow(2,i),r=this.y,e=this.x+o*this.w;return new Coordinate(e,r,i)},TileCoord.prototype.url=function(t,i,o){var r=WhooTS.getTileBBox(this.x,this.y,this.z),e=getQuadkey(this.z,this.x,this.y);return t[(this.x+this.y)%t.length].replace("{prefix}",(this.x%16).toString(16)+(this.y%16).toString(16)).replace("{z}",Math.min(this.z,i||this.z)).replace("{x}",this.x).replace("{y}","tms"===o?Math.pow(2,this.z)-this.y-1:this.y).replace("{quadkey}",e).replace("{bbox-epsg-3857}",r)},TileCoord.prototype.parent=function(t){return 0===this.z?null:this.z>t?new TileCoord(this.z-1,this.x,this.y,this.w):new TileCoord(this.z-1,Math.floor(this.x/2),Math.floor(this.y/2),this.w)},TileCoord.prototype.wrapped=function(){return new TileCoord(this.z,this.x,this.y,0)},TileCoord.prototype.children=function(t){if(this.z>=t)return[new TileCoord(this.z+1,this.x,this.y,this.w)];var i=this.z+1,o=2*this.x,r=2*this.y;return[new TileCoord(i,o,r,this.w),new TileCoord(i,o+1,r,this.w),new TileCoord(i,o,r+1,this.w),new TileCoord(i,o+1,r+1,this.w)]},TileCoord.cover=function(t,i,o,r){function e(t,i,e){var s,a,d,y;if(e>=0&&e<=n)for(s=t;s<i;s++)a=Math.floor(s/n),d=(s%n+n)%n,0!==a&&r!==!0||(y=new TileCoord(o,d,e,a),h[y.id]=y)}void 0===r&&(r=!0);var n=1<<t,h={};return scanTriangle(i[0],i[1],i[2],0,n,e),scanTriangle(i[2],i[3],i[0],0,n,e),Object.keys(h).map(function(t){return h[t]})},TileCoord.fromID=function(t){var i=t%32,o=1<<i,r=(t-i)/32,e=r%o,n=(r-e)/o%o,h=Math.floor(r/(o*o));return h%2!==0&&(h=h*-1-1),h/=2,new TileCoord(i,e,n,h)},module.exports=TileCoord;
  198 +},{"../geo/coordinate":60,"@mapbox/whoots-js":4}],96:[function(_dereq_,module,exports){
  199 +"use strict";var Evented=_dereq_("../util/evented"),util=_dereq_("../util/util"),loadTileJSON=_dereq_("./load_tilejson"),normalizeURL=_dereq_("../util/mapbox").normalizeTileURL,TileBounds=_dereq_("./tile_bounds"),VectorTileSource=function(e){function t(t,i,o,r){if(e.call(this),this.id=t,this.dispatcher=o,this.type="vector",this.minzoom=0,this.maxzoom=22,this.scheme="xyz",this.tileSize=512,this.reparseOverscaled=!0,this.isTileClipped=!0,util.extend(this,util.pick(i,["url","scheme","tileSize"])),this._options=util.extend({type:"vector"},i),512!==this.tileSize)throw new Error("vector tile sources must have a tileSize of 512");this.setEventedParent(r)}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype.load=function(){var e=this;this.fire("dataloading",{dataType:"source"}),loadTileJSON(this._options,function(t,i){return t?void e.fire("error",t):(util.extend(e,i),e.setBounds(i.bounds),e.fire("data",{dataType:"source",sourceDataType:"metadata"}),void e.fire("data",{dataType:"source",sourceDataType:"content"}))})},t.prototype.setBounds=function(e){this.bounds=e,e&&(this.tileBounds=new TileBounds(e,this.minzoom,this.maxzoom))},t.prototype.hasTile=function(e){return!this.tileBounds||this.tileBounds.contains(e,this.maxzoom)},t.prototype.onAdd=function(e){this.load(),this.map=e},t.prototype.serialize=function(){return util.extend({},this._options)},t.prototype.loadTile=function(e,t){function i(i,o){if(!e.aborted){if(i)return t(i);this.map._refreshExpiredTiles&&e.setExpiryData(o),e.loadVectorData(o,this.map.painter),e.redoWhenDone&&(e.redoWhenDone=!1,e.redoPlacement(this)),t(null),e.reloadCallback&&(this.loadTile(e,e.reloadCallback),e.reloadCallback=null)}}var o=e.coord.z>this.maxzoom?Math.pow(2,e.coord.z-this.maxzoom):1,r={url:normalizeURL(e.coord.url(this.tiles,this.maxzoom,this.scheme),this.url),uid:e.uid,coord:e.coord,zoom:e.coord.z,tileSize:this.tileSize*o,type:this.type,source:this.id,overscaling:o,angle:this.map.transform.angle,pitch:this.map.transform.pitch,cameraToCenterDistance:this.map.transform.cameraToCenterDistance,cameraToTileDistance:this.map.transform.cameraToTileDistance(e),showCollisionBoxes:this.map.showCollisionBoxes};e.workerID&&"expired"!==e.state?"loading"===e.state?e.reloadCallback=t:this.dispatcher.send("reloadTile",r,i.bind(this),e.workerID):e.workerID=this.dispatcher.send("loadTile",r,i.bind(this))},t.prototype.abortTile=function(e){this.dispatcher.send("abortTile",{uid:e.uid,type:this.type,source:this.id},null,e.workerID)},t.prototype.unloadTile=function(e){e.unloadVectorData(),this.dispatcher.send("removeTile",{uid:e.uid,type:this.type,source:this.id},null,e.workerID)},t}(Evented);module.exports=VectorTileSource;
  200 +},{"../util/evented":202,"../util/mapbox":209,"../util/util":215,"./load_tilejson":86,"./tile_bounds":94}],97:[function(_dereq_,module,exports){
  201 +"use strict";var ajax=_dereq_("../util/ajax"),vt=_dereq_("vector-tile"),Protobuf=_dereq_("pbf"),WorkerTile=_dereq_("./worker_tile"),util=_dereq_("../util/util"),VectorTileWorkerSource=function(e,r,t){this.actor=e,this.layerIndex=r,t&&(this.loadVectorData=t),this.loading={},this.loaded={}};VectorTileWorkerSource.prototype.loadTile=function(e,r){function t(e,t){return delete this.loading[o][a],e?r(e):t?(i.vectorTile=t,i.parse(t,this.layerIndex,this.actor,function(e,o,a){if(e)return r(e);var i={};t.expires&&(i.expires=t.expires),t.cacheControl&&(i.cacheControl=t.cacheControl),r(null,util.extend({rawTileData:t.rawData},o,i),a)}),this.loaded[o]=this.loaded[o]||{},void(this.loaded[o][a]=i)):r(null,null)}var o=e.source,a=e.uid;this.loading[o]||(this.loading[o]={});var i=this.loading[o][a]=new WorkerTile(e);i.abort=this.loadVectorData(e,t.bind(this))},VectorTileWorkerSource.prototype.reloadTile=function(e,r){function t(e,t){if(this.reloadCallback){var o=this.reloadCallback;delete this.reloadCallback,this.parse(this.vectorTile,i.layerIndex,i.actor,o)}r(e,t)}var o=this.loaded[e.source],a=e.uid,i=this;if(o&&o[a]){var l=o[a];"parsing"===l.status?l.reloadCallback=r:"done"===l.status&&l.parse(l.vectorTile,this.layerIndex,this.actor,t.bind(l))}},VectorTileWorkerSource.prototype.abortTile=function(e){var r=this.loading[e.source],t=e.uid;r&&r[t]&&r[t].abort&&(r[t].abort(),delete r[t])},VectorTileWorkerSource.prototype.removeTile=function(e){var r=this.loaded[e.source],t=e.uid;r&&r[t]&&delete r[t]},VectorTileWorkerSource.prototype.loadVectorData=function(e,r){function t(e,t){if(e)return r(e);var o=new vt.VectorTile(new Protobuf(t.data));o.rawData=t.data,o.cacheControl=t.cacheControl,o.expires=t.expires,r(e,o)}var o=ajax.getArrayBuffer(e.url,t.bind(this));return function(){o.abort()}},VectorTileWorkerSource.prototype.redoPlacement=function(e,r){var t=this.loaded[e.source],o=this.loading[e.source],a=e.uid;if(t&&t[a]){var i=t[a],l=i.redoPlacement(e.angle,e.pitch,e.cameraToCenterDistance,e.cameraToTileDistance,e.showCollisionBoxes);l.result&&r(null,l.result,l.transferables)}else o&&o[a]&&(o[a].angle=e.angle)},module.exports=VectorTileWorkerSource;
  202 +},{"../util/ajax":193,"../util/util":215,"./worker_tile":100,"pbf":24,"vector-tile":33}],98:[function(_dereq_,module,exports){
  203 +"use strict";var ajax=_dereq_("../util/ajax"),ImageSource=_dereq_("./image_source"),VideoSource=function(t){function e(e,o,i,r){t.call(this,e,o,i,r),this.roundZoom=!0,this.type="video",this.options=o}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.load=function(){var t=this,e=this.options;this.urls=e.urls,ajax.getVideo(e.urls,function(e,o){if(e)return t.fire("error",{error:e});t.video=o,t.video.loop=!0;var i;t.video.addEventListener("playing",function(){i=t.map.style.animationLoop.set(1/0),t.map._rerender()}),t.video.addEventListener("pause",function(){t.map.style.animationLoop.cancel(i)}),t.map&&t.video.play(),t._finishLoading()})},e.prototype.getVideo=function(){return this.video},e.prototype.onAdd=function(t){this.map||(this.load(),this.map=t,this.video&&(this.video.play(),this.setCoordinates(this.coordinates)))},e.prototype.prepare=function(){0===Object.keys(this.tiles).length||this.video.readyState<2||this._prepareImage(this.map.painter.gl,this.video)},e.prototype.serialize=function(){return{type:"video",urls:this.urls,coordinates:this.coordinates}},e}(ImageSource);module.exports=VideoSource;
  204 +},{"../util/ajax":193,"./image_source":85}],99:[function(_dereq_,module,exports){
  205 +"use strict";var Actor=_dereq_("../util/actor"),StyleLayerIndex=_dereq_("../style/style_layer_index"),VectorTileWorkerSource=_dereq_("./vector_tile_worker_source"),GeoJSONWorkerSource=_dereq_("./geojson_worker_source"),globalRTLTextPlugin=_dereq_("./rtl_text_plugin"),Worker=function(e){var r=this;this.self=e,this.actor=new Actor(e,this),this.layerIndexes={},this.workerSourceTypes={vector:VectorTileWorkerSource,geojson:GeoJSONWorkerSource},this.workerSources={},this.self.registerWorkerSource=function(e,o){if(r.workerSourceTypes[e])throw new Error('Worker source with name "'+e+'" already registered.');r.workerSourceTypes[e]=o},this.self.registerRTLTextPlugin=function(e){if(globalRTLTextPlugin.applyArabicShaping||globalRTLTextPlugin.processBidirectionalText)throw new Error("RTL text plugin already registered.");globalRTLTextPlugin.applyArabicShaping=e.applyArabicShaping,globalRTLTextPlugin.processBidirectionalText=e.processBidirectionalText}};Worker.prototype.setLayers=function(e,r){this.getLayerIndex(e).replace(r)},Worker.prototype.updateLayers=function(e,r){this.getLayerIndex(e).update(r.layers,r.removedIds,r.symbolOrder)},Worker.prototype.loadTile=function(e,r,o){this.getWorkerSource(e,r.type).loadTile(r,o)},Worker.prototype.reloadTile=function(e,r,o){this.getWorkerSource(e,r.type).reloadTile(r,o)},Worker.prototype.abortTile=function(e,r){this.getWorkerSource(e,r.type).abortTile(r)},Worker.prototype.removeTile=function(e,r){this.getWorkerSource(e,r.type).removeTile(r)},Worker.prototype.removeSource=function(e,r){var o=this.getWorkerSource(e,r.type);void 0!==o.removeSource&&o.removeSource(r)},Worker.prototype.redoPlacement=function(e,r,o){this.getWorkerSource(e,r.type).redoPlacement(r,o)},Worker.prototype.loadWorkerSource=function(e,r,o){try{this.self.importScripts(r.url),o()}catch(e){o(e)}},Worker.prototype.loadRTLTextPlugin=function(e,r,o){try{globalRTLTextPlugin.applyArabicShaping||globalRTLTextPlugin.processBidirectionalText||this.self.importScripts(r)}catch(e){o(e)}},Worker.prototype.getLayerIndex=function(e){var r=this.layerIndexes[e];return r||(r=this.layerIndexes[e]=new StyleLayerIndex),r},Worker.prototype.getWorkerSource=function(e,r){var o=this;if(this.workerSources[e]||(this.workerSources[e]={}),!this.workerSources[e][r]){var t={send:function(r,t,i,n){o.actor.send(r,t,i,n,e)}};this.workerSources[e][r]=new this.workerSourceTypes[r](t,this.getLayerIndex(e))}return this.workerSources[e][r]},module.exports=function(e){return new Worker(e)};
  206 +},{"../style/style_layer_index":156,"../util/actor":192,"./geojson_worker_source":83,"./rtl_text_plugin":90,"./vector_tile_worker_source":97}],100:[function(_dereq_,module,exports){
  207 +"use strict";function recalculateLayers(e,i){for(var r=0,t=e.layers;r<t.length;r+=1){var o=t[r];o.recalculate(i)}}function serializeBuckets(e,i){return e.filter(function(e){return!e.isEmpty()}).map(function(e){return e.serialize(i)})}var FeatureIndex=_dereq_("../data/feature_index"),CollisionTile=_dereq_("../symbol/collision_tile"),CollisionBoxArray=_dereq_("../symbol/collision_box"),DictionaryCoder=_dereq_("../util/dictionary_coder"),util=_dereq_("../util/util"),WorkerTile=function(e){this.coord=e.coord,this.uid=e.uid,this.zoom=e.zoom,this.tileSize=e.tileSize,this.source=e.source,this.overscaling=e.overscaling,this.angle=e.angle,this.pitch=e.pitch,this.cameraToCenterDistance=e.cameraToCenterDistance,this.cameraToTileDistance=e.cameraToTileDistance,this.showCollisionBoxes=e.showCollisionBoxes};WorkerTile.prototype.parse=function(e,i,r,t){var o=this;e.layers||(e={layers:{_geojsonTileLayer:e}}),this.status="parsing",this.data=e,this.collisionBoxArray=new CollisionBoxArray;var s=new DictionaryCoder(Object.keys(e.layers).sort()),a=new FeatureIndex(this.coord,this.overscaling);a.bucketLayerIDs={};var n={},l=0,c={featureIndex:a,iconDependencies:{},glyphDependencies:{}},u=i.familiesBySource[this.source];for(var h in u){var y=e.layers[h];if(y){1===y.version&&util.warnOnce('Vector tile source "'+o.source+'" layer "'+h+'" does not use vector tile spec v2 and therefore may have some rendering errors.');for(var m=s.encode(h),d=[],p=0;p<y.length;p++){var v=y.feature(p);v.index=p,v.sourceLayerIndex=m,d.push(v)}for(var f=0,g=u[h];f<g.length;f+=1){var T=g[f],x=T[0];if(!(x.minzoom&&o.zoom<x.minzoom||x.maxzoom&&o.zoom>=x.maxzoom||x.layout&&"none"===x.layout.visibility)){for(var B=0,b=T;B<b.length;B+=1){var k=b[B];k.recalculate(o.zoom)}var z=n[x.id]=x.createBucket({index:l,layers:T,zoom:o.zoom,overscaling:o.overscaling,collisionBoxArray:o.collisionBoxArray});z.populate(d,c),a.bucketLayerIDs[l]=T.map(function(e){return e.id}),l++}}}}var D=function(e){o.status="done",a.paintPropertyStatistics={};for(var i in n)util.extend(a.paintPropertyStatistics,n[i].getPaintPropertyStatistics());var r=[];t(null,{buckets:serializeBuckets(util.values(n),r),featureIndex:a.serialize(r),collisionTile:e.serialize(r),collisionBoxArray:o.collisionBoxArray.serialize()},r)};this.symbolBuckets=[];for(var C=i.symbolOrder.length-1;C>=0;C--){var w=n[i.symbolOrder[C]];w&&o.symbolBuckets.push(w)}if(0===this.symbolBuckets.length)return D(new CollisionTile(this.angle,this.pitch,this.cameraToCenterDistance,this.cameraToTileDistance,this.collisionBoxArray));var A=0,I=Object.keys(c.iconDependencies),O=util.mapObject(c.glyphDependencies,function(e){return Object.keys(e).map(Number)}),L=function(e){if(e)return t(e);if(A++,2===A){for(var i=new CollisionTile(o.angle,o.pitch,o.cameraToCenterDistance,o.cameraToTileDistance,o.collisionBoxArray),r=0,s=o.symbolBuckets;r<s.length;r+=1){var a=s[r];recalculateLayers(a,o.zoom),a.prepare(O,I),a.place(i,o.showCollisionBoxes)}D(i)}};Object.keys(O).length?r.send("getGlyphs",{uid:this.uid,stacks:O},function(e,i){O=i,L(e)}):L(),I.length?r.send("getIcons",{icons:I},function(e,i){I=i,L(e)}):L()},WorkerTile.prototype.redoPlacement=function(e,i,r,t,o){var s=this;if(this.angle=e,this.pitch=i,this.cameraToCenterDistance=r,this.cameraToTileDistance=t,"done"!==this.status)return{};for(var a=new CollisionTile(this.angle,this.pitch,this.cameraToCenterDistance,this.cameraToTileDistance,this.collisionBoxArray),n=0,l=s.symbolBuckets;n<l.length;n+=1){var c=l[n];recalculateLayers(c,s.zoom),c.place(a,o)}var u=[];return{result:{buckets:serializeBuckets(this.symbolBuckets,u),collisionTile:a.serialize(u)},transferables:u}},module.exports=WorkerTile;
  208 +},{"../data/feature_index":54,"../symbol/collision_box":162,"../symbol/collision_tile":164,"../util/dictionary_coder":199,"../util/util":215}],101:[function(_dereq_,module,exports){
  209 +"use strict";function deref(r,e){var f={};for(var t in r)"ref"!==t&&(f[t]=r[t]);return refProperties.forEach(function(r){r in e&&(f[r]=e[r])}),f}function derefLayers(r){r=r.slice();for(var e=Object.create(null),f=0;f<r.length;f++)e[r[f].id]=r[f];for(var t=0;t<r.length;t++)"ref"in r[t]&&(r[t]=deref(r[t],e[r[t].ref]));return r}var refProperties=_dereq_("./util/ref_properties");module.exports=derefLayers;
  210 +},{"./util/ref_properties":124}],102:[function(_dereq_,module,exports){
  211 +"use strict";function diffSources(e,r,o,a){e=e||{},r=r||{};var s;for(s in e)e.hasOwnProperty(s)&&(r.hasOwnProperty(s)||(o.push({command:operations.removeSource,args:[s]}),a[s]=!0));for(s in r)r.hasOwnProperty(s)&&(e.hasOwnProperty(s)?isEqual(e[s],r[s])||(o.push({command:operations.removeSource,args:[s]}),o.push({command:operations.addSource,args:[s,r[s]]}),a[s]=!0):o.push({command:operations.addSource,args:[s,r[s]]}))}function diffLayerPropertyChanges(e,r,o,a,s,t){e=e||{},r=r||{};var n;for(n in e)e.hasOwnProperty(n)&&(isEqual(e[n],r[n])||o.push({command:t,args:[a,n,r[n],s]}));for(n in r)r.hasOwnProperty(n)&&!e.hasOwnProperty(n)&&(isEqual(e[n],r[n])||o.push({command:t,args:[a,n,r[n],s]}))}function pluckId(e){return e.id}function indexById(e,r){return e[r.id]=r,e}function diffLayers(e,r,o){e=e||[],r=r||[];var a,s,t,n,i,p,m,u=e.map(pluckId),l=r.map(pluckId),y=e.reduce(indexById,{}),c=r.reduce(indexById,{}),d=u.slice(),h=Object.create(null);for(a=0,s=0;a<u.length;a++)t=u[a],c.hasOwnProperty(t)?s++:(o.push({command:operations.removeLayer,args:[t]}),d.splice(d.indexOf(t,s),1));for(a=0,s=0;a<l.length;a++)t=l[l.length-1-a],d[d.length-1-a]!==t&&(y.hasOwnProperty(t)?(o.push({command:operations.removeLayer,args:[t]}),d.splice(d.lastIndexOf(t,d.length-s),1)):s++,p=d[d.length-a],o.push({command:operations.addLayer,args:[c[t],p]}),d.splice(d.length-a,0,t),h[t]=!0);for(a=0;a<l.length;a++)if(t=l[a],n=y[t],i=c[t],!h[t]&&!isEqual(n,i))if(isEqual(n.source,i.source)&&isEqual(n["source-layer"],i["source-layer"])&&isEqual(n.type,i.type)){diffLayerPropertyChanges(n.layout,i.layout,o,t,null,operations.setLayoutProperty),diffLayerPropertyChanges(n.paint,i.paint,o,t,null,operations.setPaintProperty),isEqual(n.filter,i.filter)||o.push({command:operations.setFilter,args:[t,i.filter]}),isEqual(n.minzoom,i.minzoom)&&isEqual(n.maxzoom,i.maxzoom)||o.push({command:operations.setLayerZoomRange,args:[t,i.minzoom,i.maxzoom]});for(m in n)n.hasOwnProperty(m)&&"layout"!==m&&"paint"!==m&&"filter"!==m&&"metadata"!==m&&"minzoom"!==m&&"maxzoom"!==m&&(0===m.indexOf("paint.")?diffLayerPropertyChanges(n[m],i[m],o,t,m.slice(6),operations.setPaintProperty):isEqual(n[m],i[m])||o.push({command:operations.setLayerProperty,args:[t,m,i[m]]}));for(m in i)i.hasOwnProperty(m)&&!n.hasOwnProperty(m)&&"layout"!==m&&"paint"!==m&&"filter"!==m&&"metadata"!==m&&"minzoom"!==m&&"maxzoom"!==m&&(0===m.indexOf("paint.")?diffLayerPropertyChanges(n[m],i[m],o,t,m.slice(6),operations.setPaintProperty):isEqual(n[m],i[m])||o.push({command:operations.setLayerProperty,args:[t,m,i[m]]}))}else o.push({command:operations.removeLayer,args:[t]}),p=d[d.lastIndexOf(t)+1],o.push({command:operations.addLayer,args:[i,p]})}function diffStyles(e,r){if(!e)return[{command:operations.setStyle,args:[r]}];var o=[];try{if(!isEqual(e.version,r.version))return[{command:operations.setStyle,args:[r]}];isEqual(e.center,r.center)||o.push({command:operations.setCenter,args:[r.center]}),isEqual(e.zoom,r.zoom)||o.push({command:operations.setZoom,args:[r.zoom]}),isEqual(e.bearing,r.bearing)||o.push({command:operations.setBearing,args:[r.bearing]}),isEqual(e.pitch,r.pitch)||o.push({command:operations.setPitch,args:[r.pitch]}),isEqual(e.sprite,r.sprite)||o.push({command:operations.setSprite,args:[r.sprite]}),isEqual(e.glyphs,r.glyphs)||o.push({command:operations.setGlyphs,args:[r.glyphs]}),isEqual(e.transition,r.transition)||o.push({command:operations.setTransition,args:[r.transition]}),isEqual(e.light,r.light)||o.push({command:operations.setLight,args:[r.light]});var a={},s=[];diffSources(e.sources,r.sources,s,a);var t=[];e.layers&&e.layers.forEach(function(e){a[e.source]?o.push({command:operations.removeLayer,args:[e.id]}):t.push(e)}),o=o.concat(s),diffLayers(t,r.layers,o)}catch(e){console.warn("Unable to compute style diff:",e),o=[{command:operations.setStyle,args:[r]}]}return o}var isEqual=_dereq_("lodash.isequal"),operations={setStyle:"setStyle",addLayer:"addLayer",removeLayer:"removeLayer",setPaintProperty:"setPaintProperty",setLayoutProperty:"setLayoutProperty",setFilter:"setFilter",addSource:"addSource",removeSource:"removeSource",setLayerZoomRange:"setLayerZoomRange",setLayerProperty:"setLayerProperty",setCenter:"setCenter",setZoom:"setZoom",setBearing:"setBearing",setPitch:"setPitch",setSprite:"setSprite",setGlyphs:"setGlyphs",setTransition:"setTransition",setLight:"setLight"};module.exports=diffStyles,module.exports.operations=operations;
  212 +},{"lodash.isequal":115}],103:[function(_dereq_,module,exports){
  213 +"use strict";function ValidationError(r,i){for(var t=[],o=arguments.length-2;o-- >0;)t[o]=arguments[o+2];this.message=(r?r+": ":"")+format.apply(format,t),null!==i&&void 0!==i&&i.__line__&&(this.line=i.__line__)}var format=_dereq_("util").format;module.exports=ValidationError;
  214 +},{"util":32}],104:[function(_dereq_,module,exports){
  215 +"use strict";function createFilter(e){return new Function("f","var p = (f && f.properties || {}); return "+compile(e))}function compile(e){if(!e)return"true";var i=e[0];if(e.length<=1)return"any"===i?"false":"true";var n="=="===i?compileComparisonOp(e[1],e[2],"===",!1):"!="===i?compileComparisonOp(e[1],e[2],"!==",!1):"<"===i||">"===i||"<="===i||">="===i?compileComparisonOp(e[1],e[2],i,!0):"any"===i?compileLogicalOp(e.slice(1),"||"):"all"===i?compileLogicalOp(e.slice(1),"&&"):"none"===i?compileNegation(compileLogicalOp(e.slice(1),"||")):"in"===i?compileInOp(e[1],e.slice(2)):"!in"===i?compileNegation(compileInOp(e[1],e.slice(2))):"has"===i?compileHasOp(e[1]):"!has"===i?compileNegation(compileHasOp(e[1])):"true";return"("+n+")"}function compilePropertyReference(e){return"$type"===e?"f.type":"$id"===e?"f.id":"p["+JSON.stringify(e)+"]"}function compileComparisonOp(e,i,n,r){var o=compilePropertyReference(e),t="$type"===e?types.indexOf(i):JSON.stringify(i);return(r?"typeof "+o+"=== typeof "+t+"&&":"")+o+n+t}function compileLogicalOp(e,i){return e.map(compile).join(i)}function compileInOp(e,i){"$type"===e&&(i=i.map(function(e){return types.indexOf(e)}));var n=JSON.stringify(i.sort(compare)),r=compilePropertyReference(e);return i.length<=200?n+".indexOf("+r+") !== -1":"function(v, a, i, j) {while (i <= j) { var m = (i + j) >> 1; if (a[m] === v) return true; if (a[m] > v) j = m - 1; else i = m + 1;}return false; }("+r+", "+n+",0,"+(i.length-1)+")"}function compileHasOp(e){return"$id"===e?'"id" in f':JSON.stringify(e)+" in p"}function compileNegation(e){return"!("+e+")"}function compare(e,i){return e<i?-1:e>i?1:0}module.exports=createFilter;var types=["Unknown","Point","LineString","Polygon"];
  216 +},{}],105:[function(_dereq_,module,exports){
  217 +"use strict";function xyz2lab(r){return r>t3?Math.pow(r,1/3):r/t2+t0}function lab2xyz(r){return r>t1?r*r*r:t2*(r-t0)}function xyz2rgb(r){return 255*(r<=.0031308?12.92*r:1.055*Math.pow(r,1/2.4)-.055)}function rgb2xyz(r){return r/=255,r<=.04045?r/12.92:Math.pow((r+.055)/1.055,2.4)}function rgbToLab(r){var t=rgb2xyz(r[0]),a=rgb2xyz(r[1]),n=rgb2xyz(r[2]),b=xyz2lab((.4124564*t+.3575761*a+.1804375*n)/Xn),o=xyz2lab((.2126729*t+.7151522*a+.072175*n)/Yn),g=xyz2lab((.0193339*t+.119192*a+.9503041*n)/Zn);return[116*o-16,500*(b-o),200*(o-g),r[3]]}function labToRgb(r){var t=(r[0]+16)/116,a=isNaN(r[1])?t:t+r[1]/500,n=isNaN(r[2])?t:t-r[2]/200;return t=Yn*lab2xyz(t),a=Xn*lab2xyz(a),n=Zn*lab2xyz(n),[xyz2rgb(3.2404542*a-1.5371385*t-.4985314*n),xyz2rgb(-.969266*a+1.8760108*t+.041556*n),xyz2rgb(.0556434*a-.2040259*t+1.0572252*n),r[3]]}function rgbToHcl(r){var t=rgbToLab(r),a=t[0],n=t[1],b=t[2],o=Math.atan2(b,n)*rad2deg;return[o<0?o+360:o,Math.sqrt(n*n+b*b),a,r[3]]}function hclToRgb(r){var t=r[0]*deg2rad,a=r[1],n=r[2];return labToRgb([n,Math.cos(t)*a,Math.sin(t)*a,r[3]])}var Xn=.95047,Yn=1,Zn=1.08883,t0=4/29,t1=6/29,t2=3*t1*t1,t3=t1*t1*t1,deg2rad=Math.PI/180,rad2deg=180/Math.PI;module.exports={lab:{forward:rgbToLab,reverse:labToRgb},hcl:{forward:rgbToHcl,reverse:hclToRgb}};
  218 +},{}],106:[function(_dereq_,module,exports){
  219 +"use strict";function identityFunction(t){return t}function createFunction(t,e){var o,n="color"===e.type;if(isFunctionDefinition(t)){var r=t.stops&&"object"==typeof t.stops[0][0],a=r||void 0!==t.property,i=r||!a,s=t.type||("interpolated"===e.function?"exponential":"interval");n&&(t=extend({},t),t.stops&&(t.stops=t.stops.map(function(t){return[t[0],parseColor(t[1])]})),t.default?t.default=parseColor(t.default):t.default=parseColor(e.default));var u,p,l;if("exponential"===s)u=evaluateExponentialFunction;else if("interval"===s)u=evaluateIntervalFunction;else if("categorical"===s){u=evaluateCategoricalFunction,p=Object.create(null);for(var c=0,f=t.stops;c<f.length;c+=1){var v=f[c];p[v[0]]=v[1]}l=typeof t.stops[0][0]}else{if("identity"!==s)throw new Error('Unknown function type "'+s+'"');u=evaluateIdentityFunction}var d;if(t.colorSpace&&"rgb"!==t.colorSpace){if(!colorSpaces[t.colorSpace])throw new Error("Unknown color space: "+t.colorSpace);var y=colorSpaces[t.colorSpace];t=JSON.parse(JSON.stringify(t));for(var F=0;F<t.stops.length;F++)t.stops[F]=[t.stops[F][0],y.forward(t.stops[F][1])];d=y.reverse}else d=identityFunction;if(r){for(var h={},g=[],C=0;C<t.stops.length;C++){var m=t.stops[C],S=m[0].zoom;void 0===h[S]&&(h[S]={zoom:S,type:t.type,property:t.property,default:t.default,stops:[]},g.push(S)),h[S].stops.push([m[0].value,m[1]])}for(var T=[],x=0,b=g;x<b.length;x+=1){var q=b[x];T.push([h[q].zoom,createFunction(h[q],e)])}o=function(o,n){return d(evaluateExponentialFunction({stops:T,base:t.base},e,o)(o,n))},o.isFeatureConstant=!1,o.isZoomConstant=!1}else i?(o=function(o){return d(u(t,e,o,p,l))},o.isFeatureConstant=!0,o.isZoomConstant=!1):(o=function(o,n){var r=n[t.property];return void 0===r?coalesce(t.default,e.default):d(u(t,e,r,p,l))},o.isFeatureConstant=!1,o.isZoomConstant=!0)}else n&&t&&(t=parseColor(t)),o=function(){return t},o.isFeatureConstant=!0,o.isZoomConstant=!0;return o}function coalesce(t,e,o){return void 0!==t?t:void 0!==e?e:void 0!==o?o:void 0}function evaluateCategoricalFunction(t,e,o,n,r){var a=typeof o===r?n[o]:void 0;return coalesce(a,t.default,e.default)}function evaluateIntervalFunction(t,e,o){if("number"!==getType(o))return coalesce(t.default,e.default);var n=t.stops.length;if(1===n)return t.stops[0][1];if(o<=t.stops[0][0])return t.stops[0][1];if(o>=t.stops[n-1][0])return t.stops[n-1][1];var r=findStopLessThanOrEqualTo(t.stops,o);return t.stops[r][1]}function evaluateExponentialFunction(t,e,o){var n=void 0!==t.base?t.base:1;if("number"!==getType(o))return coalesce(t.default,e.default);var r=t.stops.length;if(1===r)return t.stops[0][1];if(o<=t.stops[0][0])return t.stops[0][1];if(o>=t.stops[r-1][0])return t.stops[r-1][1];var a=findStopLessThanOrEqualTo(t.stops,o),i=interpolationFactor(o,n,t.stops[a][0],t.stops[a+1][0]),s=t.stops[a][1],u=t.stops[a+1][1],p=interpolate[e.type]||identityFunction;return"function"==typeof s?function(){for(var t=[],e=arguments.length;e--;)t[e]=arguments[e];var o=s.apply(void 0,t),n=u.apply(void 0,t);if(void 0!==o&&void 0!==n)return p(o,n,i)}:p(s,u,i)}function evaluateIdentityFunction(t,e,o){return"color"===e.type?o=parseColor(o):getType(o)!==e.type&&(o=void 0),coalesce(o,t.default,e.default)}function findStopLessThanOrEqualTo(t,e){for(var o,n,r=t.length,a=0,i=r-1,s=0;a<=i;){if(s=Math.floor((a+i)/2),o=t[s][0],n=t[s+1][0],e===o||e>o&&e<n)return s;o<e?a=s+1:o>e&&(i=s-1)}return Math.max(s-1,0)}function isFunctionDefinition(t){return"object"==typeof t&&(t.stops||"identity"===t.type)}function interpolationFactor(t,e,o,n){var r=n-o,a=t-o;return 1===e?a/r:(Math.pow(e,a)-1)/(Math.pow(e,r)-1)}var colorSpaces=_dereq_("./color_spaces"),parseColor=_dereq_("../util/parse_color"),extend=_dereq_("../util/extend"),getType=_dereq_("../util/get_type"),interpolate=_dereq_("../util/interpolate");module.exports=createFunction,module.exports.isFunctionDefinition=isFunctionDefinition,module.exports.interpolationFactor=interpolationFactor,module.exports.findStopLessThanOrEqualTo=findStopLessThanOrEqualTo;
  220 +},{"../util/extend":120,"../util/get_type":121,"../util/interpolate":122,"../util/parse_color":123,"./color_spaces":105}],107:[function(_dereq_,module,exports){
  221 +"use strict";function key(r){return stringify(refProperties.map(function(e){return r[e]}))}function groupByLayout(r){for(var e={},t=0;t<r.length;t++){var i=key(r[t]),u=e[i];u||(u=e[i]=[]),u.push(r[t])}var n=[];for(var o in e)n.push(e[o]);return n}var refProperties=_dereq_("./util/ref_properties"),stringify=_dereq_("fast-stable-stringify");module.exports=groupByLayout;
  222 +},{"./util/ref_properties":124,"fast-stable-stringify":109}],108:[function(_dereq_,module,exports){
  223 +function clamp_css_byte(e){return e=Math.round(e),e<0?0:e>255?255:e}function clamp_css_float(e){return e<0?0:e>1?1:e}function parse_css_int(e){return clamp_css_byte("%"===e[e.length-1]?parseFloat(e)/100*255:parseInt(e))}function parse_css_float(e){return clamp_css_float("%"===e[e.length-1]?parseFloat(e)/100:parseFloat(e))}function css_hue_to_rgb(e,r,l){return l<0?l+=1:l>1&&(l-=1),6*l<1?e+(r-e)*l*6:2*l<1?r:3*l<2?e+(r-e)*(2/3-l)*6:e}function parseCSSColor(e){var r=e.replace(/ /g,"").toLowerCase();if(r in kCSSColorTable)return kCSSColorTable[r].slice();if("#"===r[0]){if(4===r.length){var l=parseInt(r.substr(1),16);return l>=0&&l<=4095?[(3840&l)>>4|(3840&l)>>8,240&l|(240&l)>>4,15&l|(15&l)<<4,1]:null}if(7===r.length){var l=parseInt(r.substr(1),16);return l>=0&&l<=16777215?[(16711680&l)>>16,(65280&l)>>8,255&l,1]:null}return null}var a=r.indexOf("("),t=r.indexOf(")");if(a!==-1&&t+1===r.length){var n=r.substr(0,a),s=r.substr(a+1,t-(a+1)).split(","),o=1;switch(n){case"rgba":if(4!==s.length)return null;o=parse_css_float(s.pop());case"rgb":return 3!==s.length?null:[parse_css_int(s[0]),parse_css_int(s[1]),parse_css_int(s[2]),o];case"hsla":if(4!==s.length)return null;o=parse_css_float(s.pop());case"hsl":if(3!==s.length)return null;var i=(parseFloat(s[0])%360+360)%360/360,u=parse_css_float(s[1]),g=parse_css_float(s[2]),d=g<=.5?g*(u+1):g+u-g*u,c=2*g-d;return[clamp_css_byte(255*css_hue_to_rgb(c,d,i+1/3)),clamp_css_byte(255*css_hue_to_rgb(c,d,i)),clamp_css_byte(255*css_hue_to_rgb(c,d,i-1/3)),o];default:return null}}return null}var kCSSColorTable={transparent:[0,0,0,0],aliceblue:[240,248,255,1],antiquewhite:[250,235,215,1],aqua:[0,255,255,1],aquamarine:[127,255,212,1],azure:[240,255,255,1],beige:[245,245,220,1],bisque:[255,228,196,1],black:[0,0,0,1],blanchedalmond:[255,235,205,1],blue:[0,0,255,1],blueviolet:[138,43,226,1],brown:[165,42,42,1],burlywood:[222,184,135,1],cadetblue:[95,158,160,1],chartreuse:[127,255,0,1],chocolate:[210,105,30,1],coral:[255,127,80,1],cornflowerblue:[100,149,237,1],cornsilk:[255,248,220,1],crimson:[220,20,60,1],cyan:[0,255,255,1],darkblue:[0,0,139,1],darkcyan:[0,139,139,1],darkgoldenrod:[184,134,11,1],darkgray:[169,169,169,1],darkgreen:[0,100,0,1],darkgrey:[169,169,169,1],darkkhaki:[189,183,107,1],darkmagenta:[139,0,139,1],darkolivegreen:[85,107,47,1],darkorange:[255,140,0,1],darkorchid:[153,50,204,1],darkred:[139,0,0,1],darksalmon:[233,150,122,1],darkseagreen:[143,188,143,1],darkslateblue:[72,61,139,1],darkslategray:[47,79,79,1],darkslategrey:[47,79,79,1],darkturquoise:[0,206,209,1],darkviolet:[148,0,211,1],deeppink:[255,20,147,1],deepskyblue:[0,191,255,1],dimgray:[105,105,105,1],dimgrey:[105,105,105,1],dodgerblue:[30,144,255,1],firebrick:[178,34,34,1],floralwhite:[255,250,240,1],forestgreen:[34,139,34,1],fuchsia:[255,0,255,1],gainsboro:[220,220,220,1],ghostwhite:[248,248,255,1],gold:[255,215,0,1],goldenrod:[218,165,32,1],gray:[128,128,128,1],green:[0,128,0,1],greenyellow:[173,255,47,1],grey:[128,128,128,1],honeydew:[240,255,240,1],hotpink:[255,105,180,1],indianred:[205,92,92,1],indigo:[75,0,130,1],ivory:[255,255,240,1],khaki:[240,230,140,1],lavender:[230,230,250,1],lavenderblush:[255,240,245,1],lawngreen:[124,252,0,1],lemonchiffon:[255,250,205,1],lightblue:[173,216,230,1],lightcoral:[240,128,128,1],lightcyan:[224,255,255,1],lightgoldenrodyellow:[250,250,210,1],lightgray:[211,211,211,1],lightgreen:[144,238,144,1],lightgrey:[211,211,211,1],lightpink:[255,182,193,1],lightsalmon:[255,160,122,1],lightseagreen:[32,178,170,1],lightskyblue:[135,206,250,1],lightslategray:[119,136,153,1],lightslategrey:[119,136,153,1],lightsteelblue:[176,196,222,1],lightyellow:[255,255,224,1],lime:[0,255,0,1],limegreen:[50,205,50,1],linen:[250,240,230,1],magenta:[255,0,255,1],maroon:[128,0,0,1],mediumaquamarine:[102,205,170,1],mediumblue:[0,0,205,1],mediumorchid:[186,85,211,1],mediumpurple:[147,112,219,1],mediumseagreen:[60,179,113,1],mediumslateblue:[123,104,238,1],mediumspringgreen:[0,250,154,1],mediumturquoise:[72,209,204,1],mediumvioletred:[199,21,133,1],midnightblue:[25,25,112,1],mintcream:[245,255,250,1],mistyrose:[255,228,225,1],moccasin:[255,228,181,1],navajowhite:[255,222,173,1],navy:[0,0,128,1],oldlace:[253,245,230,1],olive:[128,128,0,1],olivedrab:[107,142,35,1],orange:[255,165,0,1],orangered:[255,69,0,1],orchid:[218,112,214,1],palegoldenrod:[238,232,170,1],palegreen:[152,251,152,1],paleturquoise:[175,238,238,1],palevioletred:[219,112,147,1],papayawhip:[255,239,213,1],peachpuff:[255,218,185,1],peru:[205,133,63,1],pink:[255,192,203,1],plum:[221,160,221,1],powderblue:[176,224,230,1],purple:[128,0,128,1],rebeccapurple:[102,51,153,1],red:[255,0,0,1],rosybrown:[188,143,143,1],royalblue:[65,105,225,1],saddlebrown:[139,69,19,1],salmon:[250,128,114,1],sandybrown:[244,164,96,1],seagreen:[46,139,87,1],seashell:[255,245,238,1],sienna:[160,82,45,1],silver:[192,192,192,1],skyblue:[135,206,235,1],slateblue:[106,90,205,1],slategray:[112,128,144,1],slategrey:[112,128,144,1],snow:[255,250,250,1],springgreen:[0,255,127,1],steelblue:[70,130,180,1],tan:[210,180,140,1],teal:[0,128,128,1],thistle:[216,191,216,1],tomato:[255,99,71,1],turquoise:[64,224,208,1],violet:[238,130,238,1],wheat:[245,222,179,1],white:[255,255,255,1],whitesmoke:[245,245,245,1],yellow:[255,255,0,1],yellowgreen:[154,205,50,1]};try{exports.parseCSSColor=parseCSSColor}catch(e){}
  224 +},{}],109:[function(_dereq_,module,exports){
  225 +function sss(r){var e,t,s,n,u,a;switch(typeof r){case"object":if(null===r)return null;if(isArray(r)){for(s="[",t=r.length-1,e=0;e<t;e++)s+=sss(r[e])+",";return t>-1&&(s+=sss(r[e])),s+"]"}for(n=objKeys(r).sort(),t=n.length,s="{",u=n[e=0],a=t>0&&void 0!==r[u];e<t;)a?(s+='"'+u.replace(strReg,strReplace)+'":'+sss(r[u]),u=n[++e],a=e<t&&void 0!==r[u],a&&(s+=",")):(u=n[++e],a=e<t&&void 0!==r[u]);return s+"}";case"undefined":return null;case"string":return'"'+r.replace(strReg,strReplace)+'"';default:return r}}var toString={}.toString,isArray=Array.isArray||function(r){return"[object Array]"===toString.call(r)},objKeys=Object.keys||function(r){var e=[];for(var t in r)r.hasOwnProperty(t)&&e.push(t);return e},strReg=/[\u0000-\u001f"\\]/g,strReplace=function(r){var e=r.charCodeAt(0);switch(e){case 34:return'\\"';case 92:return"\\\\";case 12:return"\\f";case 10:return"\\n";case 13:return"\\r";case 9:return"\\t";case 8:return"\\b";default:return e>15?"\\u00"+e.toString(16):"\\u000"+e.toString(16)}};module.exports=function(r){if(void 0!==r)return""+sss(r)},module.exports.stringSearch=strReg,module.exports.stringReplace=strReplace;
  226 +},{}],110:[function(_dereq_,module,exports){
  227 +function isObjectLike(r){return!!r&&"object"==typeof r}function arraySome(r,e){for(var a=-1,t=r.length;++a<t;)if(e(r[a],a,r))return!0;return!1}function baseIsEqual(r,e,a,t,o,n){return r===e||(null==r||null==e||!isObject(r)&&!isObjectLike(e)?r!==r&&e!==e:baseIsEqualDeep(r,e,baseIsEqual,a,t,o,n))}function baseIsEqualDeep(r,e,a,t,o,n,u){var c=isArray(r),s=isArray(e),i=arrayTag,g=arrayTag;c||(i=objToString.call(r),i==argsTag?i=objectTag:i!=objectTag&&(c=isTypedArray(r))),s||(g=objToString.call(e),g==argsTag?g=objectTag:g!=objectTag&&(s=isTypedArray(e)));var b=i==objectTag,l=g==objectTag,f=i==g;if(f&&!c&&!b)return equalByTag(r,e,i);if(!o){var y=b&&hasOwnProperty.call(r,"__wrapped__"),T=l&&hasOwnProperty.call(e,"__wrapped__");if(y||T)return a(y?r.value():r,T?e.value():e,t,o,n,u)}if(!f)return!1;n||(n=[]),u||(u=[]);for(var j=n.length;j--;)if(n[j]==r)return u[j]==e;n.push(r),u.push(e);var p=(c?equalArrays:equalObjects)(r,e,a,t,o,n,u);return n.pop(),u.pop(),p}function equalArrays(r,e,a,t,o,n,u){var c=-1,s=r.length,i=e.length;if(s!=i&&!(o&&i>s))return!1;for(;++c<s;){var g=r[c],b=e[c],l=t?t(o?b:g,o?g:b,c):void 0;if(void 0!==l){if(l)continue;return!1}if(o){if(!arraySome(e,function(r){return g===r||a(g,r,t,o,n,u)}))return!1}else if(g!==b&&!a(g,b,t,o,n,u))return!1}return!0}function equalByTag(r,e,a){switch(a){case boolTag:case dateTag:return+r==+e;case errorTag:return r.name==e.name&&r.message==e.message;case numberTag:return r!=+r?e!=+e:r==+e;case regexpTag:case stringTag:return r==e+""}return!1}function equalObjects(r,e,a,t,o,n,u){var c=keys(r),s=c.length,i=keys(e),g=i.length;if(s!=g&&!o)return!1;for(var b=s;b--;){var l=c[b];if(!(o?l in e:hasOwnProperty.call(e,l)))return!1}for(var f=o;++b<s;){l=c[b];var y=r[l],T=e[l],j=t?t(o?T:y,o?y:T,l):void 0;if(!(void 0===j?a(y,T,t,o,n,u):j))return!1;f||(f="constructor"==l)}if(!f){var p=r.constructor,v=e.constructor;if(p!=v&&"constructor"in r&&"constructor"in e&&!("function"==typeof p&&p instanceof p&&"function"==typeof v&&v instanceof v))return!1}return!0}function isObject(r){var e=typeof r;return!!r&&("object"==e||"function"==e)}var isArray=_dereq_("lodash.isarray"),isTypedArray=_dereq_("lodash.istypedarray"),keys=_dereq_("lodash.keys"),argsTag="[object Arguments]",arrayTag="[object Array]",boolTag="[object Boolean]",dateTag="[object Date]",errorTag="[object Error]",numberTag="[object Number]",objectTag="[object Object]",regexpTag="[object RegExp]",stringTag="[object String]",objectProto=Object.prototype,hasOwnProperty=objectProto.hasOwnProperty,objToString=objectProto.toString;module.exports=baseIsEqual;
  228 +},{"lodash.isarray":114,"lodash.istypedarray":116,"lodash.keys":117}],111:[function(_dereq_,module,exports){
  229 +function bindCallback(n,t,r){if("function"!=typeof n)return identity;if(void 0===t)return n;switch(r){case 1:return function(r){return n.call(t,r)};case 3:return function(r,e,u){return n.call(t,r,e,u)};case 4:return function(r,e,u,c){return n.call(t,r,e,u,c)};case 5:return function(r,e,u,c,i){return n.call(t,r,e,u,c,i)}}return function(){return n.apply(t,arguments)}}function identity(n){return n}module.exports=bindCallback;
  230 +},{}],112:[function(_dereq_,module,exports){
  231 +function isObjectLike(t){return!!t&&"object"==typeof t}function getNative(t,o){var e=null==t?void 0:t[o];return isNative(e)?e:void 0}function isFunction(t){return isObject(t)&&objToString.call(t)==funcTag}function isObject(t){var o=typeof t;return!!t&&("object"==o||"function"==o)}function isNative(t){return null!=t&&(isFunction(t)?reIsNative.test(fnToString.call(t)):isObjectLike(t)&&reIsHostCtor.test(t))}var funcTag="[object Function]",reIsHostCtor=/^\[object .+?Constructor\]$/,objectProto=Object.prototype,fnToString=Function.prototype.toString,hasOwnProperty=objectProto.hasOwnProperty,objToString=objectProto.toString,reIsNative=RegExp("^"+fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");module.exports=getNative;
  232 +},{}],113:[function(_dereq_,module,exports){
  233 +function isArguments(t){return isArrayLikeObject(t)&&hasOwnProperty.call(t,"callee")&&(!propertyIsEnumerable.call(t,"callee")||objectToString.call(t)==argsTag)}function isArrayLike(t){return null!=t&&isLength(t.length)&&!isFunction(t)}function isArrayLikeObject(t){return isObjectLike(t)&&isArrayLike(t)}function isFunction(t){var e=isObject(t)?objectToString.call(t):"";return e==funcTag||e==genTag}function isLength(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=MAX_SAFE_INTEGER}function isObject(t){var e=typeof t;return!!t&&("object"==e||"function"==e)}function isObjectLike(t){return!!t&&"object"==typeof t}var MAX_SAFE_INTEGER=9007199254740991,argsTag="[object Arguments]",funcTag="[object Function]",genTag="[object GeneratorFunction]",objectProto=Object.prototype,hasOwnProperty=objectProto.hasOwnProperty,objectToString=objectProto.toString,propertyIsEnumerable=objectProto.propertyIsEnumerable;module.exports=isArguments;
  234 +},{}],114:[function(_dereq_,module,exports){
  235 +function isObjectLike(t){return!!t&&"object"==typeof t}function getNative(t,r){var e=null==t?void 0:t[r];return isNative(e)?e:void 0}function isLength(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=MAX_SAFE_INTEGER}function isFunction(t){return isObject(t)&&objToString.call(t)==funcTag}function isObject(t){var r=typeof t;return!!t&&("object"==r||"function"==r)}function isNative(t){return null!=t&&(isFunction(t)?reIsNative.test(fnToString.call(t)):isObjectLike(t)&&reIsHostCtor.test(t))}var arrayTag="[object Array]",funcTag="[object Function]",reIsHostCtor=/^\[object .+?Constructor\]$/,objectProto=Object.prototype,fnToString=Function.prototype.toString,hasOwnProperty=objectProto.hasOwnProperty,objToString=objectProto.toString,reIsNative=RegExp("^"+fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),nativeIsArray=getNative(Array,"isArray"),MAX_SAFE_INTEGER=9007199254740991,isArray=nativeIsArray||function(t){return isObjectLike(t)&&isLength(t.length)&&objToString.call(t)==arrayTag};module.exports=isArray;
  236 +},{}],115:[function(_dereq_,module,exports){
  237 +function isEqual(a,l,i,e){i="function"==typeof i?bindCallback(i,e,3):void 0;var s=i?i(a,l):void 0;return void 0===s?baseIsEqual(a,l,i):!!s}var baseIsEqual=_dereq_("lodash._baseisequal"),bindCallback=_dereq_("lodash._bindcallback");module.exports=isEqual;
  238 +},{"lodash._baseisequal":110,"lodash._bindcallback":111}],116:[function(_dereq_,module,exports){
  239 +function isLength(a){return"number"==typeof a&&a>-1&&a%1==0&&a<=MAX_SAFE_INTEGER}function isObjectLike(a){return!!a&&"object"==typeof a}function isTypedArray(a){return isObjectLike(a)&&isLength(a.length)&&!!typedArrayTags[objectToString.call(a)]}var MAX_SAFE_INTEGER=9007199254740991,argsTag="[object Arguments]",arrayTag="[object Array]",boolTag="[object Boolean]",dateTag="[object Date]",errorTag="[object Error]",funcTag="[object Function]",mapTag="[object Map]",numberTag="[object Number]",objectTag="[object Object]",regexpTag="[object RegExp]",setTag="[object Set]",stringTag="[object String]",weakMapTag="[object WeakMap]",arrayBufferTag="[object ArrayBuffer]",dataViewTag="[object DataView]",float32Tag="[object Float32Array]",float64Tag="[object Float64Array]",int8Tag="[object Int8Array]",int16Tag="[object Int16Array]",int32Tag="[object Int32Array]",uint8Tag="[object Uint8Array]",uint8ClampedTag="[object Uint8ClampedArray]",uint16Tag="[object Uint16Array]",uint32Tag="[object Uint32Array]",typedArrayTags={};typedArrayTags[float32Tag]=typedArrayTags[float64Tag]=typedArrayTags[int8Tag]=typedArrayTags[int16Tag]=typedArrayTags[int32Tag]=typedArrayTags[uint8Tag]=typedArrayTags[uint8ClampedTag]=typedArrayTags[uint16Tag]=typedArrayTags[uint32Tag]=!0,typedArrayTags[argsTag]=typedArrayTags[arrayTag]=typedArrayTags[arrayBufferTag]=typedArrayTags[boolTag]=typedArrayTags[dataViewTag]=typedArrayTags[dateTag]=typedArrayTags[errorTag]=typedArrayTags[funcTag]=typedArrayTags[mapTag]=typedArrayTags[numberTag]=typedArrayTags[objectTag]=typedArrayTags[regexpTag]=typedArrayTags[setTag]=typedArrayTags[stringTag]=typedArrayTags[weakMapTag]=!1;var objectProto=Object.prototype,objectToString=objectProto.toString;module.exports=isTypedArray;
  240 +},{}],117:[function(_dereq_,module,exports){
  241 +function baseProperty(e){return function(t){return null==t?void 0:t[e]}}function isArrayLike(e){return null!=e&&isLength(getLength(e))}function isIndex(e,t){return e="number"==typeof e||reIsUint.test(e)?+e:-1,t=null==t?MAX_SAFE_INTEGER:t,e>-1&&e%1==0&&e<t}function isLength(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=MAX_SAFE_INTEGER}function shimKeys(e){for(var t=keysIn(e),r=t.length,n=r&&e.length,s=!!n&&isLength(n)&&(isArray(e)||isArguments(e)),o=-1,i=[];++o<r;){var u=t[o];(s&&isIndex(u,n)||hasOwnProperty.call(e,u))&&i.push(u)}return i}function isObject(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}function keysIn(e){if(null==e)return[];isObject(e)||(e=Object(e));var t=e.length;t=t&&isLength(t)&&(isArray(e)||isArguments(e))&&t||0;for(var r=e.constructor,n=-1,s="function"==typeof r&&r.prototype===e,o=Array(t),i=t>0;++n<t;)o[n]=n+"";for(var u in e)i&&isIndex(u,t)||"constructor"==u&&(s||!hasOwnProperty.call(e,u))||o.push(u);return o}var getNative=_dereq_("lodash._getnative"),isArguments=_dereq_("lodash.isarguments"),isArray=_dereq_("lodash.isarray"),reIsUint=/^\d+$/,objectProto=Object.prototype,hasOwnProperty=objectProto.hasOwnProperty,nativeKeys=getNative(Object,"keys"),MAX_SAFE_INTEGER=9007199254740991,getLength=baseProperty("length"),keys=nativeKeys?function(e){var t=null==e?void 0:e.constructor;return"function"==typeof t&&t.prototype===e||"function"!=typeof e&&isArrayLike(e)?shimKeys(e):isObject(e)?nativeKeys(e):[]}:shimKeys;module.exports=keys;
  242 +},{"lodash._getnative":112,"lodash.isarguments":113,"lodash.isarray":114}],118:[function(_dereq_,module,exports){
  243 +"use strict";module.exports=_dereq_("./v8.json");
  244 +},{"./v8.json":119}],119:[function(_dereq_,module,exports){
  245 +module.exports={"$version":8,"$root":{"version":{"required":true,"type":"enum","values":[8]},"name":{"type":"string"},"metadata":{"type":"*"},"center":{"type":"array","value":"number"},"zoom":{"type":"number"},"bearing":{"type":"number","default":0,"period":360,"units":"degrees"},"pitch":{"type":"number","default":0,"units":"degrees"},"light":{"type":"light"},"sources":{"required":true,"type":"sources"},"sprite":{"type":"string"},"glyphs":{"type":"string"},"transition":{"type":"transition"},"layers":{"required":true,"type":"array","value":"layer"}},"sources":{"*":{"type":"source"}},"source":["source_tile","source_geojson","source_video","source_image","source_canvas"],"source_tile":{"type":{"required":true,"type":"enum","values":{"vector":{},"raster":{}}},"url":{"type":"string"},"tiles":{"type":"array","value":"string"},"minzoom":{"type":"number","default":0},"maxzoom":{"type":"number","default":22},"tileSize":{"type":"number","default":512,"units":"pixels"},"*":{"type":"*"}},"source_geojson":{"type":{"required":true,"type":"enum","values":{"geojson":{}}},"data":{"type":"*"},"maxzoom":{"type":"number","default":18},"buffer":{"type":"number","default":128,"maximum":512,"minimum":0},"tolerance":{"type":"number","default":0.375},"cluster":{"type":"boolean","default":false},"clusterRadius":{"type":"number","default":50,"minimum":0},"clusterMaxZoom":{"type":"number"}},"source_video":{"type":{"required":true,"type":"enum","values":{"video":{}}},"urls":{"required":true,"type":"array","value":"string"},"coordinates":{"required":true,"type":"array","length":4,"value":{"type":"array","length":2,"value":"number"}}},"source_image":{"type":{"required":true,"type":"enum","values":{"image":{}}},"url":{"required":true,"type":"string"},"coordinates":{"required":true,"type":"array","length":4,"value":{"type":"array","length":2,"value":"number"}}},"source_canvas":{"type":{"required":true,"type":"enum","values":{"canvas":{}}},"coordinates":{"required":true,"type":"array","length":4,"value":{"type":"array","length":2,"value":"number"}},"animate":{"type":"boolean","default":"true"},"canvas":{"type":"string","required":true}},"layer":{"id":{"type":"string","required":true},"type":{"type":"enum","values":{"fill":{},"line":{},"symbol":{},"circle":{},"fill-extrusion":{},"raster":{},"background":{}}},"metadata":{"type":"*"},"ref":{"type":"string"},"source":{"type":"string"},"source-layer":{"type":"string"},"minzoom":{"type":"number","minimum":0,"maximum":24},"maxzoom":{"type":"number","minimum":0,"maximum":24},"filter":{"type":"filter"},"layout":{"type":"layout"},"paint":{"type":"paint"},"paint.*":{"type":"paint"}},"layout":["layout_fill","layout_line","layout_circle","layout_fill-extrusion","layout_symbol","layout_raster","layout_background"],"layout_background":{"visibility":{"type":"enum","values":{"visible":{},"none":{}},"default":"visible"}},"layout_fill":{"visibility":{"type":"enum","values":{"visible":{},"none":{}},"default":"visible"}},"layout_circle":{"visibility":{"type":"enum","values":{"visible":{},"none":{}},"default":"visible"}},"layout_fill-extrusion":{"visibility":{"type":"enum","values":{"visible":{},"none":{}},"default":"visible"}},"layout_line":{"line-cap":{"type":"enum","function":"piecewise-constant","zoom-function":true,"values":{"butt":{},"round":{},"square":{}},"default":"butt"},"line-join":{"type":"enum","function":"piecewise-constant","zoom-function":true,"values":{"bevel":{},"round":{},"miter":{}},"default":"miter"},"line-miter-limit":{"type":"number","default":2,"function":"interpolated","zoom-function":true,"requires":[{"line-join":"miter"}]},"line-round-limit":{"type":"number","default":1.05,"function":"interpolated","zoom-function":true,"requires":[{"line-join":"round"}]},"visibility":{"type":"enum","values":{"visible":{},"none":{}},"default":"visible"}},"layout_symbol":{"symbol-placement":{"type":"enum","function":"piecewise-constant","zoom-function":true,"values":{"point":{},"line":{}},"default":"point"},"symbol-spacing":{"type":"number","default":250,"minimum":1,"function":"interpolated","zoom-function":true,"units":"pixels","requires":[{"symbol-placement":"line"}]},"symbol-avoid-edges":{"type":"boolean","function":"piecewise-constant","zoom-function":true,"default":false},"icon-allow-overlap":{"type":"boolean","function":"piecewise-constant","zoom-function":true,"default":false,"requires":["icon-image"]},"icon-ignore-placement":{"type":"boolean","function":"piecewise-constant","zoom-function":true,"default":false,"requires":["icon-image"]},"icon-optional":{"type":"boolean","function":"piecewise-constant","zoom-function":true,"default":false,"requires":["icon-image","text-field"]},"icon-rotation-alignment":{"type":"enum","function":"piecewise-constant","zoom-function":true,"values":{"map":{},"viewport":{},"auto":{}},"default":"auto","requires":["icon-image"]},"icon-size":{"type":"number","default":1,"minimum":0,"function":"interpolated","zoom-function":true,"property-function":true,"units":"factor of the original icon size","requires":["icon-image"]},"icon-text-fit":{"type":"enum","function":"piecewise-constant","zoom-function":true,"values":{"none":{},"width":{},"height":{},"both":{}},"default":"none","requires":["icon-image","text-field"]},"icon-text-fit-padding":{"type":"array","value":"number","length":4,"default":[0,0,0,0],"units":"pixels","function":"interpolated","zoom-function":true,"requires":["icon-image","text-field",{"icon-text-fit":["both","width","height"]}]},"icon-image":{"type":"string","function":"piecewise-constant","zoom-function":true,"property-function":true,"tokens":true},"icon-rotate":{"type":"number","default":0,"period":360,"function":"interpolated","zoom-function":true,"property-function":true,"units":"degrees","requires":["icon-image"]},"icon-padding":{"type":"number","default":2,"minimum":0,"function":"interpolated","zoom-function":true,"units":"pixels","requires":["icon-image"]},"icon-keep-upright":{"type":"boolean","function":"piecewise-constant","zoom-function":true,"default":false,"requires":["icon-image",{"icon-rotation-alignment":"map"},{"symbol-placement":"line"}]},"icon-offset":{"type":"array","value":"number","length":2,"default":[0,0],"function":"interpolated","zoom-function":true,"property-function":true,"requires":["icon-image"]},"text-pitch-alignment":{"type":"enum","function":"piecewise-constant","zoom-function":true,"values":{"map":{},"viewport":{},"auto":{}},"default":"auto","requires":["text-field"]},"text-rotation-alignment":{"type":"enum","function":"piecewise-constant","zoom-function":true,"values":{"map":{},"viewport":{},"auto":{}},"default":"auto","requires":["text-field"]},"text-field":{"type":"string","function":"piecewise-constant","zoom-function":true,"property-function":true,"default":"","tokens":true},"text-font":{"type":"array","value":"string","function":"piecewise-constant","zoom-function":true,"default":["Open Sans Regular","Arial Unicode MS Regular"],"requires":["text-field"]},"text-size":{"type":"number","default":16,"minimum":0,"units":"pixels","function":"interpolated","zoom-function":true,"property-function":true,"requires":["text-field"]},"text-max-width":{"type":"number","default":10,"minimum":0,"units":"ems","function":"interpolated","zoom-function":true,"requires":["text-field"]},"text-line-height":{"type":"number","default":1.2,"units":"ems","function":"interpolated","zoom-function":true,"requires":["text-field"]},"text-letter-spacing":{"type":"number","default":0,"units":"ems","function":"interpolated","zoom-function":true,"requires":["text-field"]},"text-justify":{"type":"enum","function":"piecewise-constant","zoom-function":true,"values":{"left":{},"center":{},"right":{}},"default":"center","requires":["text-field"]},"text-anchor":{"type":"enum","function":"piecewise-constant","zoom-function":true,"values":{"center":{},"left":{},"right":{},"top":{},"bottom":{},"top-left":{},"top-right":{},"bottom-left":{},"bottom-right":{}},"default":"center","requires":["text-field"]},"text-max-angle":{"type":"number","default":45,"units":"degrees","function":"interpolated","zoom-function":true,"requires":["text-field",{"symbol-placement":"line"}]},"text-rotate":{"type":"number","default":0,"period":360,"units":"degrees","function":"interpolated","zoom-function":true,"property-function":true,"requires":["text-field"]},"text-padding":{"type":"number","default":2,"minimum":0,"units":"pixels","function":"interpolated","zoom-function":true,"requires":["text-field"]},"text-keep-upright":{"type":"boolean","function":"piecewise-constant","zoom-function":true,"default":true,"requires":["text-field",{"text-rotation-alignment":"map"},{"symbol-placement":"line"}]},"text-transform":{"type":"enum","function":"piecewise-constant","zoom-function":true,"property-function":true,"values":{"none":{},"uppercase":{},"lowercase":{}},"default":"none","requires":["text-field"]},"text-offset":{"type":"array","value":"number","units":"ems","function":"interpolated","zoom-function":true,"property-function":true,"length":2,"default":[0,0],"requires":["text-field"]},"text-allow-overlap":{"type":"boolean","function":"piecewise-constant","zoom-function":true,"default":false,"requires":["text-field"]},"text-ignore-placement":{"type":"boolean","function":"piecewise-constant","zoom-function":true,"default":false,"requires":["text-field"]},"text-optional":{"type":"boolean","function":"piecewise-constant","zoom-function":true,"default":false,"requires":["text-field","icon-image"]},"visibility":{"type":"enum","values":{"visible":{},"none":{}},"default":"visible"}},"layout_raster":{"visibility":{"type":"enum","values":{"visible":{},"none":{}},"default":"visible"}},"filter":{"type":"array","value":"*"},"filter_operator":{"type":"enum","values":{"==":{},"!=":{},">":{},">=":{},"<":{},"<=":{},"in":{},"!in":{},"all":{},"any":{},"none":{},"has":{},"!has":{}}},"geometry_type":{"type":"enum","values":{"Point":{},"LineString":{},"Polygon":{}}},"function":{"stops":{"type":"array","value":"function_stop"},"base":{"type":"number","default":1,"minimum":0},"property":{"type":"string","default":"$zoom"},"type":{"type":"enum","values":{"identity":{},"exponential":{},"interval":{},"categorical":{}},"default":"exponential"},"colorSpace":{"type":"enum","values":{"rgb":{},"lab":{},"hcl":{}},"default":"rgb"},"default":{"type":"*","required":false}},"function_stop":{"type":"array","minimum":0,"maximum":22,"value":["number","color"],"length":2},"light":{"anchor":{"type":"enum","default":"viewport","values":{"map":{},"viewport":{}},"transition":false,"zoom-function":true,"property-function":false,"function":"piecewise-constant"},"position":{"type":"array","default":[1.15,210,30],"length":3,"value":"number","transition":true,"function":"interpolated","zoom-function":true,"property-function":false},"color":{"type":"color","default":"#ffffff","function":"interpolated","zoom-function":true,"property-function":false,"transition":true},"intensity":{"type":"number","default":0.5,"minimum":0,"maximum":1,"function":"interpolated","zoom-function":true,"property-function":false,"transition":true}},"paint":["paint_fill","paint_line","paint_circle","paint_fill-extrusion","paint_symbol","paint_raster","paint_background"],"paint_fill":{"fill-antialias":{"type":"boolean","function":"piecewise-constant","zoom-function":true,"default":true},"fill-opacity":{"type":"number","function":"interpolated","zoom-function":true,"property-function":true,"default":1,"minimum":0,"maximum":1,"transition":true},"fill-color":{"type":"color","default":"#000000","function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"requires":[{"!":"fill-pattern"}]},"fill-outline-color":{"type":"color","function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"requires":[{"!":"fill-pattern"},{"fill-antialias":true}]},"fill-translate":{"type":"array","value":"number","length":2,"default":[0,0],"function":"interpolated","zoom-function":true,"transition":true,"units":"pixels"},"fill-translate-anchor":{"type":"enum","function":"piecewise-constant","zoom-function":true,"values":{"map":{},"viewport":{}},"default":"map","requires":["fill-translate"]},"fill-pattern":{"type":"string","function":"piecewise-constant","zoom-function":true,"transition":true}},"paint_fill-extrusion":{"fill-extrusion-opacity":{"type":"number","function":"interpolated","zoom-function":true,"property-function":false,"default":1,"minimum":0,"maximum":1,"transition":true},"fill-extrusion-color":{"type":"color","default":"#000000","function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"requires":[{"!":"fill-extrusion-pattern"}]},"fill-extrusion-translate":{"type":"array","value":"number","length":2,"default":[0,0],"function":"interpolated","zoom-function":true,"transition":true,"units":"pixels"},"fill-extrusion-translate-anchor":{"type":"enum","function":"piecewise-constant","zoom-function":true,"values":{"map":{},"viewport":{}},"default":"map","requires":["fill-extrusion-translate"]},"fill-extrusion-pattern":{"type":"string","function":"piecewise-constant","zoom-function":true,"transition":true},"fill-extrusion-height":{"type":"number","function":"interpolated","zoom-function":true,"property-function":true,"default":0,"minimum":0,"maximum":65535,"units":"meters","transition":true},"fill-extrusion-base":{"type":"number","function":"interpolated","zoom-function":true,"property-function":true,"default":0,"minimum":0,"maximum":65535,"units":"meters","transition":true,"requires":["fill-extrusion-height"]}},"paint_line":{"line-opacity":{"type":"number","function":"interpolated","zoom-function":true,"property-function":true,"default":1,"minimum":0,"maximum":1,"transition":true},"line-color":{"type":"color","default":"#000000","function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"requires":[{"!":"line-pattern"}]},"line-translate":{"type":"array","value":"number","length":2,"default":[0,0],"function":"interpolated","zoom-function":true,"transition":true,"units":"pixels"},"line-translate-anchor":{"type":"enum","function":"piecewise-constant","zoom-function":true,"values":{"map":{},"viewport":{}},"default":"map","requires":["line-translate"]},"line-width":{"type":"number","default":1,"minimum":0,"function":"interpolated","zoom-function":true,"transition":true,"units":"pixels"},"line-gap-width":{"type":"number","default":0,"minimum":0,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"units":"pixels"},"line-offset":{"type":"number","default":0,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"units":"pixels"},"line-blur":{"type":"number","default":0,"minimum":0,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"units":"pixels"},"line-dasharray":{"type":"array","value":"number","function":"piecewise-constant","zoom-function":true,"minimum":0,"transition":true,"units":"line widths","requires":[{"!":"line-pattern"}]},"line-pattern":{"type":"string","function":"piecewise-constant","zoom-function":true,"transition":true}},"paint_circle":{"circle-radius":{"type":"number","default":5,"minimum":0,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"units":"pixels"},"circle-color":{"type":"color","default":"#000000","function":"interpolated","zoom-function":true,"property-function":true,"transition":true},"circle-blur":{"type":"number","default":0,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true},"circle-opacity":{"type":"number","default":1,"minimum":0,"maximum":1,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true},"circle-translate":{"type":"array","value":"number","length":2,"default":[0,0],"function":"interpolated","zoom-function":true,"transition":true,"units":"pixels"},"circle-translate-anchor":{"type":"enum","function":"piecewise-constant","zoom-function":true,"values":{"map":{},"viewport":{}},"default":"map","requires":["circle-translate"]},"circle-pitch-scale":{"type":"enum","function":"piecewise-constant","zoom-function":true,"values":{"map":{},"viewport":{}},"default":"map"},"circle-stroke-width":{"type":"number","default":0,"minimum":0,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"units":"pixels"},"circle-stroke-color":{"type":"color","default":"#000000","function":"interpolated","zoom-function":true,"property-function":true,"transition":true},"circle-stroke-opacity":{"type":"number","default":1,"minimum":0,"maximum":1,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true}},"paint_symbol":{"icon-opacity":{"type":"number","default":1,"minimum":0,"maximum":1,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"requires":["icon-image"]},"icon-color":{"type":"color","default":"#000000","function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"requires":["icon-image"]},"icon-halo-color":{"type":"color","default":"rgba(0, 0, 0, 0)","function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"requires":["icon-image"]},"icon-halo-width":{"type":"number","default":0,"minimum":0,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"units":"pixels","requires":["icon-image"]},"icon-halo-blur":{"type":"number","default":0,"minimum":0,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"units":"pixels","requires":["icon-image"]},"icon-translate":{"type":"array","value":"number","length":2,"default":[0,0],"function":"interpolated","zoom-function":true,"transition":true,"units":"pixels","requires":["icon-image"]},"icon-translate-anchor":{"type":"enum","function":"piecewise-constant","zoom-function":true,"values":{"map":{},"viewport":{}},"default":"map","requires":["icon-image","icon-translate"]},"text-opacity":{"type":"number","default":1,"minimum":0,"maximum":1,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"requires":["text-field"]},"text-color":{"type":"color","default":"#000000","function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"requires":["text-field"]},"text-halo-color":{"type":"color","default":"rgba(0, 0, 0, 0)","function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"requires":["text-field"]},"text-halo-width":{"type":"number","default":0,"minimum":0,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"units":"pixels","requires":["text-field"]},"text-halo-blur":{"type":"number","default":0,"minimum":0,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"units":"pixels","requires":["text-field"]},"text-translate":{"type":"array","value":"number","length":2,"default":[0,0],"function":"interpolated","zoom-function":true,"transition":true,"units":"pixels","requires":["text-field"]},"text-translate-anchor":{"type":"enum","function":"piecewise-constant","zoom-function":true,"values":{"map":{},"viewport":{}},"default":"map","requires":["text-field","text-translate"]}},"paint_raster":{"raster-opacity":{"type":"number","default":1,"minimum":0,"maximum":1,"function":"interpolated","zoom-function":true,"transition":true},"raster-hue-rotate":{"type":"number","default":0,"period":360,"function":"interpolated","zoom-function":true,"transition":true,"units":"degrees"},"raster-brightness-min":{"type":"number","function":"interpolated","zoom-function":true,"default":0,"minimum":0,"maximum":1,"transition":true},"raster-brightness-max":{"type":"number","function":"interpolated","zoom-function":true,"default":1,"minimum":0,"maximum":1,"transition":true},"raster-saturation":{"type":"number","default":0,"minimum":-1,"maximum":1,"function":"interpolated","zoom-function":true,"transition":true},"raster-contrast":{"type":"number","default":0,"minimum":-1,"maximum":1,"function":"interpolated","zoom-function":true,"transition":true},"raster-fade-duration":{"type":"number","default":300,"minimum":0,"function":"interpolated","zoom-function":true,"transition":true,"units":"milliseconds"}},"paint_background":{"background-color":{"type":"color","default":"#000000","function":"interpolated","zoom-function":true,"transition":true,"requires":[{"!":"background-pattern"}]},"background-pattern":{"type":"string","function":"piecewise-constant","zoom-function":true,"transition":true},"background-opacity":{"type":"number","default":1,"minimum":0,"maximum":1,"function":"interpolated","zoom-function":true,"transition":true}},"transition":{"duration":{"type":"number","default":300,"minimum":0,"units":"milliseconds"},"delay":{"type":"number","default":0,"minimum":0,"units":"milliseconds"}}}
  246 +},{}],120:[function(_dereq_,module,exports){
  247 +"use strict";module.exports=function(r){for(var t=[],e=arguments.length-1;e-- >0;)t[e]=arguments[e+1];for(var n=0,o=t;n<o.length;n+=1){var a=o[n];for(var f in a)r[f]=a[f]}return r};
  248 +},{}],121:[function(_dereq_,module,exports){
  249 +"use strict";module.exports=function(n){return n instanceof Number?"number":n instanceof String?"string":n instanceof Boolean?"boolean":Array.isArray(n)?"array":null===n?"null":typeof n};
  250 +},{}],122:[function(_dereq_,module,exports){
  251 +"use strict";function interpolate(t,e,n){return t*(1-n)+e*n}module.exports=interpolate,interpolate.number=interpolate,interpolate.vec2=function(t,e,n){return[interpolate(t[0],e[0],n),interpolate(t[1],e[1],n)]},interpolate.color=function(t,e,n){return[interpolate(t[0],e[0],n),interpolate(t[1],e[1],n),interpolate(t[2],e[2],n),interpolate(t[3],e[3],n)]},interpolate.array=function(t,e,n){return t.map(function(t,r){return interpolate(t,e[r],n)})};
  252 +},{}],123:[function(_dereq_,module,exports){
  253 +"use strict";var parseColorString=_dereq_("csscolorparser").parseCSSColor;module.exports=function(r){if("string"==typeof r){var e=parseColorString(r);if(!e)return;return[e[0]/255*e[3],e[1]/255*e[3],e[2]/255*e[3],e[3]]}return Array.isArray(r)?r:void 0};
  254 +},{"csscolorparser":108}],124:[function(_dereq_,module,exports){
  255 +"use strict";module.exports=["type","source","source-layer","minzoom","maxzoom","filter","layout"];
  256 +},{}],125:[function(_dereq_,module,exports){
  257 +"use strict";module.exports=function(n){return n instanceof Number||n instanceof String||n instanceof Boolean?n.valueOf():n};
  258 +},{}],126:[function(_dereq_,module,exports){
  259 +"use strict";var ValidationError=_dereq_("../error/validation_error"),getType=_dereq_("../util/get_type"),extend=_dereq_("../util/extend");module.exports=function(e){var r=_dereq_("./validate_function"),t=_dereq_("./validate_object"),i={"*":function(){return[]},array:_dereq_("./validate_array"),boolean:_dereq_("./validate_boolean"),number:_dereq_("./validate_number"),color:_dereq_("./validate_color"),constants:_dereq_("./validate_constants"),enum:_dereq_("./validate_enum"),filter:_dereq_("./validate_filter"),function:_dereq_("./validate_function"),layer:_dereq_("./validate_layer"),object:_dereq_("./validate_object"),source:_dereq_("./validate_source"),light:_dereq_("./validate_light"),string:_dereq_("./validate_string")},a=e.value,n=e.valueSpec,u=e.key,o=e.styleSpec,l=e.style;if("string"===getType(a)&&"@"===a[0]){if(o.$version>7)return[new ValidationError(u,a,"constants have been deprecated as of v8")];if(!(a in l.constants))return[new ValidationError(u,a,'constant "%s" not found',a)];e=extend({},e,{value:l.constants[a]})}return n.function&&"object"===getType(a)?r(e):n.type&&i[n.type]?i[n.type](e):t(extend({},e,{valueSpec:n.type?o[n.type]:n}))};
  260 +},{"../error/validation_error":103,"../util/extend":120,"../util/get_type":121,"./validate_array":127,"./validate_boolean":128,"./validate_color":129,"./validate_constants":130,"./validate_enum":131,"./validate_filter":132,"./validate_function":133,"./validate_layer":135,"./validate_light":137,"./validate_number":138,"./validate_object":139,"./validate_source":142,"./validate_string":143}],127:[function(_dereq_,module,exports){
  261 +"use strict";var getType=_dereq_("../util/get_type"),validate=_dereq_("./validate"),ValidationError=_dereq_("../error/validation_error");module.exports=function(e){var r=e.value,t=e.valueSpec,a=e.style,n=e.styleSpec,l=e.key,i=e.arrayElementValidator||validate;if("array"!==getType(r))return[new ValidationError(l,r,"array expected, %s found",getType(r))];if(t.length&&r.length!==t.length)return[new ValidationError(l,r,"array length %d expected, length %d found",t.length,r.length)];if(t["min-length"]&&r.length<t["min-length"])return[new ValidationError(l,r,"array length at least %d expected, length %d found",t["min-length"],r.length)];var o={type:t.value};n.$version<7&&(o.function=t.function),"object"===getType(t.value)&&(o=t.value);for(var u=[],d=0;d<r.length;d++)u=u.concat(i({array:r,arrayIndex:d,value:r[d],valueSpec:o,style:a,styleSpec:n,key:l+"["+d+"]"}));return u};
  262 +},{"../error/validation_error":103,"../util/get_type":121,"./validate":126}],128:[function(_dereq_,module,exports){
  263 +"use strict";var getType=_dereq_("../util/get_type"),ValidationError=_dereq_("../error/validation_error");module.exports=function(e){var r=e.value,o=e.key,t=getType(r);return"boolean"!==t?[new ValidationError(o,r,"boolean expected, %s found",t)]:[]};
  264 +},{"../error/validation_error":103,"../util/get_type":121}],129:[function(_dereq_,module,exports){
  265 +"use strict";var ValidationError=_dereq_("../error/validation_error"),getType=_dereq_("../util/get_type"),parseCSSColor=_dereq_("csscolorparser").parseCSSColor;module.exports=function(r){var e=r.key,o=r.value,t=getType(o);return"string"!==t?[new ValidationError(e,o,"color expected, %s found",t)]:null===parseCSSColor(o)?[new ValidationError(e,o,'color expected, "%s" found',o)]:[]};
  266 +},{"../error/validation_error":103,"../util/get_type":121,"csscolorparser":108}],130:[function(_dereq_,module,exports){
  267 +"use strict";var ValidationError=_dereq_("../error/validation_error"),getType=_dereq_("../util/get_type");module.exports=function(r){var e=r.key,t=r.value,a=r.styleSpec;if(a.$version>7)return t?[new ValidationError(e,t,"constants have been deprecated as of v8")]:[];var o=getType(t);if("object"!==o)return[new ValidationError(e,t,"object expected, %s found",o)];var n=[];for(var i in t)"@"!==i[0]&&n.push(new ValidationError(e+"."+i,t[i],'constants must start with "@"'));return n};
  268 +},{"../error/validation_error":103,"../util/get_type":121}],131:[function(_dereq_,module,exports){
  269 +"use strict";var ValidationError=_dereq_("../error/validation_error"),unbundle=_dereq_("../util/unbundle_jsonlint");module.exports=function(e){var r=e.key,n=e.value,u=e.valueSpec,o=[];return Array.isArray(u.values)?u.values.indexOf(unbundle(n))===-1&&o.push(new ValidationError(r,n,"expected one of [%s], %s found",u.values.join(", "),n)):Object.keys(u.values).indexOf(unbundle(n))===-1&&o.push(new ValidationError(r,n,"expected one of [%s], %s found",Object.keys(u.values).join(", "),n)),o};
  270 +},{"../error/validation_error":103,"../util/unbundle_jsonlint":125}],132:[function(_dereq_,module,exports){
  271 +"use strict";var ValidationError=_dereq_("../error/validation_error"),validateEnum=_dereq_("./validate_enum"),getType=_dereq_("../util/get_type"),unbundle=_dereq_("../util/unbundle_jsonlint");module.exports=function e(r){var t,a=r.value,n=r.key,l=r.styleSpec,s=[];if("array"!==getType(a))return[new ValidationError(n,a,"array expected, %s found",getType(a))];if(a.length<1)return[new ValidationError(n,a,"filter array must have at least 1 element")];switch(s=s.concat(validateEnum({key:n+"[0]",value:a[0],valueSpec:l.filter_operator,style:r.style,styleSpec:r.styleSpec})),unbundle(a[0])){case"<":case"<=":case">":case">=":a.length>=2&&"$type"===unbundle(a[1])&&s.push(new ValidationError(n,a,'"$type" cannot be use with operator "%s"',a[0]));case"==":case"!=":3!==a.length&&s.push(new ValidationError(n,a,'filter array for operator "%s" must have 3 elements',a[0]));case"in":case"!in":a.length>=2&&(t=getType(a[1]),"string"!==t&&s.push(new ValidationError(n+"[1]",a[1],"string expected, %s found",t)));for(var o=2;o<a.length;o++)t=getType(a[o]),"$type"===unbundle(a[1])?s=s.concat(validateEnum({key:n+"["+o+"]",value:a[o],valueSpec:l.geometry_type,style:r.style,styleSpec:r.styleSpec})):"string"!==t&&"number"!==t&&"boolean"!==t&&s.push(new ValidationError(n+"["+o+"]",a[o],"string, number, or boolean expected, %s found",t));break;case"any":case"all":case"none":for(var i=1;i<a.length;i++)s=s.concat(e({key:n+"["+i+"]",value:a[i],style:r.style,styleSpec:r.styleSpec}));break;case"has":case"!has":t=getType(a[1]),2!==a.length?s.push(new ValidationError(n,a,'filter array for "%s" operator must have 2 elements',a[0])):"string"!==t&&s.push(new ValidationError(n+"[1]",a[1],"string expected, %s found",t))}return s};
  272 +},{"../error/validation_error":103,"../util/get_type":121,"../util/unbundle_jsonlint":125,"./validate_enum":131}],133:[function(_dereq_,module,exports){
  273 +"use strict";var ValidationError=_dereq_("../error/validation_error"),getType=_dereq_("../util/get_type"),validate=_dereq_("./validate"),validateObject=_dereq_("./validate_object"),validateArray=_dereq_("./validate_array"),validateNumber=_dereq_("./validate_number"),unbundle=_dereq_("../util/unbundle_jsonlint");module.exports=function(e){function t(e){if("identity"===p)return[new ValidationError(e.key,e.value,'identity function may not have a "stops" property')];var t=[],a=e.value;return t=t.concat(validateArray({key:e.key,value:a,valueSpec:e.valueSpec,style:e.style,styleSpec:e.styleSpec,arrayElementValidator:r})),"array"===getType(a)&&0===a.length&&t.push(new ValidationError(e.key,a,"array must have at least one stop")),t}function r(e){var t=[],r=e.value,o=e.key;if("array"!==getType(r))return[new ValidationError(o,r,"array expected, %s found",getType(r))];if(2!==r.length)return[new ValidationError(o,r,"array length %d expected, length %d found",2,r.length)];if(c){if("object"!==getType(r[0]))return[new ValidationError(o,r,"object expected, %s found",getType(r[0]))];if(void 0===r[0].zoom)return[new ValidationError(o,r,"object stop key must have zoom")];if(void 0===r[0].value)return[new ValidationError(o,r,"object stop key must have value")];if(l&&l>unbundle(r[0].zoom))return[new ValidationError(o,r[0].zoom,"stop zoom values must appear in ascending order")];unbundle(r[0].zoom)!==l&&(l=unbundle(r[0].zoom),i=void 0,s={}),t=t.concat(validateObject({key:o+"[0]",value:r[0],valueSpec:{zoom:{}},style:e.style,styleSpec:e.styleSpec,objectElementValidators:{zoom:validateNumber,value:a}}))}else t=t.concat(a({key:o+"[0]",value:r[0],valueSpec:{},style:e.style,styleSpec:e.styleSpec}));return t.concat(validate({key:o+"[1]",value:r[1],valueSpec:u,style:e.style,styleSpec:e.styleSpec}))}function a(e){var t=getType(e.value),r=unbundle(e.value);if(n){if(t!==n)return[new ValidationError(e.key,e.value,"%s stop domain type must match previous stop domain type %s",t,n)]}else n=t;if("number"!==t&&"string"!==t&&"boolean"!==t)return[new ValidationError(e.key,e.value,"stop domain value must be a number, string, or boolean")];if("number"!==t&&"categorical"!==p){var a="number expected, %s found";return u["property-function"]&&void 0===p&&(a+='\nIf you intended to use a categorical function, specify `"type": "categorical"`.'),[new ValidationError(e.key,e.value,a,t)]}return"categorical"!==p||"number"!==t||isFinite(r)&&Math.floor(r)===r?"number"===t&&void 0!==i&&r<i?[new ValidationError(e.key,e.value,"stop domain values must appear in ascending order")]:(i=r,"categorical"===p&&r in s?[new ValidationError(e.key,e.value,"stop domain values must be unique")]:(s[r]=!0,[])):[new ValidationError(e.key,e.value,"integer expected, found %s",r)]}function o(e){return validate({key:e.key,value:e.value,valueSpec:u,style:e.style,styleSpec:e.styleSpec})}var n,i,l,u=e.valueSpec,p=unbundle(e.value.type),s={},y="categorical"!==p&&void 0===e.value.property,d=!y,c="array"===getType(e.value.stops)&&"array"===getType(e.value.stops[0])&&"object"===getType(e.value.stops[0][0]),v=validateObject({key:e.key,value:e.value,valueSpec:e.styleSpec.function,style:e.style,styleSpec:e.styleSpec,objectElementValidators:{stops:t,default:o}});return"identity"===p&&y&&v.push(new ValidationError(e.key,e.value,'missing required property "property"')),"identity"===p||e.value.stops||v.push(new ValidationError(e.key,e.value,'missing required property "stops"')),"exponential"===p&&"piecewise-constant"===e.valueSpec.function&&v.push(new ValidationError(e.key,e.value,"exponential functions not supported")),e.styleSpec.$version>=8&&(d&&!e.valueSpec["property-function"]?v.push(new ValidationError(e.key,e.value,"property functions not supported")):y&&!e.valueSpec["zoom-function"]&&v.push(new ValidationError(e.key,e.value,"zoom functions not supported"))),"categorical"!==p&&!c||void 0!==e.value.property||v.push(new ValidationError(e.key,e.value,'"property" property is required')),v};
  274 +},{"../error/validation_error":103,"../util/get_type":121,"../util/unbundle_jsonlint":125,"./validate":126,"./validate_array":127,"./validate_number":138,"./validate_object":139}],134:[function(_dereq_,module,exports){
  275 +"use strict";var ValidationError=_dereq_("../error/validation_error"),validateString=_dereq_("./validate_string");module.exports=function(r){var e=r.value,t=r.key,a=validateString(r);return a.length?a:(e.indexOf("{fontstack}")===-1&&a.push(new ValidationError(t,e,'"glyphs" url must include a "{fontstack}" token')),e.indexOf("{range}")===-1&&a.push(new ValidationError(t,e,'"glyphs" url must include a "{range}" token')),a)};
  276 +},{"../error/validation_error":103,"./validate_string":143}],135:[function(_dereq_,module,exports){
  277 +"use strict";var ValidationError=_dereq_("../error/validation_error"),unbundle=_dereq_("../util/unbundle_jsonlint"),validateObject=_dereq_("./validate_object"),validateFilter=_dereq_("./validate_filter"),validatePaintProperty=_dereq_("./validate_paint_property"),validateLayoutProperty=_dereq_("./validate_layout_property"),extend=_dereq_("../util/extend");module.exports=function(e){var r=[],t=e.value,a=e.key,i=e.style,l=e.styleSpec;t.type||t.ref||r.push(new ValidationError(a,t,'either "type" or "ref" is required'));var u=unbundle(t.type),n=unbundle(t.ref);if(t.id)for(var o=unbundle(t.id),s=0;s<e.arrayIndex;s++){var d=i.layers[s];unbundle(d.id)===o&&r.push(new ValidationError(a,t.id,'duplicate layer id "%s", previously used at line %d',t.id,d.id.__line__))}if("ref"in t){["type","source","source-layer","filter","layout"].forEach(function(e){e in t&&r.push(new ValidationError(a,t[e],'"%s" is prohibited for ref layers',e))});var y;i.layers.forEach(function(e){unbundle(e.id)===n&&(y=e)}),y?y.ref?r.push(new ValidationError(a,t.ref,"ref cannot reference another ref layer")):u=unbundle(y.type):r.push(new ValidationError(a,t.ref,'ref layer "%s" not found',n))}else if("background"!==u)if(t.source){var c=i.sources&&i.sources[t.source],p=c&&unbundle(c.type);c?"vector"===p&&"raster"===u?r.push(new ValidationError(a,t.source,'layer "%s" requires a raster source',t.id)):"raster"===p&&"raster"!==u?r.push(new ValidationError(a,t.source,'layer "%s" requires a vector source',t.id)):"vector"!==p||t["source-layer"]||r.push(new ValidationError(a,t,'layer "%s" must specify a "source-layer"',t.id)):r.push(new ValidationError(a,t.source,'source "%s" not found',t.source))}else r.push(new ValidationError(a,t,'missing required property "source"'));return r=r.concat(validateObject({key:a,value:t,valueSpec:l.layer,style:e.style,styleSpec:e.styleSpec,objectElementValidators:{"*":function(){return[]},filter:validateFilter,layout:function(e){return validateObject({layer:t,key:e.key,value:e.value,style:e.style,styleSpec:e.styleSpec,objectElementValidators:{"*":function(e){return validateLayoutProperty(extend({layerType:u},e))}}})},paint:function(e){return validateObject({layer:t,key:e.key,value:e.value,style:e.style,styleSpec:e.styleSpec,objectElementValidators:{"*":function(e){return validatePaintProperty(extend({layerType:u},e))}}})}}}))};
  278 +},{"../error/validation_error":103,"../util/extend":120,"../util/unbundle_jsonlint":125,"./validate_filter":132,"./validate_layout_property":136,"./validate_object":139,"./validate_paint_property":140}],136:[function(_dereq_,module,exports){
  279 +"use strict";var validateProperty=_dereq_("./validate_property");module.exports=function(r){return validateProperty(r,"layout")};
  280 +},{"./validate_property":141}],137:[function(_dereq_,module,exports){
  281 +"use strict";var ValidationError=_dereq_("../error/validation_error"),getType=_dereq_("../util/get_type"),validate=_dereq_("./validate");module.exports=function(e){var t=e.value,r=e.styleSpec,a=r.light,i=e.style,n=[],o=getType(t);if(void 0===t)return n;if("object"!==o)return n=n.concat([new ValidationError("light",t,"object expected, %s found",o)]);for(var l in t){var c=l.match(/^(.*)-transition$/);n=c&&a[c[1]]&&a[c[1]].transition?n.concat(validate({key:l,value:t[l],valueSpec:r.transition,style:i,styleSpec:r})):a[l]?n.concat(validate({key:l,value:t[l],valueSpec:a[l],style:i,styleSpec:r})):n.concat([new ValidationError(l,t[l],'unknown property "%s"',l)])}return n};
  282 +},{"../error/validation_error":103,"../util/get_type":121,"./validate":126}],138:[function(_dereq_,module,exports){
  283 +"use strict";var getType=_dereq_("../util/get_type"),ValidationError=_dereq_("../error/validation_error");module.exports=function(e){var r=e.key,i=e.value,m=e.valueSpec,a=getType(i);return"number"!==a?[new ValidationError(r,i,"number expected, %s found",a)]:"minimum"in m&&i<m.minimum?[new ValidationError(r,i,"%s is less than the minimum value %s",i,m.minimum)]:"maximum"in m&&i>m.maximum?[new ValidationError(r,i,"%s is greater than the maximum value %s",i,m.maximum)]:[]};
  284 +},{"../error/validation_error":103,"../util/get_type":121}],139:[function(_dereq_,module,exports){
  285 +"use strict";var ValidationError=_dereq_("../error/validation_error"),getType=_dereq_("../util/get_type"),validateSpec=_dereq_("./validate");module.exports=function(e){var r=e.key,t=e.value,i=e.valueSpec||{},a=e.objectElementValidators||{},o=e.style,l=e.styleSpec,n=[],u=getType(t);if("object"!==u)return[new ValidationError(r,t,"object expected, %s found",u)];for(var d in t){var p=d.split(".")[0],s=i[p]||i["*"],c=void 0;if(a[p])c=a[p];else if(i[p])c=validateSpec;else if(a["*"])c=a["*"];else{if(!i["*"]){n.push(new ValidationError(r,t[d],'unknown property "%s"',d));continue}c=validateSpec}n=n.concat(c({key:(r?r+".":r)+d,value:t[d],valueSpec:s,style:o,styleSpec:l,object:t,objectKey:d}))}for(var v in i)i[v].required&&void 0===i[v].default&&void 0===t[v]&&n.push(new ValidationError(r,t,'missing required property "%s"',v));return n};
  286 +},{"../error/validation_error":103,"../util/get_type":121,"./validate":126}],140:[function(_dereq_,module,exports){
  287 +"use strict";var validateProperty=_dereq_("./validate_property");module.exports=function(r){return validateProperty(r,"paint")};
  288 +},{"./validate_property":141}],141:[function(_dereq_,module,exports){
  289 +"use strict";var validate=_dereq_("./validate"),ValidationError=_dereq_("../error/validation_error"),getType=_dereq_("../util/get_type");module.exports=function(e,t){var r=e.key,i=e.style,a=e.styleSpec,n=e.value,o=e.objectKey,l=a[t+"_"+e.layerType];if(!l)return[];var y=o.match(/^(.*)-transition$/);if("paint"===t&&y&&l[y[1]]&&l[y[1]].transition)return validate({key:r,value:n,valueSpec:a.transition,style:i,styleSpec:a});var p=e.valueSpec||l[o];if(!p)return[new ValidationError(r,n,'unknown property "%s"',o)];var s;if("string"===getType(n)&&p["property-function"]&&!p.tokens&&(s=/^{([^}]+)}$/.exec(n)))return[new ValidationError(r,n,'"%s" does not support interpolation syntax\nUse an identity property function instead: `{ "type": "identity", "property": %s` }`.',o,JSON.stringify(s[1]))];var u=[];return"symbol"===e.layerType&&"text-field"===o&&i&&!i.glyphs&&u.push(new ValidationError(r,n,'use of "text-field" requires a style "glyphs" property')),u.concat(validate({key:e.key,value:n,valueSpec:p,style:i,styleSpec:a}))};
  290 +},{"../error/validation_error":103,"../util/get_type":121,"./validate":126}],142:[function(_dereq_,module,exports){
  291 +"use strict";var ValidationError=_dereq_("../error/validation_error"),unbundle=_dereq_("../util/unbundle_jsonlint"),validateObject=_dereq_("./validate_object"),validateEnum=_dereq_("./validate_enum");module.exports=function(e){var a=e.value,t=e.key,r=e.styleSpec,l=e.style;if(!a.type)return[new ValidationError(t,a,'"type" is required')];var u=unbundle(a.type),i=[];switch(u){case"vector":case"raster":if(i=i.concat(validateObject({key:t,value:a,valueSpec:r.source_tile,style:e.style,styleSpec:r})),"url"in a)for(var s in a)["type","url","tileSize"].indexOf(s)<0&&i.push(new ValidationError(t+"."+s,a[s],'a source with a "url" property may not include a "%s" property',s));return i;case"geojson":return validateObject({key:t,value:a,valueSpec:r.source_geojson,style:l,styleSpec:r});case"video":return validateObject({key:t,value:a,valueSpec:r.source_video,style:l,styleSpec:r});case"upload_file.py":return validateObject({key:t,value:a,valueSpec:r.source_image,style:l,styleSpec:r});case"canvas":return validateObject({key:t,value:a,valueSpec:r.source_canvas,style:l,styleSpec:r});default:return validateEnum({key:t+".type",value:a.type,valueSpec:{values:["vector","raster","geojson","video","upload_file.py","canvas"]},style:l,styleSpec:r})}};
  292 +},{"../error/validation_error":103,"../util/unbundle_jsonlint":125,"./validate_enum":131,"./validate_object":139}],143:[function(_dereq_,module,exports){
  293 +"use strict";var getType=_dereq_("../util/get_type"),ValidationError=_dereq_("../error/validation_error");module.exports=function(r){var e=r.value,t=r.key,i=getType(e);return"string"!==i?[new ValidationError(t,e,"string expected, %s found",i)]:[]};
  294 +},{"../error/validation_error":103,"../util/get_type":121}],144:[function(_dereq_,module,exports){
  295 +"use strict";function validateStyleMin(e,a){a=a||latestStyleSpec;var t=[];return t=t.concat(validate({key:"",value:e,valueSpec:a.$root,styleSpec:a,style:e,objectElementValidators:{glyphs:validateGlyphsURL,"*":function(){return[]}}})),a.$version>7&&e.constants&&(t=t.concat(validateConstants({key:"constants",value:e.constants,style:e,styleSpec:a}))),sortErrors(t)}function sortErrors(e){return[].concat(e).sort(function(e,a){return e.line-a.line})}function wrapCleanErrors(e){return function(){return sortErrors(e.apply(this,arguments))}}var validateConstants=_dereq_("./validate/validate_constants"),validate=_dereq_("./validate/validate"),latestStyleSpec=_dereq_("./reference/latest"),validateGlyphsURL=_dereq_("./validate/validate_glyphs_url");validateStyleMin.source=wrapCleanErrors(_dereq_("./validate/validate_source")),validateStyleMin.light=wrapCleanErrors(_dereq_("./validate/validate_light")),validateStyleMin.layer=wrapCleanErrors(_dereq_("./validate/validate_layer")),validateStyleMin.filter=wrapCleanErrors(_dereq_("./validate/validate_filter")),validateStyleMin.paintProperty=wrapCleanErrors(_dereq_("./validate/validate_paint_property")),validateStyleMin.layoutProperty=wrapCleanErrors(_dereq_("./validate/validate_layout_property")),module.exports=validateStyleMin;
  296 +},{"./reference/latest":118,"./validate/validate":126,"./validate/validate_constants":130,"./validate/validate_filter":132,"./validate/validate_glyphs_url":134,"./validate/validate_layer":135,"./validate/validate_layout_property":136,"./validate/validate_light":137,"./validate/validate_paint_property":140,"./validate/validate_source":142}],145:[function(_dereq_,module,exports){
  297 +"use strict";var AnimationLoop=function(){this.n=0,this.times=[]};AnimationLoop.prototype.stopped=function(){return this.times=this.times.filter(function(t){return t.time>=(new Date).getTime()}),!this.times.length},AnimationLoop.prototype.set=function(t){return this.times.push({id:this.n,time:t+(new Date).getTime()}),this.n++},AnimationLoop.prototype.cancel=function(t){this.times=this.times.filter(function(i){return i.id!==t})},module.exports=AnimationLoop;
  298 +},{}],146:[function(_dereq_,module,exports){
  299 +"use strict";var Evented=_dereq_("../util/evented"),ajax=_dereq_("../util/ajax"),browser=_dereq_("../util/browser"),normalizeURL=_dereq_("../util/mapbox").normalizeSpriteURL,SpritePosition=function(){this.x=0,this.y=0,this.width=0,this.height=0,this.pixelRatio=1,this.sdf=!1},ImageSprite=function(t){function e(e,i){var r=this;t.call(this),this.base=e,this.retina=browser.devicePixelRatio>1,this.setEventedParent(i);var a=this.retina?"@2x":"";ajax.getJSON(normalizeURL(e,a,".json"),function(t,e){return t?void r.fire("error",{error:t}):(r.data=e,void(r.imgData&&r.fire("data",{dataType:"style"})))}),ajax.getImage(normalizeURL(e,a,".png"),function(t,e){return t?void r.fire("error",{error:t}):(r.imgData=browser.getImageData(e),r.width=e.width,void(r.data&&r.fire("data",{dataType:"style"})))})}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.toJSON=function(){return this.base},e.prototype.loaded=function(){return!(!this.data||!this.imgData)},e.prototype.resize=function(){var t=this;if(browser.devicePixelRatio>1!==this.retina){var i=new e(this.base);i.on("data",function(){t.data=i.data,t.imgData=i.imgData,t.width=i.width,t.retina=i.retina})}},e.prototype.getSpritePosition=function(t){if(!this.loaded())return new SpritePosition;var e=this.data&&this.data[t];return e&&this.imgData?e:new SpritePosition},e}(Evented);module.exports=ImageSprite;
  300 +},{"../util/ajax":193,"../util/browser":194,"../util/evented":202,"../util/mapbox":209}],147:[function(_dereq_,module,exports){
  301 +"use strict";var styleSpec=_dereq_("../style-spec/reference/latest"),util=_dereq_("../util/util"),Evented=_dereq_("../util/evented"),validateStyle=_dereq_("./validate_style"),StyleDeclaration=_dereq_("./style_declaration"),StyleTransition=_dereq_("./style_transition"),TRANSITION_SUFFIX="-transition",Light=function(t){function i(i){t.call(this),this.properties=["anchor","color","position","intensity"],this._specifications=styleSpec.light,this.set(i)}return t&&(i.__proto__=t),i.prototype=Object.create(t&&t.prototype),i.prototype.constructor=i,i.prototype.set=function(t){var i=this;if(!this._validate(validateStyle.light,t)){this._declarations={},this._transitions={},this._transitionOptions={},this.calculated={},t=util.extend({anchor:this._specifications.anchor.default,color:this._specifications.color.default,position:this._specifications.position.default,intensity:this._specifications.intensity.default},t);for(var e=0,o=i.properties;e<o.length;e+=1){var n=o[e];i._declarations[n]=new StyleDeclaration(i._specifications[n],t[n])}return this}},i.prototype.getLight=function(){return{anchor:this.getLightProperty("anchor"),color:this.getLightProperty("color"),position:this.getLightProperty("position"),intensity:this.getLightProperty("intensity")}},i.prototype.getLightProperty=function(t){return util.endsWith(t,TRANSITION_SUFFIX)?this._transitionOptions[t]:this._declarations[t]&&this._declarations[t].value},i.prototype.getLightValue=function(t,i){if("position"===t){var e=this._transitions[t].calculate(i),o=util.sphericalToCartesian(e);return{x:o[0],y:o[1],z:o[2]}}return this._transitions[t].calculate(i)},i.prototype.setLight=function(t){var i=this;if(!this._validate(validateStyle.light,t))for(var e in t){var o=t[e];util.endsWith(e,TRANSITION_SUFFIX)?i._transitionOptions[e]=o:null===o||void 0===o?delete i._declarations[e]:i._declarations[e]=new StyleDeclaration(i._specifications[e],o)}},i.prototype.recalculate=function(t){var i=this;for(var e in i._declarations)i.calculated[e]=i.getLightValue(e,{zoom:t})},i.prototype._applyLightDeclaration=function(t,i,e,o,n){var r=e.transition?this._transitions[t]:void 0,a=this._specifications[t];if(null!==i&&void 0!==i||(i=new StyleDeclaration(a,a.default)),!r||r.declaration.json!==i.json){var s=util.extend({duration:300,delay:0},o,this.getLightProperty(t+TRANSITION_SUFFIX)),l=this._transitions[t]=new StyleTransition(a,i,r,s);l.instant()||(l.loopID=n.set(l.endTime-Date.now())),r&&n.cancel(r.loopID)}},i.prototype.updateLightTransitions=function(t,i,e){var o,n=this;for(o in n._declarations)n._applyLightDeclaration(o,n._declarations[o],t,i,e)},i.prototype._validate=function(t,i){return validateStyle.emitErrors(this,t.call(validateStyle,util.extend({value:i,style:{glyphs:!0,sprite:!0},styleSpec:styleSpec})))},i}(Evented);module.exports=Light;
  302 +},{"../style-spec/reference/latest":118,"../util/evented":202,"../util/util":215,"./style_declaration":149,"./style_transition":157,"./validate_style":158}],148:[function(_dereq_,module,exports){
  303 +"use strict";var Evented=_dereq_("../util/evented"),StyleLayer=_dereq_("./style_layer"),ImageSprite=_dereq_("./image_sprite"),Light=_dereq_("./light"),GlyphSource=_dereq_("../symbol/glyph_source"),SpriteAtlas=_dereq_("../symbol/sprite_atlas"),LineAtlas=_dereq_("../render/line_atlas"),util=_dereq_("../util/util"),ajax=_dereq_("../util/ajax"),mapbox=_dereq_("../util/mapbox"),browser=_dereq_("../util/browser"),Dispatcher=_dereq_("../util/dispatcher"),AnimationLoop=_dereq_("./animation_loop"),validateStyle=_dereq_("./validate_style"),Source=_dereq_("../source/source"),QueryFeatures=_dereq_("../source/query_features"),SourceCache=_dereq_("../source/source_cache"),styleSpec=_dereq_("../style-spec/reference/latest"),MapboxGLFunction=_dereq_("../style-spec/function"),getWorkerPool=_dereq_("../util/global_worker_pool"),deref=_dereq_("../style-spec/deref"),diff=_dereq_("../style-spec/diff"),rtlTextPlugin=_dereq_("../source/rtl_text_plugin"),supportedDiffOperations=util.pick(diff.operations,["addLayer","removeLayer","setPaintProperty","setLayoutProperty","setFilter","addSource","removeSource","setLayerZoomRange","setLight","setTransition"]),ignoredDiffOperations=util.pick(diff.operations,["setCenter","setZoom","setBearing","setPitch"]),Style=function(e){function t(t,r,i){var o=this;e.call(this),this.map=r,this.animationLoop=r&&r.animationLoop||new AnimationLoop,this.dispatcher=new Dispatcher(getWorkerPool(),this),this.spriteAtlas=new SpriteAtlas(1024,1024),this.spriteAtlas.setEventedParent(this),this.lineAtlas=new LineAtlas(256,512),this._layers={},this._order=[],this.sourceCaches={},this.zoomHistory={},this._loaded=!1,util.bindAll(["_redoPlacement"],this),this._resetUpdates(),i=util.extend({validate:"string"!=typeof t||!mapbox.isMapboxURL(t)},i),this.setEventedParent(r),this.fire("dataloading",{dataType:"style"});var s=this;this._rtlTextPluginCallback=rtlTextPlugin.registerForPluginAvailability(function(e){s.dispatcher.broadcast("loadRTLTextPlugin",e.pluginBlobURL,e.errorCallback);for(var t in s.sourceCaches)s.sourceCaches[t].reload()});var a=function(e,t){if(e)return void o.fire("error",{error:e});if(!i.validate||!validateStyle.emitErrors(o,validateStyle(t))){o._loaded=!0,o.stylesheet=t,o.updateClasses();for(var r in t.sources)o.addSource(r,t.sources[r],i);t.sprite&&(o.sprite=new ImageSprite(t.sprite,o)),o.glyphSource=new GlyphSource(t.glyphs),o._resolve(),o.fire("data",{dataType:"style"}),o.fire("style.load")}};"string"==typeof t?ajax.getJSON(mapbox.normalizeStyleURL(t),a):browser.frame(a.bind(this,null,t)),this.on("data",function(e){if("source"===e.dataType&&"metadata"===e.sourceDataType){var t=o.sourceCaches[e.sourceId].getSource();if(t&&t.vectorLayerIds)for(var r in o._layers){var i=o._layers[r];i.source===t.id&&o._validateLayer(i)}}})}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype._validateLayer=function(e){var t=this.sourceCaches[e.source];if(e.sourceLayer&&t){var r=t.getSource();("geojson"===r.type||r.vectorLayerIds&&r.vectorLayerIds.indexOf(e.sourceLayer)===-1)&&this.fire("error",{error:new Error('Source layer "'+e.sourceLayer+'" does not exist on source "'+r.id+'" as specified by style layer "'+e.id+'"')})}},t.prototype.loaded=function(){var e=this;if(!this._loaded)return!1;if(Object.keys(this._updatedSources).length)return!1;for(var t in e.sourceCaches)if(!e.sourceCaches[t].loaded())return!1;return!(this.sprite&&!this.sprite.loaded())},t.prototype._resolve=function(){var e=this,t=deref(this.stylesheet.layers);this._order=t.map(function(e){return e.id}),this._layers={};for(var r=0,i=t;r<i.length;r+=1){var o=i[r];o=StyleLayer.create(o),o.setEventedParent(e,{layer:{id:o.id}}),e._layers[o.id]=o}this.dispatcher.broadcast("setLayers",this._serializeLayers(this._order)),this.light=new Light(this.stylesheet.light)},t.prototype._serializeLayers=function(e){var t=this;return e.map(function(e){return t._layers[e].serialize()})},t.prototype._applyClasses=function(e,t){var r=this;if(this._loaded){e=e||[],t=t||{transition:!0};var i=this.stylesheet.transition||{},o=this._updatedAllPaintProps?this._layers:this._updatedPaintProps;for(var s in o){var a=r._layers[s],n=r._updatedPaintProps[s];if(r._updatedAllPaintProps||n.all)a.updatePaintTransitions(e,t,i,r.animationLoop,r.zoomHistory);else for(var l in n)r._layers[s].updatePaintTransition(l,e,t,i,r.animationLoop,r.zoomHistory)}this.light.updateLightTransitions(t,i,this.animationLoop)}},t.prototype._recalculate=function(e){var t=this;if(this._loaded){for(var r in t.sourceCaches)t.sourceCaches[r].used=!1;this._updateZoomHistory(e);for(var i=0,o=t._order;i<o.length;i+=1){var s=o[i],a=t._layers[s];a.recalculate(e),!a.isHidden(e)&&a.source&&(t.sourceCaches[a.source].used=!0)}this.light.recalculate(e);var n=300;Math.floor(this.z)!==Math.floor(e)&&this.animationLoop.set(n),this.z=e}},t.prototype._updateZoomHistory=function(e){var t=this.zoomHistory;void 0===t.lastIntegerZoom&&(t.lastIntegerZoom=Math.floor(e),t.lastIntegerZoomTime=0,t.lastZoom=e),Math.floor(t.lastZoom)<Math.floor(e)?(t.lastIntegerZoom=Math.floor(e),t.lastIntegerZoomTime=Date.now()):Math.floor(t.lastZoom)>Math.floor(e)&&(t.lastIntegerZoom=Math.floor(e+1),t.lastIntegerZoomTime=Date.now()),t.lastZoom=e},t.prototype._checkLoaded=function(){if(!this._loaded)throw new Error("Style is not done loading")},t.prototype.update=function(e,t){var r=this;if(this._changed){var i=Object.keys(this._updatedLayers),o=Object.keys(this._removedLayers);(i.length||o.length||this._updatedSymbolOrder)&&this._updateWorkerLayers(i,o);for(var s in r._updatedSources){var a=r._updatedSources[s];"reload"===a?r._reloadSource(s):"clear"===a&&r._clearSource(s)}this._applyClasses(e,t),this._resetUpdates(),this.fire("data",{dataType:"style"})}},t.prototype._updateWorkerLayers=function(e,t){var r=this,i=this._updatedSymbolOrder?this._order.filter(function(e){return"symbol"===r._layers[e].type}):null;this.dispatcher.broadcast("updateLayers",{layers:this._serializeLayers(e),removedIds:t,symbolOrder:i})},t.prototype._resetUpdates=function(){this._changed=!1,this._updatedLayers={},this._removedLayers={},this._updatedSymbolOrder=!1,this._updatedSources={},this._updatedPaintProps={},this._updatedAllPaintProps=!1},t.prototype.setState=function(e){var t=this;if(this._checkLoaded(),validateStyle.emitErrors(this,validateStyle(e)))return!1;e=util.extend({},e),e.layers=deref(e.layers);var r=diff(this.serialize(),e).filter(function(e){return!(e.command in ignoredDiffOperations)});if(0===r.length)return!1;var i=r.filter(function(e){return!(e.command in supportedDiffOperations)});if(i.length>0)throw new Error("Unimplemented: "+i.map(function(e){return e.command}).join(", ")+".");return r.forEach(function(e){"setTransition"!==e.command&&t[e.command].apply(t,e.args)}),this.stylesheet=e,!0},t.prototype.addSource=function(e,t,r){var i=this;if(this._checkLoaded(),void 0!==this.sourceCaches[e])throw new Error("There is already a source with this ID");if(!t.type)throw new Error("The type property must be defined, but the only the following properties were given: "+Object.keys(t)+".");var o=["vector","raster","geojson","video","upload_file.py","canvas"],s=o.indexOf(t.type)>=0;if(!s||!this._validate(validateStyle.source,"sources."+e,t,null,r)){var a=this.sourceCaches[e]=new SourceCache(e,t,this.dispatcher);a.style=this,a.setEventedParent(this,function(){return{isSourceLoaded:i.loaded(),source:a.serialize(),sourceId:e}}),a.onAdd(this.map),this._changed=!0}},t.prototype.removeSource=function(e){if(this._checkLoaded(),void 0===this.sourceCaches[e])throw new Error("There is no source with this ID");var t=this.sourceCaches[e];delete this.sourceCaches[e],delete this._updatedSources[e],t.setEventedParent(null),t.clearTiles(),t.onRemove&&t.onRemove(this.map),this._changed=!0},t.prototype.getSource=function(e){return this.sourceCaches[e]&&this.sourceCaches[e].getSource()},t.prototype.addLayer=function(e,t,r){this._checkLoaded();var i=e.id;if("object"==typeof e.source&&(this.addSource(i,e.source),e=util.extend(e,{source:i})),!this._validate(validateStyle.layer,"layers."+i,e,{arrayIndex:-1},r)){var o=StyleLayer.create(e);this._validateLayer(o),o.setEventedParent(this,{layer:{id:i}});var s=t?this._order.indexOf(t):this._order.length;if(this._order.splice(s,0,i),this._layers[i]=o,this._removedLayers[i]&&o.source){var a=this._removedLayers[i];delete this._removedLayers[i],this._updatedSources[o.source]=a.type!==o.type?"clear":"reload"}this._updateLayer(o),"symbol"===o.type&&(this._updatedSymbolOrder=!0),this.updateClasses(i)}},t.prototype.moveLayer=function(e,t){this._checkLoaded(),this._changed=!0;var r=this._layers[e];if(!r)return void this.fire("error",{error:new Error("The layer '"+e+"' does not exist in the map's style and cannot be moved.")});var i=this._order.indexOf(e);this._order.splice(i,1);var o=t?this._order.indexOf(t):this._order.length;this._order.splice(o,0,e),"symbol"===r.type&&(this._updatedSymbolOrder=!0,r.source&&!this._updatedSources[r.source]&&(this._updatedSources[r.source]="reload"))},t.prototype.removeLayer=function(e){this._checkLoaded();var t=this._layers[e];if(!t)return void this.fire("error",{error:new Error("The layer '"+e+"' does not exist in the map's style and cannot be removed.")});t.setEventedParent(null);var r=this._order.indexOf(e);this._order.splice(r,1),"symbol"===t.type&&(this._updatedSymbolOrder=!0),this._changed=!0,this._removedLayers[e]=t,delete this._layers[e],delete this._updatedLayers[e],delete this._updatedPaintProps[e]},t.prototype.getLayer=function(e){return this._layers[e]},t.prototype.setLayerZoomRange=function(e,t,r){this._checkLoaded();var i=this.getLayer(e);return i?void(i.minzoom===t&&i.maxzoom===r||(null!=t&&(i.minzoom=t),null!=r&&(i.maxzoom=r),this._updateLayer(i))):void this.fire("error",{error:new Error("The layer '"+e+"' does not exist in the map's style and cannot have zoom extent.")})},t.prototype.setFilter=function(e,t){this._checkLoaded();var r=this.getLayer(e);return r?void(null!==t&&void 0!==t&&this._validate(validateStyle.filter,"layers."+r.id+".filter",t)||util.deepEqual(r.filter,t)||(r.filter=util.clone(t),this._updateLayer(r))):void this.fire("error",{error:new Error("The layer '"+e+"' does not exist in the map's style and cannot be filtered.")})},t.prototype.getFilter=function(e){return util.clone(this.getLayer(e).filter)},t.prototype.setLayoutProperty=function(e,t,r){this._checkLoaded();var i=this.getLayer(e);return i?void(util.deepEqual(i.getLayoutProperty(t),r)||(i.setLayoutProperty(t,r),this._updateLayer(i))):void this.fire("error",{error:new Error("The layer '"+e+"' does not exist in the map's style and cannot be styled.")})},t.prototype.getLayoutProperty=function(e,t){return this.getLayer(e).getLayoutProperty(t)},t.prototype.setPaintProperty=function(e,t,r,i){this._checkLoaded();var o=this.getLayer(e);if(!o)return void this.fire("error",{error:new Error("The layer '"+e+"' does not exist in the map's style and cannot be styled.")});if(!util.deepEqual(o.getPaintProperty(t,i),r)){var s=o.isPaintValueFeatureConstant(t);o.setPaintProperty(t,r,i);var a=!(r&&MapboxGLFunction.isFunctionDefinition(r)&&"$zoom"!==r.property&&void 0!==r.property);a&&s||this._updateLayer(o),this.updateClasses(e,t)}},t.prototype.getPaintProperty=function(e,t,r){return this.getLayer(e).getPaintProperty(t,r)},t.prototype.getTransition=function(){return util.extend({duration:300,delay:0},this.stylesheet&&this.stylesheet.transition)},t.prototype.updateClasses=function(e,t){if(this._changed=!0,e){var r=this._updatedPaintProps;r[e]||(r[e]={}),r[e][t||"all"]=!0}else this._updatedAllPaintProps=!0},t.prototype.serialize=function(){var e=this;return util.filterObject({version:this.stylesheet.version,name:this.stylesheet.name,metadata:this.stylesheet.metadata,light:this.stylesheet.light,center:this.stylesheet.center,zoom:this.stylesheet.zoom,bearing:this.stylesheet.bearing,pitch:this.stylesheet.pitch,sprite:this.stylesheet.sprite,glyphs:this.stylesheet.glyphs,transition:this.stylesheet.transition,sources:util.mapObject(this.sourceCaches,function(e){return e.serialize()}),layers:this._order.map(function(t){return e._layers[t].serialize()})},function(e){return void 0!==e})},t.prototype._updateLayer=function(e){this._updatedLayers[e.id]=!0,e.source&&!this._updatedSources[e.source]&&(this._updatedSources[e.source]="reload"),this._changed=!0},t.prototype._flattenRenderedFeatures=function(e){for(var t=this,r=[],i=this._order.length-1;i>=0;i--)for(var o=t._order[i],s=0,a=e;s<a.length;s+=1){var n=a[s],l=n[o];if(l)for(var d=0,u=l;d<u.length;d+=1){var h=u[d];r.push(h)}}return r},t.prototype.queryRenderedFeatures=function(e,t,r,i){var o=this;t&&t.filter&&this._validate(validateStyle.filter,"queryRenderedFeatures.filter",t.filter);var s={};if(t&&t.layers){if(!Array.isArray(t.layers))return void this.fire("error",{error:"parameters.layers must be an Array."});for(var a=0,n=t.layers;a<n.length;a+=1){var l=n[a],d=o._layers[l];if(!d)return void o.fire("error",{error:"The layer '"+l+"' does not exist in the map's style and cannot be queried for features."});s[d.source]=!0}}var u=[];for(var h in o.sourceCaches)if(!t.layers||s[h]){var c=QueryFeatures.rendered(o.sourceCaches[h],o._layers,e,t,r,i);u.push(c)}return this._flattenRenderedFeatures(u)},t.prototype.querySourceFeatures=function(e,t){t&&t.filter&&this._validate(validateStyle.filter,"querySourceFeatures.filter",t.filter);var r=this.sourceCaches[e];return r?QueryFeatures.source(r,t):[]},t.prototype.addSourceType=function(e,t,r){return Source.getType(e)?r(new Error('A source type called "'+e+'" already exists.')):(Source.setType(e,t),t.workerSourceURL?void this.dispatcher.broadcast("loadWorkerSource",{name:e,url:t.workerSourceURL},r):r(null,null))},t.prototype.getLight=function(){return this.light.getLight()},t.prototype.setLight=function(e,t){this._checkLoaded();var r=this.light.getLight(),i=!1;for(var o in e)if(!util.deepEqual(e[o],r[o])){i=!0;break}if(i){var s=this.stylesheet.transition||{};this.light.setLight(e),this.light.updateLightTransitions(t||{transition:!0},s,this.animationLoop)}},t.prototype._validate=function(e,t,r,i,o){return(!o||o.validate!==!1)&&validateStyle.emitErrors(this,e.call(validateStyle,util.extend({key:t,style:this.serialize(),value:r,styleSpec:styleSpec},i)))},t.prototype._remove=function(){var e=this;rtlTextPlugin.evented.off("pluginAvailable",this._rtlTextPluginCallback);for(var t in e.sourceCaches)e.sourceCaches[t].clearTiles();this.dispatcher.remove()},t.prototype._clearSource=function(e){this.sourceCaches[e].clearTiles()},t.prototype._reloadSource=function(e){this.sourceCaches[e].reload()},t.prototype._updateSources=function(e){var t=this;for(var r in t.sourceCaches)t.sourceCaches[r].update(e)},t.prototype._redoPlacement=function(){var e=this;for(var t in e.sourceCaches)e.sourceCaches[t].redoPlacement()},t.prototype.getIcons=function(e,t,r){var i=this,o=function(){i.spriteAtlas.setSprite(i.sprite),i.spriteAtlas.addIcons(t.icons,r)};!this.sprite||this.sprite.loaded()?o():this.sprite.on("data",o)},t.prototype.getGlyphs=function(e,t,r){function i(e,t,i){e&&console.error(e),n[i]=t,a--,0===a&&r(null,n)}var o=this,s=t.stacks,a=Object.keys(s).length,n={};for(var l in s)o.glyphSource.getSimpleGlyphs(l,s[l],t.uid,i)},t}(Evented);module.exports=Style;
  304 +},{"../render/line_atlas":75,"../source/query_features":88,"../source/rtl_text_plugin":90,"../source/source":91,"../source/source_cache":92,"../style-spec/deref":101,"../style-spec/diff":102,"../style-spec/function":106,"../style-spec/reference/latest":118,"../symbol/glyph_source":167,"../symbol/sprite_atlas":171,"../util/ajax":193,"../util/browser":194,"../util/dispatcher":200,"../util/evented":202,"../util/global_worker_pool":204,"../util/mapbox":209,"../util/util":215,"./animation_loop":145,"./image_sprite":146,"./light":147,"./style_layer":150,"./validate_style":158}],149:[function(_dereq_,module,exports){
  305 +"use strict";var createFunction=_dereq_("../style-spec/function"),util=_dereq_("../util/util"),StyleDeclaration=function(t,i){var o=this;if(this.value=util.clone(i),this.isFunction=createFunction.isFunctionDefinition(i),this.json=JSON.stringify(this.value),this.minimum=t.minimum,this.function=createFunction(this.value,t),this.isFeatureConstant=this.function.isFeatureConstant,this.isZoomConstant=this.function.isZoomConstant,this.isFeatureConstant||this.isZoomConstant){if(!this.isZoomConstant){this.stopZoomLevels=[];for(var n=0,s=o.value.stops;n<s.length;n+=1){var e=s[n];o.stopZoomLevels.indexOf(e[0])<0&&o.stopZoomLevels.push(e[0])}}}else{this.stopZoomLevels=[];for(var a=[],u=0,l=o.value.stops;u<l.length;u+=1){var r=l[u],c=r[0].zoom;o.stopZoomLevels.indexOf(c)<0&&(o.stopZoomLevels.push(c),a.push([c,a.length]))}this._functionInterpolationT=createFunction({type:"exponential",stops:a,base:i.base},{type:"number"})}};StyleDeclaration.prototype.calculate=function(t,i){var o=this.function(t&&t.zoom,i||{});return void 0!==this.minimum&&o<this.minimum?this.minimum:o},StyleDeclaration.prototype.calculateInterpolationT=function(t){return this.isFeatureConstant||this.isZoomConstant?0:this._functionInterpolationT(t&&t.zoom,{})},module.exports=StyleDeclaration;
  306 +},{"../style-spec/function":106,"../util/util":215}],150:[function(_dereq_,module,exports){
  307 +"use strict";function getDeclarationValue(t){return t.value}var util=_dereq_("../util/util"),StyleTransition=_dereq_("./style_transition"),StyleDeclaration=_dereq_("./style_declaration"),styleSpec=_dereq_("../style-spec/reference/latest"),validateStyle=_dereq_("./validate_style"),parseColor=_dereq_("./../style-spec/util/parse_color"),Evented=_dereq_("../util/evented"),TRANSITION_SUFFIX="-transition",StyleLayer=function(t){function i(i){var a=this;t.call(this),this.id=i.id,this.metadata=i.metadata,this.type=i.type,this.source=i.source,this.sourceLayer=i["source-layer"],this.minzoom=i.minzoom,this.maxzoom=i.maxzoom,this.filter=i.filter,this.paint={},this.layout={},this._paintSpecifications=styleSpec["paint_"+this.type],this._layoutSpecifications=styleSpec["layout_"+this.type],this._paintTransitions={},this._paintTransitionOptions={},this._paintDeclarations={},this._layoutDeclarations={},this._layoutFunctions={};var e,o,n={validate:!1};for(var r in i){var s=r.match(/^paint(?:\.(.*))?$/);if(s){var l=s[1]||"";for(e in i[r])a.setPaintProperty(e,i[r][e],l,n)}}for(o in i.layout)a.setLayoutProperty(o,i.layout[o],n);for(e in a._paintSpecifications)a.paint[e]=a.getPaintValue(e);for(o in a._layoutSpecifications)a._updateLayoutValue(o)}return t&&(i.__proto__=t),i.prototype=Object.create(t&&t.prototype),i.prototype.constructor=i,i.prototype.setLayoutProperty=function(t,i,a){if(null==i)delete this._layoutDeclarations[t];else{var e="layers."+this.id+".layout."+t;if(this._validate(validateStyle.layoutProperty,e,t,i,a))return;this._layoutDeclarations[t]=new StyleDeclaration(this._layoutSpecifications[t],i)}this._updateLayoutValue(t)},i.prototype.getLayoutProperty=function(t){return this._layoutDeclarations[t]&&this._layoutDeclarations[t].value},i.prototype.getLayoutValue=function(t,i,a){var e=this._layoutSpecifications[t],o=this._layoutDeclarations[t];return o?o.calculate(i,a):e.default},i.prototype.setPaintProperty=function(t,i,a,e){var o="layers."+this.id+(a?'["paint.'+a+'"].':".paint.")+t;if(util.endsWith(t,TRANSITION_SUFFIX))if(this._paintTransitionOptions[a||""]||(this._paintTransitionOptions[a||""]={}),null===i||void 0===i)delete this._paintTransitionOptions[a||""][t];else{if(this._validate(validateStyle.paintProperty,o,t,i,e))return;this._paintTransitionOptions[a||""][t]=i}else if(this._paintDeclarations[a||""]||(this._paintDeclarations[a||""]={}),null===i||void 0===i)delete this._paintDeclarations[a||""][t];else{if(this._validate(validateStyle.paintProperty,o,t,i,e))return;this._paintDeclarations[a||""][t]=new StyleDeclaration(this._paintSpecifications[t],i)}},i.prototype.getPaintProperty=function(t,i){return i=i||"",util.endsWith(t,TRANSITION_SUFFIX)?this._paintTransitionOptions[i]&&this._paintTransitionOptions[i][t]:this._paintDeclarations[i]&&this._paintDeclarations[i][t]&&this._paintDeclarations[i][t].value},i.prototype.getPaintValue=function(t,i,a){var e=this._paintSpecifications[t],o=this._paintTransitions[t];return o?o.calculate(i,a):"color"===e.type&&e.default?parseColor(e.default):e.default},i.prototype.getPaintValueStopZoomLevels=function(t){var i=this._paintTransitions[t];return i?i.declaration.stopZoomLevels:[]},i.prototype.getLayoutValueStopZoomLevels=function(t){var i=this._layoutDeclarations[t];return i?i.stopZoomLevels:[]},i.prototype.getPaintInterpolationT=function(t,i){var a=this._paintTransitions[t];return a.declaration.calculateInterpolationT(i)},i.prototype.getLayoutInterpolationT=function(t,i){var a=this._layoutDeclarations[t];return a.calculateInterpolationT(i)},i.prototype.isPaintValueFeatureConstant=function(t){var i=this._paintTransitions[t];return!i||i.declaration.isFeatureConstant},i.prototype.isLayoutValueFeatureConstant=function(t){var i=this._layoutDeclarations[t];return!i||i.isFeatureConstant},i.prototype.isPaintValueZoomConstant=function(t){var i=this._paintTransitions[t];return!i||i.declaration.isZoomConstant},i.prototype.isLayoutValueZoomConstant=function(t){var i=this._layoutDeclarations[t];return!i||i.isZoomConstant},i.prototype.isHidden=function(t){return!!(this.minzoom&&t<this.minzoom)||(!!(this.maxzoom&&t>=this.maxzoom)||"none"===this.layout.visibility)},i.prototype.updatePaintTransitions=function(t,i,a,e,o){for(var n=this,r=util.extend({},this._paintDeclarations[""]),s=0;s<t.length;s++)util.extend(r,n._paintDeclarations[t[s]]);var l;for(l in r)n._applyPaintDeclaration(l,r[l],i,a,e,o);for(l in n._paintTransitions)l in r||n._applyPaintDeclaration(l,null,i,a,e,o)},i.prototype.updatePaintTransition=function(t,i,a,e,o,n){for(var r=this,s=this._paintDeclarations[""][t],l=0;l<i.length;l++){var u=r._paintDeclarations[i[l]];u&&u[t]&&(s=u[t])}this._applyPaintDeclaration(t,s,a,e,o,n)},i.prototype.recalculate=function(t){var i=this;for(var a in i._paintTransitions)i.paint[a]=i.getPaintValue(a,{zoom:t});for(var e in i._layoutFunctions)i.layout[e]=i.getLayoutValue(e,{zoom:t})},i.prototype.serialize=function(){var t=this,i={id:this.id,type:this.type,source:this.source,"source-layer":this.sourceLayer,metadata:this.metadata,minzoom:this.minzoom,maxzoom:this.maxzoom,filter:this.filter,layout:util.mapObject(this._layoutDeclarations,getDeclarationValue)};for(var a in t._paintDeclarations){var e=""===a?"paint":"paint."+a;i[e]=util.mapObject(t._paintDeclarations[a],getDeclarationValue)}return util.filterObject(i,function(t,i){return void 0!==t&&!("layout"===i&&!Object.keys(t).length)})},i.prototype._applyPaintDeclaration=function(t,i,a,e,o,n){var r=a.transition?this._paintTransitions[t]:void 0,s=this._paintSpecifications[t];if(null!==i&&void 0!==i||(i=new StyleDeclaration(s,s.default)),!r||r.declaration.json!==i.json){var l=util.extend({duration:300,delay:0},e,this.getPaintProperty(t+TRANSITION_SUFFIX)),u=this._paintTransitions[t]=new StyleTransition(s,i,r,l,n);u.instant()||(u.loopID=o.set(u.endTime-Date.now())),r&&o.cancel(r.loopID)}},i.prototype._updateLayoutValue=function(t){var i=this._layoutDeclarations[t];i&&i.isFunction?this._layoutFunctions[t]=!0:(delete this._layoutFunctions[t],this.layout[t]=this.getLayoutValue(t))},i.prototype._validate=function(t,i,a,e,o){return(!o||o.validate!==!1)&&validateStyle.emitErrors(this,t.call(validateStyle,{key:i,layerType:this.type,objectKey:a,value:e,styleSpec:styleSpec,style:{glyphs:!0,sprite:!0}}))},i}(Evented);module.exports=StyleLayer;var subclasses={circle:_dereq_("./style_layer/circle_style_layer"),fill:_dereq_("./style_layer/fill_style_layer"),"fill-extrusion":_dereq_("./style_layer/fill_extrusion_style_layer"),line:_dereq_("./style_layer/line_style_layer"),symbol:_dereq_("./style_layer/symbol_style_layer")};StyleLayer.create=function(t){var i=subclasses[t.type]||StyleLayer;return new i(t)};
  308 +},{"../style-spec/reference/latest":118,"../util/evented":202,"../util/util":215,"./../style-spec/util/parse_color":123,"./style_declaration":149,"./style_layer/circle_style_layer":151,"./style_layer/fill_extrusion_style_layer":152,"./style_layer/fill_style_layer":153,"./style_layer/line_style_layer":154,"./style_layer/symbol_style_layer":155,"./style_transition":157,"./validate_style":158}],151:[function(_dereq_,module,exports){
  309 +"use strict";var StyleLayer=_dereq_("../style_layer"),CircleBucket=_dereq_("../../data/bucket/circle_bucket"),CircleStyleLayer=function(e){function t(){e.apply(this,arguments)}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype.createBucket=function(e){return new CircleBucket(e)},t}(StyleLayer);module.exports=CircleStyleLayer;
  310 +},{"../../data/bucket/circle_bucket":45,"../style_layer":150}],152:[function(_dereq_,module,exports){
  311 +"use strict";var StyleLayer=_dereq_("../style_layer"),FillExtrusionBucket=_dereq_("../../data/bucket/fill_extrusion_bucket"),FillExtrusionStyleLayer=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.getPaintValue=function(e,r,o){var l=t.prototype.getPaintValue.call(this,e,r,o);return"fill-extrusion-color"===e&&l&&(l[3]=1),l},e.prototype.createBucket=function(t){return new FillExtrusionBucket(t)},e}(StyleLayer);module.exports=FillExtrusionStyleLayer;
  312 +},{"../../data/bucket/fill_extrusion_bucket":47,"../style_layer":150}],153:[function(_dereq_,module,exports){
  313 +"use strict";var StyleLayer=_dereq_("../style_layer"),FillBucket=_dereq_("../../data/bucket/fill_bucket"),FillStyleLayer=function(t){function o(){t.apply(this,arguments)}return t&&(o.__proto__=t),o.prototype=Object.create(t&&t.prototype),o.prototype.constructor=o,o.prototype.getPaintValue=function(o,l,e){var i=this;if("fill-outline-color"===o){if(void 0===this.getPaintProperty("fill-outline-color"))return t.prototype.getPaintValue.call(this,"fill-color",l,e);for(var r=this._paintTransitions["fill-outline-color"];r;){var n=r&&r.declaration&&r.declaration.value;if(!n)return t.prototype.getPaintValue.call(i,"fill-color",l,e);r=r.oldTransition}}return t.prototype.getPaintValue.call(this,o,l,e)},o.prototype.getPaintValueStopZoomLevels=function(o){return"fill-outline-color"===o&&void 0===this.getPaintProperty("fill-outline-color")?t.prototype.getPaintValueStopZoomLevels.call(this,"fill-color"):t.prototype.getPaintValueStopZoomLevels.call(this,o)},o.prototype.getPaintInterpolationT=function(o,l){return"fill-outline-color"===o&&void 0===this.getPaintProperty("fill-outline-color")?t.prototype.getPaintInterpolationT.call(this,"fill-color",l):t.prototype.getPaintInterpolationT.call(this,o,l)},o.prototype.isPaintValueFeatureConstant=function(o){return"fill-outline-color"===o&&void 0===this.getPaintProperty("fill-outline-color")?t.prototype.isPaintValueFeatureConstant.call(this,"fill-color"):t.prototype.isPaintValueFeatureConstant.call(this,o)},o.prototype.isPaintValueZoomConstant=function(o){return"fill-outline-color"===o&&void 0===this.getPaintProperty("fill-outline-color")?t.prototype.isPaintValueZoomConstant.call(this,"fill-color"):t.prototype.isPaintValueZoomConstant.call(this,o)},o.prototype.createBucket=function(t){return new FillBucket(t)},o}(StyleLayer);module.exports=FillStyleLayer;
  314 +},{"../../data/bucket/fill_bucket":46,"../style_layer":150}],154:[function(_dereq_,module,exports){
  315 +"use strict";var StyleLayer=_dereq_("../style_layer"),LineBucket=_dereq_("../../data/bucket/line_bucket"),util=_dereq_("../../util/util"),LineStyleLayer=function(e){function t(){e.apply(this,arguments)}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype.getPaintValue=function(t,r,o){var i=e.prototype.getPaintValue.call(this,t,r,o);if(i&&"line-dasharray"===t){var a=this.getPaintValue("line-width",util.extend({},r,{zoom:Math.floor(r.zoom)}),o);i.fromScale*=a,i.toScale*=a}return i},t.prototype.createBucket=function(e){return new LineBucket(e)},t}(StyleLayer);module.exports=LineStyleLayer;
  316 +},{"../../data/bucket/line_bucket":48,"../../util/util":215,"../style_layer":150}],155:[function(_dereq_,module,exports){
  317 +"use strict";var StyleLayer=_dereq_("../style_layer"),SymbolBucket=_dereq_("../../data/bucket/symbol_bucket"),SymbolStyleLayer=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.getLayoutValue=function(e,o,r){var a=t.prototype.getLayoutValue.call(this,e,o,r);if("auto"!==a)return a;switch(e){case"text-rotation-alignment":case"icon-rotation-alignment":return"line"===this.getLayoutValue("symbol-placement",o,r)?"map":"viewport";case"text-pitch-alignment":return this.getLayoutValue("text-rotation-alignment",o,r);default:return a}},e.prototype.createBucket=function(t){return new SymbolBucket(t)},e}(StyleLayer);module.exports=SymbolStyleLayer;
  318 +},{"../../data/bucket/symbol_bucket":49,"../style_layer":150}],156:[function(_dereq_,module,exports){
  319 +"use strict";var StyleLayer=_dereq_("./style_layer"),util=_dereq_("../util/util"),featureFilter=_dereq_("../style-spec/feature_filter"),groupByLayout=_dereq_("../style-spec/group_by_layout"),StyleLayerIndex=function(e){e&&this.replace(e)};StyleLayerIndex.prototype.replace=function(e){var r=this;this.symbolOrder=[];for(var t=0,i=e;t<i.length;t+=1){var a=i[t];"symbol"===a.type&&r.symbolOrder.push(a.id)}this._layerConfigs={},this._layers={},this.update(e,[])},StyleLayerIndex.prototype.update=function(e,r,t){for(var i=this,a=0,l=e;a<l.length;a+=1){var y=l[a];i._layerConfigs[y.id]=y;var s=i._layers[y.id]=StyleLayer.create(y);s.updatePaintTransitions({},{transition:!1}),s.filter=featureFilter(s.filter)}for(var o=0,u=r;o<u.length;o+=1){var n=u[o];delete i._layerConfigs[n],delete i._layers[n]}t&&(this.symbolOrder=t),this.familiesBySource={};for(var f=groupByLayout(util.values(this._layerConfigs)),p=0,d=f;p<d.length;p+=1){var h=d[p],c=h.map(function(e){return i._layers[e.id]}),v=c[0];if(!v.layout||"none"!==v.layout.visibility){var _=v.source||"",g=i.familiesBySource[_];g||(g=i.familiesBySource[_]={});var L=v.sourceLayer||"_geojsonTileLayer",m=g[L];m||(m=g[L]=[]),m.push(c)}}},module.exports=StyleLayerIndex;
  320 +},{"../style-spec/feature_filter":104,"../style-spec/group_by_layout":107,"../util/util":215,"./style_layer":150}],157:[function(_dereq_,module,exports){
  321 +"use strict";function interpZoomTransitioned(t,i,e){if(void 0!==t&&void 0!==i)return{from:t.to,fromScale:t.toScale,to:i.to,toScale:i.toScale,t:e}}var util=_dereq_("../util/util"),interpolate=_dereq_("../style-spec/util/interpolate"),fakeZoomHistory={lastIntegerZoom:0,lastIntegerZoomTime:0,lastZoom:0},StyleTransition=function(t,i,e,o,a){this.declaration=i,this.startTime=this.endTime=(new Date).getTime(),this.oldTransition=e,this.duration=o.duration||0,this.delay=o.delay||0,this.zoomTransitioned="piecewise-constant"===t.function&&t.transition,this.interp=this.zoomTransitioned?interpZoomTransitioned:interpolate[t.type],this.zoomHistory=a||fakeZoomHistory,this.instant()||(this.endTime=this.startTime+this.duration+this.delay),e&&e.endTime<=this.startTime&&delete e.oldTransition};StyleTransition.prototype.instant=function(){return!this.oldTransition||!this.interp||0===this.duration&&0===this.delay},StyleTransition.prototype.calculate=function(t,i,e){var o=this._calculateTargetValue(t,i);if(this.instant())return o;if(e=e||Date.now(),e>=this.endTime)return o;var a=this.oldTransition.calculate(t,i,this.startTime),n=util.easeCubicInOut((e-this.startTime-this.delay)/this.duration);return this.interp(a,o,n)},StyleTransition.prototype._calculateTargetValue=function(t,i){if(!this.zoomTransitioned)return this.declaration.calculate(t,i);var e=t.zoom,o=this.zoomHistory.lastIntegerZoom,a=e>o?2:.5,n=this.declaration.calculate({zoom:e>o?e-1:e+1},i),r=this.declaration.calculate({zoom:e},i),s=Math.min((Date.now()-this.zoomHistory.lastIntegerZoomTime)/this.duration,1),l=Math.abs(e-o),u=interpolate(s,1,l);return void 0!==n&&void 0!==r?{from:n,fromScale:a,to:r,toScale:1,t:u}:void 0},module.exports=StyleTransition;
  322 +},{"../style-spec/util/interpolate":122,"../util/util":215}],158:[function(_dereq_,module,exports){
  323 +"use strict";module.exports=_dereq_("../style-spec/validate_style.min"),module.exports.emitErrors=function(r,e){if(e&&e.length){for(var t=0;t<e.length;t++)r.fire("error",{error:new Error(e[t].message)});return!0}return!1};
  324 +},{"../style-spec/validate_style.min":144}],159:[function(_dereq_,module,exports){
  325 +"use strict";var Point=_dereq_("point-geometry"),Anchor=function(t){function o(o,e,n,r){t.call(this,o,e),this.angle=n,void 0!==r&&(this.segment=r)}return t&&(o.__proto__=t),o.prototype=Object.create(t&&t.prototype),o.prototype.constructor=o,o.prototype.clone=function(){return new o(this.x,this.y,this.angle,this.segment)},o}(Point);module.exports=Anchor;
  326 +},{"point-geometry":25}],160:[function(_dereq_,module,exports){
  327 +"use strict";function checkMaxAngle(e,t,a,r,n){if(void 0===t.segment)return!0;for(var i=t,s=t.segment+1,f=0;f>-a/2;){if(s--,s<0)return!1;f-=e[s].dist(i),i=e[s]}f+=e[s].dist(e[s+1]),s++;for(var l=[],o=0;f<a/2;){var u=e[s-1],c=e[s],g=e[s+1];if(!g)return!1;var h=u.angleTo(c)-c.angleTo(g);for(h=Math.abs((h+3*Math.PI)%(2*Math.PI)-Math.PI),l.push({distance:f,angleDelta:h}),o+=h;f-l[0].distance>r;)o-=l.shift().angleDelta;if(o>n)return!1;s++,f+=c.dist(g)}return!0}module.exports=checkMaxAngle;
  328 +},{}],161:[function(_dereq_,module,exports){
  329 +"use strict";function clipLine(n,x,y,o,e){for(var r=[],t=0;t<n.length;t++)for(var i=n[t],u=void 0,d=0;d<i.length-1;d++){var P=i[d],w=i[d+1];P.x<x&&w.x<x||(P.x<x?P=new Point(x,P.y+(w.y-P.y)*((x-P.x)/(w.x-P.x)))._round():w.x<x&&(w=new Point(x,P.y+(w.y-P.y)*((x-P.x)/(w.x-P.x)))._round()),P.y<y&&w.y<y||(P.y<y?P=new Point(P.x+(w.x-P.x)*((y-P.y)/(w.y-P.y)),y)._round():w.y<y&&(w=new Point(P.x+(w.x-P.x)*((y-P.y)/(w.y-P.y)),y)._round()),P.x>=o&&w.x>=o||(P.x>=o?P=new Point(o,P.y+(w.y-P.y)*((o-P.x)/(w.x-P.x)))._round():w.x>=o&&(w=new Point(o,P.y+(w.y-P.y)*((o-P.x)/(w.x-P.x)))._round()),P.y>=e&&w.y>=e||(P.y>=e?P=new Point(P.x+(w.x-P.x)*((e-P.y)/(w.y-P.y)),e)._round():w.y>=e&&(w=new Point(P.x+(w.x-P.x)*((e-P.y)/(w.y-P.y)),e)._round()),u&&P.equals(u[u.length-1])||(u=[P],r.push(u)),u.push(w)))))}return r}var Point=_dereq_("point-geometry");module.exports=clipLine;
  330 +},{"point-geometry":25}],162:[function(_dereq_,module,exports){
  331 +"use strict";var createStructArrayType=_dereq_("../util/struct_array"),Point=_dereq_("point-geometry"),CollisionBoxArray=createStructArrayType({members:[{type:"Int16",name:"anchorPointX"},{type:"Int16",name:"anchorPointY"},{type:"Int16",name:"x1"},{type:"Int16",name:"y1"},{type:"Int16",name:"x2"},{type:"Int16",name:"y2"},{type:"Float32",name:"maxScale"},{type:"Uint32",name:"featureIndex"},{type:"Uint16",name:"sourceLayerIndex"},{type:"Uint16",name:"bucketIndex"},{type:"Int16",name:"bbox0"},{type:"Int16",name:"bbox1"},{type:"Int16",name:"bbox2"},{type:"Int16",name:"bbox3"},{type:"Float32",name:"placementScale"}]});Object.defineProperty(CollisionBoxArray.prototype.StructType.prototype,"anchorPoint",{get:function(){return new Point(this.anchorPointX,this.anchorPointY)}}),module.exports=CollisionBoxArray;
  332 +},{"../util/struct_array":212,"point-geometry":25}],163:[function(_dereq_,module,exports){
  333 +"use strict";var CollisionFeature=function(t,e,i,o,a,n,s,l,r,d,u){var h=s.top*l-r,f=s.bottom*l+r,m=s.left*l-r,x=s.right*l+r;if(this.boxStartIndex=t.length,d){var _=f-h,b=x-m;if(_>0)if(_=Math.max(10*l,_),u){var v=e[i.segment+1].sub(e[i.segment])._unit()._mult(b),c=[i.sub(v),i.add(v)];this._addLineCollisionBoxes(t,c,i,0,b,_,o,a,n)}else this._addLineCollisionBoxes(t,e,i,i.segment,b,_,o,a,n)}else t.emplaceBack(i.x,i.y,m,h,x,f,1/0,o,a,n,0,0,0,0,0);this.boxEndIndex=t.length};CollisionFeature.prototype._addLineCollisionBoxes=function(t,e,i,o,a,n,s,l,r){var d=n/2,u=Math.floor(a/d),h=Math.floor(u/4),f=-n/2,m=i,x=o+1,_=f,b=-a/2,v=b-a/8;do{if(x--,x<0){if(_>b)return;x=0;break}_-=e[x].dist(m),m=e[x]}while(_>v);for(var c=e[x].dist(e[x+1]),g=-h;g<u+h;g++){var p=b+g*d;if(!(p<_)){for(;_+c<p;){if(_+=c,x++,x+1>=e.length)return;c=e[x].dist(e[x+1])}var C=p-_,M=e[x],B=e[x+1],k=B.sub(M)._unit()._mult(C)._add(M)._round(),y=Math.max(Math.abs(p-f)-d/2,0),F=a/2/y;(g<0||g>=u)&&(F=Math.min(F,.99)),t.emplaceBack(k.x,k.y,-n/2,-n/2,n/2,n/2,F,s,l,r,0,0,0,0,0)}}},module.exports=CollisionFeature;
  334 +},{}],164:[function(_dereq_,module,exports){
  335 +"use strict";var Point=_dereq_("point-geometry"),EXTENT=_dereq_("../data/extent"),Grid=_dereq_("grid-index"),intersectionTests=_dereq_("../util/intersection_tests"),CollisionTile=function(t,e,i,a,r){if("object"==typeof t){var o=t;r=e,t=o.angle,e=o.pitch,i=o.cameraToCenterDistance,a=o.cameraToTileDistance,this.grid=new Grid(o.grid),this.ignoredGrid=new Grid(o.ignoredGrid)}else this.grid=new Grid(EXTENT,12,6),this.ignoredGrid=new Grid(EXTENT,12,0);this.perspectiveRatio=1+.5*(a/i-1),this.minScale=.5/this.perspectiveRatio,this.maxScale=2/this.perspectiveRatio,this.angle=t,this.pitch=e,this.cameraToCenterDistance=i,this.cameraToTileDistance=a;var n=Math.sin(t),s=Math.cos(t);if(this.rotationMatrix=[s,-n,n,s],this.reverseRotationMatrix=[s,n,-n,s],this.yStretch=Math.max(1,a/(i*Math.cos(e/180*Math.PI))),this.collisionBoxArray=r,0===r.length){r.emplaceBack();var l=32767;r.emplaceBack(0,0,0,-l,0,l,l,0,0,0,0,0,0,0,0,0),r.emplaceBack(EXTENT,0,0,-l,0,l,l,0,0,0,0,0,0,0,0,0),r.emplaceBack(0,0,-l,0,l,0,l,0,0,0,0,0,0,0,0,0),r.emplaceBack(0,EXTENT,-l,0,l,0,l,0,0,0,0,0,0,0,0,0)}this.tempCollisionBox=r.get(0),this.edges=[r.get(1),r.get(2),r.get(3),r.get(4)]};CollisionTile.prototype.serialize=function(t){var e=this.grid.toArrayBuffer(),i=this.ignoredGrid.toArrayBuffer();return t&&(t.push(e),t.push(i)),{angle:this.angle,pitch:this.pitch,cameraToCenterDistance:this.cameraToCenterDistance,cameraToTileDistance:this.cameraToTileDistance,grid:e,ignoredGrid:i}},CollisionTile.prototype.placeCollisionFeature=function(t,e,i){for(var a=this,r=this.collisionBoxArray,o=this.minScale,n=this.rotationMatrix,s=this.yStretch,l=t.boxStartIndex;l<t.boxEndIndex;l++){var c=r.get(l),h=c.anchorPoint._matMult(n),x=h.x,m=h.y,p=x+c.x1*a.perspectiveRatio,g=m+c.y1*s*a.perspectiveRatio,y=x+c.x2*a.perspectiveRatio,d=m+c.y2*s*a.perspectiveRatio;if(c.bbox0=p,c.bbox1=g,c.bbox2=y,c.bbox3=d,!e)for(var u=a.grid.query(p,g,y,d),v=0;v<u.length;v++){var M=r.get(u[v]),T=M.anchorPoint._matMult(n);if(o=a.getPlacementScale(o,h,c,T,M),o>=a.maxScale)return o}if(i){var f=void 0;if(a.angle){var S=a.reverseRotationMatrix,P=new Point(c.x1,c.y1).matMult(S),b=new Point(c.x2,c.y1).matMult(S),C=new Point(c.x1,c.y2).matMult(S),N=new Point(c.x2,c.y2).matMult(S);f=a.tempCollisionBox,f.anchorPointX=c.anchorPoint.x,f.anchorPointY=c.anchorPoint.y,f.x1=Math.min(P.x,b.x,C.x,N.x),f.y1=Math.min(P.y,b.x,C.x,N.x),f.x2=Math.max(P.x,b.x,C.x,N.x),f.y2=Math.max(P.y,b.x,C.x,N.x),f.maxScale=c.maxScale}else f=c;for(var w=0;w<this.edges.length;w++){var B=a.edges[w];if(o=a.getPlacementScale(o,c.anchorPoint,f,B.anchorPoint,B),o>=a.maxScale)return o}}}return o},CollisionTile.prototype.queryRenderedSymbols=function(t,e){var i={},a=[];if(0===t.length||0===this.grid.keys.length&&0===this.ignoredGrid.keys.length)return a;for(var r=this.collisionBoxArray,o=this.rotationMatrix,n=this.yStretch,s=[],l=1/0,c=1/0,h=-(1/0),x=-(1/0),m=0;m<t.length;m++)for(var p=t[m],g=0;g<p.length;g++){var y=p[g].matMult(o);l=Math.min(l,y.x),c=Math.min(c,y.y),h=Math.max(h,y.x),x=Math.max(x,y.y),s.push(y)}for(var d=this.grid.query(l,c,h,x),u=this.ignoredGrid.query(l,c,h,x),v=0;v<u.length;v++)d.push(u[v]);for(var M=e/this.perspectiveRatio,T=Math.pow(2,Math.ceil(Math.log(M)/Math.LN2*10)/10),f=0;f<d.length;f++){var S=r.get(d[f]),P=S.sourceLayerIndex,b=S.featureIndex;if(void 0===i[P]&&(i[P]={}),!i[P][b]&&!(T<S.placementScale||T>S.maxScale)){var C=S.anchorPoint.matMult(o),N=C.x+S.x1/M,w=C.y+S.y1/M*n,B=C.x+S.x2/M,G=C.y+S.y2/M*n,E=[new Point(N,w),new Point(B,w),new Point(B,G),new Point(N,G)];intersectionTests.polygonIntersectsPolygon(s,E)&&(i[P][b]=!0,a.push(d[f]))}}return a},CollisionTile.prototype.getPlacementScale=function(t,e,i,a,r){var o=e.x-a.x,n=e.y-a.y,s=(r.x1-i.x2)/o,l=(r.x2-i.x1)/o,c=(r.y1-i.y2)*this.yStretch/n,h=(r.y2-i.y1)*this.yStretch/n;(isNaN(s)||isNaN(l))&&(s=l=1),(isNaN(c)||isNaN(h))&&(c=h=1);var x=Math.min(Math.max(s,l),Math.max(c,h)),m=r.maxScale,p=i.maxScale;return x>m&&(x=m),x>p&&(x=p),x>t&&x>=r.placementScale&&(t=x),t},CollisionTile.prototype.insertCollisionFeature=function(t,e,i){for(var a=this,r=i?this.ignoredGrid:this.grid,o=this.collisionBoxArray,n=t.boxStartIndex;n<t.boxEndIndex;n++){var s=o.get(n);s.placementScale=e,e<a.maxScale&&(1===a.perspectiveRatio||s.maxScale>=1)&&r.insert(n,s.bbox0,s.bbox1,s.bbox2,s.bbox3)}},module.exports=CollisionTile;
  336 +},{"../data/extent":53,"../util/intersection_tests":206,"grid-index":16,"point-geometry":25}],165:[function(_dereq_,module,exports){
  337 +"use strict";function getAnchors(e,r,t,n,a,l,o,i,c){var h=n?.6*l*o:0,s=Math.max(n?n.right-n.left:0,a?a.right-a.left:0),u=0===e[0].x||e[0].x===c||0===e[0].y||e[0].y===c;r-s*o<r/4&&(r=s*o+r/4);var g=2*l,p=u?r/2*i%r:(s/2+g)*o*i%r;return resample(e,p,r,h,t,s*o,u,!1,c)}function resample(e,r,t,n,a,l,o,i,c){for(var h=l/2,s=0,u=0;u<e.length-1;u++)s+=e[u].dist(e[u+1]);for(var g=0,p=r-t,x=[],f=0;f<e.length-1;f++){for(var v=e[f],m=e[f+1],y=v.dist(m),A=m.angleTo(v);p+t<g+y;){p+=t;var d=(p-g)/y,k=interpolate(v.x,m.x,d),q=interpolate(v.y,m.y,d);if(k>=0&&k<c&&q>=0&&q<c&&p-h>=0&&p+h<=s){var M=new Anchor(k,q,A,f)._round();n&&!checkMaxAngle(e,M,l,n,a)||x.push(M)}}g+=y}return i||x.length||o||(x=resample(e,g/2,t,n,a,l,o,!0,c)),x}var interpolate=_dereq_("../style-spec/util/interpolate"),Anchor=_dereq_("../symbol/anchor"),checkMaxAngle=_dereq_("./check_max_angle");module.exports=getAnchors;
  338 +},{"../style-spec/util/interpolate":122,"../symbol/anchor":159,"./check_max_angle":160}],166:[function(_dereq_,module,exports){
  339 +"use strict";var ShelfPack=_dereq_("@mapbox/shelf-pack"),util=_dereq_("../util/util"),SIZE_GROWTH_RATE=4,DEFAULT_SIZE=128,MAX_SIZE=2048,GlyphAtlas=function(){this.width=DEFAULT_SIZE,this.height=DEFAULT_SIZE,this.atlas=new ShelfPack(this.width,this.height),this.index={},this.ids={},this.data=new Uint8Array(this.width*this.height)};GlyphAtlas.prototype.getGlyphs=function(){var t,i,e,h=this,r={};for(var s in h.ids)t=s.split("#"),i=t[0],e=t[1],r[i]||(r[i]=[]),r[i].push(e);return r},GlyphAtlas.prototype.getRects=function(){var t,i,e,h=this,r={};for(var s in h.ids)t=s.split("#"),i=t[0],e=t[1],r[i]||(r[i]={}),r[i][e]=h.index[s];return r},GlyphAtlas.prototype.addGlyph=function(t,i,e,h){var r=this;if(!e)return null;var s=i+"#"+e.id;if(this.index[s])return this.ids[s].indexOf(t)<0&&this.ids[s].push(t),this.index[s];if(!e.bitmap)return null;var a=e.width+2*h,E=e.height+2*h,n=1,l=a+2*n,T=E+2*n,u=this.atlas.packOne(l,T);if(u||(this.resize(),u=this.atlas.packOne(l,T)),!u)return util.warnOnce("glyph bitmap overflow"),null;this.index[s]=u,this.ids[s]=[t];for(var d=this.data,p=e.bitmap,A=0;A<E;A++)for(var _=r.width*(u.y+A+n)+u.x+n,o=a*A,x=0;x<a;x++)d[_+x]=p[o+x];return this.dirty=!0,u},GlyphAtlas.prototype.resize=function(){var t=this,i=this.width,e=this.height;if(!(i>=MAX_SIZE||e>=MAX_SIZE)){this.texture&&(this.gl&&this.gl.deleteTexture(this.texture),this.texture=null),this.width*=SIZE_GROWTH_RATE,this.height*=SIZE_GROWTH_RATE,this.atlas.resize(this.width,this.height);for(var h=new ArrayBuffer(this.width*this.height),r=0;r<e;r++){var s=new Uint8Array(t.data.buffer,e*r,i),a=new Uint8Array(h,e*r*SIZE_GROWTH_RATE,i);a.set(s)}this.data=new Uint8Array(h)}},GlyphAtlas.prototype.bind=function(t){this.gl=t,this.texture?t.bindTexture(t.TEXTURE_2D,this.texture):(this.texture=t.createTexture(),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texImage2D(t.TEXTURE_2D,0,t.ALPHA,this.width,this.height,0,t.ALPHA,t.UNSIGNED_BYTE,null))},GlyphAtlas.prototype.updateTexture=function(t){this.bind(t),this.dirty&&(t.texSubImage2D(t.TEXTURE_2D,0,0,0,this.width,this.height,t.ALPHA,t.UNSIGNED_BYTE,this.data),this.dirty=!1)},module.exports=GlyphAtlas;
  340 +},{"../util/util":215,"@mapbox/shelf-pack":2}],167:[function(_dereq_,module,exports){
  341 +"use strict";function glyphUrl(t,e,a,l){return l=l||"abc",a.replace("{s}",l[t.length%l.length]).replace("{fontstack}",t).replace("{range}",e)}var normalizeURL=_dereq_("../util/mapbox").normalizeGlyphsURL,ajax=_dereq_("../util/ajax"),verticalizePunctuation=_dereq_("../util/verticalize_punctuation"),Glyphs=_dereq_("../util/glyphs"),GlyphAtlas=_dereq_("../symbol/glyph_atlas"),Protobuf=_dereq_("pbf"),SimpleGlyph=function(t,e,a){var l=1;this.advance=t.advance,this.left=t.left-a-l,this.top=t.top+a+l,this.rect=e},GlyphSource=function(t){this.url=t&&normalizeURL(t),this.atlases={},this.stacks={},this.loading={}};GlyphSource.prototype.getSimpleGlyphs=function(t,e,a,l){var i=this;void 0===this.stacks[t]&&(this.stacks[t]={}),void 0===this.atlases[t]&&(this.atlases[t]=new GlyphAtlas);for(var r={},o=this.stacks[t],s=this.atlases[t],n=3,h={},p=0,u=function(e){var l=Math.floor(e/256);if(o[l]){var i=o[l].glyphs[e],u=s.addGlyph(a,t,i,n);i&&(r[e]=new SimpleGlyph(i,u,n))}else void 0===h[l]&&(h[l]=[],p++),h[l].push(e)},c=0;c<e.length;c++){var y=e[c],f=String.fromCharCode(y);u(y),verticalizePunctuation.lookup[f]&&u(verticalizePunctuation.lookup[f].charCodeAt(0))}p||l(void 0,r,t);var v=function(e,o,u){if(!e)for(var c=i.stacks[t][o]=u.stacks[0],y=0;y<h[o].length;y++){var f=h[o][y],v=c.glyphs[f],d=s.addGlyph(a,t,v,n);v&&(r[f]=new SimpleGlyph(v,d,n))}p--,p||l(void 0,r,t)};for(var d in h)i.loadRange(t,d,v)},GlyphSource.prototype.loadRange=function(t,e,a){if(256*e>65535)return a("glyphs > 65535 not supported");void 0===this.loading[t]&&(this.loading[t]={});var l=this.loading[t];if(l[e])l[e].push(a);else{l[e]=[a];var i=256*e+"-"+(256*e+255),r=glyphUrl(t,i,this.url);ajax.getArrayBuffer(r,function(t,a){for(var i=!t&&new Glyphs(new Protobuf(a.data)),r=0;r<l[e].length;r++)l[e][r](t,e,i);delete l[e]})}},GlyphSource.prototype.getGlyphAtlas=function(t){return this.atlases[t]},module.exports=GlyphSource;
  342 +},{"../symbol/glyph_atlas":166,"../util/ajax":193,"../util/glyphs":205,"../util/mapbox":209,"../util/verticalize_punctuation":217,"pbf":24}],168:[function(_dereq_,module,exports){
  343 +"use strict";module.exports=function(e){function t(t){g.push(e[t]),l++}function r(e,t,r){var n=u[e];return delete u[e],u[t]=n,g[n].geometry[0].pop(),g[n].geometry[0]=g[n].geometry[0].concat(r[0]),n}function n(e,t,r){var n=i[t];return delete i[t],i[e]=n,g[n].geometry[0].shift(),g[n].geometry[0]=r[0].concat(g[n].geometry[0]),n}function o(e,t,r){var n=r?t[0][t[0].length-1]:t[0][0];return e+":"+n.x+":"+n.y}for(var i={},u={},g=[],l=0,m=0;m<e.length;m++){var y=e[m],c=y.geometry,f=y.text;if(f){var a=o(f,c),s=o(f,c,!0);if(a in u&&s in i&&u[a]!==i[s]){var v=n(a,s,c),d=r(a,s,g[v].geometry);delete i[a],delete u[s],u[o(f,g[d].geometry,!0)]=d,g[v].geometry=null}else a in u?r(a,s,c):s in i?n(a,s,c):(t(m),i[a]=l-1,u[s]=l-1)}else t(m)}return g.filter(function(e){return e.geometry})};
  344 +},{}],169:[function(_dereq_,module,exports){
  345 +"use strict";function SymbolQuad(t,e,n,a,i,o,r,l,u,c,h){this.anchorPoint=t,this.tl=e,this.tr=n,this.bl=a,this.br=i,this.tex=o,this.anchorAngle=r,this.glyphAngle=l,this.minScale=u,this.maxScale=c,this.writingMode=h}function getIconQuads(t,e,n,a,i,o,r,l,u){var c,h,g,s,m=e.file_upload,d=i.layout,x=1,f=e.top-x/m.pixelRatio,S=e.left-x/m.pixelRatio,p=e.bottom+x/m.pixelRatio,y=e.right+x/m.pixelRatio;if("none"!==d["icon-text-fit"]&&r){var M=y-S,P=p-f,w=d["text-size"]/24,v=r.left*w,b=r.right*w,I=r.top*w,Q=r.bottom*w,_=b-v,G=Q-I,R=d["icon-text-fit-padding"][0],D=d["icon-text-fit-padding"][1],V=d["icon-text-fit-padding"][2],L=d["icon-text-fit-padding"][3],A="width"===d["icon-text-fit"]?.5*(G-P):0,B="height"===d["icon-text-fit"]?.5*(_-M):0,E="width"===d["icon-text-fit"]||"both"===d["icon-text-fit"]?_:M,F="height"===d["icon-text-fit"]||"both"===d["icon-text-fit"]?G:P;c=new Point(v+B-L,I+A-R),h=new Point(v+B+D+E,I+A-R),g=new Point(v+B+D+E,I+A+V+F),s=new Point(v+B-L,I+A+V+F)}else c=new Point(S,f),h=new Point(y,f),g=new Point(y,p),s=new Point(S,p);var q=i.getLayoutValue("icon-rotate",l,u)*Math.PI/180;if(o){var N=a[t.segment];if(t.y===N.y&&t.x===N.x&&t.segment+1<a.length){var k=a[t.segment+1];q+=Math.atan2(t.y-k.y,t.x-k.x)+Math.PI}else q+=Math.atan2(t.y-N.y,t.x-N.x)}if(q){var z=Math.sin(q),j=Math.cos(q),C=[j,-z,z,j];c=c.matMult(C),h=h.matMult(C),s=s.matMult(C),g=g.matMult(C)}var H={x:m.textureRect.x-x,y:m.textureRect.y-x,w:m.textureRect.w+2*x,h:m.textureRect.h+2*x};return[new SymbolQuad(new Point(t.x,t.y),c,h,s,g,H,0,0,minScale,1/0)]}function getGlyphQuads(t,e,n,a,i,o,r,l){for(var u=24,c=i.getLayoutValue("text-rotate",r,l)*Math.PI/180,h=i.layout["text-keep-upright"],g=i.getLayoutValue("text-offset",r,l).map(function(t){return t*u}),s=e.positionedGlyphs,m=[],d=minScale,x=0;x<s.length;x++){var f=s[x],S=f.glyph;if(S){var p=S.rect;if(p){var y=(f.x+S.advance/2)*n,M=void 0;o?(M=[],d=Math.max(d,getLineGlyphs(M,t,y,a,t.segment,!1)),h&&(d=Math.max(d,getLineGlyphs(M,t,y,a,t.segment,!0)))):M=[{anchorPoint:new Point(t.x,t.y),upsideDown:!1,angle:0,maxScale:1/0,minScale:minScale}];for(var P={upright:calculateBaseQuad(f,S,p,g),upsideDown:calculateBaseQuad(f,S,p,[g[0],-g[1]])},w=0;w<M.length;w++){var v=M[w],b=P[v.upsideDown?"upsideDown":"upright"],I=b.tl,Q=b.tr,_=b.bl,G=b.br;if(c){var R=Math.sin(c),D=Math.cos(c),V=[D,-R,R,D];I=I.matMult(V),Q=Q.matMult(V),_=_.matMult(V),G=G.matMult(V)}var L=Math.max(v.minScale,d),A=(t.angle+(v.upsideDown?Math.PI:0)+2*Math.PI)%(2*Math.PI),B=(v.angle+(v.upsideDown?Math.PI:0)+2*Math.PI)%(2*Math.PI);m.push(new SymbolQuad(v.anchorPoint,I,Q,_,G,p,A,B,L,v.maxScale,e.writingMode))}}}}return m}function calculateBaseQuad(t,e,n,a){var i=t.x+e.left+a[0],o=t.y-e.top+a[1],r=i+n.w,l=o+n.h,u=new Point(t.x,e.advance/2),c=new Point(i,o),h=new Point(r,o),g=new Point(i,l),s=new Point(r,l);return 0!==t.angle&&(c._sub(u)._rotate(t.angle)._add(u),h._sub(u)._rotate(t.angle)._add(u),g._sub(u)._rotate(t.angle)._add(u),s._sub(u)._rotate(t.angle)._add(u)),{tl:c,tr:h,bl:g,br:s}}function getLineGlyphs(t,e,n,a,i,o){for(var r=n>=0^o,l=Math.abs(n),u=new Point(e.x,e.y),c=getSegmentEnd(r,a,i),h={anchor:u,end:c,index:i,minScale:getMinScaleForSegment(l,u,c),maxScale:1/0};;){if(insertSegmentGlyph(t,h,r,o),h.minScale<=e.scale)return e.scale;var g=getNextVirtualSegment(h,a,l,r);if(!g)return h.minScale;h=g}}function insertSegmentGlyph(t,e,n,a){var i=Math.atan2(e.end.y-e.anchor.y,e.end.x-e.anchor.x),o=n?i:i+Math.PI;t.push({anchorPoint:e.anchor,upsideDown:a,minScale:e.minScale,maxScale:e.maxScale,angle:(o+2*Math.PI)%(2*Math.PI)})}function getVirtualSegmentAnchor(t,e,n){var a=e.sub(t)._unit();return t.sub(a._mult(n))}function getMinScaleForSegment(t,e,n){var a=e.dist(n);return t/a}function getSegmentEnd(t,e,n){return t?e[n+1]:e[n]}function getNextVirtualSegment(t,e,n,a){for(var i=t.end,o=i,r=t.index;o.equals(i);){if(a&&r+2<e.length)r+=1;else{if(a||0===r)return null;r-=1}o=getSegmentEnd(a,e,r)}var l=getVirtualSegmentAnchor(i,o,t.anchor.dist(t.end));return{anchor:l,end:o,index:r,minScale:getMinScaleForSegment(n,l,o),maxScale:t.minScale}}var Point=_dereq_("point-geometry");module.exports={getIconQuads:getIconQuads,getGlyphQuads:getGlyphQuads,SymbolQuad:SymbolQuad};var minScale=.5;
  346 +},{"point-geometry":25}],170:[function(_dereq_,module,exports){
  347 +"use strict";function PositionedGlyph(e,t,i,n,a){this.codePoint=e,this.x=t,this.y=i,this.glyph=n||null,this.angle=a}function Shaping(e,t,i,n,a,r,o){this.positionedGlyphs=e,this.text=t,this.top=i,this.bottom=n,this.left=a,this.right=r,this.writingMode=o}function breakLines(e,t){for(var i=[],n=0,a=0,r=t;a<r.length;a+=1){var o=r[a];i.push(e.substring(n,o)),n=o}return n<e.length&&i.push(e.substring(n,e.length)),i}function shapeText(e,t,i,n,a,r,o,s,l,h,c){var u=e.trim();c===WritingMode.vertical&&(u=verticalizePunctuation(u));var d,p=[],g=new Shaping(p,u,l[1],l[1],l[0],l[0],c);return d=rtlTextPlugin.processBidirectionalText?rtlTextPlugin.processBidirectionalText(u,determineLineBreaks(u,s,i,t)):breakLines(u,determineLineBreaks(u,s,i,t)),shapeLines(g,t,d,n,a,r,o,l,c,s,h),!!p.length&&g}function determineAverageLineWidth(e,t,i,n){var a=0;for(var r in e){var o=n[e.charCodeAt(r)];o&&(a+=o.advance+t)}var s=Math.max(1,Math.ceil(a/i));return a/s}function calculateBadness(e,t,i,n){var a=Math.pow(e-t,2);return n?e<t?a/2:2*a:a+Math.abs(i)*i}function calculatePenalty(e,t){var i=0;return 10===e&&(i-=1e4),40!==e&&65288!==e||(i+=50),41!==t&&65289!==t||(i+=50),i}function evaluateBreak(e,t,i,n,a,r){for(var o=null,s=calculateBadness(t,i,a,r),l=0,h=n;l<h.length;l+=1){var c=h[l],u=t-c.x,d=calculateBadness(u,i,a,r)+c.badness;d<=s&&(o=c,s=d)}return{index:e,x:t,priorBreak:o,badness:s}}function leastBadBreaks(e){return e?leastBadBreaks(e.priorBreak).concat(e.index):[]}function determineLineBreaks(e,t,i,n){if(!i)return[];if(!e)return[];for(var a=[],r=determineAverageLineWidth(e,t,i,n),o=0,s=0;s<e.length;s++){var l=e.charCodeAt(s),h=n[l];h&&!whitespace[l]&&(o+=h.advance+t),s<e.length-1&&(breakable[l]||scriptDetection.charAllowsIdeographicBreaking(l))&&a.push(evaluateBreak(s+1,o,r,a,calculatePenalty(l,e.charCodeAt(s+1)),!1))}return leastBadBreaks(evaluateBreak(e.length,o,r,a,0,!0))}function shapeLines(e,t,i,n,a,r,o,s,l,h,c){var u=-17,d=0,p=u,g=0,v=e.positionedGlyphs;for(var f in i){var x=i[f].trim();if(x.length){for(var B=v.length,k=0;k<x.length;k++){var y=x.charCodeAt(k),P=t[y];P&&(scriptDetection.charHasUprightVerticalOrientation(y)&&l!==WritingMode.horizontal?(v.push(new PositionedGlyph(y,d,0,P,-Math.PI/2)),d+=c+h):(v.push(new PositionedGlyph(y,d,p,P,0)),d+=P.advance+h))}if(v.length!==B){var b=d-h;g=Math.max(b,g),justifyLine(v,t,B,v.length-1,o)}d=0,p+=n}else p+=n}align(v,o,a,r,g,n,i.length);var m=i.length*n;e.top+=-r*m,e.bottom=e.top+m,e.left+=-a*g,e.right=e.left+g}function justifyLine(e,t,i,n,a){if(a)for(var r=t[e[n].codePoint].advance,o=(e[n].x+r)*a,s=i;s<=n;s++)e[s].x-=o}function align(e,t,i,n,a,r,o){for(var s=(t-i)*a,l=(-n*o+.5)*r,h=0;h<e.length;h++)e[h].x+=s,e[h].y+=l}function shapeIcon(e,t){var i=t[0],n=t[1],a=i-e.displaySize[0]/2,r=a+e.displaySize[0],o=n-e.displaySize[1]/2,s=o+e.displaySize[1];return new PositionedIcon(e,o,s,a,r)}function PositionedIcon(e,t,i,n,a){this.image=e,this.top=t,this.bottom=i,this.left=n,this.right=a}var scriptDetection=_dereq_("../util/script_detection"),verticalizePunctuation=_dereq_("../util/verticalize_punctuation"),rtlTextPlugin=_dereq_("../source/rtl_text_plugin"),WritingMode={horizontal:1,vertical:2};module.exports={shapeText:shapeText,shapeIcon:shapeIcon,WritingMode:WritingMode};var whitespace={9:!0,10:!0,11:!0,12:!0,13:!0,32:!0},breakable={10:!0,32:!0,38:!0,40:!0,41:!0,43:!0,45:!0,47:!0,173:!0,183:!0,8203:!0,8208:!0,8211:!0,8231:!0};
  348 +},{"../source/rtl_text_plugin":90,"../util/script_detection":210,"../util/verticalize_punctuation":217}],171:[function(_dereq_,module,exports){
  349 +"use strict";function spriteAtlasElement(t){var e={x:t.rect.x+padding,y:t.rect.y+padding,w:t.rect.w-2*padding,h:t.rect.h-2*padding};return{sdf:t.sdf,pixelRatio:t.pixelRatio,isNativePixelRatio:t.pixelRatio===browser.devicePixelRatio,textureRect:e,tl:[e.x,e.y],br:[e.x+e.w,e.y+e.h],displaySize:[e.w/t.pixelRatio,e.h/t.pixelRatio]}}function copyBitmap(t,e,i,r,a,h,s,o,n,d,p){var l,u,f=r*e+i,g=o*h+s;if(p)for(g-=h,u=-1;u<=d;u++,g+=h)for(f=((u+d)%d+r)*e+i,l=-1;l<=n;l++)a[g+l]=t[f+(l+n)%n];else for(u=0;u<d;u++,f+=e,g+=h)for(l=0;l<n;l++)a[g+l]=t[f+l]}var ShelfPack=_dereq_("@mapbox/shelf-pack"),browser=_dereq_("../util/browser"),util=_dereq_("../util/util"),window=_dereq_("../util/window"),Evented=_dereq_("../util/evented"),padding=1,SpriteAtlas=function(t){function e(e,i){t.call(this),this.images={},this.data=!1,this.texture=0,this.filter=0,this.width=e*browser.devicePixelRatio,this.height=i*browser.devicePixelRatio,this.shelfPack=new ShelfPack(this.width,this.height),this.dirty=!0}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.getPixelSize=function(){return[this.width,this.height]},e.prototype.allocateImage=function(t,e){var i=t+2*padding,r=e+2*padding,a=this.shelfPack.packOne(i,r);return a?a:(util.warnOnce("SpriteAtlas out of space."),null)},e.prototype.addImage=function(t,e,i){var r,a,h;if(e instanceof window.HTMLImageElement?(r=e.width,a=e.height,e=browser.getImageData(e),h=1):(r=i.width,a=i.height,h=i.pixelRatio||1),ArrayBuffer.isView(e)&&(e=new Uint32Array(e.buffer)),!(e instanceof Uint32Array))return this.fire("error",{error:new Error("Image provided in an invalid format. Supported formats are HTMLImageElement and ArrayBufferView.")});if(this.images[t])return this.fire("error",{error:new Error("An image with this name already exists.")});var s=this.allocateImage(r,a);return s?(this.images[t]={rect:s,width:r,height:a,pixelRatio:h,sdf:!1},this.copy(e,r,s,{x:0,y:0,width:r,height:a},!1),void this.fire("data",{dataType:"style"})):this.fire("error",{error:new Error("There is not enough space to add this image.")})},e.prototype.removeImage=function(t){var e=this.images[t];return delete this.images[t],e?(this.shelfPack.unref(e.rect),void this.fire("data",{dataType:"style"})):this.fire("error",{error:new Error("No image with this name exists.")})},e.prototype.getIcon=function(t){return this._getImage(t,!1)},e.prototype.getPattern=function(t){return this._getImage(t,!0)},e.prototype._getImage=function(t,e){if(this.images[t])return spriteAtlasElement(this.images[t]);if(!this.sprite)return null;var i=this.sprite.getSpritePosition(t);if(!i.width||!i.height)return null;var r=this.allocateImage(i.width,i.height);if(!r)return null;var a={rect:r,width:i.width,height:i.height,sdf:i.sdf,pixelRatio:i.pixelRatio};if(this.images[t]=a,!this.sprite.imgData)return null;var h=new Uint32Array(this.sprite.imgData.buffer);return this.copy(h,this.sprite.width,r,i,e),spriteAtlasElement(a)},e.prototype.allocate=function(){var t=this;if(!this.data){this.data=new Uint32Array(this.width*this.height);for(var e=0;e<this.data.length;e++)t.data[e]=0}},e.prototype.copy=function(t,e,i,r,a){this.allocate();var h=this.data;copyBitmap(t,e,r.x,r.y,h,this.getPixelSize()[0],i.x+padding,i.y+padding,r.width,r.height,a),this.dirty=!0},e.prototype.setSprite=function(t){t&&this.canvas&&(this.canvas.width=this.width,this.canvas.height=this.height),this.sprite=t},e.prototype.addIcons=function(t,e){for(var i=this,r={},a=0,h=t;a<h.length;a+=1){var s=h[a];r[s]=i.getIcon(s)}e(null,r)},e.prototype.bind=function(t,e){var i=!1;this.texture?t.bindTexture(t.TEXTURE_2D,this.texture):(this.texture=t.createTexture(),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.pixelStorei(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0),i=!0);var r=e?t.LINEAR:t.NEAREST;r!==this.filter&&(t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,r),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,r),this.filter=r),this.dirty&&(this.allocate(),i?t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.width,this.height,0,t.RGBA,t.UNSIGNED_BYTE,new Uint8Array(this.data.buffer)):t.texSubImage2D(t.TEXTURE_2D,0,0,0,this.width,this.height,t.RGBA,t.UNSIGNED_BYTE,new Uint8Array(this.data.buffer)),this.dirty=!1)},e}(Evented);module.exports=SpriteAtlas;
  350 +},{"../util/browser":194,"../util/evented":202,"../util/util":215,"../util/window":196,"@mapbox/shelf-pack":2}],172:[function(_dereq_,module,exports){
  351 +"use strict";var rtlTextPlugin=_dereq_("../source/rtl_text_plugin");module.exports=function(e,r,t,a){var l=r.getLayoutValue("text-transform",t,a);return"uppercase"===l?e=e.toLocaleUpperCase():"lowercase"===l&&(e=e.toLocaleLowerCase()),rtlTextPlugin.applyArabicShaping&&(e=rtlTextPlugin.applyArabicShaping(e)),e};
  352 +},{"../source/rtl_text_plugin":90}],173:[function(_dereq_,module,exports){
  353 +"use strict";var DOM=_dereq_("../util/dom"),Point=_dereq_("point-geometry"),handlers={scrollZoom:_dereq_("./handler/scroll_zoom"),boxZoom:_dereq_("./handler/box_zoom"),dragRotate:_dereq_("./handler/drag_rotate"),dragPan:_dereq_("./handler/drag_pan"),keyboard:_dereq_("./handler/keyboard"),doubleClickZoom:_dereq_("./handler/dblclick_zoom"),touchZoomRotate:_dereq_("./handler/touch_zoom_rotate")};module.exports=function(e,t){function n(e){h("mouseout",e)}function o(t){e.stop(),L=DOM.mousePos(g,t),h("mousedown",t),E=!0}function r(t){var n=e.dragRotate&&e.dragRotate.isActive();p&&!n&&h("contextmenu",p),p=null,E=!1,h("mouseup",t)}function a(t){if(!(e.dragPan&&e.dragPan.isActive()||e.dragRotate&&e.dragRotate.isActive())){for(var n=t.toElement||t.target;n&&n!==g;)n=n.parentNode;n===g&&h("mousemove",t)}}function u(t){e.stop(),f("touchstart",t),!t.touches||t.touches.length>1||(b?(clearTimeout(b),b=null,h("dblclick",t)):b=setTimeout(l,300))}function i(e){f("touchmove",e)}function c(e){f("touchend",e)}function d(e){f("touchcancel",e)}function l(){b=null}function s(e){var t=DOM.mousePos(g,e);t.equals(L)&&h("click",e)}function v(e){h("dblclick",e),e.preventDefault()}function m(t){var n=e.dragRotate&&e.dragRotate.isActive();E||n?E&&(p=t):h("contextmenu",t),t.preventDefault()}function h(t,n){var o=DOM.mousePos(g,n);return e.fire(t,{lngLat:e.unproject(o),point:o,originalEvent:n})}function f(t,n){var o=DOM.touchPos(g,n),r=o.reduce(function(e,t,n,o){return e.add(t.div(o.length))},new Point(0,0));return e.fire(t,{lngLat:e.unproject(r),point:r,lngLats:o.map(function(t){return e.unproject(t)},this),points:o,originalEvent:n})}var g=e.getCanvasContainer(),p=null,E=!1,L=null,b=null;for(var q in handlers)e[q]=new handlers[q](e,t),t.interactive&&t[q]&&e[q].enable(t[q]);g.addEventListener("mouseout",n,!1),g.addEventListener("mousedown",o,!1),g.addEventListener("mouseup",r,!1),g.addEventListener("mousemove",a,!1),g.addEventListener("touchstart",u,!1),g.addEventListener("touchend",c,!1),g.addEventListener("touchmove",i,!1),g.addEventListener("touchcancel",d,!1),g.addEventListener("click",s,!1),g.addEventListener("dblclick",v,!1),g.addEventListener("contextmenu",m,!1)};
  354 +},{"../util/dom":201,"./handler/box_zoom":181,"./handler/dblclick_zoom":182,"./handler/drag_pan":183,"./handler/drag_rotate":184,"./handler/keyboard":185,"./handler/scroll_zoom":186,"./handler/touch_zoom_rotate":187,"point-geometry":25}],174:[function(_dereq_,module,exports){
  355 +"use strict";var util=_dereq_("../util/util"),interpolate=_dereq_("../style-spec/util/interpolate"),browser=_dereq_("../util/browser"),LngLat=_dereq_("../geo/lng_lat"),LngLatBounds=_dereq_("../geo/lng_lat_bounds"),Point=_dereq_("point-geometry"),Evented=_dereq_("../util/evented"),Camera=function(t){function e(e,i){t.call(this),this.moving=!1,this.transform=e,this._bearingSnap=i.bearingSnap}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.getCenter=function(){return this.transform.center},e.prototype.setCenter=function(t,e){return this.jumpTo({center:t},e)},e.prototype.panBy=function(t,e,i){return t=Point.convert(t).mult(-1),this.panTo(this.transform.center,util.extend({offset:t},e),i)},e.prototype.panTo=function(t,e,i){return this.easeTo(util.extend({center:t},e),i)},e.prototype.getZoom=function(){return this.transform.zoom},e.prototype.setZoom=function(t,e){return this.jumpTo({zoom:t},e),this},e.prototype.zoomTo=function(t,e,i){return this.easeTo(util.extend({zoom:t},e),i)},e.prototype.zoomIn=function(t,e){return this.zoomTo(this.getZoom()+1,t,e),this},e.prototype.zoomOut=function(t,e){return this.zoomTo(this.getZoom()-1,t,e),this},e.prototype.getBearing=function(){return this.transform.bearing},e.prototype.setBearing=function(t,e){return this.jumpTo({bearing:t},e),this},e.prototype.rotateTo=function(t,e,i){return this.easeTo(util.extend({bearing:t},e),i)},e.prototype.resetNorth=function(t,e){return this.rotateTo(0,util.extend({duration:1e3},t),e),this},e.prototype.snapToNorth=function(t,e){return Math.abs(this.getBearing())<this._bearingSnap?this.resetNorth(t,e):this},e.prototype.getPitch=function(){return this.transform.pitch},e.prototype.setPitch=function(t,e){return this.jumpTo({pitch:t},e),this},e.prototype.fitBounds=function(t,e,i){if(e=util.extend({padding:{top:0,bottom:0,right:0,left:0},offset:[0,0],maxZoom:this.transform.maxZoom},e),"number"==typeof e.padding){var o=e.padding;e.padding={top:o,bottom:o,right:o,left:o}}if(!util.deepEqual(Object.keys(e.padding).sort(function(t,e){return t<e?-1:t>e?1:0}),["bottom","left","right","top"]))return void util.warnOnce("options.padding must be a positive number, or an Object with keys 'bottom', 'left', 'right', 'top'");t=LngLatBounds.convert(t);var n=[e.padding.left-e.padding.right,e.padding.top-e.padding.bottom],r=Math.min(e.padding.right,e.padding.left),a=Math.min(e.padding.top,e.padding.bottom);e.offset=[e.offset[0]+n[0],e.offset[1]+n[1]];var s=Point.convert(e.offset),h=this.transform,p=h.project(t.getNorthWest()),u=h.project(t.getSouthEast()),c=u.sub(p),m=(h.width-2*r-2*Math.abs(s.x))/c.x,f=(h.height-2*a-2*Math.abs(s.y))/c.y;return f<0||m<0?void util.warnOnce("Map cannot fit within canvas with the given bounds, padding, and/or offset."):(e.center=h.unproject(p.add(u).div(2)),e.zoom=Math.min(h.scaleZoom(h.scale*Math.min(m,f)),e.maxZoom),e.bearing=0,e.linear?this.easeTo(e,i):this.flyTo(e,i))},e.prototype.jumpTo=function(t,e){this.stop();var i=this.transform,o=!1,n=!1,r=!1;return"zoom"in t&&i.zoom!==+t.zoom&&(o=!0,i.zoom=+t.zoom),"center"in t&&(i.center=LngLat.convert(t.center)),"bearing"in t&&i.bearing!==+t.bearing&&(n=!0,i.bearing=+t.bearing),"pitch"in t&&i.pitch!==+t.pitch&&(r=!0,i.pitch=+t.pitch),this.fire("movestart",e).fire("move",e),o&&this.fire("zoomstart",e).fire("zoom",e).fire("zoomend",e),n&&this.fire("rotate",e),r&&this.fire("pitchstart",e).fire("pitch",e).fire("pitchend",e),this.fire("moveend",e)},e.prototype.easeTo=function(t,e){var i=this;this.stop(),t=util.extend({offset:[0,0],duration:500,easing:util.ease},t),t.animate===!1&&(t.duration=0),t.smoothEasing&&0!==t.duration&&(t.easing=this._smoothOutEasing(t.duration));var o=this.transform,n=this.getZoom(),r=this.getBearing(),a=this.getPitch(),s="zoom"in t?+t.zoom:n,h="bearing"in t?this._normalizeBearing(t.bearing,r):r,p="pitch"in t?+t.pitch:a,u=o.centerPoint.add(Point.convert(t.offset)),c=o.pointLocation(u),m=LngLat.convert(t.center||c);this._normalizeCenter(m);var f,g,d=o.project(c),l=o.project(m).sub(d),v=o.zoomScale(s-n);return t.around&&(f=LngLat.convert(t.around),g=o.locationPoint(f)),this.zooming=s!==n,this.rotating=r!==h,this.pitching=p!==a,this._prepareEase(e,t.noMoveStart),clearTimeout(this._onEaseEnd),this._ease(function(t){if(this.zooming&&(o.zoom=interpolate(n,s,t)),this.rotating&&(o.bearing=interpolate(r,h,t)),this.pitching&&(o.pitch=interpolate(a,p,t)),f)o.setLocationAtPoint(f,g);else{var i=o.zoomScale(o.zoom-n),c=s>n?Math.min(2,v):Math.max(.5,v),m=Math.pow(c,1-t),b=o.unproject(d.add(l.mult(t*m)).mult(i));o.setLocationAtPoint(o.renderWorldCopies?b.wrap():b,u)}this._fireMoveEvents(e)},function(){t.delayEndEvents?i._onEaseEnd=setTimeout(function(){return i._easeToEnd(e)},t.delayEndEvents):i._easeToEnd(e)},t),this},e.prototype._prepareEase=function(t,e){this.moving=!0,e||this.fire("movestart",t),this.zooming&&this.fire("zoomstart",t),this.pitching&&this.fire("pitchstart",t)},e.prototype._fireMoveEvents=function(t){this.fire("move",t),this.zooming&&this.fire("zoom",t),this.rotating&&this.fire("rotate",t),this.pitching&&this.fire("pitch",t)},e.prototype._easeToEnd=function(t){var e=this.zooming,i=this.pitching;this.moving=!1,this.zooming=!1,this.rotating=!1,this.pitching=!1,e&&this.fire("zoomend",t),i&&this.fire("pitchend",t),this.fire("moveend",t)},e.prototype.flyTo=function(t,e){function i(t){var e=(M*M-z*z+(t?-1:1)*L*L*E*E)/(2*(t?M:z)*L*E);return Math.log(Math.sqrt(e*e+1)-e)}function o(t){return(Math.exp(t)-Math.exp(-t))/2}function n(t){return(Math.exp(t)+Math.exp(-t))/2}function r(t){return o(t)/n(t)}var a=this;this.stop(),t=util.extend({offset:[0,0],speed:1.2,curve:1.42,easing:util.ease},t);var s=this.transform,h=this.getZoom(),p=this.getBearing(),u=this.getPitch(),c="zoom"in t?util.clamp(+t.zoom,s.minZoom,s.maxZoom):h,m="bearing"in t?this._normalizeBearing(t.bearing,p):p,f="pitch"in t?+t.pitch:u,g=s.zoomScale(c-h),d=s.centerPoint.add(Point.convert(t.offset)),l=s.pointLocation(d),v=LngLat.convert(t.center||l);this._normalizeCenter(v);var b=s.project(l),y=s.project(v).sub(b),_=t.curve,z=Math.max(s.width,s.height),M=z/g,E=y.mag();if("minZoom"in t){var T=util.clamp(Math.min(t.minZoom,h,c),s.minZoom,s.maxZoom),x=z/s.zoomScale(T-h);_=Math.sqrt(x/E*2)}var L=_*_,j=i(0),Z=function(t){return n(j)/n(j+_*t)},w=function(t){return z*((n(j)*r(j+_*t)-o(j))/L)/E},P=(i(1)-j)/_;if(Math.abs(E)<1e-6||isNaN(P)){if(Math.abs(z-M)<1e-6)return this.easeTo(t,e);var q=M<z?-1:1;P=Math.abs(Math.log(M/z))/_,w=function(){return 0},Z=function(t){return Math.exp(q*_*t)}}if("duration"in t)t.duration=+t.duration;else{var B="screenSpeed"in t?+t.screenSpeed/_:+t.speed;t.duration=1e3*P/B}return this.zooming=!0,this.rotating=p!==m,this.pitching=f!==u,this._prepareEase(e,!1),this._ease(function(t){var i=t*P,o=1/Z(i);s.zoom=h+s.scaleZoom(o),this.rotating&&(s.bearing=interpolate(p,m,t)),this.pitching&&(s.pitch=interpolate(u,f,t));var n=s.unproject(b.add(y.mult(w(i))).mult(o));s.setLocationAtPoint(s.renderWorldCopies?n.wrap():n,d),this._fireMoveEvents(e)},function(){return a._easeToEnd(e)},t),this},e.prototype.isEasing=function(){return!!this._abortFn},e.prototype.isMoving=function(){return this.moving},e.prototype.stop=function(){return this._abortFn&&(this._abortFn(),this._finishEase()),this},e.prototype._ease=function(t,e,i){this._finishFn=e,this._abortFn=browser.timed(function(e){t.call(this,i.easing(e)),1===e&&this._finishEase()},i.animate===!1?0:i.duration,this)},e.prototype._finishEase=function(){delete this._abortFn;var t=this._finishFn;delete this._finishFn,t.call(this)},e.prototype._normalizeBearing=function(t,e){t=util.wrap(t,-180,180);var i=Math.abs(t-e);return Math.abs(t-360-e)<i&&(t-=360),Math.abs(t+360-e)<i&&(t+=360),t},e.prototype._normalizeCenter=function(t){var e=this.transform;if(e.renderWorldCopies&&!e.lngRange){var i=t.lng-e.center.lng;t.lng+=i>180?-360:i<-180?360:0}},e.prototype._smoothOutEasing=function(t){var e=util.ease;if(this._prevEase){var i=this._prevEase,o=(Date.now()-i.start)/i.duration,n=i.easing(o+.01)-i.easing(o),r=.27/Math.sqrt(n*n+1e-4)*.01,a=Math.sqrt(.0729-r*r);e=util.bezier(r,a,.25,1)}return this._prevEase={start:(new Date).getTime(),duration:t,easing:e},e},e}(Evented);module.exports=Camera;
  356 +},{"../geo/lng_lat":61,"../geo/lng_lat_bounds":62,"../style-spec/util/interpolate":122,"../util/browser":194,"../util/evented":202,"../util/util":215,"point-geometry":25}],175:[function(_dereq_,module,exports){
  357 +"use strict";var DOM=_dereq_("../../util/dom"),util=_dereq_("../../util/util"),config=_dereq_("../../util/config"),AttributionControl=function(t){this.options=t,util.bindAll(["_updateEditLink","_updateData","_updateCompact"],this)};AttributionControl.prototype.getDefaultPosition=function(){return"bottom-right"},AttributionControl.prototype.onAdd=function(t){var i=this.options&&this.options.compact;return this._map=t,this._container=DOM.create("div","mapboxgl-ctrl mapboxgl-ctrl-attrib"),i&&this._container.classList.add("mapboxgl-compact"),this._updateAttributions(),this._updateEditLink(),this._map.on("sourcedata",this._updateData),this._map.on("moveend",this._updateEditLink),void 0===i&&(this._map.on("resize",this._updateCompact),this._updateCompact()),this._container},AttributionControl.prototype.onRemove=function(){this._container.parentNode.removeChild(this._container),this._map.off("sourcedata",this._updateData),this._map.off("moveend",this._updateEditLink),this._map.off("resize",this._updateCompact),this._map=void 0},AttributionControl.prototype._updateEditLink=function(){this._editLink||(this._editLink=this._container.querySelector(".mapbox-improve-map"));var t=[{key:"owner",value:this.styleOwner},{key:"id",value:this.styleId},{key:"access_token",value:config.ACCESS_TOKEN}];if(this._editLink){var i=t.reduce(function(i,e,o){return void 0!==e.value&&(i+=e.key+"="+e.value+(o<t.length-1?"&":"")),i},"?");this._editLink.href="https://www.mapbox.com/feedback/"+i+(this._map._hash?this._map._hash.getHashString(!0):"")}},AttributionControl.prototype._updateData=function(t){t&&"metadata"===t.sourceDataType&&(this._updateAttributions(),this._updateEditLink())},AttributionControl.prototype._updateAttributions=function(){if(this._map.style){var t=[];if(this._map.style.stylesheet){var i=this._map.style.stylesheet;this.styleOwner=i.owner,this.styleId=i.id}var e=this._map.style.sourceCaches;for(var o in e){var n=e[o].getSource();n.attribution&&t.indexOf(n.attribution)<0&&t.push(n.attribution)}t.sort(function(t,i){return t.length-i.length}),t=t.filter(function(i,e){for(var o=e+1;o<t.length;o++)if(t[o].indexOf(i)>=0)return!1;return!0}),this._container.innerHTML=t.join(" | "),this._editLink=null}},AttributionControl.prototype._updateCompact=function(){var t=this._map.getCanvasContainer().offsetWidth<=640;this._container.classList[t?"add":"remove"]("mapboxgl-compact")},module.exports=AttributionControl;
  358 +},{"../../util/config":198,"../../util/dom":201,"../../util/util":215}],176:[function(_dereq_,module,exports){
  359 +"use strict";var DOM=_dereq_("../../util/dom"),util=_dereq_("../../util/util"),window=_dereq_("../../util/window"),FullscreenControl=function(){this._fullscreen=!1,util.bindAll(["_onClickFullscreen","_changeIcon"],this),"onfullscreenchange"in window.document?this._fullscreenchange="fullscreenchange":"onmozfullscreenchange"in window.document?this._fullscreenchange="mozfullscreenchange":"onwebkitfullscreenchange"in window.document?this._fullscreenchange="webkitfullscreenchange":"onmsfullscreenchange"in window.document&&(this._fullscreenchange="MSFullscreenChange")};FullscreenControl.prototype.onAdd=function(e){var n="mapboxgl-ctrl",l=this._container=DOM.create("div",n+" mapboxgl-ctrl-group"),t=this._fullscreenButton=DOM.create("button",n+"-icon "+n+"-fullscreen",this._container);return t.setAttribute("aria-label","Toggle fullscreen"),t.type="button",this._fullscreenButton.addEventListener("click",this._onClickFullscreen),this._mapContainer=e.getContainer(),window.document.addEventListener(this._fullscreenchange,this._changeIcon),l},FullscreenControl.prototype.onRemove=function(){this._container.parentNode.removeChild(this._container),this._map=null,window.document.removeEventListener(this._fullscreenchange,this._changeIcon)},FullscreenControl.prototype._isFullscreen=function(){return this._fullscreen},FullscreenControl.prototype._changeIcon=function(){var e=window.document.fullscreenElement||window.document.mozFullScreenElement||window.document.webkitFullscreenElement||window.document.msFullscreenElement;if(e===this._mapContainer!==this._fullscreen){this._fullscreen=!this._fullscreen;var n="mapboxgl-ctrl";this._fullscreenButton.classList.toggle(n+"-shrink"),this._fullscreenButton.classList.toggle(n+"-fullscreen")}},FullscreenControl.prototype._onClickFullscreen=function(){this._isFullscreen()?window.document.exitFullscreen?window.document.exitFullscreen():window.document.mozCancelFullScreen?window.document.mozCancelFullScreen():window.document.msExitFullscreen?window.document.msExitFullscreen():window.document.webkitCancelFullScreen&&window.document.webkitCancelFullScreen():this._mapContainer.requestFullscreen?this._mapContainer.requestFullscreen():this._mapContainer.mozRequestFullScreen?this._mapContainer.mozRequestFullScreen():this._mapContainer.msRequestFullscreen?this._mapContainer.msRequestFullscreen():this._mapContainer.webkitRequestFullscreen&&this._mapContainer.webkitRequestFullscreen()},module.exports=FullscreenControl;
  360 +},{"../../util/dom":201,"../../util/util":215,"../../util/window":196}],177:[function(_dereq_,module,exports){
  361 +"use strict";function checkGeolocationSupport(t){void 0!==supportsGeolocation?t(supportsGeolocation):void 0!==window.navigator.permissions?window.navigator.permissions.query({name:"geolocation"}).then(function(o){supportsGeolocation="denied"!==o.state,t(supportsGeolocation)}):(supportsGeolocation=!!window.navigator.geolocation,t(supportsGeolocation))}var Evented=_dereq_("../../util/evented"),DOM=_dereq_("../../util/dom"),window=_dereq_("../../util/window"),util=_dereq_("../../util/util"),defaultGeoPositionOptions={enableHighAccuracy:!1,timeout:6e3},className="mapboxgl-ctrl",supportsGeolocation,GeolocateControl=function(t){function o(o){t.call(this),this.options=o||{},util.bindAll(["_onSuccess","_onError","_finish","_setupUI"],this)}return t&&(o.__proto__=t),o.prototype=Object.create(t&&t.prototype),o.prototype.constructor=o,o.prototype.onAdd=function(t){return this._map=t,this._container=DOM.create("div",className+" "+className+"-group"),checkGeolocationSupport(this._setupUI),this._container},o.prototype.onRemove=function(){this._container.parentNode.removeChild(this._container),this._map=void 0},o.prototype._onSuccess=function(t){this._map.jumpTo({center:[t.coords.longitude,t.coords.latitude],zoom:17,bearing:0,pitch:0}),this.fire("geolocate",t),this._finish()},o.prototype._onError=function(t){this.fire("error",t),this._finish()},o.prototype._finish=function(){this._timeoutId&&clearTimeout(this._timeoutId),this._timeoutId=void 0},o.prototype._setupUI=function(t){t!==!1&&(this._container.addEventListener("contextmenu",function(t){return t.preventDefault()}),this._geolocateButton=DOM.create("button",className+"-icon "+className+"-geolocate",this._container),this._geolocateButton.type="button",this._geolocateButton.setAttribute("aria-label","Geolocate"),this.options.watchPosition&&this._geolocateButton.setAttribute("aria-pressed",!1),this._geolocateButton.addEventListener("click",this._onClickGeolocate.bind(this)))},o.prototype._onClickGeolocate=function(){var t=util.extend(defaultGeoPositionOptions,this.options&&this.options.positionOptions||{});this.options.watchPosition?void 0!==this._geolocationWatchID?(this._geolocateButton.classList.remove("mapboxgl-watching"),this._geolocateButton.setAttribute("aria-pressed",!1),window.navigator.geolocation.clearWatch(this._geolocationWatchID),this._geolocationWatchID=void 0):(this._geolocateButton.classList.add("mapboxgl-watching"),this._geolocateButton.setAttribute("aria-pressed",!0),this._geolocationWatchID=window.navigator.geolocation.watchPosition(this._onSuccess,this._onError,t)):(window.navigator.geolocation.getCurrentPosition(this._onSuccess,this._onError,t),this._timeoutId=setTimeout(this._finish,1e4))},o}(Evented);module.exports=GeolocateControl;
  362 +},{"../../util/dom":201,"../../util/evented":202,"../../util/util":215,"../../util/window":196}],178:[function(_dereq_,module,exports){
  363 +"use strict";var DOM=_dereq_("../../util/dom"),util=_dereq_("../../util/util"),LogoControl=function(){util.bindAll(["_updateLogo"],this)};LogoControl.prototype.onAdd=function(o){return this._map=o,this._container=DOM.create("div","mapboxgl-ctrl"),this._map.on("sourcedata",this._updateLogo),this._updateLogo(),this._container},LogoControl.prototype.onRemove=function(){this._container.parentNode.removeChild(this._container),this._map.off("sourcedata",this._updateLogo)},LogoControl.prototype.getDefaultPosition=function(){return"bottom-left"},LogoControl.prototype._updateLogo=function(o){if(o&&"metadata"===o.sourceDataType)if(!this._container.childNodes.length&&this._logoRequired()){var t=DOM.create("a","mapboxgl-ctrl-logo");t.target="_blank",t.href="https://www.mapbox.com/",t.setAttribute("aria-label","Mapbox logo"),this._container.appendChild(t),this._map.off("data",this._updateLogo)}else this._container.childNodes.length&&!this._logoRequired()&&this.onRemove()},LogoControl.prototype._logoRequired=function(){if(this._map.style){var o=this._map.style.sourceCaches;for(var t in o){var e=o[t].getSource();if(e.mapbox_logo)return!0}return!1}},module.exports=LogoControl;
  364 +},{"../../util/dom":201,"../../util/util":215}],179:[function(_dereq_,module,exports){
  365 +"use strict";function copyMouseEvent(t){return new window.MouseEvent(t.type,{button:2,buttons:2,bubbles:!0,cancelable:!0,detail:t.detail,view:t.view,screenX:t.screenX,screenY:t.screenY,clientX:t.clientX,clientY:t.clientY,movementX:t.movementX,movementY:t.movementY,ctrlKey:t.ctrlKey,shiftKey:t.shiftKey,altKey:t.altKey,metaKey:t.metaKey})}var DOM=_dereq_("../../util/dom"),window=_dereq_("../../util/window"),util=_dereq_("../../util/util"),className="mapboxgl-ctrl",NavigationControl=function(){util.bindAll(["_rotateCompassArrow"],this)};NavigationControl.prototype._rotateCompassArrow=function(){var t="rotate("+this._map.transform.angle*(180/Math.PI)+"deg)";this._compassArrow.style.transform=t},NavigationControl.prototype.onAdd=function(t){return this._map=t,this._container=DOM.create("div",className+" "+className+"-group",t.getContainer()),this._container.addEventListener("contextmenu",this._onContextMenu.bind(this)),this._zoomInButton=this._createButton(className+"-icon "+className+"-zoom-in","Zoom In",t.zoomIn.bind(t)),this._zoomOutButton=this._createButton(className+"-icon "+className+"-zoom-out","Zoom Out",t.zoomOut.bind(t)),this._compass=this._createButton(className+"-icon "+className+"-compass","Reset North",t.resetNorth.bind(t)),this._compassArrow=DOM.create("span",className+"-compass-arrow",this._compass),this._compass.addEventListener("mousedown",this._onCompassDown.bind(this)),this._onCompassMove=this._onCompassMove.bind(this),this._onCompassUp=this._onCompassUp.bind(this),this._map.on("rotate",this._rotateCompassArrow),this._rotateCompassArrow(),this._container},NavigationControl.prototype.onRemove=function(){this._container.parentNode.removeChild(this._container),this._map.off("rotate",this._rotateCompassArrow),this._map=void 0},NavigationControl.prototype._onContextMenu=function(t){t.preventDefault()},NavigationControl.prototype._onCompassDown=function(t){0===t.button&&(DOM.disableDrag(),window.document.addEventListener("mousemove",this._onCompassMove),window.document.addEventListener("mouseup",this._onCompassUp),this._map.getCanvasContainer().dispatchEvent(copyMouseEvent(t)),t.stopPropagation())},NavigationControl.prototype._onCompassMove=function(t){0===t.button&&(this._map.getCanvasContainer().dispatchEvent(copyMouseEvent(t)),t.stopPropagation())},NavigationControl.prototype._onCompassUp=function(t){0===t.button&&(window.document.removeEventListener("mousemove",this._onCompassMove),window.document.removeEventListener("mouseup",this._onCompassUp),DOM.enableDrag(),this._map.getCanvasContainer().dispatchEvent(copyMouseEvent(t)),t.stopPropagation())},NavigationControl.prototype._createButton=function(t,o,e){var n=DOM.create("button",t,this._container);return n.type="button",n.setAttribute("aria-label",o),n.addEventListener("click",function(){e()}),n},module.exports=NavigationControl;
  366 +},{"../../util/dom":201,"../../util/util":215,"../../util/window":196}],180:[function(_dereq_,module,exports){
  367 +"use strict";function updateScale(t,e,o){var n=o&&o.maxWidth||100,i=t._container.clientHeight/2,a=getDistance(t.unproject([0,i]),t.unproject([n,i]));if(o&&"imperial"===o.unit){var r=3.2808*a;if(r>5280){var l=r/5280;setScale(e,n,l,"mi")}else setScale(e,n,r,"ft")}else setScale(e,n,a,"m")}function setScale(t,e,o,n){var i=getRoundNum(o),a=i/o;"m"===n&&i>=1e3&&(i/=1e3,n="km"),t.style.width=e*a+"px",t.innerHTML=i+n}function getDistance(t,e){var o=6371e3,n=Math.PI/180,i=t.lat*n,a=e.lat*n,r=Math.sin(i)*Math.sin(a)+Math.cos(i)*Math.cos(a)*Math.cos((e.lng-t.lng)*n),l=o*Math.acos(Math.min(r,1));return l}function getRoundNum(t){var e=Math.pow(10,(""+Math.floor(t)).length-1),o=t/e;return o=o>=10?10:o>=5?5:o>=3?3:o>=2?2:1,e*o}var DOM=_dereq_("../../util/dom"),util=_dereq_("../../util/util"),ScaleControl=function(t){this.options=t,util.bindAll(["_onMove"],this)};ScaleControl.prototype.getDefaultPosition=function(){return"bottom-left"},ScaleControl.prototype._onMove=function(){updateScale(this._map,this._container,this.options)},ScaleControl.prototype.onAdd=function(t){return this._map=t,this._container=DOM.create("div","mapboxgl-ctrl mapboxgl-ctrl-scale",t.getContainer()),this._map.on("move",this._onMove),this._onMove(),this._container},ScaleControl.prototype.onRemove=function(){this._container.parentNode.removeChild(this._container),this._map.off("move",this._onMove),this._map=void 0},module.exports=ScaleControl;
  368 +},{"../../util/dom":201,"../../util/util":215}],181:[function(_dereq_,module,exports){
  369 +"use strict";var DOM=_dereq_("../../util/dom"),LngLatBounds=_dereq_("../../geo/lng_lat_bounds"),util=_dereq_("../../util/util"),window=_dereq_("../../util/window"),BoxZoomHandler=function(o){this._map=o,this._el=o.getCanvasContainer(),this._container=o.getContainer(),util.bindAll(["_onMouseDown","_onMouseMove","_onMouseUp","_onKeyDown"],this)};BoxZoomHandler.prototype.isEnabled=function(){return!!this._enabled},BoxZoomHandler.prototype.isActive=function(){return!!this._active},BoxZoomHandler.prototype.enable=function(){this.isEnabled()||(this._map.dragPan&&this._map.dragPan.disable(),this._el.addEventListener("mousedown",this._onMouseDown,!1),this._map.dragPan&&this._map.dragPan.enable(),this._enabled=!0)},BoxZoomHandler.prototype.disable=function(){this.isEnabled()&&(this._el.removeEventListener("mousedown",this._onMouseDown),this._enabled=!1)},BoxZoomHandler.prototype._onMouseDown=function(o){o.shiftKey&&0===o.button&&(window.document.addEventListener("mousemove",this._onMouseMove,!1),window.document.addEventListener("keydown",this._onKeyDown,!1),window.document.addEventListener("mouseup",this._onMouseUp,!1),DOM.disableDrag(),this._startPos=DOM.mousePos(this._el,o),this._active=!0)},BoxZoomHandler.prototype._onMouseMove=function(o){var e=this._startPos,t=DOM.mousePos(this._el,o);this._box||(this._box=DOM.create("div","mapboxgl-boxzoom",this._container),this._container.classList.add("mapboxgl-crosshair"),this._fireEvent("boxzoomstart",o));var n=Math.min(e.x,t.x),i=Math.max(e.x,t.x),s=Math.min(e.y,t.y),a=Math.max(e.y,t.y);DOM.setTransform(this._box,"translate("+n+"px,"+s+"px)"),this._box.style.width=i-n+"px",this._box.style.height=a-s+"px"},BoxZoomHandler.prototype._onMouseUp=function(o){if(0===o.button){var e=this._startPos,t=DOM.mousePos(this._el,o),n=(new LngLatBounds).extend(this._map.unproject(e)).extend(this._map.unproject(t));this._finish(),e.x===t.x&&e.y===t.y?this._fireEvent("boxzoomcancel",o):this._map.fitBounds(n,{linear:!0}).fire("boxzoomend",{originalEvent:o,boxZoomBounds:n})}},BoxZoomHandler.prototype._onKeyDown=function(o){27===o.keyCode&&(this._finish(),this._fireEvent("boxzoomcancel",o))},BoxZoomHandler.prototype._finish=function(){this._active=!1,window.document.removeEventListener("mousemove",this._onMouseMove,!1),window.document.removeEventListener("keydown",this._onKeyDown,!1),window.document.removeEventListener("mouseup",this._onMouseUp,!1),this._container.classList.remove("mapboxgl-crosshair"),this._box&&(this._box.parentNode.removeChild(this._box),this._box=null),DOM.enableDrag()},BoxZoomHandler.prototype._fireEvent=function(o,e){return this._map.fire(o,{originalEvent:e})},module.exports=BoxZoomHandler;
  370 +},{"../../geo/lng_lat_bounds":62,"../../util/dom":201,"../../util/util":215,"../../util/window":196}],182:[function(_dereq_,module,exports){
  371 +"use strict";var DoubleClickZoomHandler=function(o){this._map=o,this._onDblClick=this._onDblClick.bind(this)};DoubleClickZoomHandler.prototype.isEnabled=function(){return!!this._enabled},DoubleClickZoomHandler.prototype.enable=function(){this.isEnabled()||(this._map.on("dblclick",this._onDblClick),this._enabled=!0)},DoubleClickZoomHandler.prototype.disable=function(){this.isEnabled()&&(this._map.off("dblclick",this._onDblClick),this._enabled=!1)},DoubleClickZoomHandler.prototype._onDblClick=function(o){this._map.zoomTo(this._map.getZoom()+(o.originalEvent.shiftKey?-1:1),{around:o.lngLat},o)},module.exports=DoubleClickZoomHandler;
  372 +},{}],183:[function(_dereq_,module,exports){
  373 +"use strict";var DOM=_dereq_("../../util/dom"),util=_dereq_("../../util/util"),window=_dereq_("../../util/window"),inertiaLinearity=.3,inertiaEasing=util.bezier(0,0,inertiaLinearity,1),inertiaMaxSpeed=1400,inertiaDeceleration=2500,DragPanHandler=function(t){this._map=t,this._el=t.getCanvasContainer(),util.bindAll(["_onDown","_onMove","_onUp","_onTouchEnd","_onMouseUp"],this)};DragPanHandler.prototype.isEnabled=function(){return!!this._enabled},DragPanHandler.prototype.isActive=function(){return!!this._active},DragPanHandler.prototype.enable=function(){this.isEnabled()||(this._el.classList.add("mapboxgl-touch-drag-pan"),this._el.addEventListener("mousedown",this._onDown),this._el.addEventListener("touchstart",this._onDown),this._enabled=!0)},DragPanHandler.prototype.disable=function(){this.isEnabled()&&(this._el.classList.remove("mapboxgl-touch-drag-pan"),this._el.removeEventListener("mousedown",this._onDown),this._el.removeEventListener("touchstart",this._onDown),this._enabled=!1)},DragPanHandler.prototype._onDown=function(t){this._ignoreEvent(t)||this.isActive()||(t.touches?(window.document.addEventListener("touchmove",this._onMove),window.document.addEventListener("touchend",this._onTouchEnd)):(window.document.addEventListener("mousemove",this._onMove),window.document.addEventListener("mouseup",this._onMouseUp)),window.addEventListener("blur",this._onMouseUp),this._active=!1,this._startPos=this._pos=DOM.mousePos(this._el,t),this._inertia=[[Date.now(),this._pos]])},DragPanHandler.prototype._onMove=function(t){if(!this._ignoreEvent(t)){this.isActive()||(this._active=!0,this._map.moving=!0,this._fireEvent("dragstart",t),this._fireEvent("movestart",t));var e=DOM.mousePos(this._el,t),n=this._map;n.stop(),this._drainInertiaBuffer(),this._inertia.push([Date.now(),e]),n.transform.setLocationAtPoint(n.transform.pointLocation(this._pos),e),this._fireEvent("drag",t),this._fireEvent("move",t),this._pos=e,t.preventDefault()}},DragPanHandler.prototype._onUp=function(t){var e=this;if(this.isActive()){this._active=!1,this._fireEvent("dragend",t),this._drainInertiaBuffer();var n=function(){e._map.moving=!1,e._fireEvent("moveend",t)},i=this._inertia;if(i.length<2)return void n();var o=i[i.length-1],r=i[0],a=o[1].sub(r[1]),s=(o[0]-r[0])/1e3;if(0===s||o[1].equals(r[1]))return void n();var u=a.mult(inertiaLinearity/s),d=u.mag();d>inertiaMaxSpeed&&(d=inertiaMaxSpeed,u._unit()._mult(d));var h=d/(inertiaDeceleration*inertiaLinearity),v=u.mult(-h/2);this._map.panBy(v,{duration:1e3*h,easing:inertiaEasing,noMoveStart:!0},{originalEvent:t})}},DragPanHandler.prototype._onMouseUp=function(t){this._ignoreEvent(t)||(this._onUp(t),window.document.removeEventListener("mousemove",this._onMove),window.document.removeEventListener("mouseup",this._onMouseUp),window.removeEventListener("blur",this._onMouseUp))},DragPanHandler.prototype._onTouchEnd=function(t){this._ignoreEvent(t)||(this._onUp(t),window.document.removeEventListener("touchmove",this._onMove),window.document.removeEventListener("touchend",this._onTouchEnd))},DragPanHandler.prototype._fireEvent=function(t,e){return this._map.fire(t,{originalEvent:e})},DragPanHandler.prototype._ignoreEvent=function(t){var e=this._map;if(e.boxZoom&&e.boxZoom.isActive())return!0;if(e.dragRotate&&e.dragRotate.isActive())return!0;if(t.touches)return t.touches.length>1;if(t.ctrlKey)return!0;var n=1,i=0;return"mousemove"===t.type?t.buttons&0===n:t.button&&t.button!==i},DragPanHandler.prototype._drainInertiaBuffer=function(){for(var t=this._inertia,e=Date.now(),n=160;t.length>0&&e-t[0][0]>n;)t.shift()},module.exports=DragPanHandler;
  374 +},{"../../util/dom":201,"../../util/util":215,"../../util/window":196}],184:[function(_dereq_,module,exports){
  375 +"use strict";var DOM=_dereq_("../../util/dom"),util=_dereq_("../../util/util"),window=_dereq_("../../util/window"),inertiaLinearity=.25,inertiaEasing=util.bezier(0,0,inertiaLinearity,1),inertiaMaxSpeed=180,inertiaDeceleration=720,DragRotateHandler=function(t,e){this._map=t,this._el=t.getCanvasContainer(),this._bearingSnap=e.bearingSnap,this._pitchWithRotate=e.pitchWithRotate!==!1,util.bindAll(["_onDown","_onMove","_onUp"],this)};DragRotateHandler.prototype.isEnabled=function(){return!!this._enabled},DragRotateHandler.prototype.isActive=function(){return!!this._active},DragRotateHandler.prototype.enable=function(){this.isEnabled()||(this._el.addEventListener("mousedown",this._onDown),this._enabled=!0)},DragRotateHandler.prototype.disable=function(){this.isEnabled()&&(this._el.removeEventListener("mousedown",this._onDown),this._enabled=!1)},DragRotateHandler.prototype._onDown=function(t){this._ignoreEvent(t)||this.isActive()||(window.document.addEventListener("mousemove",this._onMove),window.document.addEventListener("mouseup",this._onUp),window.addEventListener("blur",this._onUp),this._active=!1,this._inertia=[[Date.now(),this._map.getBearing()]],this._startPos=this._pos=DOM.mousePos(this._el,t),this._center=this._map.transform.centerPoint,t.preventDefault())},DragRotateHandler.prototype._onMove=function(t){if(!this._ignoreEvent(t)){this.isActive()||(this._active=!0,this._map.moving=!0,this._fireEvent("rotatestart",t),this._fireEvent("movestart",t),this._pitchWithRotate&&this._fireEvent("pitchstart",t));var e=this._map;e.stop();var i=this._pos,n=DOM.mousePos(this._el,t),r=.8*(i.x-n.x),a=(i.y-n.y)*-.5,o=e.getBearing()-r,s=e.getPitch()-a,h=this._inertia,_=h[h.length-1];this._drainInertiaBuffer(),h.push([Date.now(),e._normalizeBearing(o,_[1])]),e.transform.bearing=o,this._pitchWithRotate&&(this._fireEvent("pitch",t),e.transform.pitch=s),this._fireEvent("rotate",t),this._fireEvent("move",t),this._pos=n}},DragRotateHandler.prototype._onUp=function(t){var e=this;if(!this._ignoreEvent(t)&&(window.document.removeEventListener("mousemove",this._onMove),window.document.removeEventListener("mouseup",this._onUp),window.removeEventListener("blur",this._onUp),this.isActive())){this._active=!1,this._fireEvent("rotateend",t),this._drainInertiaBuffer();var i=this._map,n=i.getBearing(),r=this._inertia,a=function(){Math.abs(n)<e._bearingSnap?i.resetNorth({noMoveStart:!0},{originalEvent:t}):(e._map.moving=!1,e._fireEvent("moveend",t)),e._pitchWithRotate&&e._fireEvent("pitchend",t)};if(r.length<2)return void a();var o=r[0],s=r[r.length-1],h=r[r.length-2],_=i._normalizeBearing(n,h[1]),v=s[1]-o[1],p=v<0?-1:1,d=(s[0]-o[0])/1e3;if(0===v||0===d)return void a();var u=Math.abs(v*(inertiaLinearity/d));u>inertiaMaxSpeed&&(u=inertiaMaxSpeed);var l=u/(inertiaDeceleration*inertiaLinearity),g=p*u*(l/2);_+=g,Math.abs(i._normalizeBearing(_,0))<this._bearingSnap&&(_=i._normalizeBearing(0,_)),i.rotateTo(_,{duration:1e3*l,easing:inertiaEasing,noMoveStart:!0},{originalEvent:t})}},DragRotateHandler.prototype._fireEvent=function(t,e){return this._map.fire(t,{originalEvent:e})},DragRotateHandler.prototype._ignoreEvent=function(t){var e=this._map;if(e.boxZoom&&e.boxZoom.isActive())return!0;if(e.dragPan&&e.dragPan.isActive())return!0;if(t.touches)return t.touches.length>1;var i=t.ctrlKey?1:2,n=t.ctrlKey?0:2,r=t.button;return"undefined"!=typeof InstallTrigger&&2===t.button&&t.ctrlKey&&window.navigator.platform.toUpperCase().indexOf("MAC")>=0&&(r=0),"mousemove"===t.type?t.buttons&0===i:!this.isActive()&&r!==n},DragRotateHandler.prototype._drainInertiaBuffer=function(){for(var t=this._inertia,e=Date.now(),i=160;t.length>0&&e-t[0][0]>i;)t.shift()},module.exports=DragRotateHandler;
  376 +},{"../../util/dom":201,"../../util/util":215,"../../util/window":196}],185:[function(_dereq_,module,exports){
  377 +"use strict";function easeOut(e){return e*(2-e)}var panStep=100,bearingStep=15,pitchStep=10,KeyboardHandler=function(e){this._map=e,this._el=e.getCanvasContainer(),this._onKeyDown=this._onKeyDown.bind(this)};KeyboardHandler.prototype.isEnabled=function(){return!!this._enabled},KeyboardHandler.prototype.enable=function(){this.isEnabled()||(this._el.addEventListener("keydown",this._onKeyDown,!1),this._enabled=!0)},KeyboardHandler.prototype.disable=function(){this.isEnabled()&&(this._el.removeEventListener("keydown",this._onKeyDown),this._enabled=!1)},KeyboardHandler.prototype._onKeyDown=function(e){if(!(e.altKey||e.ctrlKey||e.metaKey)){var t=0,a=0,n=0,r=0,i=0;switch(e.keyCode){case 61:case 107:case 171:case 187:t=1;break;case 189:case 109:case 173:t=-1;break;case 37:e.shiftKey?a=-1:(e.preventDefault(),r=-1);break;case 39:e.shiftKey?a=1:(e.preventDefault(),r=1);break;case 38:e.shiftKey?n=1:(e.preventDefault(),i=-1);break;case 40:e.shiftKey?n=-1:(i=1,e.preventDefault());break;default:return}var s=this._map,o=s.getZoom(),d={duration:300,delayEndEvents:500,easing:easeOut,zoom:t?Math.round(o)+t*(e.shiftKey?2:1):o,bearing:s.getBearing()+a*bearingStep,pitch:s.getPitch()+n*pitchStep,offset:[-r*panStep,-i*panStep],center:s.getCenter()};s.easeTo(d,{originalEvent:e})}},module.exports=KeyboardHandler;
  378 +},{}],186:[function(_dereq_,module,exports){
  379 +"use strict";var DOM=_dereq_("../../util/dom"),util=_dereq_("../../util/util"),browser=_dereq_("../../util/browser"),window=_dereq_("../../util/window"),ua=window.navigator.userAgent.toLowerCase(),firefox=ua.indexOf("firefox")!==-1,safari=ua.indexOf("safari")!==-1&&ua.indexOf("chrom")===-1,ScrollZoomHandler=function(e){this._map=e,this._el=e.getCanvasContainer(),util.bindAll(["_onWheel","_onTimeout"],this)};ScrollZoomHandler.prototype.isEnabled=function(){return!!this._enabled},ScrollZoomHandler.prototype.enable=function(e){this.isEnabled()||(this._el.addEventListener("wheel",this._onWheel,!1),this._el.addEventListener("mousewheel",this._onWheel,!1),this._enabled=!0,this._aroundCenter=e&&"center"===e.around)},ScrollZoomHandler.prototype.disable=function(){this.isEnabled()&&(this._el.removeEventListener("wheel",this._onWheel),this._el.removeEventListener("mousewheel",this._onWheel),this._enabled=!1)},ScrollZoomHandler.prototype._onWheel=function(e){var t;"wheel"===e.type?(t=e.deltaY,firefox&&e.deltaMode===window.WheelEvent.DOM_DELTA_PIXEL&&(t/=browser.devicePixelRatio),e.deltaMode===window.WheelEvent.DOM_DELTA_LINE&&(t*=40)):"mousewheel"===e.type&&(t=-e.wheelDeltaY,safari&&(t/=3));var o=browser.now(),i=o-(this._time||0);this._pos=DOM.mousePos(this._el,e),this._time=o,0!==t&&t%4.000244140625===0?this._type="wheel":0!==t&&Math.abs(t)<4?this._type="trackpad":i>400?(this._type=null,this._lastValue=t,this._timeout=setTimeout(this._onTimeout,40)):this._type||(this._type=Math.abs(i*t)<200?"trackpad":"wheel",this._timeout&&(clearTimeout(this._timeout),this._timeout=null,t+=this._lastValue)),e.shiftKey&&t&&(t/=4),this._type&&this._zoom(-t,e),e.preventDefault()},ScrollZoomHandler.prototype._onTimeout=function(){this._type="wheel",this._zoom(-this._lastValue)},ScrollZoomHandler.prototype._zoom=function(e,t){if(0!==e){var o=this._map,i=2/(1+Math.exp(-Math.abs(e/100)));e<0&&0!==i&&(i=1/i);var l=o.ease?o.ease.to:o.transform.scale,s=o.transform.scaleZoom(l*i);o.zoomTo(s,{duration:"wheel"===this._type?200:0,around:this._aroundCenter?o.getCenter():o.unproject(this._pos),delayEndEvents:200,smoothEasing:!0},{originalEvent:t})}},module.exports=ScrollZoomHandler;
  380 +},{"../../util/browser":194,"../../util/dom":201,"../../util/util":215,"../../util/window":196}],187:[function(_dereq_,module,exports){
  381 +"use strict";var DOM=_dereq_("../../util/dom"),util=_dereq_("../../util/util"),window=_dereq_("../../util/window"),inertiaLinearity=.15,inertiaEasing=util.bezier(0,0,inertiaLinearity,1),inertiaDeceleration=12,inertiaMaxSpeed=2.5,significantScaleThreshold=.15,significantRotateThreshold=4,TouchZoomRotateHandler=function(t){this._map=t,this._el=t.getCanvasContainer(),util.bindAll(["_onStart","_onMove","_onEnd"],this)};TouchZoomRotateHandler.prototype.isEnabled=function(){return!!this._enabled},TouchZoomRotateHandler.prototype.enable=function(t){this.isEnabled()||(this._el.classList.add("mapboxgl-touch-zoom-rotate"),this._el.addEventListener("touchstart",this._onStart,!1),this._enabled=!0,this._aroundCenter=t&&"center"===t.around)},TouchZoomRotateHandler.prototype.disable=function(){this.isEnabled()&&(this._el.classList.remove("mapboxgl-touch-zoom-rotate"),this._el.removeEventListener("touchstart",this._onStart),this._enabled=!1)},TouchZoomRotateHandler.prototype.disableRotation=function(){this._rotationDisabled=!0},TouchZoomRotateHandler.prototype.enableRotation=function(){this._rotationDisabled=!1},TouchZoomRotateHandler.prototype._onStart=function(t){if(2===t.touches.length){var e=DOM.mousePos(this._el,t.touches[0]),o=DOM.mousePos(this._el,t.touches[1]);this._startVec=e.sub(o),this._startScale=this._map.transform.scale,this._startBearing=this._map.transform.bearing,this._gestureIntent=void 0,this._inertia=[],window.document.addEventListener("touchmove",this._onMove,!1),window.document.addEventListener("touchend",this._onEnd,!1)}},TouchZoomRotateHandler.prototype._onMove=function(t){if(2===t.touches.length){var e=DOM.mousePos(this._el,t.touches[0]),o=DOM.mousePos(this._el,t.touches[1]),i=e.add(o).div(2),n=e.sub(o),a=n.mag()/this._startVec.mag(),r=this._rotationDisabled?0:180*n.angleWith(this._startVec)/Math.PI,s=this._map;if(this._gestureIntent){var h={duration:0,around:s.unproject(i)};"rotate"===this._gestureIntent&&(h.bearing=this._startBearing+r),"zoom"!==this._gestureIntent&&"rotate"!==this._gestureIntent||(h.zoom=s.transform.scaleZoom(this._startScale*a)),s.stop(),this._drainInertiaBuffer(),this._inertia.push([Date.now(),a,i]),s.easeTo(h,{originalEvent:t})}else{var u=Math.abs(1-a)>significantScaleThreshold,l=Math.abs(r)>significantRotateThreshold;l?this._gestureIntent="rotate":u&&(this._gestureIntent="zoom"),this._gestureIntent&&(this._startVec=n,this._startScale=s.transform.scale,this._startBearing=s.transform.bearing)}t.preventDefault()}},TouchZoomRotateHandler.prototype._onEnd=function(t){window.document.removeEventListener("touchmove",this._onMove),window.document.removeEventListener("touchend",this._onEnd),this._drainInertiaBuffer();var e=this._inertia,o=this._map;if(e.length<2)return void o.snapToNorth({},{originalEvent:t});var i=e[e.length-1],n=e[0],a=o.transform.scaleZoom(this._startScale*i[1]),r=o.transform.scaleZoom(this._startScale*n[1]),s=a-r,h=(i[0]-n[0])/1e3,u=i[2];if(0===h||a===r)return void o.snapToNorth({},{originalEvent:t});var l=s*inertiaLinearity/h;Math.abs(l)>inertiaMaxSpeed&&(l=l>0?inertiaMaxSpeed:-inertiaMaxSpeed);var d=1e3*Math.abs(l/(inertiaDeceleration*inertiaLinearity)),c=a+l*d/2e3;c<0&&(c=0),o.easeTo({zoom:c,duration:d,easing:inertiaEasing,around:this._aroundCenter?o.getCenter():o.unproject(u)},{originalEvent:t})},TouchZoomRotateHandler.prototype._drainInertiaBuffer=function(){for(var t=this._inertia,e=Date.now(),o=160;t.length>2&&e-t[0][0]>o;)t.shift()},module.exports=TouchZoomRotateHandler;
  382 +},{"../../util/dom":201,"../../util/util":215,"../../util/window":196}],188:[function(_dereq_,module,exports){
  383 +"use strict";var util=_dereq_("../util/util"),window=_dereq_("../util/window"),Hash=function(){util.bindAll(["_onHashChange","_updateHash"],this)};Hash.prototype.addTo=function(t){return this._map=t,window.addEventListener("hashchange",this._onHashChange,!1),this._map.on("moveend",this._updateHash),this},Hash.prototype.remove=function(){return window.removeEventListener("hashchange",this._onHashChange,!1),this._map.off("moveend",this._updateHash),delete this._map,this},Hash.prototype.getHashString=function(t){var a=this._map.getCenter(),h=Math.round(100*this._map.getZoom())/100,e=Math.max(0,Math.ceil(Math.log(h)/Math.LN2)),n=Math.round(a.lng*Math.pow(10,e))/Math.pow(10,e),o=Math.round(a.lat*Math.pow(10,e))/Math.pow(10,e),i=this._map.getBearing(),s=this._map.getPitch(),r="";return r+=t?"#/"+n+"/"+o+"/"+h:"#"+h+"/"+o+"/"+n,(i||s)&&(r+="/"+Math.round(10*i)/10),s&&(r+="/"+Math.round(s)),r},Hash.prototype._onHashChange=function(){var t=window.location.hash.replace("#","").split("/");return t.length>=3&&(this._map.jumpTo({center:[+t[2],+t[1]],zoom:+t[0],bearing:+(t[3]||0),pitch:+(t[4]||0)}),!0)},Hash.prototype._updateHash=function(){var t=this.getHashString();window.history.replaceState("","",t)},module.exports=Hash;
  384 +},{"../util/util":215,"../util/window":196}],189:[function(_dereq_,module,exports){
  385 +"use strict";function removeNode(t){t.parentNode&&t.parentNode.removeChild(t)}var util=_dereq_("../util/util"),browser=_dereq_("../util/browser"),window=_dereq_("../util/window"),DOM=_dereq_("../util/dom"),ajax=_dereq_("../util/ajax"),Style=_dereq_("../style/style"),AnimationLoop=_dereq_("../style/animation_loop"),Painter=_dereq_("../render/painter"),Transform=_dereq_("../geo/transform"),Hash=_dereq_("./hash"),bindHandlers=_dereq_("./bind_handlers"),Camera=_dereq_("./camera"),LngLat=_dereq_("../geo/lng_lat"),LngLatBounds=_dereq_("../geo/lng_lat_bounds"),Point=_dereq_("point-geometry"),AttributionControl=_dereq_("./control/attribution_control"),LogoControl=_dereq_("./control/logo_control"),isSupported=_dereq_("mapbox-gl-supported"),defaultMinZoom=0,defaultMaxZoom=22,defaultOptions={center:[0,0],zoom:0,bearing:0,pitch:0,minZoom:defaultMinZoom,maxZoom:defaultMaxZoom,interactive:!0,scrollZoom:!0,boxZoom:!0,dragRotate:!0,dragPan:!0,keyboard:!0,doubleClickZoom:!0,touchZoomRotate:!0,bearingSnap:7,hash:!1,attributionControl:!0,failIfMajorPerformanceCaveat:!1,preserveDrawingBuffer:!1,trackResize:!0,renderWorldCopies:!0,refreshExpiredTiles:!0},Map=function(t){function e(e){var o=this;if(e=util.extend({},defaultOptions,e),null!=e.minZoom&&null!=e.maxZoom&&e.minZoom>e.maxZoom)throw new Error("maxZoom must be greater than minZoom");var i=new Transform(e.minZoom,e.maxZoom,e.renderWorldCopies);if(t.call(this,i,e),this._interactive=e.interactive,this._failIfMajorPerformanceCaveat=e.failIfMajorPerformanceCaveat,this._preserveDrawingBuffer=e.preserveDrawingBuffer,this._trackResize=e.trackResize,this._bearingSnap=e.bearingSnap,this._refreshExpiredTiles=e.refreshExpiredTiles,"string"==typeof e.container){if(this._container=window.document.getElementById(e.container),!this._container)throw new Error("Container '"+e.container+"' not found.")}else this._container=e.container;this.animationLoop=new AnimationLoop,e.maxBounds&&this.setMaxBounds(e.maxBounds),util.bindAll(["_onWindowOnline","_onWindowResize","_contextLost","_contextRestored","_update","_render","_onData","_onDataLoading"],this),this._setupContainer(),this._setupPainter(),this.on("move",this._update.bind(this,!1)),this.on("zoom",this._update.bind(this,!0)),this.on("moveend",function(){o.animationLoop.set(300),o._rerender()}),"undefined"!=typeof window&&(window.addEventListener("online",this._onWindowOnline,!1),window.addEventListener("resize",this._onWindowResize,!1)),bindHandlers(this,e),this._hash=e.hash&&(new Hash).addTo(this),this._hash&&this._hash._onHashChange()||this.jumpTo({center:e.center,zoom:e.zoom,bearing:e.bearing,pitch:e.pitch}),this._classes=[],this.resize(),e.classes&&this.setClasses(e.classes),e.style&&this.setStyle(e.style),e.attributionControl&&this.addControl(new AttributionControl),this.addControl(new LogoControl,e.logoPosition),this.on("style.load",function(){this.transform.unmodified&&this.jumpTo(this.style.stylesheet),this.style.update(this._classes,{transition:!1})}),this.on("data",this._onData),this.on("dataloading",this._onDataLoading)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var o={showTileBoundaries:{},showCollisionBoxes:{},showOverdrawInspector:{},repaint:{},vertices:{}};return e.prototype.addControl=function(t,e){void 0===e&&t.getDefaultPosition&&(e=t.getDefaultPosition()),void 0===e&&(e="top-right");var o=t.onAdd(this),i=this._controlPositions[e];return e.indexOf("bottom")!==-1?i.insertBefore(o,i.firstChild):i.appendChild(o),this},e.prototype.removeControl=function(t){return t.onRemove(this),this},e.prototype.addClass=function(t,e){return util.warnOnce("Style classes are deprecated and will be removed in an upcoming release of Mapbox GL JS."),this._classes.indexOf(t)>=0||""===t?this:(this._classes.push(t),this._classOptions=e,this.style&&this.style.updateClasses(),this._update(!0))},e.prototype.removeClass=function(t,e){util.warnOnce("Style classes are deprecated and will be removed in an upcoming release of Mapbox GL JS.");var o=this._classes.indexOf(t);return o<0||""===t?this:(this._classes.splice(o,1),this._classOptions=e,this.style&&this.style.updateClasses(),this._update(!0))},e.prototype.setClasses=function(t,e){util.warnOnce("Style classes are deprecated and will be removed in an upcoming release of Mapbox GL JS.");for(var o={},i=0;i<t.length;i++)""!==t[i]&&(o[t[i]]=!0);return this._classes=Object.keys(o),this._classOptions=e,this.style&&this.style.updateClasses(),this._update(!0)},e.prototype.hasClass=function(t){return util.warnOnce("Style classes are deprecated and will be removed in an upcoming release of Mapbox GL JS."),this._classes.indexOf(t)>=0},e.prototype.getClasses=function(){return util.warnOnce("Style classes are deprecated and will be removed in an upcoming release of Mapbox GL JS."),this._classes},e.prototype.resize=function(){var t=this._containerDimensions(),e=t[0],o=t[1];return this._resizeCanvas(e,o),this.transform.resize(e,o),this.painter.resize(e,o),this.fire("movestart").fire("move").fire("resize").fire("moveend")},e.prototype.getBounds=function(){var t=new LngLatBounds(this.transform.pointLocation(new Point(0,this.transform.height)),this.transform.pointLocation(new Point(this.transform.width,0)));return(this.transform.angle||this.transform.pitch)&&(t.extend(this.transform.pointLocation(new Point(this.transform.size.x,0))),t.extend(this.transform.pointLocation(new Point(0,this.transform.size.y)))),t},e.prototype.setMaxBounds=function(t){if(t){var e=LngLatBounds.convert(t);this.transform.lngRange=[e.getWest(),e.getEast()],this.transform.latRange=[e.getSouth(),e.getNorth()],this.transform._constrain(),this._update()}else null!==t&&void 0!==t||(this.transform.lngRange=[],this.transform.latRange=[],this._update());return this},e.prototype.setMinZoom=function(t){if(t=null===t||void 0===t?defaultMinZoom:t,t>=defaultMinZoom&&t<=this.transform.maxZoom)return this.transform.minZoom=t,this._update(),this.getZoom()<t&&this.setZoom(t),this;throw new Error("minZoom must be between "+defaultMinZoom+" and the current maxZoom, inclusive")},e.prototype.getMinZoom=function(){return this.transform.minZoom},e.prototype.setMaxZoom=function(t){if(t=null===t||void 0===t?defaultMaxZoom:t,t>=this.transform.minZoom)return this.transform.maxZoom=t,this._update(),this.getZoom()>t&&this.setZoom(t),this;throw new Error("maxZoom must be greater than the current minZoom")},e.prototype.getMaxZoom=function(){return this.transform.maxZoom},e.prototype.project=function(t){return this.transform.locationPoint(LngLat.convert(t))},e.prototype.unproject=function(t){return this.transform.pointLocation(Point.convert(t))},e.prototype.on=function(e,o,i){var r=this;if(void 0===i)return t.prototype.on.call(this,e,o);var s=function(){if("mouseenter"===e||"mouseover"===e){var t=!1,s=function(s){var n=r.queryRenderedFeatures(s.point,{layers:[o]});n.length?t||(t=!0,i.call(r,util.extend({features:n},s,{type:e}))):t=!1},n=function(){t=!1};return{layer:o,listener:i,delegates:{mousemove:s,mouseout:n}}}if("mouseleave"===e||"mouseout"===e){var a=!1,h=function(t){var s=r.queryRenderedFeatures(t.point,{layers:[o]});s.length?a=!0:a&&(a=!1,i.call(r,util.extend({},t,{type:e})))},l=function(t){a&&(a=!1,i.call(r,util.extend({},t,{type:e})))};return{layer:o,listener:i,delegates:{mousemove:h,mouseout:l}}}var u=function(t){var e=r.queryRenderedFeatures(t.point,{layers:[o]});e.length&&i.call(r,util.extend({features:e},t))};return{layer:o,listener:i,delegates:(d={},d[e]=u,d)};var d}();this._delegatedListeners=this._delegatedListeners||{},this._delegatedListeners[e]=this._delegatedListeners[e]||[],this._delegatedListeners[e].push(s);for(var n in s.delegates)r.on(n,s.delegates[n]);return this},e.prototype.off=function(e,o,i){var r=this;if(void 0===i)return t.prototype.off.call(this,e,o);if(this._delegatedListeners&&this._delegatedListeners[e])for(var s=this._delegatedListeners[e],n=0;n<s.length;n++){var a=s[n];if(a.layer===o&&a.listener===i){for(var h in a.delegates)r.off(h,a.delegates[h]);return s.splice(n,1),r}}},e.prototype.queryRenderedFeatures=function(){function t(t){return t instanceof Point||Array.isArray(t)}var e,o={};return 2===arguments.length?(e=arguments[0],o=arguments[1]):1===arguments.length&&t(arguments[0])?e=arguments[0]:1===arguments.length&&(o=arguments[0]),this.style?this.style.queryRenderedFeatures(this._makeQueryGeometry(e),o,this.transform.zoom,this.transform.angle):[]},e.prototype._makeQueryGeometry=function(t){var e=this;void 0===t&&(t=[Point.convert([0,0]),Point.convert([this.transform.width,this.transform.height])]);var o,i=t instanceof Point||"number"==typeof t[0];if(i){var r=Point.convert(t);o=[r]}else{var s=[Point.convert(t[0]),Point.convert(t[1])];o=[s[0],new Point(s[1].x,s[0].y),s[1],new Point(s[0].x,s[1].y),s[0]]}return o=o.map(function(t){return e.transform.pointCoordinate(t)})},e.prototype.querySourceFeatures=function(t,e){return this.style.querySourceFeatures(t,e)},e.prototype.setStyle=function(t,e){var o=(!e||e.diff!==!1)&&this.style&&t&&!(t instanceof Style)&&"string"!=typeof t;if(o)try{return this.style.setState(t)&&this._update(!0),this}catch(t){util.warnOnce("Unable to perform style diff: "+(t.message||t.error||t)+". Rebuilding the style from scratch.")}return this.style&&(this.style.setEventedParent(null),this.style._remove(),this.off("rotate",this.style._redoPlacement),this.off("pitch",this.style._redoPlacement),this.off("move",this.style._redoPlacement)),t?(t instanceof Style?this.style=t:this.style=new Style(t,this),this.style.setEventedParent(this,{style:this.style}),this.on("rotate",this.style._redoPlacement),this.on("pitch",this.style._redoPlacement),this.on("move",this.style._redoPlacement),this):(this.style=null,this)},e.prototype.getStyle=function(){if(this.style)return this.style.serialize()},e.prototype.isStyleLoaded=function(){return this.style?this.style.loaded():util.warnOnce("There is no style added to the map.")},e.prototype.addSource=function(t,e){return this.style.addSource(t,e),this._update(!0),this},e.prototype.isSourceLoaded=function(t){var e=this.style&&this.style.sourceCaches[t];return void 0===e?void this.fire("error",{error:new Error("There is no source with ID '"+t+"'")}):e.loaded()},e.prototype.areTilesLoaded=function(){var t=this.style&&this.style.sourceCaches;for(var e in t){var o=t[e],i=o._tiles;for(var r in i){var s=i[r];if("loaded"!==s.state&&"errored"!==s.state)return!1}}return!0},e.prototype.addSourceType=function(t,e,o){return this.style.addSourceType(t,e,o)},e.prototype.removeSource=function(t){return this.style.removeSource(t),this._update(!0),this},e.prototype.getSource=function(t){return this.style.getSource(t)},e.prototype.addImage=function(t,e,o){this.style.spriteAtlas.addImage(t,e,o)},e.prototype.removeImage=function(t){this.style.spriteAtlas.removeImage(t)},e.prototype.loadImage=function(t,e){ajax.getImage(t,e)},e.prototype.addLayer=function(t,e){return this.style.addLayer(t,e),this._update(!0),this},e.prototype.moveLayer=function(t,e){return this.style.moveLayer(t,e),this._update(!0),this},e.prototype.removeLayer=function(t){return this.style.removeLayer(t),this._update(!0),this},e.prototype.getLayer=function(t){return this.style.getLayer(t)},e.prototype.setFilter=function(t,e){return this.style.setFilter(t,e),this._update(!0),this},e.prototype.setLayerZoomRange=function(t,e,o){return this.style.setLayerZoomRange(t,e,o),this._update(!0),this},e.prototype.getFilter=function(t){return this.style.getFilter(t)},e.prototype.setPaintProperty=function(t,e,o,i){return this.style.setPaintProperty(t,e,o,i),this._update(!0),this},e.prototype.getPaintProperty=function(t,e,o){return this.style.getPaintProperty(t,e,o)},e.prototype.setLayoutProperty=function(t,e,o){return this.style.setLayoutProperty(t,e,o),this._update(!0),this},e.prototype.getLayoutProperty=function(t,e){return this.style.getLayoutProperty(t,e)},e.prototype.setLight=function(t){return this.style.setLight(t),this._update(!0),this},e.prototype.getLight=function(){return this.style.getLight()},e.prototype.getContainer=function(){return this._container},e.prototype.getCanvasContainer=function(){return this._canvasContainer},e.prototype.getCanvas=function(){return this._canvas},e.prototype._containerDimensions=function(){var t=0,e=0;return this._container&&(t=this._container.offsetWidth||400,e=this._container.offsetHeight||300),[t,e]},e.prototype._setupContainer=function(){var t=this._container;t.classList.add("mapboxgl-map");var e=this._canvasContainer=DOM.create("div","mapboxgl-canvas-container",t);this._interactive&&e.classList.add("mapboxgl-interactive"),this._canvas=DOM.create("canvas","mapboxgl-canvas",e),this._canvas.style.position="absolute",this._canvas.addEventListener("webglcontextlost",this._contextLost,!1),this._canvas.addEventListener("webglcontextrestored",this._contextRestored,!1),this._canvas.setAttribute("tabindex",0),this._canvas.setAttribute("aria-label","Map");var o=this._containerDimensions();this._resizeCanvas(o[0],o[1]);var i=this._controlContainer=DOM.create("div","mapboxgl-control-container",t),r=this._controlPositions={};["top-left","top-right","bottom-left","bottom-right"].forEach(function(t){r[t]=DOM.create("div","mapboxgl-ctrl-"+t,i)})},e.prototype._resizeCanvas=function(t,e){var o=window.devicePixelRatio||1;this._canvas.width=o*t,this._canvas.height=o*e,this._canvas.style.width=t+"px",this._canvas.style.height=e+"px"},e.prototype._setupPainter=function(){var t=util.extend({failIfMajorPerformanceCaveat:this._failIfMajorPerformanceCaveat,preserveDrawingBuffer:this._preserveDrawingBuffer},isSupported.webGLContextAttributes),e=this._canvas.getContext("webgl",t)||this._canvas.getContext("experimental-webgl",t);return e?void(this.painter=new Painter(e,this.transform)):void this.fire("error",{error:new Error("Failed to initialize WebGL")})},e.prototype._contextLost=function(t){t.preventDefault(),this._frameId&&(browser.cancelFrame(this._frameId),this._frameId=null),this.fire("webglcontextlost",{originalEvent:t})},e.prototype._contextRestored=function(t){this._setupPainter(),this.resize(),this._update(),this.fire("webglcontextrestored",{originalEvent:t})},e.prototype.loaded=function(){return!this._styleDirty&&!this._sourcesDirty&&!(!this.style||!this.style.loaded())},e.prototype._update=function(t){return this.style?(this._styleDirty=this._styleDirty||t,this._sourcesDirty=!0,this._rerender(),this):this},e.prototype._render=function(){return this.style&&this._styleDirty&&(this._styleDirty=!1,this.style.update(this._classes,this._classOptions),this._classOptions=null,this.style._recalculate(this.transform.zoom)),this.style&&this._sourcesDirty&&(this._sourcesDirty=!1,this.style._updateSources(this.transform)),this.painter.render(this.style,{showTileBoundaries:this.showTileBoundaries,showOverdrawInspector:this._showOverdrawInspector,rotating:this.rotating,zooming:this.zooming}),this.fire("render"),this.loaded()&&!this._loaded&&(this._loaded=!0,this.fire("load")),this._frameId=null,this.animationLoop.stopped()||(this._styleDirty=!0),(this._sourcesDirty||this._repaint||this._styleDirty)&&this._rerender(),this},e.prototype.remove=function(){this._hash&&this._hash.remove(),browser.cancelFrame(this._frameId),this._frameId=null,this.setStyle(null),"undefined"!=typeof window&&(window.removeEventListener("resize",this._onWindowResize,!1),window.removeEventListener("online",this._onWindowOnline,!1));var t=this.painter.gl.getExtension("WEBGL_lose_context");t&&t.loseContext(),removeNode(this._canvasContainer),removeNode(this._controlContainer),this._container.classList.remove("mapboxgl-map"),this.fire("remove")},e.prototype._rerender=function(){this.style&&!this._frameId&&(this._frameId=browser.frame(this._render))},e.prototype._onWindowOnline=function(){this._update()},e.prototype._onWindowResize=function(){this._trackResize&&this.stop().resize()._update()},o.showTileBoundaries.get=function(){return!!this._showTileBoundaries},o.showTileBoundaries.set=function(t){this._showTileBoundaries!==t&&(this._showTileBoundaries=t,this._update())},o.showCollisionBoxes.get=function(){return!!this._showCollisionBoxes},o.showCollisionBoxes.set=function(t){this._showCollisionBoxes!==t&&(this._showCollisionBoxes=t,this.style._redoPlacement())},o.showOverdrawInspector.get=function(){return!!this._showOverdrawInspector},o.showOverdrawInspector.set=function(t){this._showOverdrawInspector!==t&&(this._showOverdrawInspector=t,this._update())},o.repaint.get=function(){return!!this._repaint},o.repaint.set=function(t){this._repaint=t,this._update()},o.vertices.get=function(){return!!this._vertices},o.vertices.set=function(t){this._vertices=t,this._update()},e.prototype._onData=function(t){this._update("style"===t.dataType),this.fire(t.dataType+"data",t)},e.prototype._onDataLoading=function(t){this.fire(t.dataType+"dataloading",t)},Object.defineProperties(e.prototype,o),e}(Camera);module.exports=Map;
  386 +},{"../geo/lng_lat":61,"../geo/lng_lat_bounds":62,"../geo/transform":63,"../render/painter":76,"../style/animation_loop":145,"../style/style":148,"../util/ajax":193,"../util/browser":194,"../util/dom":201,"../util/util":215,"../util/window":196,"./bind_handlers":173,"./camera":174,"./control/attribution_control":175,"./control/logo_control":178,"./hash":188,"mapbox-gl-supported":22,"point-geometry":25}],190:[function(_dereq_,module,exports){
  387 +"use strict";var DOM=_dereq_("../util/dom"),LngLat=_dereq_("../geo/lng_lat"),Point=_dereq_("point-geometry"),smartWrap=_dereq_("../util/smart_wrap"),Marker=function(t,e){this._offset=Point.convert(e&&e.offset||[0,0]),this._update=this._update.bind(this),this._onMapClick=this._onMapClick.bind(this),t||(t=DOM.create("div")),t.classList.add("mapboxgl-marker"),this._element=t,this._popup=null};Marker.prototype.addTo=function(t){return this.remove(),this._map=t,t.getCanvasContainer().appendChild(this._element),t.on("move",this._update),t.on("moveend",this._update),this._update(),this._map.on("click",this._onMapClick),this},Marker.prototype.remove=function(){return this._map&&(this._map.off("click",this._onMapClick),this._map.off("move",this._update),this._map.off("moveend",this._update),this._map=null),DOM.remove(this._element),this._popup&&this._popup.remove(),this},Marker.prototype.getLngLat=function(){return this._lngLat},Marker.prototype.setLngLat=function(t){return this._lngLat=LngLat.convert(t),this._pos=null,this._popup&&this._popup.setLngLat(this._lngLat),this._update(),this},Marker.prototype.getElement=function(){return this._element},Marker.prototype.setPopup=function(t){return this._popup&&(this._popup.remove(),this._popup=null),t&&(this._popup=t,this._popup.setLngLat(this._lngLat)),this},Marker.prototype._onMapClick=function(t){var e=t.originalEvent.target,p=this._element;this._popup&&(e===p||p.contains(e))&&this.togglePopup()},Marker.prototype.getPopup=function(){return this._popup},Marker.prototype.togglePopup=function(){var t=this._popup;t&&(t.isOpen()?t.remove():t.addTo(this._map))},Marker.prototype._update=function(t){this._map&&(this._map.transform.renderWorldCopies&&(this._lngLat=smartWrap(this._lngLat,this._pos,this._map.transform)),this._pos=this._map.project(this._lngLat)._add(this._offset),t&&"moveend"!==t.type||(this._pos=this._pos.round()),DOM.setTransform(this._element,"translate("+this._pos.x+"px, "+this._pos.y+"px)"))},module.exports=Marker;
  388 +},{"../geo/lng_lat":61,"../util/dom":201,"../util/smart_wrap":211,"point-geometry":25}],191:[function(_dereq_,module,exports){
  389 +"use strict";function normalizeOffset(t){if(t){if("number"==typeof t){var o=Math.round(Math.sqrt(.5*Math.pow(t,2)));return{top:new Point(0,t),"top-left":new Point(o,o),"top-right":new Point(-o,o),bottom:new Point(0,-t),"bottom-left":new Point(o,-o),"bottom-right":new Point(-o,-o),left:new Point(t,0),right:new Point(-t,0)}}if(isPointLike(t)){var e=Point.convert(t);return{top:e,"top-left":e,"top-right":e,bottom:e,"bottom-left":e,"bottom-right":e,left:e,right:e}}return{top:Point.convert(t.top||[0,0]),"top-left":Point.convert(t["top-left"]||[0,0]),"top-right":Point.convert(t["top-right"]||[0,0]),bottom:Point.convert(t.bottom||[0,0]),"bottom-left":Point.convert(t["bottom-left"]||[0,0]),"bottom-right":Point.convert(t["bottom-right"]||[0,0]),left:Point.convert(t.left||[0,0]),right:Point.convert(t.right||[0,0])}}return normalizeOffset(new Point(0,0))}function isPointLike(t){return t instanceof Point||Array.isArray(t)}var util=_dereq_("../util/util"),Evented=_dereq_("../util/evented"),DOM=_dereq_("../util/dom"),LngLat=_dereq_("../geo/lng_lat"),Point=_dereq_("point-geometry"),window=_dereq_("../util/window"),smartWrap=_dereq_("../util/smart_wrap"),defaultOptions={closeButton:!0,closeOnClick:!0},Popup=function(t){function o(o){t.call(this),this.options=util.extend(Object.create(defaultOptions),o),util.bindAll(["_update","_onClickClose"],this)}return t&&(o.__proto__=t),o.prototype=Object.create(t&&t.prototype),o.prototype.constructor=o,o.prototype.addTo=function(t){return this._map=t,this._map.on("move",this._update),this.options.closeOnClick&&this._map.on("click",this._onClickClose),this._update(),this},o.prototype.isOpen=function(){return!!this._map},o.prototype.remove=function(){return this._content&&this._content.parentNode&&this._content.parentNode.removeChild(this._content),this._container&&(this._container.parentNode.removeChild(this._container),delete this._container),this._map&&(this._map.off("move",this._update),this._map.off("click",this._onClickClose),delete this._map),this.fire("close"),this},o.prototype.getLngLat=function(){return this._lngLat},o.prototype.setLngLat=function(t){return this._lngLat=LngLat.convert(t),this._pos=null,this._update(),this},o.prototype.setText=function(t){return this.setDOMContent(window.document.createTextNode(t))},o.prototype.setHTML=function(t){var o,e=window.document.createDocumentFragment(),n=window.document.createElement("body");for(n.innerHTML=t;;){if(o=n.firstChild,!o)break;e.appendChild(o)}return this.setDOMContent(e)},o.prototype.setDOMContent=function(t){return this._createContent(),this._content.appendChild(t),this._update(),this},o.prototype._createContent=function(){this._content&&this._content.parentNode&&this._content.parentNode.removeChild(this._content),this._content=DOM.create("div","mapboxgl-popup-content",this._container),this.options.closeButton&&(this._closeButton=DOM.create("button","mapboxgl-popup-close-button",this._content),this._closeButton.type="button",this._closeButton.setAttribute("aria-label","Close popup"),this._closeButton.innerHTML="&#215;",this._closeButton.addEventListener("click",this._onClickClose))},o.prototype._update=function(){if(this._map&&this._lngLat&&this._content){this._container||(this._container=DOM.create("div","mapboxgl-popup",this._map.getContainer()),this._tip=DOM.create("div","mapboxgl-popup-tip",this._container),this._container.appendChild(this._content)),this._map.transform.renderWorldCopies&&(this._lngLat=smartWrap(this._lngLat,this._pos,this._map.transform)),this._pos=this._map.project(this._lngLat);var t=this.options.anchor,o=normalizeOffset(this.options.offset);if(!t){var e=this._container.offsetWidth,n=this._container.offsetHeight;t=this._pos.y+o.bottom.y<n?["top"]:this._pos.y>this._map.transform.height-n?["bottom"]:[],this._pos.x<e/2?t.push("left"):this._pos.x>this._map.transform.width-e/2&&t.push("right"),t=0===t.length?"bottom":t.join("-")}var i=this._pos.add(o[t]).round(),r={top:"translate(-50%,0)","top-left":"translate(0,0)","top-right":"translate(-100%,0)",bottom:"translate(-50%,-100%)","bottom-left":"translate(0,-100%)","bottom-right":"translate(-100%,-100%)",left:"translate(0,-50%)",right:"translate(-100%,-50%)"},s=this._container.classList;for(var p in r)s.remove("mapboxgl-popup-anchor-"+p);s.add("mapboxgl-popup-anchor-"+t),DOM.setTransform(this._container,r[t]+" translate("+i.x+"px,"+i.y+"px)")}},o.prototype._onClickClose=function(){this.remove()},o}(Evented);module.exports=Popup;
  390 +},{"../geo/lng_lat":61,"../util/dom":201,"../util/evented":202,"../util/smart_wrap":211,"../util/util":215,"../util/window":196,"point-geometry":25}],192:[function(_dereq_,module,exports){
  391 +"use strict";var Actor=function(t,e,a){this.target=t,this.parent=e,this.mapId=a,this.callbacks={},this.callbackID=0,this.receive=this.receive.bind(this),this.target.addEventListener("message",this.receive,!1)};Actor.prototype.send=function(t,e,a,r,s){var i=a?this.mapId+":"+this.callbackID++:null;a&&(this.callbacks[i]=a),this.target.postMessage({targetMapId:s,sourceMapId:this.mapId,type:t,id:String(i),data:e},r)},Actor.prototype.receive=function(t){var e,a=this,r=t.data,s=r.id;if(!r.targetMapId||this.mapId===r.targetMapId){var i=function(t,e,r){a.target.postMessage({sourceMapId:a.mapId,type:"<response>",id:String(s),error:t?String(t):null,data:e},r)};if("<response>"===r.type)e=this.callbacks[r.id],delete this.callbacks[r.id],e&&e(r.error||null,r.data);else if("undefined"!=typeof r.id&&this.parent[r.type])this.parent[r.type](r.sourceMapId,r.data,i);else if("undefined"!=typeof r.id&&this.parent.getWorkerSource){var p=r.type.split("."),d=this.parent.getWorkerSource(r.sourceMapId,p[0]);d[p[1]](r.data,i)}else this.parent[r.type](r.data)}},Actor.prototype.remove=function(){this.target.removeEventListener("message",this.receive,!1)},module.exports=Actor;
  392 +},{}],193:[function(_dereq_,module,exports){
  393 +"use strict";function sameOrigin(e){var t=window.document.createElement("a");return t.href=e,t.protocol===window.document.location.protocol&&t.host===window.document.location.host}var window=_dereq_("./window"),AJAXError=function(e){function t(t,r){e.call(this,t),this.status=r}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t}(Error);exports.getJSON=function(e,t){var r=new window.XMLHttpRequest;return r.open("GET",e,!0),r.setRequestHeader("Accept","application/json"),r.onerror=function(e){t(e)},r.onload=function(){if(r.status>=200&&r.status<300&&r.response){var e;try{e=JSON.parse(r.response)}catch(e){return t(e)}t(null,e)}else t(new AJAXError(r.statusText,r.status))},r.send(),r},exports.getArrayBuffer=function(e,t){var r=new window.XMLHttpRequest;return r.open("GET",e,!0),r.responseType="arraybuffer",r.onerror=function(e){t(e)},r.onload=function(){return 0===r.response.byteLength&&200===r.status?t(new Error("http status 200 returned without content.")):void(r.status>=200&&r.status<300&&r.response?t(null,{data:r.response,cacheControl:r.getResponseHeader("Cache-Control"),expires:r.getResponseHeader("Expires")}):t(new AJAXError(r.statusText,r.status)))},r.send(),r};var transparentPngUrl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQYV2NgAAIAAAUAAarVyFEAAAAASUVORK5CYII=";exports.getImage=function(e,t){return exports.getArrayBuffer(e,function(e,r){if(e)return t(e);var n=new window.Image,o=window.URL||window.webkitURL;n.onload=function(){t(null,n),o.revokeObjectURL(n.src)};var s=new window.Blob([new Uint8Array(r.data)],{type:"image/png"});n.cacheControl=r.cacheControl,n.expires=r.expires,n.src=r.data.byteLength?o.createObjectURL(s):transparentPngUrl})},exports.getVideo=function(e,t){var r=window.document.createElement("video");r.onloadstart=function(){t(null,r)};for(var n=0;n<e.length;n++){var o=window.document.createElement("source");sameOrigin(e[n])||(r.crossOrigin="Anonymous"),o.src=e[n],r.appendChild(o)}return r};
  394 +},{"./window":196}],194:[function(_dereq_,module,exports){
  395 +"use strict";var window=_dereq_("./window");module.exports.now=function(){return window.performance&&window.performance.now?window.performance.now.bind(window.performance):Date.now.bind(Date)}();var frame=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame;exports.frame=function(e){return frame(e)};var cancel=window.cancelAnimationFrame||window.mozCancelAnimationFrame||window.webkitCancelAnimationFrame||window.msCancelAnimationFrame;exports.cancelFrame=function(e){cancel(e)},exports.timed=function(e,n,t){function o(i){r||(i=module.exports.now(),i>=a+n?e.call(t,1):(e.call(t,(i-a)/n),exports.frame(o)))}if(!n)return e.call(t,1),null;var r=!1,a=module.exports.now();return exports.frame(o),function(){r=!0}},exports.getImageData=function(e){var n=window.document.createElement("canvas"),t=n.getContext("2d");return n.width=e.width,n.height=e.height,t.drawImage(e,0,0,e.width,e.height),t.getImageData(0,0,e.width,e.height).data},exports.supported=_dereq_("mapbox-gl-supported"),exports.hardwareConcurrency=window.navigator.hardwareConcurrency||4,Object.defineProperty(exports,"devicePixelRatio",{get:function(){return window.devicePixelRatio}}),exports.supportsWebp=!1;var webpImgTest=window.document.createElement("img");webpImgTest.onload=function(){exports.supportsWebp=!0},webpImgTest.src="data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAQAAAAfQ//73v/+BiOh/AAA=";
  396 +},{"./window":196,"mapbox-gl-supported":22}],195:[function(_dereq_,module,exports){
  397 +"use strict";var WebWorkify=_dereq_("webworkify"),window=_dereq_("../window"),workerURL=window.URL.createObjectURL(new WebWorkify(_dereq_("../../source/worker"),{bare:!0}));module.exports=function(){return new window.Worker(workerURL)};
  398 +},{"../../source/worker":99,"../window":196,"webworkify":40}],196:[function(_dereq_,module,exports){
  399 +"use strict";module.exports=self;
  400 +},{}],197:[function(_dereq_,module,exports){
  401 +"use strict";function compareAreas(e,r){return r.area-e.area}var quickselect=_dereq_("quickselect"),calculateSignedArea=_dereq_("./util").calculateSignedArea;module.exports=function(e,r){var a=e.length;if(a<=1)return[e];for(var t,u,c=[],i=0;i<a;i++){var l=calculateSignedArea(e[i]);0!==l&&(e[i].area=Math.abs(l),void 0===u&&(u=l<0),u===l<0?(t&&c.push(t),t=[e[i]]):t.push(e[i]))}if(t&&c.push(t),r>1)for(var n=0;n<c.length;n++)c[n].length<=r||(quickselect(c[n],r,1,c[n].length-1,compareAreas),c[n]=c[n].slice(0,r));return c};
  402 +},{"./util":215,"quickselect":27}],198:[function(_dereq_,module,exports){
  403 +"use strict";var config={API_URL:"https://api.mapbox.com",REQUIRE_ACCESS_TOKEN:!0,ACCESS_TOKEN:null};module.exports=config;
  404 +},{}],199:[function(_dereq_,module,exports){
  405 +"use strict";var DictionaryCoder=function(r){var t=this;this._stringToNumber={},this._numberToString=[];for(var o=0;o<r.length;o++){var i=r[o];t._stringToNumber[i]=o,t._numberToString[o]=i}};DictionaryCoder.prototype.encode=function(r){return this._stringToNumber[r]},DictionaryCoder.prototype.decode=function(r){return this._numberToString[r]},module.exports=DictionaryCoder;
  406 +},{}],200:[function(_dereq_,module,exports){
  407 +"use strict";var util=_dereq_("./util"),Actor=_dereq_("./actor"),Dispatcher=function(t,r){var o=this;this.workerPool=t,this.actors=[],this.currentActor=0,this.id=util.uniqueId();for(var i=this.workerPool.acquire(this.id),e=0;e<i.length;e++){var s=i[e],c=new Actor(s,r,o.id);c.name="Worker "+e,o.actors.push(c)}};Dispatcher.prototype.broadcast=function(t,r,o){o=o||function(){},util.asyncAll(this.actors,function(o,i){o.send(t,r,i)},o)},Dispatcher.prototype.send=function(t,r,o,i,e){return("number"!=typeof i||isNaN(i))&&(i=this.currentActor=(this.currentActor+1)%this.actors.length),this.actors[i].send(t,r,o,e),i},Dispatcher.prototype.remove=function(){this.actors.forEach(function(t){t.remove()}),this.actors=[],this.workerPool.release(this.id)},module.exports=Dispatcher;
  408 +},{"./actor":192,"./util":215}],201:[function(_dereq_,module,exports){
  409 +"use strict";function testProp(e){for(var t=0;t<e.length;t++)if(e[t]in docStyle)return e[t];return e[0]}function suppressClick(e){e.preventDefault(),e.stopPropagation(),window.removeEventListener("click",suppressClick,!0)}var Point=_dereq_("point-geometry"),window=_dereq_("./window");exports.create=function(e,t,o){var n=window.document.createElement(e);return t&&(n.className=t),o&&o.appendChild(n),n};var docStyle=window.document.documentElement.style,selectProp=testProp(["userSelect","MozUserSelect","WebkitUserSelect","msUserSelect"]),userSelect;exports.disableDrag=function(){selectProp&&(userSelect=docStyle[selectProp],docStyle[selectProp]="none")},exports.enableDrag=function(){selectProp&&(docStyle[selectProp]=userSelect)};var transformProp=testProp(["transform","WebkitTransform"]);exports.setTransform=function(e,t){e.style[transformProp]=t},exports.suppressClick=function(){window.addEventListener("click",suppressClick,!0),window.setTimeout(function(){window.removeEventListener("click",suppressClick,!0)},0)},exports.mousePos=function(e,t){var o=e.getBoundingClientRect();return t=t.touches?t.touches[0]:t,new Point(t.clientX-o.left-e.clientLeft,t.clientY-o.top-e.clientTop)},exports.touchPos=function(e,t){for(var o=e.getBoundingClientRect(),n=[],r="touchend"===t.type?t.changedTouches:t.touches,s=0;s<r.length;s++)n.push(new Point(r[s].clientX-o.left-e.clientLeft,r[s].clientY-o.top-e.clientTop));return n},exports.remove=function(e){e.parentNode&&e.parentNode.removeChild(e)};
  410 +},{"./window":196,"point-geometry":25}],202:[function(_dereq_,module,exports){
  411 +"use strict";function _addEventListener(e,t,n){n[e]=n[e]||[],n[e].push(t)}function _removeEventListener(e,t,n){if(n&&n[e]){var i=n[e].indexOf(t);i!==-1&&n[e].splice(i,1)}}var util=_dereq_("./util"),Evented=function(){};Evented.prototype.on=function(e,t){return this._listeners=this._listeners||{},_addEventListener(e,t,this._listeners),this},Evented.prototype.off=function(e,t){return _removeEventListener(e,t,this._listeners),_removeEventListener(e,t,this._oneTimeListeners),this},Evented.prototype.once=function(e,t){return this._oneTimeListeners=this._oneTimeListeners||{},_addEventListener(e,t,this._oneTimeListeners),this},Evented.prototype.fire=function(e,t){var n=this;if(this.listens(e)){t=util.extend({},t,{type:e,target:this});for(var i=this._listeners&&this._listeners[e]?this._listeners[e].slice():[],s=0;s<i.length;s++)i[s].call(n,t);for(var r=this._oneTimeListeners&&this._oneTimeListeners[e]?this._oneTimeListeners[e].slice():[],o=0;o<r.length;o++)r[o].call(n,t),_removeEventListener(e,r[o],n._oneTimeListeners);this._eventedParent&&this._eventedParent.fire(e,util.extend({},t,"function"==typeof this._eventedParentData?this._eventedParentData():this._eventedParentData))}else util.endsWith(e,"error")&&console.error(t&&t.error||t||"Empty error event");return this},Evented.prototype.listens=function(e){return this._listeners&&this._listeners[e]&&this._listeners[e].length>0||this._oneTimeListeners&&this._oneTimeListeners[e]&&this._oneTimeListeners[e].length>0||this._eventedParent&&this._eventedParent.listens(e)},Evented.prototype.setEventedParent=function(e,t){return this._eventedParent=e,this._eventedParentData=t,this},module.exports=Evented;
  412 +},{"./util":215}],203:[function(_dereq_,module,exports){
  413 +"use strict";function compareMax(e,t){return t.max-e.max}function Cell(e,t,n,r){this.p=new Point(e,t),this.h=n,this.d=pointToPolygonDist(this.p,r),this.max=this.d+this.h*Math.SQRT2}function pointToPolygonDist(e,t){for(var n=!1,r=1/0,o=0;o<t.length;o++)for(var i=t[o],l=0,u=i.length,s=u-1;l<u;s=l++){var a=i[l],h=i[s];a.y>e.y!=h.y>e.y&&e.x<(h.x-a.x)*(e.y-a.y)/(h.y-a.y)+a.x&&(n=!n),r=Math.min(r,distToSegmentSquared(e,a,h))}return(n?1:-1)*Math.sqrt(r)}function getCentroidCell(e){for(var t=0,n=0,r=0,o=e[0],i=0,l=o.length,u=l-1;i<l;u=i++){var s=o[i],a=o[u],h=s.x*a.y-a.x*s.y;n+=(s.x+a.x)*h,r+=(s.y+a.y)*h,t+=3*h}return new Cell(n/t,r/t,0,e)}var Queue=_dereq_("tinyqueue"),Point=_dereq_("point-geometry"),distToSegmentSquared=_dereq_("./intersection_tests").distToSegmentSquared;module.exports=function(e,t,n){t=t||1;for(var r,o,i,l,u=e[0],s=0;s<u.length;s++){var a=u[s];(!s||a.x<r)&&(r=a.x),(!s||a.y<o)&&(o=a.y),(!s||a.x>i)&&(i=a.x),(!s||a.y>l)&&(l=a.y)}var h=i-r,p=l-o,y=Math.min(h,p),x=y/2,d=new Queue(null,compareMax);if(0===y)return[r,o];for(var g=r;g<i;g+=y)for(var f=o;f<l;f+=y)d.push(new Cell(g+x,f+x,x,e));for(var m=getCentroidCell(e),c=d.length;d.length;){var v=d.pop();(v.d>m.d||!m.d)&&(m=v,n&&console.log("found best %d after %d probes",Math.round(1e4*v.d)/1e4,c)),v.max-m.d<=t||(x=v.h/2,d.push(new Cell(v.p.x-x,v.p.y-x,x,e)),d.push(new Cell(v.p.x+x,v.p.y-x,x,e)),d.push(new Cell(v.p.x-x,v.p.y+x,x,e)),d.push(new Cell(v.p.x+x,v.p.y+x,x,e)),c+=4)}return n&&(console.log("num probes: "+c),console.log("best distance: "+m.d)),m.p};
  414 +},{"./intersection_tests":206,"point-geometry":25,"tinyqueue":29}],204:[function(_dereq_,module,exports){
  415 +"use strict";var WorkerPool=_dereq_("./worker_pool"),globalWorkerPool;module.exports=function(){return globalWorkerPool||(globalWorkerPool=new WorkerPool),globalWorkerPool};
  416 +},{"./worker_pool":218}],205:[function(_dereq_,module,exports){
  417 +"use strict";function Glyphs(a,e){this.stacks=a.readFields(readFontstacks,[],e)}function readFontstacks(a,e,r){if(1===a){var t=r.readMessage(readFontstack,{glyphs:{}});e.push(t)}}function readFontstack(a,e,r){if(1===a)e.name=r.readString();else if(2===a)e.range=r.readString();else if(3===a){var t=r.readMessage(readGlyph,{});e.glyphs[t.id]=t}}function readGlyph(a,e,r){1===a?e.id=r.readVarint():2===a?e.bitmap=r.readBytes():3===a?e.width=r.readVarint():4===a?e.height=r.readVarint():5===a?e.left=r.readSVarint():6===a?e.top=r.readSVarint():7===a&&(e.advance=r.readVarint())}module.exports=Glyphs;
  418 +},{}],206:[function(_dereq_,module,exports){
  419 +"use strict";function polygonIntersectsPolygon(n,t){for(var e=0;e<n.length;e++)if(polygonContainsPoint(t,n[e]))return!0;for(var r=0;r<t.length;r++)if(polygonContainsPoint(n,t[r]))return!0;return!!lineIntersectsLine(n,t)}function multiPolygonIntersectsBufferedMultiPoint(n,t,e){for(var r=0;r<n.length;r++)for(var o=n[r],i=0;i<t.length;i++)for(var l=t[i],u=0;u<l.length;u++){var s=l[u];if(polygonContainsPoint(o,s))return!0;if(pointIntersectsBufferedLine(s,o,e))return!0}return!1}function multiPolygonIntersectsMultiPolygon(n,t){if(1===n.length&&1===n[0].length)return multiPolygonContainsPoint(t,n[0][0]);for(var e=0;e<t.length;e++)for(var r=t[e],o=0;o<r.length;o++)if(multiPolygonContainsPoint(n,r[o]))return!0;for(var i=0;i<n.length;i++){for(var l=n[i],u=0;u<l.length;u++)if(multiPolygonContainsPoint(t,l[u]))return!0;for(var s=0;s<t.length;s++)if(lineIntersectsLine(l,t[s]))return!0}return!1}function multiPolygonIntersectsBufferedMultiLine(n,t,e){for(var r=0;r<t.length;r++)for(var o=t[r],i=0;i<n.length;i++){var l=n[i];if(l.length>=3)for(var u=0;u<o.length;u++)if(polygonContainsPoint(l,o[u]))return!0;if(lineIntersectsBufferedLine(l,o,e))return!0}return!1}function lineIntersectsBufferedLine(n,t,e){if(n.length>1){if(lineIntersectsLine(n,t))return!0;for(var r=0;r<t.length;r++)if(pointIntersectsBufferedLine(t[r],n,e))return!0}for(var o=0;o<n.length;o++)if(pointIntersectsBufferedLine(n[o],t,e))return!0;return!1}function lineIntersectsLine(n,t){if(0===n.length||0===t.length)return!1;for(var e=0;e<n.length-1;e++)for(var r=n[e],o=n[e+1],i=0;i<t.length-1;i++){var l=t[i],u=t[i+1];if(lineSegmentIntersectsLineSegment(r,o,l,u))return!0}return!1}function lineSegmentIntersectsLineSegment(n,t,e,r){return isCounterClockwise(n,e,r)!==isCounterClockwise(t,e,r)&&isCounterClockwise(n,t,e)!==isCounterClockwise(n,t,r)}function pointIntersectsBufferedLine(n,t,e){var r=e*e;if(1===t.length)return n.distSqr(t[0])<r;for(var o=1;o<t.length;o++){var i=t[o-1],l=t[o];if(distToSegmentSquared(n,i,l)<r)return!0}return!1}function distToSegmentSquared(n,t,e){var r=t.distSqr(e);if(0===r)return n.distSqr(t);var o=((n.x-t.x)*(e.x-t.x)+(n.y-t.y)*(e.y-t.y))/r;return o<0?n.distSqr(t):o>1?n.distSqr(e):n.distSqr(e.sub(t)._mult(o)._add(t))}function multiPolygonContainsPoint(n,t){for(var e,r,o,i=!1,l=0;l<n.length;l++){e=n[l];for(var u=0,s=e.length-1;u<e.length;s=u++)r=e[u],o=e[s],r.y>t.y!=o.y>t.y&&t.x<(o.x-r.x)*(t.y-r.y)/(o.y-r.y)+r.x&&(i=!i)}return i}function polygonContainsPoint(n,t){for(var e=!1,r=0,o=n.length-1;r<n.length;o=r++){var i=n[r],l=n[o];i.y>t.y!=l.y>t.y&&t.x<(l.x-i.x)*(t.y-i.y)/(l.y-i.y)+i.x&&(e=!e)}return e}var isCounterClockwise=_dereq_("./util").isCounterClockwise;module.exports={multiPolygonIntersectsBufferedMultiPoint:multiPolygonIntersectsBufferedMultiPoint,multiPolygonIntersectsMultiPolygon:multiPolygonIntersectsMultiPolygon,multiPolygonIntersectsBufferedMultiLine:multiPolygonIntersectsBufferedMultiLine,polygonIntersectsPolygon:polygonIntersectsPolygon,distToSegmentSquared:distToSegmentSquared};
  420 +},{"./util":215}],207:[function(_dereq_,module,exports){
  421 +"use strict";var unicodeBlockLookup={"Latin-1 Supplement":function(n){return n>=128&&n<=255},Arabic:function(n){return n>=1536&&n<=1791},"Arabic Supplement":function(n){return n>=1872&&n<=1919},"Arabic Extended-A":function(n){return n>=2208&&n<=2303},"Hangul Jamo":function(n){return n>=4352&&n<=4607},"Unified Canadian Aboriginal Syllabics":function(n){return n>=5120&&n<=5759},"Unified Canadian Aboriginal Syllabics Extended":function(n){return n>=6320&&n<=6399},"General Punctuation":function(n){return n>=8192&&n<=8303},"Letterlike Symbols":function(n){return n>=8448&&n<=8527},"Number Forms":function(n){return n>=8528&&n<=8591},"Miscellaneous Technical":function(n){return n>=8960&&n<=9215},"Control Pictures":function(n){return n>=9216&&n<=9279},"Optical Character Recognition":function(n){return n>=9280&&n<=9311},"Enclosed Alphanumerics":function(n){return n>=9312&&n<=9471},"Geometric Shapes":function(n){return n>=9632&&n<=9727},"Miscellaneous Symbols":function(n){return n>=9728&&n<=9983},"Miscellaneous Symbols and Arrows":function(n){return n>=11008&&n<=11263},"CJK Radicals Supplement":function(n){return n>=11904&&n<=12031},"Kangxi Radicals":function(n){return n>=12032&&n<=12255},"Ideographic Description Characters":function(n){return n>=12272&&n<=12287},"CJK Symbols and Punctuation":function(n){return n>=12288&&n<=12351},Hiragana:function(n){return n>=12352&&n<=12447},Katakana:function(n){return n>=12448&&n<=12543},Bopomofo:function(n){return n>=12544&&n<=12591},"Hangul Compatibility Jamo":function(n){return n>=12592&&n<=12687},Kanbun:function(n){return n>=12688&&n<=12703},"Bopomofo Extended":function(n){return n>=12704&&n<=12735},"CJK Strokes":function(n){return n>=12736&&n<=12783},"Katakana Phonetic Extensions":function(n){return n>=12784&&n<=12799},"Enclosed CJK Letters and Months":function(n){return n>=12800&&n<=13055},"CJK Compatibility":function(n){return n>=13056&&n<=13311},"CJK Unified Ideographs Extension A":function(n){return n>=13312&&n<=19903},"Yijing Hexagram Symbols":function(n){return n>=19904&&n<=19967},"CJK Unified Ideographs":function(n){return n>=19968&&n<=40959},"Yi Syllables":function(n){return n>=40960&&n<=42127},"Yi Radicals":function(n){return n>=42128&&n<=42191},"Hangul Jamo Extended-A":function(n){return n>=43360&&n<=43391},"Hangul Syllables":function(n){return n>=44032&&n<=55215},"Hangul Jamo Extended-B":function(n){return n>=55216&&n<=55295},"Private Use Area":function(n){return n>=57344&&n<=63743},"CJK Compatibility Ideographs":function(n){return n>=63744&&n<=64255},"Arabic Presentation Forms-A":function(n){return n>=64336&&n<=65023},"Vertical Forms":function(n){return n>=65040&&n<=65055},"CJK Compatibility Forms":function(n){return n>=65072&&n<=65103},"Small Form Variants":function(n){return n>=65104&&n<=65135},"Arabic Presentation Forms-B":function(n){return n>=65136&&n<=65279},"Halfwidth and Fullwidth Forms":function(n){return n>=65280&&n<=65519}};module.exports=unicodeBlockLookup;
  422 +},{}],208:[function(_dereq_,module,exports){
  423 +"use strict";var LRUCache=function(t,e){this.max=t,this.onRemove=e,this.reset()};LRUCache.prototype.reset=function(){var t=this;for(var e in t.data)t.onRemove(t.data[e]);return this.data={},this.order=[],this},LRUCache.prototype.add=function(t,e){if(this.has(t))this.order.splice(this.order.indexOf(t),1),this.data[t]=e,this.order.push(t);else if(this.data[t]=e,this.order.push(t),this.order.length>this.max){var r=this.get(this.order[0]);r&&this.onRemove(r)}return this},LRUCache.prototype.has=function(t){return t in this.data},LRUCache.prototype.keys=function(){return this.order},LRUCache.prototype.get=function(t){if(!this.has(t))return null;var e=this.data[t];return delete this.data[t],this.order.splice(this.order.indexOf(t),1),e},LRUCache.prototype.getWithoutRemoving=function(t){if(!this.has(t))return null;var e=this.data[t];return e},LRUCache.prototype.remove=function(t){if(!this.has(t))return this;var e=this.data[t];return delete this.data[t],this.onRemove(e),this.order.splice(this.order.indexOf(t),1),this},LRUCache.prototype.setMaxSize=function(t){var e=this;for(this.max=t;this.order.length>this.max;){var r=e.get(e.order[0]);r&&e.onRemove(r)}return this},module.exports=LRUCache;
  424 +},{}],209:[function(_dereq_,module,exports){
  425 +"use strict";function makeAPIURL(r,e){var t=parseUrl(config.API_URL);if(r.protocol=t.protocol,r.authority=t.authority,!config.REQUIRE_ACCESS_TOKEN)return formatUrl(r);if(e=e||config.ACCESS_TOKEN,!e)throw new Error("An API access token is required to use Mapbox GL. "+help);if("s"===e[0])throw new Error("Use a public access token (pk.*) with Mapbox GL, not a secret access token (sk.*). "+help);return r.params.push("access_token="+e),formatUrl(r)}function isMapboxURL(r){return 0===r.indexOf("mapbox:")}function replaceTempAccessToken(r){for(var e=0;e<r.length;e++)0===r[e].indexOf("access_token=tk.")&&(r[e]="access_token="+(config.ACCESS_TOKEN||""))}function parseUrl(r){var e=r.match(urlRe);if(!e)throw new Error("Unable to parse URL object");return{protocol:e[1],authority:e[2],path:e[3]||"/",params:e[4]?e[4].split("&"):[]}}function formatUrl(r){var e=r.params.length?"?"+r.params.join("&"):"";return r.protocol+"://"+r.authority+r.path+e}var config=_dereq_("./config"),browser=_dereq_("./browser"),help="See https://www.mapbox.com/api-documentation/#access-tokens";exports.isMapboxURL=isMapboxURL,exports.normalizeStyleURL=function(r,e){if(!isMapboxURL(r))return r;var t=parseUrl(r);return t.path="/styles/v1"+t.path,makeAPIURL(t,e)},exports.normalizeGlyphsURL=function(r,e){if(!isMapboxURL(r))return r;var t=parseUrl(r);return t.path="/fonts/v1"+t.path,makeAPIURL(t,e)},exports.normalizeSourceURL=function(r,e){if(!isMapboxURL(r))return r;var t=parseUrl(r);return t.path="/v4/"+t.authority+".json",t.params.push("secure"),makeAPIURL(t,e)},exports.normalizeSpriteURL=function(r,e,t,o){var a=parseUrl(r);return isMapboxURL(r)?(a.path="/styles/v1"+a.path+"/sprite"+e+t,makeAPIURL(a,o)):(a.path+=""+e+t,formatUrl(a))};var imageExtensionRe=/(\.(png|jpg)\d*)(?=$)/;exports.normalizeTileURL=function(r,e,t){if(!e||!isMapboxURL(e))return r;var o=parseUrl(r),a=browser.devicePixelRatio>=2||512===t?"@2x":"",s=browser.supportsWebp?".webp":"$1";return o.path=o.path.replace(imageExtensionRe,""+a+s),replaceTempAccessToken(o.params),formatUrl(o)};var urlRe=/^(\w+):\/\/([^\/?]*)(\/[^?]+)?\??(.+)?/;
  426 +},{"./browser":194,"./config":198}],210:[function(_dereq_,module,exports){
  427 +"use strict";var isChar=_dereq_("./is_char_in_unicode_block");module.exports.allowsIdeographicBreaking=function(a){for(var i=0,r=a;i<r.length;i+=1){var s=r[i];if(!exports.charAllowsIdeographicBreaking(s.charCodeAt(0)))return!1}return!0},module.exports.allowsVerticalWritingMode=function(a){for(var i=0,r=a;i<r.length;i+=1){var s=r[i];if(exports.charHasUprightVerticalOrientation(s.charCodeAt(0)))return!0}return!1},module.exports.allowsLetterSpacing=function(a){for(var i=0,r=a;i<r.length;i+=1){var s=r[i];if(!exports.charAllowsLetterSpacing(s.charCodeAt(0)))return!1}return!0},module.exports.charAllowsLetterSpacing=function(a){return!isChar.Arabic(a)&&(!isChar["Arabic Supplement"](a)&&(!isChar["Arabic Extended-A"](a)&&(!isChar["Arabic Presentation Forms-A"](a)&&!isChar["Arabic Presentation Forms-B"](a))))},module.exports.charAllowsIdeographicBreaking=function(a){return!(a<11904)&&(!!isChar["Bopomofo Extended"](a)||(!!isChar.Bopomofo(a)||(!!isChar["CJK Compatibility Forms"](a)||(!!isChar["CJK Compatibility Ideographs"](a)||(!!isChar["CJK Compatibility"](a)||(!!isChar["CJK Radicals Supplement"](a)||(!!isChar["CJK Strokes"](a)||(!!isChar["CJK Symbols and Punctuation"](a)||(!!isChar["CJK Unified Ideographs Extension A"](a)||(!!isChar["CJK Unified Ideographs"](a)||(!!isChar["Enclosed CJK Letters and Months"](a)||(!!isChar["Halfwidth and Fullwidth Forms"](a)||(!!isChar.Hiragana(a)||(!!isChar["Ideographic Description Characters"](a)||(!!isChar["Kangxi Radicals"](a)||(!!isChar["Katakana Phonetic Extensions"](a)||(!!isChar.Katakana(a)||(!!isChar["Vertical Forms"](a)||(!!isChar["Yi Radicals"](a)||!!isChar["Yi Syllables"](a))))))))))))))))))))},exports.charHasUprightVerticalOrientation=function(a){return 746===a||747===a||!(a<4352)&&(!!isChar["Bopomofo Extended"](a)||(!!isChar.Bopomofo(a)||(!(!isChar["CJK Compatibility Forms"](a)||a>=65097&&a<=65103)||(!!isChar["CJK Compatibility Ideographs"](a)||(!!isChar["CJK Compatibility"](a)||(!!isChar["CJK Radicals Supplement"](a)||(!!isChar["CJK Strokes"](a)||(!(!isChar["CJK Symbols and Punctuation"](a)||a>=12296&&a<=12305||a>=12308&&a<=12319||12336===a)||(!!isChar["CJK Unified Ideographs Extension A"](a)||(!!isChar["CJK Unified Ideographs"](a)||(!!isChar["Enclosed CJK Letters and Months"](a)||(!!isChar["Hangul Compatibility Jamo"](a)||(!!isChar["Hangul Jamo Extended-A"](a)||(!!isChar["Hangul Jamo Extended-B"](a)||(!!isChar["Hangul Jamo"](a)||(!!isChar["Hangul Syllables"](a)||(!!isChar.Hiragana(a)||(!!isChar["Ideographic Description Characters"](a)||(!!isChar.Kanbun(a)||(!!isChar["Kangxi Radicals"](a)||(!!isChar["Katakana Phonetic Extensions"](a)||(!(!isChar.Katakana(a)||12540===a)||(!(!isChar["Halfwidth and Fullwidth Forms"](a)||65288===a||65289===a||65293===a||a>=65306&&a<=65310||65339===a||65341===a||65343===a||a>=65371&&a<=65503||65507===a||a>=65512&&a<=65519)||(!(!isChar["Small Form Variants"](a)||a>=65112&&a<=65118||a>=65123&&a<=65126)||(!!isChar["Unified Canadian Aboriginal Syllabics"](a)||(!!isChar["Unified Canadian Aboriginal Syllabics Extended"](a)||(!!isChar["Vertical Forms"](a)||(!!isChar["Yijing Hexagram Symbols"](a)||(!!isChar["Yi Syllables"](a)||!!isChar["Yi Radicals"](a))))))))))))))))))))))))))))))},exports.charHasNeutralVerticalOrientation=function(a){return!(!isChar["Latin-1 Supplement"](a)||167!==a&&169!==a&&174!==a&&177!==a&&188!==a&&189!==a&&190!==a&&215!==a&&247!==a)||(!(!isChar["General Punctuation"](a)||8214!==a&&8224!==a&&8225!==a&&8240!==a&&8241!==a&&8251!==a&&8252!==a&&8258!==a&&8263!==a&&8264!==a&&8265!==a&&8273!==a)||(!!isChar["Letterlike Symbols"](a)||(!!isChar["Number Forms"](a)||(!(!isChar["Miscellaneous Technical"](a)||!(a>=8960&&a<=8967||a>=8972&&a<=8991||a>=8996&&a<=9e3||9003===a||a>=9085&&a<=9114||a>=9150&&a<=9165||9167===a||a>=9169&&a<=9179||a>=9186&&a<=9215))||(!(!isChar["Control Pictures"](a)||9251===a)||(!!isChar["Optical Character Recognition"](a)||(!!isChar["Enclosed Alphanumerics"](a)||(!!isChar["Geometric Shapes"](a)||(!(!isChar["Miscellaneous Symbols"](a)||a>=9754&&a<=9759)||(!(!isChar["Miscellaneous Symbols and Arrows"](a)||!(a>=11026&&a<=11055||a>=11088&&a<=11097||a>=11192&&a<=11243))||(!!isChar["CJK Symbols and Punctuation"](a)||(!!isChar.Katakana(a)||(!!isChar["Private Use Area"](a)||(!!isChar["CJK Compatibility Forms"](a)||(!!isChar["Small Form Variants"](a)||(!!isChar["Halfwidth and Fullwidth Forms"](a)||(8734===a||8756===a||8757===a||a>=9984&&a<=10087||a>=10102&&a<=10131||65532===a||65533===a)))))))))))))))))},exports.charHasRotatedVerticalOrientation=function(a){return!(exports.charHasUprightVerticalOrientation(a)||exports.charHasNeutralVerticalOrientation(a))};
  428 +},{"./is_char_in_unicode_block":207}],211:[function(_dereq_,module,exports){
  429 +"use strict";var LngLat=_dereq_("../geo/lng_lat");module.exports=function(n,t,l){if(n=new LngLat(n.lng,n.lat),t){var a=new LngLat(n.lng-360,n.lat),i=new LngLat(n.lng+360,n.lat),o=l.locationPoint(n).distSqr(t);l.locationPoint(a).distSqr(t)<o?n=a:l.locationPoint(i).distSqr(t)<o&&(n=i)}for(;Math.abs(n.lng-l.center.lng)>180;){var e=l.locationPoint(n);if(e.x>=0&&e.y>=0&&e.x<=l.width&&e.y<=l.height)break;n.lng>l.center.lng?n.lng-=360:n.lng+=360}return n};
  430 +},{"../geo/lng_lat":61}],212:[function(_dereq_,module,exports){
  431 +"use strict";function createStructArrayType(t){var e=JSON.stringify(t);if(structArrayTypeCache[e])return structArrayTypeCache[e];var r=void 0===t.alignment?1:t.alignment,i=0,n=0,a=["Uint8"],o=t.members.map(function(t){a.indexOf(t.type)<0&&a.push(t.type);var e=sizeOf(t.type),o=i=align(i,Math.max(r,e)),s=t.components||1;return n=Math.max(n,e),i+=e*s,{name:t.name,type:t.type,components:s,offset:o}}),s=align(i,Math.max(n,r)),p=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e}(Struct);p.prototype.alignment=r,p.prototype.size=s;for(var y=0,c=o;y<c.length;y+=1)for(var h=c[y],u=0;u<h.components;u++){var f=h.name+(1===h.components?"":u);Object.defineProperty(p.prototype,f,{get:createGetter(h,u),set:createSetter(h,u)})}var m=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e}(StructArray);return m.prototype.members=o,m.prototype.StructType=p,m.prototype.bytesPerElement=s,m.prototype.emplaceBack=createEmplaceBack(o,s),m.prototype._usedTypes=a,structArrayTypeCache[e]=m,m}function align(t,e){return Math.ceil(t/e)*e}function sizeOf(t){return viewTypes[t].BYTES_PER_ELEMENT}function getArrayViewName(t){return t.toLowerCase()}function createEmplaceBack(t,e){for(var r=[],i=[],n="var i = this.length;\nthis.resize(this.length + 1);\n",a=0,o=t;a<o.length;a+=1){var s=o[a],p=sizeOf(s.type);r.indexOf(p)<0&&(r.push(p),n+="var o"+p.toFixed(0)+" = i * "+(e/p).toFixed(0)+";\n");for(var y=0;y<s.components;y++){var c="v"+i.length,h="o"+p.toFixed(0)+" + "+(s.offset/p+y).toFixed(0);n+="this."+getArrayViewName(s.type)+"["+h+"] = "+c+";\n",i.push(c)}}return n+="return i;",new Function(i.toString(),n)}function createMemberComponentString(t,e){var r="this._pos"+sizeOf(t.type).toFixed(0),i=(t.offset/sizeOf(t.type)+e).toFixed(0),n=r+" + "+i;return"this._structArray."+getArrayViewName(t.type)+"["+n+"]"}function createGetter(t,e){return new Function("return "+createMemberComponentString(t,e)+";")}function createSetter(t,e){return new Function("x",createMemberComponentString(t,e)+" = x;")}module.exports=createStructArrayType;var viewTypes={Int8:Int8Array,Uint8:Uint8Array,Uint8Clamped:Uint8ClampedArray,Int16:Int16Array,Uint16:Uint16Array,Int32:Int32Array,Uint32:Uint32Array,Float32:Float32Array,Float64:Float64Array},Struct=function(t,e){this._structArray=t,this._pos1=e*this.size,this._pos2=this._pos1/2,this._pos4=this._pos1/4,this._pos8=this._pos1/8},DEFAULT_CAPACITY=128,RESIZE_MULTIPLIER=5,StructArray=function(t){this.isTransferred=!1,void 0!==t?(this.arrayBuffer=t.arrayBuffer,this.length=t.length,this.capacity=this.arrayBuffer.byteLength/this.bytesPerElement,this._refreshViews()):(this.capacity=-1,this.resize(0))};StructArray.serialize=function(){return{members:this.prototype.members,alignment:this.prototype.StructType.prototype.alignment,bytesPerElement:this.prototype.bytesPerElement}},StructArray.prototype.serialize=function(t){return this._trim(),t&&(this.isTransferred=!0,t.push(this.arrayBuffer)),{length:this.length,arrayBuffer:this.arrayBuffer}},StructArray.prototype.get=function(t){return new this.StructType(this,t)},StructArray.prototype._trim=function(){this.length!==this.capacity&&(this.capacity=this.length,this.arrayBuffer=this.arrayBuffer.slice(0,this.length*this.bytesPerElement),this._refreshViews())},StructArray.prototype.resize=function(t){if(this.length=t,t>this.capacity){this.capacity=Math.max(t,Math.floor(this.capacity*RESIZE_MULTIPLIER),DEFAULT_CAPACITY),this.arrayBuffer=new ArrayBuffer(this.capacity*this.bytesPerElement);var e=this.uint8;this._refreshViews(),e&&this.uint8.set(e)}},StructArray.prototype._refreshViews=function(){for(var t=this,e=0,r=t._usedTypes;e<r.length;e+=1){var i=r[e];t[getArrayViewName(i)]=new viewTypes[i](t.arrayBuffer)}},StructArray.prototype.toArray=function(t,e){for(var r=this,i=[],n=t;n<e;n++){var a=r.get(n);i.push(a)}return i};var structArrayTypeCache={};
  432 +},{}],213:[function(_dereq_,module,exports){
  433 +"use strict";var browser=_dereq_("./browser"),Throttler=function(t,o){this.frequency=t,this.throttledFunction=o,this.lastInvocation=0};Throttler.prototype.invoke=function(){var t=this;if(!this.pendingInvocation){var o=0===this.lastInvocation?0:this.lastInvocation+this.frequency-browser.now();o<=0?(this.lastInvocation=browser.now(),this.throttledFunction()):this.pendingInvocation=setTimeout(function(){t.pendingInvocation=void 0,t.lastInvocation=browser.now(),t.throttledFunction()},o)}},Throttler.prototype.stop=function(){this.pendingInvocation&&(clearTimeout(this.pendingInvocation),this.pendingInvocation=void 0)},module.exports=Throttler;
  434 +},{"./browser":194}],214:[function(_dereq_,module,exports){
  435 +"use strict";function resolveTokens(e,n){return n.replace(/{([^{}]+)}/g,function(n,r){return r in e?e[r]:""})}module.exports=resolveTokens;
  436 +},{}],215:[function(_dereq_,module,exports){
  437 +"use strict";var UnitBezier=_dereq_("@mapbox/unitbezier"),Coordinate=_dereq_("../geo/coordinate"),Point=_dereq_("point-geometry");exports.easeCubicInOut=function(r){if(r<=0)return 0;if(r>=1)return 1;var e=r*r,t=e*r;return 4*(r<.5?t:3*(r-e)+t-.75)},exports.bezier=function(r,e,t,n){var o=new UnitBezier(r,e,t,n);return function(r){return o.solve(r)}},exports.ease=exports.bezier(.25,.1,.25,1),exports.clamp=function(r,e,t){return Math.min(t,Math.max(e,r))},exports.wrap=function(r,e,t){var n=t-e,o=((r-e)%n+n)%n+e;return o===e?t:o},exports.asyncAll=function(r,e,t){if(!r.length)return t(null,[]);var n=r.length,o=new Array(r.length),a=null;r.forEach(function(r,i){e(r,function(r,e){r&&(a=r),o[i]=e,0===--n&&t(a,o)})})},exports.values=function(r){var e=[];for(var t in r)e.push(r[t]);return e},exports.keysDifference=function(r,e){var t=[];for(var n in r)n in e||t.push(n);return t},exports.extend=function(r){for(var e=[],t=arguments.length-1;t-- >0;)e[t]=arguments[t+1];for(var n=0,o=e;n<o.length;n+=1){var a=o[n];for(var i in a)r[i]=a[i]}return r},exports.pick=function(r,e){for(var t={},n=0;n<e.length;n++){var o=e[n];o in r&&(t[o]=r[o])}return t};var id=1;exports.uniqueId=function(){return id++},exports.bindAll=function(r,e){r.forEach(function(r){e[r]&&(e[r]=e[r].bind(e))})},exports.getCoordinatesCenter=function(r){for(var e=1/0,t=1/0,n=-(1/0),o=-(1/0),a=0;a<r.length;a++)e=Math.min(e,r[a].column),t=Math.min(t,r[a].row),n=Math.max(n,r[a].column),o=Math.max(o,r[a].row);var i=n-e,u=o-t,s=Math.max(i,u),c=Math.max(0,Math.floor(-Math.log(s)/Math.LN2));return new Coordinate((e+n)/2,(t+o)/2,0).zoomTo(c)},exports.endsWith=function(r,e){return r.indexOf(e,r.length-e.length)!==-1},exports.mapObject=function(r,e,t){var n=this,o={};for(var a in r)o[a]=e.call(t||n,r[a],a,r);return o},exports.filterObject=function(r,e,t){var n=this,o={};for(var a in r)e.call(t||n,r[a],a,r)&&(o[a]=r[a]);return o},exports.deepEqual=function(r,e){if(Array.isArray(r)){if(!Array.isArray(e)||r.length!==e.length)return!1;for(var t=0;t<r.length;t++)if(!exports.deepEqual(r[t],e[t]))return!1;return!0}if("object"==typeof r&&null!==r&&null!==e){if("object"!=typeof e)return!1;var n=Object.keys(r);if(n.length!==Object.keys(e).length)return!1;for(var o in r)if(!exports.deepEqual(r[o],e[o]))return!1;return!0}return r===e},exports.clone=function(r){return Array.isArray(r)?r.map(exports.clone):"object"==typeof r&&r?exports.mapObject(r,exports.clone):r},exports.arraysIntersect=function(r,e){for(var t=0;t<r.length;t++)if(e.indexOf(r[t])>=0)return!0;return!1};var warnOnceHistory={};exports.warnOnce=function(r){warnOnceHistory[r]||("undefined"!=typeof console&&console.warn(r),warnOnceHistory[r]=!0)},exports.isCounterClockwise=function(r,e,t){return(t.y-r.y)*(e.x-r.x)>(e.y-r.y)*(t.x-r.x)},exports.calculateSignedArea=function(r){for(var e=0,t=0,n=r.length,o=n-1,a=void 0,i=void 0;t<n;o=t++)a=r[t],i=r[o],e+=(i.x-a.x)*(a.y+i.y);return e},exports.isClosedPolygon=function(r){if(r.length<4)return!1;var e=r[0],t=r[r.length-1];return!(Math.abs(e.x-t.x)>0||Math.abs(e.y-t.y)>0)&&Math.abs(exports.calculateSignedArea(r))>.01},exports.sphericalToCartesian=function(r){var e=r[0],t=r[1],n=r[2];return t+=90,t*=Math.PI/180,n*=Math.PI/180,[e*Math.cos(t)*Math.sin(n),e*Math.sin(t)*Math.sin(n),e*Math.cos(n)]},exports.parseCacheControl=function(r){var e=/(?:^|(?:\s*\,\s*))([^\x00-\x20\(\)<>@\,;\:\\"\/\[\]\?\=\{\}\x7F]+)(?:\=(?:([^\x00-\x20\(\)<>@\,;\:\\"\/\[\]\?\=\{\}\x7F]+)|(?:\"((?:[^"\\]|\\.)*)\")))?/g,t={};if(r.replace(e,function(r,e,n,o){var a=n||o;return t[e]=!a||a.toLowerCase(),""}),t["max-age"]){var n=parseInt(t["max-age"],10);isNaN(n)?delete t["max-age"]:t["max-age"]=n}return t};
  438 +},{"../geo/coordinate":60,"@mapbox/unitbezier":3,"point-geometry":25}],216:[function(_dereq_,module,exports){
  439 +"use strict";var Feature=function(e,t,r,o){this.type="Feature",this._vectorTileFeature=e,e._z=t,e._x=r,e._y=o,this.properties=e.properties,null!=e.id&&(this.id=e.id)},prototypeAccessors={geometry:{}};prototypeAccessors.geometry.get=function(){return void 0===this._geometry&&(this._geometry=this._vectorTileFeature.toGeoJSON(this._vectorTileFeature._x,this._vectorTileFeature._y,this._vectorTileFeature._z).geometry),this._geometry},prototypeAccessors.geometry.set=function(e){this._geometry=e},Feature.prototype.toJSON=function(){var e=this,t={geometry:this.geometry};for(var r in e)"_geometry"!==r&&"_vectorTileFeature"!==r&&(t[r]=e[r]);return t},Object.defineProperties(Feature.prototype,prototypeAccessors),module.exports=Feature;
  440 +},{}],217:[function(_dereq_,module,exports){
  441 +"use strict";var scriptDetection=_dereq_("./script_detection");module.exports=function(t){for(var o="",e=0;e<t.length;e++){var r=t.charCodeAt(e+1)||null,l=t.charCodeAt(e-1)||null,i=(!r||!scriptDetection.charHasRotatedVerticalOrientation(r)||module.exports.lookup[t[e+1]])&&(!l||!scriptDetection.charHasRotatedVerticalOrientation(l)||module.exports.lookup[t[e-1]]);o+=i&&module.exports.lookup[t[e]]?module.exports.lookup[t[e]]:t[e]}return o},module.exports.lookup={"!":"?","#":"��",$:"��","%":"��","&":"��","(":"��",")":"��","*":"��","+":"��",",":"?","-":"?",".":"?","/":"��",":":"?",";":"?","<":"��","=":"��",">":"��","?":"?","@":"��","[":"?","\\":"��","]":"?","^":"��",_:"��","`":"��","{":"��","|":"�D","}":"��","~":"��","?":"��","?":"��","?":"��","?":"�W","?":"�V","?":"��","�C":"?","��":"��","��":"��","��":"��","��":"��","��":"��","��":"?","?":"?","?":"?","��":"?","��":"?","��":"��","��":"��","��":"��","��":"��","��":"��","��":"��","��":"��","��":"��","��":"��","��":"��","��":"��","��":"��","��":"?","��":"?","��":"?","��":"��","��":"��","��":"?","��":"?","��":"?","��":"?","��":"?","��":"��","��":"��","��":"?","��":"?","��":"?","��":"��","��":"��","��":"�D","��":"��","?":"��","?":"��","?":"?","?":"��","?":"��"};
  442 +},{"./script_detection":210}],218:[function(_dereq_,module,exports){
  443 +"use strict";var WebWorker=_dereq_("./web_worker"),WorkerPool=function(){this.active={}};WorkerPool.prototype.acquire=function(r){var e=this;if(!this.workers){var o=_dereq_("../").workerCount;for(this.workers=[];this.workers.length<o;)e.workers.push(new WebWorker)}return this.active[r]=!0,this.workers.slice()},WorkerPool.prototype.release=function(r){delete this.active[r],0===Object.keys(this.active).length&&(this.workers.forEach(function(r){r.terminate()}),this.workers=null)},module.exports=WorkerPool;
  444 +},{"../":64,"./web_worker":195}]},{},[64])(64)
  445 +});
  446 +
  447 +
  448 +//# sourceMappingURL=mapbox-gl.js.map
  1 +html { font-family: sans-serif; background: #eee; padding: 1rem; }
  2 +body { max-width: 960px; margin: 0 auto; background: white; }
  3 +h1 { font-family: serif; color: #377ba8; margin: 1rem 0; }
  4 +a { color: #377ba8; }
  5 +hr { border: none; border-top: 1px solid lightgray; }
  6 +nav { background: lightgray; display: flex; align-items: center; padding: 0 0.5rem; }
  7 +nav h1 { flex: auto; margin: 0; }
  8 +nav h1 a { text-decoration: none; padding: 0.25rem 0.5rem; }
  9 +nav ul { display: flex; list-style: none; margin: 0; padding: 0; }
  10 +nav ul li a, nav ul li span, header .action { display: block; padding: 0.5rem; }
  11 +.content { padding: 0 1rem 1rem; }
  12 +.content > header { border-bottom: 1px solid lightgray; display: flex; align-items: flex-end; }
  13 +.content > header h1 { flex: auto; margin: 1rem 0 0.25rem 0; }
  14 +.flash { margin: 1em 0; padding: 1em; background: #cae6f6; border: 1px solid #377ba8; }
  15 +.post > header { display: flex; align-items: flex-end; font-size: 0.85em; }
  16 +.post > header > div:first-of-type { flex: auto; }
  17 +.post > header h1 { font-size: 1.5em; margin-bottom: 0; }
  18 +.post .about { color: slategray; font-style: italic; }
  19 +.post .body { white-space: pre-line; }
  20 +.content:last-child { margin-bottom: 0; }
  21 +.content form { margin: 1em 0; display: flex; flex-direction: column; }
  22 +.content label { font-weight: bold; margin-bottom: 0.5em; }
  23 +.content input, .content textarea { margin-bottom: 1em; }
  24 +.content textarea { min-height: 12em; resize: vertical; }
  25 +input.danger { color: #cc2f2e; }
  26 +input[type=submit] { align-self: start; min-width: 10em; }
  1 +<!doctype html>
  2 +<title>{% block title %}{% endblock %} - KS</title>
  3 +<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
  4 +<nav>
  5 + <h1>DataManagerSystem</h1>
  6 + <ul>
  7 +{# {% if g.db %}#}
  8 +{# <li><a href="{{ url_for('data.index') }}">数据列表</a>#}
  9 +{# <li><a href="{{ url_for('databaseauth.logout') }}">Disconnet</a>#}
  10 +{# <li><a >{{g.host}}:{{g.database}}</a>#}
  11 +{# <li><a href="{{ url_for('data.add') }}">Add data</a>#}
  12 +{# {% else %}#}
  13 +{# <li><a href="{{ url_for('databaseauth.login') }}">Connect</a>#}
  14 +{# {% endif %}#}
  15 +
  16 +{# <li><a href="{{ url_for('data.index') }}">数据列表</a>#}
  17 +{# <li><a href="{{ url_for('data.add') }}">Register data</a>#}
  18 + </ul>
  19 +</nav>
  20 +<section class="content">
  21 + <header>
  22 + {% block header %}{% endblock %}
  23 + </header>
  24 + {% for message in get_flashed_messages() %}
  25 + <div class="flash">{{ message }}</div>
  26 + {% endfor %}
  27 + {% block content %}{% endblock %}
  28 +</section>
  1 +{% extends 'base.html' %}
  2 +
  3 +{% block header %}
  4 + <h1>{% block title %}添加分析服务{% endblock %}</h1>
  5 +{% endblock %}
  6 +
  7 +{% block content %}
  8 + <form method="post">
  9 +
  10 + <label for="dataGUID">dataGUID</label>
  11 + <input name="dataGUID" id="dataGUID" required>
  12 +
  13 + <label for="asGUID">asGUID</label>
  14 + <input name="asGUID" id="asGUID" required>
  15 +
  16 +
  17 + <input type="submit" value="添加">
  18 + </form>
  19 +{% endblock %}
  1 +{% extends 'base.html' %}
  2 +
  3 +{% block header %}
  4 + <h1>{% block title %}添加服务{% endblock %}</h1>
  5 +{% endblock %}
  6 +
  7 +{% block content %}
  8 + <form method="post">
  9 +
  10 + <label for="GUID">GUID</label>
  11 + <input name="GUID" id="GUID" required>
  12 +
  13 + <label for="serviceName">serviceName</label>
  14 + <input name="serviceName" id="serviceName">
  15 +
  16 + <label for="serviceUrl">serviceUrl</label>
  17 + <input name="serviceUrl" id="serviceUrl">
  18 +
  19 + <input type="submit" value="添加">
  20 + </form>
  21 +{% endblock %}
  1 +{% extends 'base.html' %}
  2 +
  3 +{% block header %}
  4 + <h1>{% block title %}删除分析服务{% endblock %}</h1>
  5 +{% endblock %}
  6 +
  7 +{% block content %}
  8 + <form method="post">
  9 +
  10 + <label for="dataGUID">dataGUID</label>
  11 + <input name="dataGUID" id="dataGUID" required>
  12 +
  13 + <label for="asGUID">asGUID</label>
  14 + <input name="asGUID" id="asGUID" required>
  15 +
  16 +
  17 + <input type="submit" value="删除">
  18 + </form>
  19 +{% endblock %}
  1 +{% extends 'base.html' %}
  2 +
  3 +{% block header %}
  4 + <h1>{% block title %}数据录入{% endblock %}</h1>
  5 +{% endblock %}
  6 +
  7 +{% block content %}
  8 + <form method="post" action="" enctype="multipart/form-data">
  9 + <label>Choose file</label>
  10 +
  11 + <input type="file" name="file" id="file" required>
  12 +
  13 + <input type="submit" value="上传红线">
  14 + </form>
  15 +{% endblock %}
  1 +{% extends 'base.html' %}
  2 +
  3 +{% block header %}
  4 + <h1>{% block title %}数据录入到指定元数据中{% endblock %}</h1>
  5 +{% endblock %}
  6 +
  7 +{% block content %}
  8 + <form method="post" action="" enctype="multipart/form-data">
  9 + <label>Choose file</label>
  10 +
  11 + <input type="file" name="file" id="file" required>
  12 +
  13 + <label for="GUID">GUID</label>
  14 + <input name="GUID" id="GUID" required>
  15 +
  16 + <input type="submit" value="录入">
  17 + </form>
  18 +{% endblock %}
  1 +{% extends 'base.html' %}
  2 +
  3 +{% block header %}
  4 + <h1>{% block title %}数据录入{% endblock %}</h1>
  5 +{% endblock %}
  6 +
  7 +{% block content %}
  8 + <form method="post" action="" enctype="multipart/form-data">
  9 + <label>Choose file</label>
  10 +
  11 + <input type="file" name="file" id="file" required>
  12 +
  13 + <label for="separator">separator</label>
  14 + <input name="separator" id="separator" required>
  15 +
  16 + <label for="dateTimeColumn">dateTimeColumn</label>
  17 + <input name="dateTimeColumn" id="dateTimeColumn" required>
  18 +
  19 + <label for="dateTimeFormat">dateTimeFormat</label>
  20 + <input name="dateTimeFormat" id="dateTimeFormat" required>
  21 +
  22 + <label for="databaseGUID">databaseGUID</label>
  23 + <input name="databaseGUID" id="databaseGUID" required>
  24 +
  25 +
  26 + <label for="tableName">tableName</label>
  27 + <input name="tableName" id="tableName" required>
  28 +
  29 +
  30 + <label for="ifExist">ifExist</label>
  31 + <input name="ifExist" id="ifExist" required>
  32 +{# <label for="table">Table</label>#}
  33 +{# <input name="table" id="table" required>#}
  34 +{# <label for="encode">encode</label>#}
  35 +{# <input name="encode" id="encode" required>#}
  36 + <input type="submit" value="录入">
  37 + </form>
  38 +{% endblock %}
  1 +{% extends 'base.html' %}
  2 +
  3 +{% block header %}
  4 + <h1>{% block title %}Data{% endblock %}</h1>
  5 +{% endblock %}
  6 +
  7 +{% block content %}
  8 + {% for post in posts %}
  9 + <div class="item">{{post}}</div>
  10 + {% endfor %}
  11 + <h1>Insert</h1>
  12 + {% for insertstate in insertstates %}
  13 + <div class="item2">{{insertstate}}</div>
  14 + {% endfor %}
  15 +{% endblock %}
  16 +
  1 +{% extends 'base.html' %}
  2 +
  3 +{% block header %}
  4 + <h1>{% block title %}注册分析服务{% endblock %}</h1>
  5 +{% endblock %}
  6 +
  7 +{% block content %}
  8 + <form method="post">
  9 +
  10 + <label for="name">name</label>
  11 + <input name="name" id="name" required>
  12 +
  13 + <label for="parameter">parameter</label>
  14 + <input name="parameter" id="parameter" required>
  15 +
  16 + <input type="submit" value="注册">
  17 +
  18 + </form>
  19 +{% endblock %}R
  1 +{% extends 'base.html' %}
  2 +
  3 +{% block header %}
  4 + <h1>{% block title %}注册数据{% endblock %}</h1>
  5 +{% endblock %}
  6 +
  7 +{% block content %}
  8 + <form method="post">
  9 +
  10 + <label for="alias">Alias</label>
  11 + <input name="alias" id="alias" required>
  12 +
  13 + <label for="resourcePath">ResourcePath</label>
  14 + <input name="resourcePath" id="resourcePath" required>
  15 +
  16 + <input type="submit" value="注册">
  17 +
  18 + </form>
  19 +{% endblock %}R
  1 +{% extends 'base.html' %}
  2 +
  3 +{% block header %}
  4 + <h1>{% block title %}注册元数据{% endblock %}</h1>
  5 +{% endblock %}
  6 +
  7 +{% block content %}
  8 + <form method="post">
  9 +
  10 + <label for="dataAlias">dataAlias</label>
  11 + <input name="dataAlias" id="dataAlias" required>
  12 +
  13 + <label for="tableName">tableName</label>
  14 + <input name="tableName" id="tableName" required>
  15 +
  16 + <label for="description">description</label>
  17 + <input name="description" id="description">
  18 +
  19 + <label for="dataTypeGUID">dataTypeGUID</label>
  20 + <input name="dataTypeGUID" id="dataTypeGUID">
  21 +
  22 + <label for="categoryGUID">categoryGUID</label>
  23 + <input name="categoryGUID" id="categoryGUID">
  24 +
  25 + <label for="coordinateName">coordinateName</label>
  26 + <input name="coordinateName" id="coordinateName">
  27 +
  28 + <label for="resourcePath">resourcePath</label>
  29 + <input name="resourcePath" id="resourcePath">
  30 +
  31 + <input type="submit" value="注册">
  32 + </form>
  33 +{% endblock %}
  1 +{% extends 'base.html' %}
  2 +
  3 +{% block header %}
  4 + <h1>{% block title %}注册Postgis数据{% endblock %}</h1>
  5 +{% endblock %}
  6 +
  7 +{% block content %}
  8 + <form method="post">
  9 +
  10 + <label for="host">Host</label>
  11 + <input name="host" id="host" required>
  12 +
  13 + <label for="port">Port</label>
  14 + <input name="port" id="port" required>
  15 +
  16 + <label for="database">Database</label>
  17 + <input name="database" id="database" required>
  18 +
  19 + <label for="user">User</label>
  20 + <input name="user" id="user" required>
  21 +
  22 + <label for="password">Password</label>
  23 + <input type="password" name="password" id="password" required>
  24 +
  25 + <label for="table">Table</label>
  26 + <input name="table" id="table" required>
  27 +
  28 + <input type="submit" value="注册">
  29 + </form>
  30 +{% endblock %}
  1 +{% extends 'base.html' %}
  2 +
  3 +{% block header %}
  4 + <h1>{% block title %}更新数据信息{% endblock %}</h1>
  5 +{% endblock %}
  6 +
  7 +{% block content %}
  8 + <form method="post">
  9 +
  10 + <label for="GUID">GUID</label>
  11 + <input name="GUID" id="GUID" required>
  12 +
  13 + <label for="dataAlias">dataAlias</label>
  14 + <input name="dataAlias" id="dataAlias">
  15 +
  16 +{# <label for="tableName">tableName</label>#}
  17 +{# <input name="tableName" id="tableName">#}
  18 +
  19 + <label for="coordinateName">coordinateName</label>
  20 + <input name="coordinateName" id="coordinateName">
  21 +
  22 + <label for="description">description</label>
  23 + <input name="description" id="description">
  24 +
  25 +
  26 + <label for="categoryGUID">categoryGUID</label>
  27 + <input name="categoryGUID" id="categoryGUID">
  28 +
  29 +
  30 + <label for="dataTypeGUID">dataTypeGUID</label>
  31 + <input name="dataTypeGUID" id="dataTypeGUID">
  32 +
  33 + <label for="departmentGUID">departmentGUID</label>
  34 + <input name="departmentGUID" id="departmentGUID">
  35 +
  36 + <label for="resourcePath">resourcePath</label>
  37 + <input name="resourcePath" id="resourcePath">
  38 +
  39 + <input type="submit" value="更新">
  40 + </form>
  41 +{% endblock %}
  1 +# Portuguese translations for PROJECT.
  2 +# Copyright (C) 2015 ORGANIZATION
  3 +# This file is distributed under the same license as the PROJECT project.
  4 +# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
  5 +#
  6 +#, fuzzy
  7 +msgid ""
  8 +msgstr ""
  9 +"Project-Id-Version: PROJECT VERSION\n"
  10 +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
  11 +"POT-Creation-Date: 2015-10-26 13:23+0000\n"
  12 +"PO-Revision-Date: 2015-10-26 13:22+0000\n"
  13 +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
  14 +"Language-Team: pt <LL@li.org>\n"
  15 +"Plural-Forms: nplurals=2; plural=(n != 1)\n"
  16 +"MIME-Version: 1.0\n"
  17 +"Content-Type: text/plain; charset=utf-8\n"
  18 +"Content-Transfer-Encoding: 8bit\n"
  19 +"Generated-By: Babel 2.0\n"
  20 +
  21 +#: app/templates/404.html:4
  22 +msgid "Page not found"
  23 +msgstr "Página não encontrada"
  24 +
  1 +# coding=utf-8
  2 +
  3 +import datetime
  4 +import importlib
  5 +import inspect
  6 +import json
  7 +import pkgutil
  8 +
  9 +from osgeo import ogr
  10 +import configure
  11 +import math
  12 +from flask import request
  13 +import zipfile
  14 +import os
  15 +from flask import current_app
  16 +from sqlalchemy import create_engine
  17 +from sqlalchemy.orm import sessionmaker,session
  18 +
  19 +# 蓝图的父类,用作标识蓝图
  20 +class BlueprintApi():
  21 + pass
  22 +
  23 +# 递归查找某个模块下特定父类的子类
  24 +def find_class(modname, class_name):
  25 + module = importlib.import_module(modname)
  26 + path = getattr(module, "__path__", None)
  27 + basename = module.__name__ + "."
  28 +
  29 + for _importer, modname, ispkg in pkgutil.iter_modules(path):
  30 + modname = basename + modname
  31 + if ispkg:
  32 + for name, obj in inspect.getmembers(importlib.import_module(modname), inspect.isclass):
  33 + if obj.__base__ == class_name:
  34 + yield obj
  35 + for i in find_class(modname, class_name):
  36 + yield i
  37 +
  38 +#
  39 +#
  40 +# # 从sqlachemy_uri解析出相关信息
  41 +# def get_info_from_sqlachemy_uri(uri):
  42 +# parts = uri.split(":")
  43 +# user = parts[1][2:]
  44 +#
  45 +# password_list = parts[2].split("@")
  46 +# if password_list.__len__()>2:
  47 +# password = "@".join(password_list[:-1])
  48 +# else:
  49 +# password = parts[2].split("@")[0]
  50 +# host = parts[2].split("@")[-1]
  51 +# port = parts[3].split("/")[0]
  52 +# database = parts[3].split("/")[1]
  53 +# return user, password, host, port, database
  54 +#
  55 +#
  56 +# # 获取请求参数
  57 +# def get_parameter():
  58 +# parameter = {}
  59 +# parameter.update(request.args.items())
  60 +# parameter.update(request.form.items())
  61 +# try:
  62 +# request_json = request.get_json()
  63 +# if json:
  64 +# parameter.update(request_json)
  65 +# except:
  66 +# pass
  67 +# for key in parameter.keys():
  68 +# if parameter.get(key) == "":
  69 +# parameter[key] = None
  70 +# return parameter
  71 +#
  72 +#
  73 +# def togeojson(dict):
  74 +# geojson = {}
  75 +# geojson["type"] = "Feature"
  76 +# geojson["geometry"] = json.loads(dict.pop("geojson"))
  77 +# del dict["geojson"]
  78 +# if dict.get("wkb_geometry"):
  79 +# del dict["wkb_geometry"]
  80 +# geojson["properties"] = dict
  81 +# return geojson
  82 +#
  83 +#
  84 +# def to_feature_collection(result):
  85 +# geojsonresult = [togeojson(x) for x in result]
  86 +# data = {}
  87 +# data["type"] = "FeatureCollection"
  88 +# data["features"] = geojsonresult
  89 +# return data
  90 +#
  91 +#
  92 +# def getType(layer):
  93 +# origin = layer.GetGeomType() # type:str
  94 +# if origin == 1 or origin == 4:
  95 +# return "point"
  96 +# elif origin == 2 or origin == 5:
  97 +# return "linestring"
  98 +# elif origin == 3 or origin == 6:
  99 +# return "polygon"
  100 +# return str(origin)
  101 +#
  102 +#
  103 +# def objects_to_jsonarray(object):
  104 +# result = []
  105 +# for o in object:
  106 +# result.append(object_to_json(o))
  107 +# return result
  108 +#
  109 +#
  110 +# def object_to_json(object):
  111 +# info = {}
  112 +# if object:
  113 +# info = object.__dict__
  114 +# try:
  115 +# del info['_sa_instance_state']
  116 +# except:
  117 +# pass
  118 +# for key in info:
  119 +# if isinstance(info[key], datetime.datetime):
  120 +# info[key] = info[key].strftime('%Y-%m-%d %H:%M:%S')
  121 +# if isinstance(info[key], datetime.time):
  122 +# info[key] = info[key].strftime('%H:%M:%S')
  123 +# return info
  124 +#
  125 +#
  126 +# def create_zip(path, filepaths: list):
  127 +# """
  128 +# 创建ZIP文件 并写入文件 (支持大文件夹)
  129 +# :param path: 创建的ZIP文件路径
  130 +# :param filepaths:
  131 +# :return:
  132 +# """
  133 +# try:
  134 +# with zipfile.ZipFile(path, 'w', zipfile.ZIP_DEFLATED) as zip:
  135 +# for filepath in filepaths:
  136 +# if os.path.isdir(filepath):
  137 +# pre_len = len(os.path.dirname(filepath))
  138 +# for parent, dirnames, filenames in os.walk(filepath):
  139 +# for filename in filenames:
  140 +# pathfile = os.path.join(parent, filename)
  141 +# if pathfile != path: # 避免将新创建的zip写入该zip文件
  142 +# arcname = pathfile[pre_len:].strip(os.path.sep) # 相对路径 不进行则会生成目录树
  143 +# zip.write(pathfile, arcname)
  144 +# elif os.path.isfile(filepath):
  145 +# zip.write(filepath, os.path.basename(filepath))
  146 +# else:
  147 +# print("创建zip文件对象失败!原因:未识别到路径")
  148 +# return "创建zip文件对象失败!原因:未识别到路径"
  149 +# return True
  150 +#
  151 +# except Exception as e:
  152 +# print("创建zip文件对象失败!原因:%s" % str(e))
  153 +# return "创建zip文件对象失败!原因:%s" % str(e)
  154 +#
  155 +# def unzip(store_file):
  156 +# #处理zip
  157 +# store_path = os.path.dirname(store_file)
  158 +# zip_file = zipfile.ZipFile(store_file, 'r')
  159 +#
  160 +# #是否要重命名文件夹
  161 +# rename_path = False
  162 +# rename_path_origin=None
  163 +# rename_path_after =None
  164 +# for names in zip_file.namelist():
  165 +# #zipfile解压中文文件会有编码问题,需要解压后重命名
  166 +# try:
  167 +# name_t = names.encode('cp437').decode('gbk')
  168 +# except:
  169 +# name_t = names.encode('utf-8').decode('utf-8')
  170 +#
  171 +# zip_file.extract(names,store_path,)
  172 +#
  173 +# os.chdir(store_path) # 切换到目标目录
  174 +#
  175 +# if names.__contains__("/"):
  176 +# pat = names.split("/")
  177 +# pat2 = name_t.split("/")[-1]
  178 +# pat[-1] = pat2
  179 +# name_tt = "/".join(pat)
  180 +# os.rename(names, name_tt)
  181 +# if not names[-1].__eq__("/"):
  182 +# rename_path = True
  183 +# rename_path_origin = names.split("/")[:-1]
  184 +# rename_path_after = name_t.split("/")[:-1]
  185 +# else:
  186 +#
  187 +# os.rename(names, name_t) # 重命名文件
  188 +# # 重命名文件夹
  189 +# if rename_path:
  190 +# for i in range(len(rename_path_origin),0,-1):
  191 +# origin = "/".join(rename_path_origin[:i])
  192 +# rename_path_origin[i-1] = rename_path_after[i-1]
  193 +# after = "/".join(rename_path_origin[:i])
  194 +# os.rename(origin, after)
  195 +#
  196 +# os.chdir(os.path.dirname(store_path))
  197 +# zip_file.close()
  198 +#
  199 +#
  200 +#
  201 +# file_for_open = None
  202 +# encoding = None
  203 +# for root, dirs, files in os.walk(store_path):
  204 +# for fn in files:
  205 +# if fn.endswith("shp"):
  206 +# file_for_open = os.path.join(root, fn)
  207 +# if fn.endswith("cpg"):
  208 +# with open(os.path.join(root, fn)) as fd:
  209 +# encoding = fd.readline().strip()
  210 +# if fn.endswith("gdb"):
  211 +# print(fn)
  212 +# file_for_open =root
  213 +#
  214 +# return file_for_open,encoding
  215 +#
  216 +# def open_pg_data_source(iswrite,uri=configure.SQLALCHEMY_DATABASE_URI):
  217 +# """
  218 +# # 获取PostGIS数据源
  219 +# :return:
  220 +# """
  221 +# db_conn_tuple = get_info_from_sqlachemy_uri(uri)
  222 +# fn = "PG: user=%s password=%s host=%s port=%s dbname=%s " % db_conn_tuple
  223 +# driver = ogr.GetDriverByName("PostgreSQL")
  224 +# if driver is None:
  225 +# raise Exception("打开PostgreSQL驱动失败,可能是当前GDAL未支持PostgreSQL驱动!")
  226 +# ds = driver.Open(fn, iswrite)
  227 +# if ds is None:
  228 +# raise Exception("打开数据源失败!")
  229 +# return ds
  230 +#
  231 +#
  232 +# def is_chinese(string):
  233 +# """
  234 +# 检查整个字符串是否包含中文
  235 +# :param string: 需要检查的字符串
  236 +# :return: bool
  237 +# """
  238 +# for ch in string:
  239 +# if u'\u4e00' <= ch <= u'\u9fff':
  240 +# return True
  241 +#
  242 +# return False
  243 +#
  244 +#
  245 +# def get_db_session(db_url=configure.SQLALCHEMY_DATABASE_URI,autocommit=False) -> session:
  246 +# engine = create_engine(db_url)
  247 +# system_session = sessionmaker(bind=engine,autocommit=autocommit)()
  248 +# return system_session
  249 +#
  250 +#
  251 +# class Queue:
  252 +# def __init__(self):
  253 +# self.items = []
  254 +# def init(self,items):
  255 +# self.items = items
  256 +# def empty(self):
  257 +# return self.items == []
  258 +# def append(self, item):
  259 +# self.items.insert(0,item)
  260 +# def pop(self):
  261 +# return self.items.pop()
  262 +# def size(self):
  263 +# return len(self.items)
  264 +# def __str__(self):
  265 +# return self.items.__str__()
  266 +#
  267 +# def structured_print(mes,type="info"):
  268 +# message = "[{}] {} {}".format(type.upper(),datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), mes)
  269 +# print(message)
  270 +#
  271 +#
  272 +#
  273 +# if __name__ == '__main__':
  274 +# print(get_info_from_sqlachemy_uri("postgresql://postgres:CDchinadci@2020@10.48.0.50:5432/dcidms"))
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/5/18
  4 +#email: nheweijun@sina.com
  5 +from app.util.component.ParameterUtil import ParameterUtil,StructurePrint
  6 +from flask import current_app
  7 +import traceback
  8 +import json
  9 +class ApiTemplate:
  10 + #模板方法
  11 + para = dict()
  12 + api_doc = dict()
  13 + api_name="[未命名]"
  14 + def __init__(self):
  15 + pass
  16 + def get_para(self):
  17 + self.para = ParameterUtil.get_parameter()
  18 + def para_check(self):
  19 + pass
  20 + def process(self):
  21 + pass
  22 + def log(self):
  23 + current_app.logger.info("{}调用了:{},参数为:{}".format(self.para.get("apiuser","4N"),self.api_name,json.dumps(self.para,ensure_ascii=False)))
  24 + # 接口模板
  25 + @property
  26 + def result(self):
  27 + try:
  28 + self.get_para()
  29 + self.para_check()
  30 + self.log()
  31 + res = self.process()
  32 + except Exception as e:
  33 + res=dict()
  34 + res["result"]=False
  35 + res["msg"]=e.__str__()
  36 + current_app.logger.error(e.__str__()+":"+ traceback.format_exc())
  37 + return res
  38 +
  39 +
  1 +
  2 +from osgeo.ogr import *
  3 +from osgeo import ogr
  4 +from osgeo import gdal
  5 +import os
  6 +import uuid
  7 +import shutil
  8 +import time
  9 +from app.models import *
  10 +from app.util.component.PGUtil import PGUtil
  11 +from app.util.component.StructuredPrint import StructurePrint
  12 +from sqlalchemy.orm import Session
  13 +import configure
  14 +import copy
  15 +class EntryData:
  16 +
  17 + def entry(self,parameter):
  18 + meta:dict = parameter.get("meta")
  19 +
  20 + #设置编码
  21 + encoding = parameter.get("encoding")
  22 + if encoding:
  23 + gdal.SetConfigOption("SHAPE_ENCODING",encoding)
  24 + else:
  25 + gdal.SetConfigOption("SHAPE_ENCODING", "GBK")
  26 +
  27 + #如果包含cpg文件,优先使用cpg文件中声明的编码
  28 + encoding_cpg = meta.get("encoding")
  29 + if encoding_cpg:
  30 + gdal.SetConfigOption("SHAPE_ENCODING", encoding_cpg)
  31 +
  32 +
  33 + # 初始化任务
  34 + this_task = ThisTask(parameter)
  35 + data_path = meta.get("data_path")
  36 +
  37 + try:
  38 + this_task.write_process("入库任务初始化...")
  39 +
  40 + this_task.update({"process": "入库中"})
  41 + is_success = None
  42 + if not data_path:
  43 + raise Exception("数据错误!")
  44 + # 分为shp和gdb 2种录入形式
  45 +
  46 + # 开始事务
  47 + this_task.pg_ds.StartTransaction()
  48 + if data_path.endswith("shp"):
  49 + is_success,new_layer_name = self.entry_shp(data_path,this_task)
  50 +
  51 + if data_path.endswith("gdb"):
  52 + is_success,new_layer_names = self.entry_gdb(data_path,this_task)
  53 +
  54 + this_task.write_process("数据入库结束。")
  55 +
  56 + if is_success:
  57 + # 更新任务为成功任务
  58 + this_task.pg_ds.CommitTransaction()
  59 + this_task.update({"state": 1,"process":"入库完成","update_time": datetime.datetime.now()})
  60 + else:
  61 + # 更新任务为失败任务
  62 + this_task.update({"state": -1, "process": "入库失败", "update_time": datetime.datetime.now()})
  63 + # rollback
  64 + this_task.pg_ds.RollbackTransaction()
  65 + except Exception as e:
  66 + this_task.write_process("{} 任务结束!".format(e.__str__()))
  67 + this_task.update({"state": -1, "process": "入库失败", "update_time": datetime.datetime.now()})
  68 + StructurePrint.print(e.__str__(),"ERROR")
  69 + # rollback
  70 + this_task.pg_ds.RollbackTransaction()
  71 + finally:
  72 + this_task.end()
  73 + try:
  74 + file_tmp_path = os.path.join(data_path.split("file_tmp")[0],"file_tmp")
  75 + dir_path = os.path.dirname(data_path)
  76 + i=0
  77 + while not os.path.dirname(dir_path).__eq__(file_tmp_path) and i<30:
  78 + dir_path = os.path.dirname(dir_path)
  79 + i+=1
  80 + if i<30:
  81 + shutil.rmtree(dir_path,True)
  82 + StructurePrint.print("删除文件成功!")
  83 + else:
  84 + raise Exception("找不到文件!")
  85 +
  86 + except Exception as e:
  87 + StructurePrint.print(e.__str__(), "ERROR")
  88 + StructurePrint.print("删除文件失败!","ERROR")
  89 +
  90 + def entry_shp(self,data_path,this_task):
  91 + '''
  92 + 录入shp
  93 + :param data_path:
  94 + :return:
  95 + '''
  96 +
  97 + driver: Driver = ogr.GetDriverByName("ESRI Shapefile")
  98 + ds: DataSource = driver.Open(data_path, 1)
  99 + if not ds:
  100 + raise Exception("打开数据失败!")
  101 + layer: Layer = ds.GetLayer(0)
  102 +
  103 + return self.entry_one_layer(layer, this_task)
  104 +
  105 + def entry_gdb(self,data_path,this_task):
  106 + '''
  107 + 录入gdb
  108 + :param data_path:
  109 + :return:
  110 + '''
  111 +
  112 + is_successes = []
  113 + new_layer_names=[]
  114 + driver: Driver = ogr.GetDriverByName("OpenFileGDB")
  115 + ds: DataSource = driver.Open(data_path, 0)
  116 + if not ds:
  117 + raise Exception("打开数据失败!")
  118 +
  119 +
  120 + for i in range(ds.GetLayerCount()):
  121 + layer: Layer = ds.GetLayer(i)
  122 + is_success, new_layer_name = self.entry_one_layer(layer,this_task)
  123 + new_layer_names.append(new_layer_name)
  124 + is_successes.append(is_success)
  125 +
  126 + if is_successes.__contains__(False):
  127 + return False,new_layer_names
  128 + else:
  129 + return True,new_layer_names
  130 +
  131 + def entry_one_layer(self,layer: Layer,this_task):
  132 +
  133 + # this_task.pg_ds.StartTransaction()
  134 + new_layer_name = None
  135 +
  136 +
  137 + try:
  138 + # 图层设置
  139 + parameter = this_task.parameter
  140 +
  141 + meta: dict = parameter.get("meta")
  142 + overwrite = parameter.get("overwrite") if parameter.get("overwrite") is not None and parameter.get("overwrite")=="yes" else "no"
  143 + geom_name = parameter.get("geom_name") if parameter.get("geom_name") is not None else "geom"
  144 + fid = parameter.get("fid") if parameter.get("fid") is not None else "fid"
  145 + options = ["OVERWRITE={}".format(overwrite), "FID={}".format(fid), "GEOMETRY_NAME={}".format(geom_name),"PRECISION=NO"]
  146 +
  147 +
  148 +
  149 + # # 中文名处理
  150 + # chinese = is_chinese(new_layer_name)
  151 + # if chinese:
  152 + # new_layer_name = new_layer_name.__hash__()
  153 +
  154 + # 将线/面转多线多面,dmap只支持多线面
  155 + geom_type = self.change_geom_type(layer.GetGeomType())
  156 +
  157 + # 更改图层名
  158 + change_name = False
  159 + origin_name = layer.GetName().lower()
  160 +
  161 + # 新图层名
  162 + new_layer_name: str = meta.get("layer").get(origin_name)
  163 + origin_name = new_layer_name
  164 + no = 1
  165 + while overwrite.__eq__("no") and this_task.pg_ds.GetLayerByName(new_layer_name) :
  166 + change_name=True
  167 + new_layer_name = origin_name+"_{}".format(no)
  168 + no+=1
  169 +
  170 + if change_name:
  171 + this_task.write_process("{}图层已存在,更名为{}入库".format(origin_name, new_layer_name))
  172 +
  173 +
  174 + this_task.write_process("{}图层正在入库...".format(new_layer_name))
  175 +
  176 + pg_layer: Layer = this_task.pg_ds.CreateLayer(new_layer_name, layer.GetSpatialRef(), geom_type, options)
  177 +
  178 + # 复制原图层的属性
  179 + # 去掉fid的属性
  180 + schema = [sche for sche in layer.schema if not sche.name.__eq__(fid)]
  181 +
  182 + pg_layer.CreateFields(schema)
  183 +
  184 + count =0
  185 + this_time = time.time()
  186 + for feature in layer:
  187 + count+=1
  188 + if count%10000==0:
  189 + StructurePrint.print("{}图层已入库{}个对象".format(new_layer_name,count))
  190 + # print(time.time()-this_time)
  191 + this_time=time.time()
  192 + geo :Geometry = feature.GetGeometryRef()
  193 + # 如果是空对象不录入
  194 + if geo is not None:
  195 + if geo.IsEmpty():
  196 + this_task.write_process("FID:{}要素的空间字段为空,跳过该要素!".format(feature.GetFID()))
  197 + StructurePrint.print("FID:{}要素的空间字段为空,跳过该要素!".format(feature.GetFID()),"WARN")
  198 + continue
  199 + out_feature: Feature = copy.copy(feature)
  200 +
  201 + if geo is not None:
  202 + out_geom:Geometry = self.change_geom(geo, geom_type)
  203 + out_feature.SetGeometry(out_geom)
  204 +
  205 + pg_layer.CreateFeature(out_feature)
  206 +
  207 + # 注册图层信息
  208 + this_task.register_table(pg_layer,new_layer_name,overwrite,parameter.get("creator"))
  209 + this_task.write_process("{}图层入库成功。".format(new_layer_name))
  210 + except Exception as e:
  211 + # this_task.pg_ds.RollbackTransaction()
  212 + this_task.write_process("{}入库失败,数据回滚!原因:{}".format(new_layer_name,e.__str__()))
  213 + StructurePrint.print("{}入库失败,数据回滚!原因:{}".format(new_layer_name,e.__str__()), "error")
  214 + return False,new_layer_name
  215 + # finally:
  216 +
  217 + return True,new_layer_name
  218 +
  219 + def entry_feature(self):
  220 + pass
  221 +
  222 +
  223 + def change_geom_type(self,raw):
  224 + if raw.__eq__(-2147483646):
  225 + return 5
  226 + if raw.__eq__(-2147483645):
  227 + return 6
  228 + if raw==2 or raw ==3:
  229 + return raw+3
  230 + if raw==4:
  231 + return 1
  232 + return raw
  233 +
  234 + def get_table_type(self,raw):
  235 + if raw==4 or raw ==5 or raw ==6:
  236 + return raw-3
  237 + return raw
  238 +
  239 + def change_geom(self,geo:Geometry,geom_type):
  240 + '''
  241 + 转换空间对象的类型,以适应dmap只支持Multi类型
  242 + :param geo:
  243 + :param geom_type:
  244 + :return: 转换后的空间对象
  245 + '''
  246 +
  247 +
  248 + # Point = 1,
  249 + # LineString = 2,
  250 + # Polygon = 3,
  251 + # MultiPoint = 4,
  252 + # MultiLineString = 5,
  253 + # MultiPolygon = 6,
  254 + # GeometryCollection = 7,
  255 + # CircularString = 8,
  256 + # CompoundCurve = 9,
  257 + # CurvePolygon = 10,
  258 + # MultiCurve = 11,
  259 + # MultiSurface = 12,
  260 + # PolyhedralSurface = 15,
  261 + # LinearRing = 101,
  262 +
  263 + # MultiPointZ = -2147483644
  264 + # MultiPolygonZ = -2147483643
  265 + # MultiLineStringZ = -2147483642
  266 +
  267 +
  268 + # PointZ = -2147483647
  269 + # LINESTRINGZ=-2147483646
  270 + # POLYGONZ=-2147483645
  271 +
  272 + if geom_type==5 or geom_type.__eq__(-2147483646):
  273 + return ogr.ForceToMultiLineString(geo)
  274 + if geom_type==6 or geom_type.__eq__(-2147483645):
  275 + return ogr.ForceToMultiPolygon(geo)
  276 + if geom_type==1:
  277 + # 多点转单点,会有问题,只拿了第一个点
  278 + xy = geo.GetPoint()
  279 + point = ogr.Geometry(ogr.wkbPoint)
  280 + point.AddPoint(xy[0], xy[1])
  281 + return point
  282 + return geo
  283 +
  284 + def write_task_process(self,session, task_guid, message):
  285 + '''
  286 + 写详细过程
  287 + :param session:
  288 + :param task_guid:
  289 + :param message:
  290 + :return:
  291 + '''
  292 +
  293 + task_process_guid = uuid.uuid1().__str__()
  294 + task_process = Process(guid=task_process_guid,
  295 + message=message,
  296 + time=datetime.datetime.now(),
  297 + task_guid=task_guid)
  298 + session.add(task_process)
  299 +
  300 +
  301 + def data_check(self):
  302 + pass
  303 +
  304 +class ThisTask:
  305 +
  306 + def __init__(self, parameter):
  307 + try:
  308 + self.sys_session: Session = PGUtil.get_db_session(configure.SQLALCHEMY_DATABASE_URI)
  309 + except Exception as e:
  310 + raise Exception("打开数据库失败!")
  311 + self.parameter = parameter
  312 +
  313 + # # 初始化task
  314 + # task = Task(guid=parameter.get("task_guid"), name=parameter.get("task_name"),create_time=datetime.datetime.now(),state=0)
  315 + # self.sys_session.add(task)
  316 + # self.sys_session.commit()
  317 +
  318 + self.task = self.sys_session.query(Task).filter_by(guid=parameter.get("task_guid"))
  319 +
  320 + self.database = self.sys_session.query(Database).filter_by(
  321 + guid=parameter.get("database_guid")).one_or_none()
  322 +
  323 + self.catalog_guid = parameter.get("catalog_guid")
  324 +
  325 + self.pg_ds: DataSource = PGUtil.open_pg_data_source(1, DES.decode(self.database.sqlalchemy_uri))
  326 +
  327 + if self.pg_ds is None:
  328 + raise Exception("打开系统数据库失败!")
  329 +
  330 + def update(self, update_dict):
  331 + self.task.update(update_dict)
  332 + self.sys_session.commit()
  333 +
  334 + def write_process(self, message):
  335 + message = "{} {}".format(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), message)
  336 + task_process_guid = uuid.uuid1().__str__()
  337 + task_process = Process(guid=task_process_guid, message=message, time=datetime.datetime.now(),
  338 + task_guid=self.parameter.get("task_guid"))
  339 + self.sys_session.add(task_process)
  340 + self.sys_session.commit()
  341 +
  342 + def register_table(self, layer: Layer, new_layer_name, overwrite, creator):
  343 + '''
  344 + 注册表
  345 + :param layer: 图层
  346 + :param new_layer_name: 图层名
  347 + :return: 表名
  348 + '''
  349 +
  350 + # 在覆盖模式下,删除原有记录
  351 + if overwrite.__eq__("yes"):
  352 + old_table = self.sys_session.query(Table).filter_by(name=new_layer_name).one_or_none()
  353 + if old_table:
  354 + self.sys_session.delete(old_table)
  355 + self.sys_session.commit()
  356 +
  357 + this_time = datetime.datetime.now()
  358 +
  359 + ext = layer.GetExtent()
  360 + if ext[0] < 360:
  361 + ext = [round(e, 6) for e in ext]
  362 + else:
  363 + ext = [round(e, 2) for e in ext]
  364 +
  365 + # extent = "西:{},东:{},南:{},北:{}".format(ext[0],ext[1],ext[2],ext[3])
  366 + extent = "{},{},{},{}".format(ext[0], ext[1], ext[2], ext[3])
  367 +
  368 + # 其他相同库也更新
  369 + connectstr = self.database.connectstr
  370 + databs = self.sys_session.query(Database).filter_by(connectstr=connectstr).all()
  371 + databs_guid = [d.guid for d in databs]
  372 + for d_guid in databs_guid:
  373 + table_guid = uuid.uuid1().__str__()
  374 + table = Table(guid=table_guid,
  375 + database_guid=d_guid,
  376 + # alias=new_layer_name,
  377 + creator=creator,
  378 + name=new_layer_name, create_time=this_time, update_time=this_time,
  379 + catalog_guid=self.catalog_guid, table_type=self.get_table_type(layer.GetGeomType()),
  380 + extent=extent,
  381 + feature_count=layer.GetFeatureCount()
  382 + )
  383 + self.sys_session.add(table)
  384 +
  385 + feature_defn: FeatureDefn = layer.GetLayerDefn()
  386 +
  387 + for i in range(feature_defn.GetFieldCount()):
  388 + field_defn: FieldDefn = feature_defn.GetFieldDefn(i)
  389 + field_name = field_defn.GetName().lower()
  390 + field_alias = field_name if field_defn.GetAlternativeName() is None or field_defn.GetAlternativeName().__eq__(
  391 + "") else field_defn.GetAlternativeName()
  392 + column = Columns(guid=uuid.uuid1().__str__(), table_guid=table_guid,
  393 + name=field_name, alias=field_alias, create_time=this_time, update_time=this_time)
  394 + self.sys_session.add(column)
  395 +
  396 + self.sys_session.commit()
  397 +
  398 + def end(self):
  399 + if self.sys_session:
  400 + self.sys_session.close()
  401 + if self.pg_ds:
  402 + self.pg_ds.Destroy()
  403 +
  404 + def get_table_type(self,raw):
  405 + if raw==4 or raw ==5 or raw ==6:
  406 + return raw-3
  407 + return raw
  1 +
  2 +from osgeo.ogr import *
  3 +from osgeo import ogr
  4 +from osgeo import gdal
  5 +import os
  6 +import uuid
  7 +import shutil
  8 +import time
  9 +from app.models import *
  10 +from app.util.component.PGUtil import PGUtil
  11 +from app.util.component.StructuredPrint import StructurePrint
  12 +from sqlalchemy.orm import Session
  13 +import configure
  14 +import math
  15 +from functools import lru_cache
  16 +import traceback
  17 +import copy
  18 +from app.util.component.GeometryAdapter import GeometryAdapter
  19 +class EntryDataVacuate:
  20 +
  21 + def entry(self,parameter):
  22 + # meta:dict = parameter.get("meta")
  23 +
  24 + # 初始化任务
  25 + this_task = ThisTask(parameter)
  26 + this_task.write_process("入库任务初始化...")
  27 +
  28 + # 数据路径,用作删除
  29 + _data_path=None
  30 + try:
  31 + metas: list = parameter.get("meta")
  32 + # 总的入库是否成功
  33 + is_success=True
  34 +
  35 + this_task.update({"process": "入库中"})
  36 +
  37 + # 开始入库事务
  38 + this_task.start()
  39 +
  40 + # 多个文件依次入库
  41 + for meta in metas:
  42 + #设置编码
  43 + encoding = parameter.get("encoding")
  44 + if encoding:
  45 + gdal.SetConfigOption("SHAPE_ENCODING",encoding)
  46 + else:
  47 + gdal.SetConfigOption("SHAPE_ENCODING", "GBK")
  48 +
  49 + #如果包含cpg文件,优先使用cpg文件中声明的编码
  50 + encoding_cpg = meta.get("encoding")
  51 + if encoding_cpg:
  52 + gdal.SetConfigOption("SHAPE_ENCODING", encoding_cpg)
  53 +
  54 + data_path = meta.get("data_path")
  55 +
  56 + #设定删除路径
  57 + if not _data_path:
  58 + _data_path=data_path
  59 +
  60 +
  61 + if not data_path:
  62 + raise Exception("数据错误!")
  63 + # 分为shp和gdb 2种录入形式
  64 +
  65 + if data_path.endswith("shp"):
  66 + is_success_one,new_layer_name = self.entry_shp(data_path,this_task,meta)
  67 + else:
  68 + is_success_one,new_layer_names = self.entry_gdb(data_path,this_task,meta)
  69 +
  70 + #如果其中一个失败,总的入库就失败
  71 + if not is_success_one:
  72 + is_success=False
  73 +
  74 + this_task.write_process("数据入库结束。")
  75 +
  76 + if is_success:
  77 + # 更新任务为成功任务
  78 + this_task.update({"state": 1,"process":"入库完成","update_time": datetime.datetime.now()})
  79 + this_task.commit()
  80 + else:
  81 + # 更新任务为失败任务
  82 + this_task.update({"state": -1, "process": "入库失败", "update_time": datetime.datetime.now()})
  83 + # rollback
  84 + this_task.rollback()
  85 +
  86 + except Exception as e:
  87 + this_task.write_process("{} 任务结束!".format(e.__str__()))
  88 + this_task.update({"state": -1, "process": "入库失败", "update_time": datetime.datetime.now()})
  89 + StructurePrint.print(e.__str__(),"ERROR")
  90 + # rollback
  91 + this_task.rollback()
  92 + finally:
  93 + this_task.end()
  94 + try:
  95 + file_tmp_path = os.path.join(_data_path.split("file_tmp")[0],"file_tmp")
  96 + dir_path = os.path.dirname(_data_path)
  97 + i=0
  98 + while not os.path.dirname(dir_path).__eq__(file_tmp_path) and i<30:
  99 + dir_path = os.path.dirname(dir_path)
  100 + i+=1
  101 + if i<30:
  102 + shutil.rmtree(dir_path,True)
  103 + StructurePrint.print("删除文件成功!")
  104 + else:
  105 + raise Exception("找不到文件!")
  106 +
  107 + except Exception as e:
  108 + StructurePrint.print(e.__str__(), "ERROR")
  109 + StructurePrint.print("删除文件失败!","ERROR")
  110 +
  111 +
  112 + def entry_shp(self,data_path,this_task,meta):
  113 + '''
  114 + 录入shp
  115 + :param data_path:
  116 + :return:
  117 + '''
  118 +
  119 + driver: Driver = ogr.GetDriverByName("ESRI Shapefile")
  120 + ds: DataSource = driver.Open(data_path, 1)
  121 + if not ds:
  122 + raise Exception("打开数据失败!")
  123 + layer: Layer = ds.GetLayer(0)
  124 +
  125 + is_success_one, new_layer_name =self.entry_one_layer(layer, this_task,meta)
  126 + ds.Destroy()
  127 + return is_success_one, new_layer_name
  128 +
  129 + def entry_gdb(self,data_path,this_task,meta):
  130 + '''
  131 + 录入gdb
  132 + :param data_path:
  133 + :return:
  134 + '''
  135 +
  136 + is_successes = []
  137 + new_layer_names=[]
  138 + driver: Driver = ogr.GetDriverByName("OpenFileGDB")
  139 + ds: DataSource = driver.Open(data_path, 0)
  140 + if not ds:
  141 + raise Exception("打开数据失败!")
  142 +
  143 +
  144 + for i in range(ds.GetLayerCount()):
  145 + layer: Layer = ds.GetLayer(i)
  146 + is_success, new_layer_name = self.entry_one_layer(layer,this_task,meta)
  147 + new_layer_names.append(new_layer_name)
  148 + is_successes.append(is_success)
  149 + ds.Destroy()
  150 + if is_successes.__contains__(False):
  151 + return False,new_layer_names
  152 + else:
  153 + return True,new_layer_names
  154 +
  155 + def entry_one_layer(self,layer: Layer,this_task,meta):
  156 +
  157 + # this_task.pg_ds.StartTransaction()
  158 + new_layer_name = None
  159 + vacuate_process= None
  160 + success = True
  161 +
  162 + try:
  163 + # 图层设置
  164 + parameter = this_task.parameter
  165 +
  166 + overwrite = parameter.get("overwrite") if parameter.get("overwrite") is not None and parameter.get("overwrite")=="yes" else "no"
  167 + geom_name = parameter.get("geom_name") if parameter.get("geom_name") is not None else "geom"
  168 + fid = parameter.get("fid") if parameter.get("fid") is not None else "fid"
  169 + options = ["OVERWRITE={}".format(overwrite), "FID={}".format(fid), "GEOMETRY_NAME={}".format(geom_name),"PRECISION=NO"]
  170 +
  171 +
  172 + # 将线/面转多线多面
  173 + geom_type = GeometryAdapter.change_geom_type(layer.GetGeomType())
  174 +
  175 + # 更改图层名
  176 + change_name = False
  177 + origin_name = layer.GetName().lower()
  178 +
  179 + # 新图层名
  180 + new_layer_name: str = meta.get("layer").get(origin_name)
  181 + origin_name = new_layer_name
  182 + no = 1
  183 + while overwrite.__eq__("no") and this_task.pg_ds.GetLayerByName(new_layer_name) :
  184 + change_name=True
  185 + new_layer_name = origin_name+"_{}".format(no)
  186 + no+=1
  187 +
  188 + if change_name:
  189 + this_task.write_process("{}图层已存在,更名为{}入库".format(origin_name, new_layer_name))
  190 +
  191 +
  192 + this_task.write_process("{}图层正在入库...".format(new_layer_name))
  193 +
  194 + pg_layer: Layer = this_task.pg_ds.CreateLayer(new_layer_name, layer.GetSpatialRef(), geom_type, options)
  195 +
  196 + # 复制原图层的属性
  197 + # 去掉fid的属性
  198 + schema = [sche for sche in layer.schema if not sche.name.__eq__(fid)]
  199 + pg_layer.CreateFields(schema)
  200 +
  201 + #创建抽稀过程
  202 + vacuate_process = VacuateProcess(layer,new_layer_name,schema, geom_type, options,this_task.database.sqlalchemy_uri)
  203 +
  204 +
  205 +
  206 + count =0
  207 +
  208 + for feature in layer:
  209 + count+=1
  210 + if count%10000==0:
  211 + StructurePrint.print("{}图层已入库{}个对象".format(new_layer_name,count))
  212 + # print(time.time()-this_time)
  213 + #this_time=time.time()
  214 + geo :Geometry = feature.GetGeometryRef()
  215 + # 如果是空对象不录入
  216 + if geo is not None:
  217 + if geo.IsEmpty():
  218 + this_task.write_process("FID:{}要素的空间字段为空,跳过该要素!".format(feature.GetFID()))
  219 + StructurePrint.print("FID:{}要素的空间字段为空,跳过该要素!".format(feature.GetFID()),"WARN")
  220 + continue
  221 +
  222 + out_feature: Feature = copy.copy(feature)
  223 + out_geom = None
  224 + if geo is not None:
  225 + out_geom:Geometry = GeometryAdapter.change_geom(geo, geom_type)
  226 + out_feature.SetGeometry(out_geom)
  227 +
  228 + pg_layer.CreateFeature(out_feature)
  229 +
  230 + #插入抽稀图层
  231 + if out_geom is not None:
  232 + vacuate_process.vacuate(out_geom)
  233 +
  234 + # 注册图层信息
  235 + table_guid = this_task.register_table(pg_layer,new_layer_name,overwrite,parameter.get("creator"))
  236 +
  237 + # 注册抽稀表
  238 + this_task.register_table_vacuate(table_guid,vacuate_process.vacuate_layers)
  239 +
  240 + this_task.write_process("{}图层入库成功。".format(new_layer_name))
  241 +
  242 + except Exception as e:
  243 +
  244 + this_task.write_process("{}入库失败,数据回滚!原因:{}".format(new_layer_name,e.__str__()))
  245 + StructurePrint.print("{}入库失败,数据回滚!原因:{}".format(new_layer_name,e.__str__()), "error")
  246 + print(traceback.format_exc())
  247 + # 抽稀回滚
  248 + vacuate_process.rollback()
  249 + success =False
  250 +
  251 + finally:
  252 + vacuate_process.end()
  253 + return success,new_layer_name
  254 +
  255 +
  256 +
  257 +class ThisTask:
  258 +
  259 + def __init__(self, parameter):
  260 + try:
  261 + # 该任务事务的连接
  262 + self.sys_session: Session = PGUtil.get_db_session(configure.SQLALCHEMY_DATABASE_URI)
  263 + # 专门的写过程的连接
  264 + self.process_session: Session = PGUtil.get_db_session(configure.SQLALCHEMY_DATABASE_URI)
  265 +
  266 + except Exception as e:
  267 + raise Exception("打开数据库失败!")
  268 + self.parameter = parameter
  269 +
  270 + self.task = self.process_session.query(Task).filter_by(guid=parameter.get("task_guid"))
  271 +
  272 + self.database = self.sys_session.query(Database).filter_by(
  273 + guid=parameter.get("database_guid")).one_or_none()
  274 +
  275 + self.catalog_guid = parameter.get("catalog_guid")
  276 +
  277 + self.pg_ds: DataSource = PGUtil.open_pg_data_source(1, DES.decode(self.database.sqlalchemy_uri))
  278 +
  279 +
  280 + def start(self):
  281 + self.pg_ds.StartTransaction()
  282 +
  283 + def update(self, update_dict):
  284 + self.task.update(update_dict)
  285 + self.process_session.commit()
  286 +
  287 + def write_process(self, message):
  288 + message = "{} {}".format(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), message)
  289 + task_process_guid = uuid.uuid1().__str__()
  290 + task_process = Process(guid=task_process_guid, message=message, time=datetime.datetime.now(),
  291 + task_guid=self.parameter.get("task_guid"))
  292 + self.process_session.add(task_process)
  293 + self.process_session.commit()
  294 +
  295 + def register_table(self, layer: Layer, new_layer_name, overwrite, creator):
  296 + '''
  297 + 注册表
  298 + :param layer: 图层
  299 + :param new_layer_name: 图层名
  300 + :return: 表名
  301 + '''
  302 +
  303 + # 在覆盖模式下,删除原有记录
  304 + if overwrite.__eq__("yes"):
  305 + old_table = self.sys_session.query(Table).filter_by(name=new_layer_name).one_or_none()
  306 + if old_table:
  307 + self.sys_session.delete(old_table)
  308 +
  309 +
  310 + this_time = datetime.datetime.now()
  311 +
  312 + ext = layer.GetExtent()
  313 + if ext[0] < 360:
  314 + ext = [round(e, 6) for e in ext]
  315 + else:
  316 + ext = [round(e, 2) for e in ext]
  317 +
  318 + extent = "{},{},{},{}".format(ext[0], ext[1], ext[2], ext[3])
  319 + table_guid = uuid.uuid1().__str__()
  320 + table = Table(guid=table_guid,
  321 + database_guid=self.database.guid,
  322 + creator=creator,
  323 + name=new_layer_name, create_time=this_time, update_time=this_time,
  324 + catalog_guid=self.catalog_guid, table_type=GeometryAdapter.get_table_type(layer.GetGeomType()),
  325 + extent=extent,
  326 + feature_count=layer.GetFeatureCount()
  327 + )
  328 + # 删除遗留业务数据
  329 + history_table = self.sys_session.query(Table).filter_by(name=new_layer_name).all()
  330 + if history_table:
  331 + for ht in history_table:
  332 + self.sys_session.delete(ht)
  333 + self.sys_session.add(table)
  334 +
  335 + feature_defn: FeatureDefn = layer.GetLayerDefn()
  336 +
  337 + for i in range(feature_defn.GetFieldCount()):
  338 + field_defn: FieldDefn = feature_defn.GetFieldDefn(i)
  339 + field_name = field_defn.GetName().lower()
  340 + field_alias = field_name if field_defn.GetAlternativeName() is None or field_defn.GetAlternativeName().__eq__(
  341 + "") else field_defn.GetAlternativeName()
  342 + column = Columns(guid=uuid.uuid1().__str__(), table_guid=table_guid,
  343 + name=field_name, alias=field_alias, create_time=this_time, update_time=this_time)
  344 + self.sys_session.add(column)
  345 + return table_guid
  346 +
  347 +
  348 + def register_table_vacuate(self,table_guid,vacuate_layers:dict):
  349 +
  350 + # 抽稀表有固定的命名规则
  351 + for level,layer in vacuate_layers.items():
  352 + pixel_distance_str:str=layer.GetName().split("_")[-1]
  353 + if pixel_distance_str.startswith("0"):
  354 + pixel_distance_str="0.{}".format(pixel_distance_str)
  355 +
  356 + pixel_distance = float(pixel_distance_str)
  357 + table_vacuate = TableVacuate(guid=uuid.uuid1().__str__(),
  358 + table_guid=table_guid,
  359 + level=level,
  360 + name=layer.GetName(),
  361 + pixel_distance=pixel_distance)
  362 + self.sys_session.add(table_vacuate)
  363 +
  364 +
  365 + def commit(self):
  366 + if self.sys_session:
  367 + self.sys_session.commit()
  368 + if self.pg_ds:
  369 + self.pg_ds.CommitTransaction()
  370 + if self.process_session:
  371 + self.process_session.commit()
  372 +
  373 +
  374 + def end(self):
  375 + if self.sys_session:
  376 + self.sys_session.close()
  377 + if self.pg_ds:
  378 + self.pg_ds.Destroy()
  379 + if self.process_session:
  380 + self.process_session.close()
  381 +
  382 + def rollback(self):
  383 + if self.sys_session:
  384 + self.sys_session.rollback()
  385 + if self.pg_ds:
  386 + self.pg_ds.RollbackTransaction()
  387 +
  388 +
  389 +
  390 +class VacuateProcess:
  391 +
  392 + max_level=0
  393 + fill_dict={}
  394 + vacuate_layers={}
  395 + vacuate_layers_gridsize={}
  396 + pg_ds_dict = {}
  397 + # 图层要素大于5W才抽稀
  398 + least_vacuate_count = 20000
  399 +
  400 + extent=[]
  401 + is_spatial=False
  402 + # 网格大小是固定的,根据图层的信息滑动选取需要抽稀的等级
  403 + lonlat_gridsize=[0.000075,0.00015,0.0003,0.0006,0.0012,0.0024,0.0048,0.0096,0.0192,0.0384,0.0768]
  404 + project_gridsize=[15,30,60,120,240,480,960,1920,3840,7680]
  405 +
  406 + this_gridsize=[]
  407 +
  408 +
  409 + def __init__(self,layer:Layer,new_layer_name,schema, geom_type, options,sqlalchemy_uri):
  410 +
  411 + #是空间图层才初始化
  412 + if layer.GetExtent()[0] > 0 or layer.GetExtent()[0] < 0:
  413 +
  414 + self.is_spatial=True
  415 +
  416 + # 判断需要抽稀多少级
  417 +
  418 + lc = layer.GetFeatureCount()
  419 + extent = layer.GetExtent()
  420 + self.extent=extent
  421 +
  422 + #判断疏密程度
  423 + p_x = (extent[1]-extent[0])/10.0
  424 + p_y = (extent[3] - extent[2]) / 10.0
  425 + fill_precent=0
  426 + StructurePrint.print("判断疏密")
  427 + for ix in range(10):
  428 + for iy in range(10):
  429 + grid_extent = [extent[0]+ix*p_x,extent[0]+ix*p_x+p_x,extent[2]+iy*p_y,extent[2]+iy*p_y+p_y]
  430 + poly = GeometryAdapter.envelop_2_polygon(grid_extent)
  431 +
  432 + layer.SetSpatialFilter(None)
  433 + layer.SetSpatialFilter(poly)
  434 + layer.ResetReading()
  435 + if layer.GetNextFeature():
  436 + fill_precent += 1
  437 +
  438 + print(fill_precent)
  439 + StructurePrint.print("判断疏密结束")
  440 +
  441 + layer.SetSpatialFilter(None)
  442 + layer.ResetReading()
  443 + # 固有疏密程度
  444 + original_density=8
  445 +
  446 +
  447 + # 额外一层
  448 + # self.this_gridsize.append(0.000075)
  449 + # self.max_level += 1
  450 + ######
  451 +
  452 + if extent[0]>180:
  453 + t_grid_size=self.project_gridsize
  454 + else:
  455 + t_grid_size = self.lonlat_gridsize
  456 + for grid_size in t_grid_size:
  457 + # 最少抽稀个数
  458 + if lc>self.least_vacuate_count:
  459 + # 网格数至少大于
  460 + if ((extent[1] - extent[0])*(extent[3] - extent[2]))/(grid_size**2)>self.least_vacuate_count:
  461 + # 要素数量大于网格数量
  462 + # 要考虑图层的疏密程度,original_density*(100.0/fill_precent) 为疏密指数
  463 + if lc*original_density*(100.0/fill_precent)>((extent[1] - extent[0])*(extent[3] - extent[2]))/(grid_size**2) :
  464 + print(grid_size)
  465 + self.this_gridsize.append(grid_size)
  466 + self.max_level += 1
  467 +
  468 +
  469 +
  470 + # 创建抽稀ds
  471 + for l in range(self.max_level):
  472 + pg_ds_l: DataSource = PGUtil.open_pg_data_source(1, DES.decode(sqlalchemy_uri))
  473 + pg_ds_l.StartTransaction()
  474 + self.pg_ds_dict[l] = pg_ds_l
  475 +
  476 + # 生成抽稀图层
  477 + # 抽稀表一定要覆盖
  478 + options = options[1:]
  479 + options.append("OVERWRITE=yes")
  480 + for l in range(self.max_level):
  481 + this_grid_len = self.this_gridsize[l]
  482 +
  483 + self.vacuate_layers_gridsize[l] = this_grid_len
  484 +
  485 + pg = self.pg_ds_dict[l]
  486 +
  487 + grid_name = str(this_grid_len)
  488 + if this_grid_len<1:
  489 + grid_name = str(this_grid_len).split(".")[-1]
  490 + if this_grid_len.__eq__(0.000075):
  491 + grid_name = "000075"
  492 +
  493 + # 抽稀图层是点面混合的
  494 + # 抽稀表有固定的命名规则
  495 +
  496 + vl = pg.CreateLayer("{}_vacuate_{}_{}".format(new_layer_name, l, grid_name), layer.GetSpatialRef(),
  497 + ogr.wkbUnknown, options)
  498 + # 抽稀表不需要属性
  499 + # vl.CreateFields(schema)
  500 + self.vacuate_layers[l] = vl
  501 +
  502 + else:
  503 + pass
  504 +
  505 +
  506 + def vacuate(self,g):
  507 +
  508 + if self.is_spatial:
  509 +
  510 + # 插入到所有抽稀图层中
  511 + for level in range(self.max_level):
  512 +
  513 + center: Geometry = g.Centroid()
  514 +
  515 + extent = g.GetEnvelope()
  516 + long_extent= extent[1]-extent[0]
  517 + lat_extent = extent[3]-extent[2]
  518 +
  519 + this_grid_len =self.vacuate_layers_gridsize[level]
  520 +
  521 + row = int((center.GetY() - self.extent[2]) / this_grid_len)
  522 + col = int((center.GetX() - self.extent[0]) / this_grid_len)
  523 + key = "{}.{}.{}".format(level, row, col)
  524 +
  525 + if not self.fill_dict.get(key):
  526 + self.fill_dict[key] = 0
  527 + if self.fill_dict[key] == 0:
  528 +
  529 + vacuate_layer: Layer = self.vacuate_layers.get(level)
  530 + feat = ogr.Feature(vacuate_layer.GetLayerDefn())
  531 + # 如果图形比网格小,直接存储其中心点
  532 + if this_grid_len>long_extent and this_grid_len>lat_extent:
  533 + feat.SetGeometry(center)
  534 + else:
  535 + feat.SetGeometry(g)
  536 + vacuate_layer.CreateFeature(feat)
  537 + self.fill_dict[key] += 1
  538 +
  539 + def end(self):
  540 + for pg in self.pg_ds_dict.values():
  541 + pg.Destroy()
  542 +
  543 + def rollback(self):
  544 + for pg in self.pg_ds_dict.values():
  545 + pg.RollbackTransaction()
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/5/31
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +class Feature:
  8 +
  9 + @classmethod
  10 + def to_geojson(cls,fea):
  11 + pass
  12 +
  13 +
  14 +class FeatureCollation:
  15 + pass
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/5/17
  4 +#email: nheweijun@sina.com
  5 +
  6 +from flask import request
  7 +import uuid
  8 +import os
  9 +
  10 +
  11 +class FileProcess:
  12 + @classmethod
  13 + def save(cls,parent):
  14 + '''
  15 + :return:
  16 + '''
  17 + # 保存文件
  18 + file = request.files['file']
  19 + uuid_ = uuid.uuid1().__str__()
  20 + dir_path = os.path.join(parent, "file_tmp", uuid_)
  21 + os.makedirs(dir_path)
  22 + #有时候文件最后会多一个"
  23 + filename = file.filename.split('"')[0]
  24 + store_file = os.path.join(dir_path, filename)
  25 + file.save(store_file)
  26 +
  27 + return dir_path, store_file
  28 +
  29 + @classmethod
  30 + def get_spatial_file2(cls,store_path):
  31 + file_for_open = None
  32 + encoding = None
  33 + for root, dirs, files in os.walk(store_path):
  34 + for fn in files:
  35 + if fn.endswith("shp"):
  36 + file_for_open = os.path.join(root, fn)
  37 + if fn.endswith("cpg"):
  38 + with open(os.path.join(root, fn)) as fd:
  39 + encoding = fd.readline().strip()
  40 + if fn.endswith("gdb"):
  41 + file_for_open = root
  42 + return file_for_open, encoding
  43 +
  44 + @classmethod
  45 + def get_spatial_file(cls,store_path):
  46 + spatial_file= []
  47 + for root, dirs, files in os.walk(store_path):
  48 + for fn in files:
  49 + if fn.endswith("shp"):
  50 + file_for_open=os.path.join(root, fn)
  51 + encoding = None
  52 + cpg_path = os.path.join(root,"{}.cpg".format(fn.split(".shp")[0]))
  53 + if os.path.exists(cpg_path):
  54 + with open(cpg_path) as fd:
  55 + encoding=fd.readline().strip()
  56 + spatial_file.append((file_for_open,encoding))
  57 + if fn.endswith("gdb"):
  58 + spatial_file.append((root,None))
  59 + return spatial_file
  60 +
  61 +
  62 +
  63 + @classmethod
  64 + def get_file_size(cls,file_path):
  65 + if os.path.isdir(file_path):
  66 + fsize = cls.get_dir_size(file_path)
  67 + else:
  68 + fsize = os.path.getsize(file_path)
  69 +
  70 + if fsize>1024**3:
  71 + text_size= "{}GB".format(round(fsize/float(1024 **3), 1))
  72 + elif fsize>1024**2:
  73 + text_size = "{}MB".format(round(fsize / float(1024 ** 2), 1))
  74 + elif fsize>1024:
  75 + text_size = "{}KB".format(round(fsize / float(1024), 1))
  76 + else:
  77 + text_size = "{}B".format(round(fsize / float(1), 1))
  78 + return text_size
  79 +
  80 +
  81 +
  82 + @classmethod
  83 + def get_dir_size(cls,dir):
  84 + size = 0
  85 + for root, dirs, files in os.walk(dir):
  86 + size += sum([os.path.getsize(os.path.join(root, name)) for name in files])
  87 + return size
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/6/3
  4 +#email: nheweijun@sina.com
  5 +from osgeo import ogr
  6 +from osgeo.ogr import Geometry
  7 +
  8 +class GeometryAdapter:
  9 +
  10 + @classmethod
  11 + def getType(cls,layer):
  12 + origin = layer.GetGeomType() # type:str
  13 + if origin == 1 or origin == 4:
  14 + return "point"
  15 + elif origin == 2 or origin == 5:
  16 + return "linestring"
  17 + elif origin == 3 or origin == 6:
  18 + return "polygon"
  19 + return str(origin)
  20 +
  21 + @classmethod
  22 + def change_geom_type(cls,raw):
  23 + if raw==2 or raw ==3:
  24 + return raw+3
  25 + if raw==4:
  26 + return 1
  27 + if raw==-2147483647 or raw.__eq__(-2147483644):
  28 + return 1
  29 + if raw==-2147483646 or raw.__eq__(-2147483643):
  30 + return 5
  31 + if raw==-2147483645 or raw.__eq__(-2147483642):
  32 + return 6
  33 + return raw
  34 +
  35 + @classmethod
  36 + def change_geom(cls,geo:Geometry,geom_type):
  37 + '''
  38 + 转换空间对象的类型,以适应dmap只支持Multi类型
  39 + :param geo:
  40 + :param geom_type:
  41 + :return: 转换后的空间对象
  42 + '''
  43 +
  44 +
  45 + # Point = 1,
  46 + # LineString = 2,
  47 + # Polygon = 3,
  48 + # MultiPoint = 4,
  49 + # MultiLineString = 5,
  50 + # MultiPolygon = 6,
  51 + # GeometryCollection = 7,
  52 + # CircularString = 8,
  53 + # CompoundCurve = 9,
  54 + # CurvePolygon = 10,
  55 + # MultiCurve = 11,
  56 + # MultiSurface = 12,
  57 + # PolyhedralSurface = 15,
  58 + # LinearRing = 101,
  59 +
  60 + # MultiPointZ = -2147483644
  61 + # MultiLineStringZ = -2147483643
  62 + # MultiPolygonZ = -2147483642
  63 +
  64 +
  65 +
  66 + # PointZ = -2147483647
  67 + # LINESTRINGZ=-2147483646
  68 + # POLYGONZ=-2147483645
  69 +
  70 + if geom_type==5 or geom_type.__eq__(-2147483646) or geom_type.__eq__(-2147483643):
  71 + return ogr.ForceToMultiLineString(geo)
  72 + if geom_type==6 or geom_type.__eq__(-2147483645) or geom_type.__eq__(-2147483642):
  73 + return ogr.ForceToMultiPolygon(geo)
  74 + if geom_type==1:
  75 + return geo.Centroid()
  76 + return geo
  77 +
  78 + @classmethod
  79 + def get_table_type(cls, raw):
  80 + # Point = 1,
  81 + # LineString = 2,
  82 + # Polygon = 3,
  83 + # MultiPoint = 4,
  84 + # MultiLineString = 5,
  85 + # MultiPolygon = 6,
  86 + # GeometryCollection = 7,
  87 + # CircularString = 8,
  88 + # CompoundCurve = 9,
  89 + # CurvePolygon = 10,
  90 + # MultiCurve = 11,
  91 + # MultiSurface = 12,
  92 + # PolyhedralSurface = 15,
  93 + # LinearRing = 101,
  94 +
  95 + # MultiPointZ = -2147483644
  96 + # MultiLineStringZ = -2147483643
  97 + # MultiPolygonZ = -2147483642
  98 +
  99 + # PointZ = -2147483647
  100 + # LINESTRINGZ=-2147483646
  101 + # POLYGONZ=-2147483645
  102 +
  103 + if raw == 4 or raw == 5 or raw == 6:
  104 + return raw - 3
  105 + elif raw == -2147483644 or raw == -2147483647:
  106 + return 1
  107 + elif raw == -2147483643 or raw == -2147483646:
  108 + return 2
  109 + elif raw == -2147483642 or raw == -2147483645:
  110 + return 3
  111 + return raw
  112 +
  113 + def move(self,geo: Geometry, offx, offy):
  114 +
  115 + g = geo.GetGeometryRef(0)
  116 + num = g.GetPointCount()
  117 +
  118 + coor = []
  119 +
  120 + for j in range(num):
  121 + point = g.GetPoint(j)
  122 + x = point[0]
  123 + y = point[1]
  124 + x += offx
  125 + y += offy
  126 + coor.append([x, y])
  127 + if num == 1:
  128 + point = ogr.Geometry(ogr.wkbPoint)
  129 + point.AddPoint(coor[0][0], coor[0][1])
  130 + return point
  131 + elif coor[0].__eq__(coor[-1]):
  132 + ring = ogr.Geometry(ogr.wkbLinearRing)
  133 + for co in coor:
  134 + ring.AddPoint(co[0], co[1])
  135 + poly = ogr.Geometry(ogr.wkbPolygon)
  136 + poly.AddGeometry(ring)
  137 + return poly
  138 + else:
  139 + line = ogr.Geometry(ogr.wkbLineString)
  140 + for co in coor:
  141 + line.AddPoint(co[0], co[1])
  142 + return line
  143 +
  144 + @classmethod
  145 + def envelop_2_polygon(cls,env):
  146 + ring = ogr.Geometry(ogr.wkbLinearRing)
  147 + ring.AddPoint(env[0], env[2])
  148 + ring.AddPoint(env[0], env[3])
  149 + ring.AddPoint(env[1], env[3])
  150 + ring.AddPoint(env[1], env[2])
  151 + ring.AddPoint(env[0], env[2])
  152 + # Create polygon
  153 + poly = ogr.Geometry(ogr.wkbPolygon)
  154 + poly.AddGeometry(ring)
  155 + return poly
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/5/17
  4 +#email: nheweijun@sina.com
  5 +from .PGUtil import PGUtil
  6 +from app.models import DES
  7 +
  8 +import datetime
  9 +from flask_sqlalchemy import SQLAlchemy,Model
  10 +
  11 +
  12 +
  13 +class ModelVisitor:
  14 + @classmethod
  15 + def to_json(cls,model):
  16 + pass
  17 +
  18 + @classmethod
  19 + def object_to_json(cls,obj):
  20 + info={}
  21 + if obj:
  22 + info = cls.formatter(obj.__dict__)
  23 + return info
  24 +
  25 + @classmethod
  26 + def formatter(cls,kvdict:dict):
  27 + def generator():
  28 + for k,value in kvdict.items():
  29 + if isinstance(value, Model) or k.__eq__('_sa_instance_state'):
  30 + continue
  31 + if isinstance(value, datetime.datetime):
  32 + value = value.strftime('%Y-%m-%d %H:%M:%S')
  33 + elif isinstance(value, datetime.time):
  34 + value = value.strftime('%H:%M:%S')
  35 + yield k,value
  36 + return dict(generator())
  37 +
  38 +
  39 + @classmethod
  40 + def objects_to_jsonarray(cls,objects):
  41 + result = []
  42 + for o in objects:
  43 + result.append(cls.object_to_json(o))
  44 + return result
  45 +
  46 +
  47 +
  48 + @classmethod
  49 + def table_to_json(cls,table):
  50 + info = {}
  51 + info["catalog_name"] = table.relate_catalog.name if table.relate_catalog else None
  52 + info["database_alias"] = table.relate_database.alias if table.relate_database else None
  53 + if table:
  54 + info.update(cls.formatter(table.__dict__))
  55 + return info
  56 +
  57 +
  58 + @classmethod
  59 + def task_to_json(cls,task):
  60 + info = {}
  61 + info["catalog_name"] = task.relate_catalog.name if task.relate_catalog else None
  62 + info["database_alias"] = task.relate_database.alias if task.relate_database else None
  63 + info["consume_time"]=None
  64 + if task.update_time:
  65 +
  66 + consume_time = int(task.update_time.timestamp()-task.create_time.timestamp())
  67 + minute = int(consume_time/60)
  68 + sec = 1 if (int(consume_time%60)==0 and minute==0) else int(consume_time%60)
  69 + if minute>0:
  70 + info["consume_time"] = "{}分{}秒".format(minute,sec)
  71 + else:
  72 + info["consume_time"] = "{}秒".format(sec)
  73 + if object:
  74 + info.update(cls.formatter(task.__dict__))
  75 + del info["parameter"]
  76 + return info
  77 +
  78 + @classmethod
  79 + def database_to_json(cls,database):
  80 + info = {}
  81 + if object:
  82 + info.update(cls.formatter(database.__dict__))
  83 + user, password, host, port, db= PGUtil.get_info_from_sqlachemy_uri(DES.decode(info["sqlalchemy_uri"]))
  84 + info["user"] = user
  85 + info["host"] = host
  86 + info["port"] = port
  87 + info["database"] = db
  88 + del info["sqlalchemy_uri"]
  89 + return info
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/5/24
  4 +#email: nheweijun@sina.com
  5 +from osgeo import ogr
  6 +from sqlalchemy import create_engine
  7 +from sqlalchemy.orm import sessionmaker,Session
  8 +from sqlalchemy.engine import ResultProxy
  9 +
  10 +class PGUtil:
  11 +
  12 + @classmethod
  13 + def open_pg_data_source(cls,iswrite, uri):
  14 + """
  15 + # 获取PostGIS数据源
  16 + :return:
  17 + """
  18 + db_conn_tuple = cls.get_info_from_sqlachemy_uri(uri)
  19 + fn = "PG: user=%s password=%s host=%s port=%s dbname=%s " % db_conn_tuple
  20 + driver = ogr.GetDriverByName("PostgreSQL")
  21 + if driver is None:
  22 + raise Exception("打开PostgreSQL驱动失败,可能是当前GDAL未支持PostgreSQL驱动!")
  23 + ds = driver.Open(fn, iswrite)
  24 + if ds is None:
  25 + raise Exception("打开数据源失败!")
  26 + return ds
  27 +
  28 + @classmethod
  29 + def get_info_from_sqlachemy_uri(cls,uri):
  30 + parts = uri.split(":")
  31 + user = parts[1][2:]
  32 +
  33 + password_list = parts[2].split("@")
  34 + if password_list.__len__() > 2:
  35 + password = "@".join(password_list[:-1])
  36 + else:
  37 + password = parts[2].split("@")[0]
  38 + host = parts[2].split("@")[-1]
  39 + port = parts[3].split("/")[0]
  40 + database = parts[3].split("/")[1]
  41 +
  42 + return user, password, host, port, database
  43 +
  44 + @classmethod
  45 + def get_db_session(cls,db_url, autocommit=False) -> Session:
  46 + engine = create_engine(db_url)
  47 +
  48 + system_session :Session= sessionmaker(bind=engine, autocommit=autocommit)()
  49 +
  50 + return system_session
  51 +
  52 + @classmethod
  53 + def get_geo_column(cls,table_name,db_session):
  54 + # 判断空间列
  55 + geom_col_sql = '''
  56 + SELECT a.attname AS field,t.typname AS type
  57 + FROM
  58 + pg_class c,
  59 + pg_attribute a,
  60 + pg_type t
  61 + WHERE
  62 + c.relname = '{}'
  63 + and a.attnum > 0
  64 + and a.attrelid = c.oid
  65 + and a.atttypid = t.oid
  66 + '''.format(table_name)
  67 + geom_col = None
  68 + geom_result: ResultProxy = db_session.execute(geom_col_sql)
  69 + for row_proxy in geom_result:
  70 + if row_proxy[1].__eq__("geometry"):
  71 + geom_col = row_proxy[0]
  72 +
  73 + return geom_col
  74 +
  75 + @classmethod
  76 + def get_table_count(cls,table_name,db_session):
  77 + count_result = db_session.execute("SELECT reltuples::bigint AS ec FROM pg_class WHERE oid = 'public.{}'::regclass".format(
  78 + table_name)).fetchone()
  79 + count = count_result[0]
  80 + if count< 1000000:
  81 + count_result: ResultProxy = db_session.execute('select count(*) from "{}"'.format(table_name)).fetchone()
  82 + count=count_result[0]
  83 + return count
  84 +
  85 + @classmethod
  86 + def check_space(cls, sqlachemy_uri):
  87 + system_session = None
  88 + check = True
  89 + try:
  90 + test_sql = "select st_geometryfromtext('POINT(1 1)')"
  91 + engine = create_engine(sqlachemy_uri)
  92 + system_session = sessionmaker(bind=engine)()
  93 + system_session.execute(test_sql).fetchone()
  94 + except:
  95 + check = False
  96 + finally:
  97 + if system_session:
  98 + system_session.close()
  99 +
  100 + return check
  101 +
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/5/24
  4 +#email: nheweijun@sina.com
  5 +
  6 +from flask import request
  7 +import json
  8 +from .StructuredPrint import StructurePrint
  9 +
  10 +class ParameterUtil:
  11 +
  12 + # 获取请求参数
  13 + @classmethod
  14 + def get_parameter(cls):
  15 + parameter = dict()
  16 + parameter.update(request.args.items())
  17 + parameter.update(request.form.items())
  18 + try:
  19 + request_json = request.get_json()
  20 + if json:
  21 + parameter.update(request_json)
  22 + except Exception as e:
  23 + pass
  24 + for key in parameter.keys():
  25 + if parameter.get(key) == "":
  26 + parameter[key] = None
  27 + return parameter
  28 +
  29 +
  30 + # 转换参数
  31 + @classmethod
  32 + def to_lower(cls,parameter):
  33 + new_para=dict()
  34 + for key in parameter.keys():
  35 + new_para[key.lower()] = parameter[key]
  36 + parameter = new_para
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/5/17
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +class Queue:
  8 + def __init__(self):
  9 + self.items = []
  10 + def init(self,items):
  11 + self.items = items
  12 + def empty(self):
  13 + return self.items == []
  14 + def append(self, item):
  15 + self.items.insert(0,item)
  16 + def pop(self):
  17 + return self.items.pop()
  18 + def size(self):
  19 + return len(self.items)
  20 + def __str__(self):
  21 + return self.items.__str__()
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/6/29
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +class SQLUtil:
  8 +
  9 +
  10 + @classmethod
  11 + def get_count(cls,session,table_name):
  12 + count = session.execute('select count(*) from "{}"'.format(table_name)).fetchone()[0]
  13 + return count
  14 +
  15 + @classmethod
  16 + def rename(cls,session,origin,after_name):
  17 + rename_sql = 'alter table "{}" rename to "{}"'.format(origin, after_name)
  18 + session.execute(rename_sql)
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/5/17
  4 +#email: nheweijun@sina.com
  5 +
  6 +import xml.etree.ElementTree as ET
  7 +from xml.etree.ElementTree import Element
  8 +import math
  9 +
  10 +
  11 +
  12 +class SliceScheme:
  13 +
  14 + parameter={}
  15 + def __init__(self,slice_scheme_path):
  16 + tree = ET.parse(slice_scheme_path)
  17 + root:Element = tree.getroot()
  18 + if root.tag.__eq__("TileCacheInfo"):
  19 + TileCacheInfo: Element =root
  20 + else:
  21 + TileCacheInfo :Element= root.find("TileCacheInfo")
  22 +
  23 +
  24 + self.parameter["rows"] = float(TileCacheInfo.find("TileRows").text)
  25 + self.parameter["cols"] = float(TileCacheInfo.find("TileCols").text)
  26 + self.parameter["x"] = float(TileCacheInfo.find("TileOrigin").find("X").text)
  27 + self.parameter["y"] = float(TileCacheInfo.find("TileOrigin").find("Y").text)
  28 + self.parameter["dpi"] = float(TileCacheInfo.find("DPI").text)
  29 +
  30 +
  31 + LODInfos:Element = TileCacheInfo.find("LODInfos")
  32 +
  33 +
  34 + for info in LODInfos.iter("LODInfo"):
  35 + info_dict={}
  36 + info_dict["scale"] = float(info.find("Scale").text)
  37 + info_dict["resolution"] = float(info.find("Resolution").text)
  38 + self.parameter[info.find("LevelID").text] =info_dict
  39 +
  40 + @staticmethod
  41 + def get_polygon(parameter,level,row,col):
  42 + level=int(level)
  43 + row = int(row)
  44 + col = int(col)
  45 + detaxy = parameter.get(str(level)).get("resolution")* parameter.get("cols")
  46 +
  47 + minx = detaxy*col + parameter.get("x")
  48 + maxy = -detaxy*row +parameter.get("y")
  49 + maxx = detaxy + minx
  50 + miny = -detaxy + maxy
  51 +
  52 +
  53 + return [minx,miny,maxx,maxy]
  54 +
  55 +
  56 +
  57 + def get_polygon2(self,level,row,col):
  58 + level=int(level)
  59 + row = int(row)
  60 + col = int(col)
  61 + detaxy = self.parameter.get(str(level)).get("resolution")* self.parameter.get("cols")
  62 +
  63 + minx = detaxy*col + self.parameter.get("x")
  64 + maxy = -detaxy*row +self.parameter.get("y")
  65 + maxx = detaxy + minx
  66 + miny = -detaxy + maxy
  67 +
  68 + minx = math.ceil((detaxy*col + self.parameter.get("x"))*1000)/1000.0
  69 + maxy = math.ceil((-detaxy*row +self.parameter.get("y"))*1000)/1000.0
  70 + maxx = math.ceil((detaxy + minx)*1000)/1000.0
  71 + miny = math.ceil((-detaxy + maxy)*1000)/1000.0
  72 +
  73 + return [minx,miny,maxx,maxy]
  74 +
  75 +
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/5/17
  4 +#email: nheweijun@sina.com
  5 +import datetime
  6 +
  7 +
  8 +class StructurePrint:
  9 +
  10 + @classmethod
  11 + def print(cls,mes, type="info"):
  12 + message = "[{}] {} {}".format(type.upper(), datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), mes)
  13 + print(message)
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/6/7
  4 +#email: nheweijun@sina.com
  5 +# -*- coding: utf-8 -*-
  6 +
  7 +"""
  8 +***************************************************************************
  9 + TilesXYZ.py
  10 + ---------------------
  11 + Date : April 2019
  12 + Copyright : (C) 2019 by Lutra Consulting Limited
  13 + Email : marcel.dancak@lutraconsulting.co.uk
  14 +***************************************************************************
  15 +* *
  16 +* This program is free software; you can redistribute it and/or modify *
  17 +* it under the terms of the GNU General Public License as published by *
  18 +* the Free Software Foundation; either version 2 of the License, or *
  19 +* (at your option) any later version. *
  20 +* *
  21 +***************************************************************************
  22 +"""
  23 +
  24 +__author__ = 'Marcel Dancak'
  25 +__date__ = 'April 2019'
  26 +__copyright__ = '(C) 2019 by Lutra Consulting Limited'
  27 +
  28 +import os
  29 +import math
  30 +import re
  31 +import urllib.parse
  32 +from uuid import uuid4
  33 +
  34 +import sqlite3
  35 +from osgeo import gdal
  36 +# from qgis.PyQt.QtCore import QSize, Qt, QByteArray, QBuffer
  37 +# from qgis.PyQt.QtGui import QColor, QImage, QPainter
  38 +# from qgis.core import (QgsProcessingException,
  39 +# QgsProcessingParameterEnum,
  40 +# QgsProcessingParameterNumber,
  41 +# QgsProcessingParameterBoolean,
  42 +# QgsProcessingParameterString,
  43 +# QgsProcessingParameterExtent,
  44 +# QgsProcessingParameterColor,
  45 +# QgsProcessingOutputFile,
  46 +# QgsProcessingParameterFileDestination,
  47 +# QgsProcessingParameterFolderDestination,
  48 +# QgsGeometry,
  49 +# QgsRectangle,
  50 +# QgsMapSettings,
  51 +# QgsCoordinateTransform,
  52 +# QgsCoordinateReferenceSystem,
  53 +# QgsMapRendererCustomPainterJob,
  54 +# QgsLabelingEngineSettings,
  55 +# QgsApplication,
  56 +# QgsExpressionContextUtils)
  57 +# from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
  58 +# import threading
  59 +from concurrent.futures import ThreadPoolExecutor
  60 +# from processing.core.ProcessingConfig import ProcessingConfig
  61 +
  62 +
  63 +# TMS functions taken from https://alastaira.wordpress.com/2011/07/06/converting-tms-tile-coordinates-to-googlebingosm-tile-coordinates/ #spellok
  64 +
  65 +# 这个是OGC TMS 与GoogeleTMS的欢欢
  66 +def tms(ytile, zoom):
  67 + n = 2.0 ** zoom
  68 + ytile = n - ytile - 1
  69 + return int(ytile)
  70 +
  71 +
  72 +
  73 +
  74 +# Math functions taken from https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames #spellok
  75 +# 根据经纬度判断在那个瓦片
  76 +# def deg2num(lat_deg, lon_deg, zoom):
  77 +# lat_rad = math.radians(lat_deg)
  78 +# n = 2.0 ** zoom
  79 +# xtile = int((lon_deg + 180.0) / 360.0 * n)
  80 +# ytile = int((1.0 - math.log(math.tan(lat_rad) + (1 / math.cos(lat_rad))) / math.pi) / 2.0 * n)
  81 +# return (xtile, ytile)
  82 +
  83 +# def deg2num(lat_deg, lon_deg, zoom):
  84 +# lat_rad = math.radians(lat_deg)
  85 +# nn = 2.0 ** (zoom+1)
  86 +# n = 2.0 ** zoom
  87 +# xtile = int((lon_deg + 180.0) / 360.0 * nn)
  88 +# ytile = int((1.0 - math.log(math.tan(lat_rad) + (1 / math.cos(lat_rad))) / math.pi) / 2.0 * n)
  89 +# return (xtile, ytile)
  90 +
  91 +def deg2num(lat_deg, lon_deg, zoom):
  92 + nn = 2** (zoom+1)
  93 + n = 2** zoom
  94 + xtile = int((lon_deg + 180.0) / (360.0 / nn))
  95 + ytile = n-int((lat_deg + 90.0) / (180.0/ n))-1
  96 + return (xtile, ytile)
  97 +
  98 +
  99 +
  100 +
  101 +#Math functions taken from https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames #spellok
  102 +# def num2deg(xtile, ytile, zoom):
  103 +# n = 2.0 ** zoom
  104 +# lon_deg = xtile / n * 360.0 - 180.0
  105 +# lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * ytile / n)))
  106 +# lat_deg = math.degrees(lat_rad)
  107 +# return (lat_deg, lon_deg)
  108 +
  109 +
  110 +
  111 +
  112 +def num2deg(xtile, ytile, zoom):
  113 + parameter = {'rows': 256.0, 'cols': 256.0, 'x': -180.0, 'y': 90.0, 'dpi': 96.0,
  114 + '0': {'scale': 295497593.05875003, 'resolution': 0.7031250000000002},
  115 + '1': {'scale': 147748796.52937502, 'resolution': 0.3515625000000001},
  116 + '2': {'scale': 73874398.26468751, 'resolution': 0.17578125000000006},
  117 + '3': {'scale': 36937199.132343754, 'resolution': 0.08789062500000003},
  118 + '4': {'scale': 18468599.566171877, 'resolution': 0.043945312500000014},
  119 + '5': {'scale': 9234299.783085939, 'resolution': 0.021972656250000007},
  120 + '6': {'scale': 4617149.891542969, 'resolution': 0.010986328125000003},
  121 + '7': {'scale': 2308574.9457714846, 'resolution': 0.005493164062500002},
  122 + '8': {'scale': 1154287.4728857423, 'resolution': 0.002746582031250001},
  123 + '9': {'scale': 577143.7364428712, 'resolution': 0.0013732910156250004},
  124 + '10': {'scale': 288571.8682214356, 'resolution': 0.0006866455078125002},
  125 + '11': {'scale': 144285.9341107178, 'resolution': 0.0003433227539062501},
  126 + '12': {'scale': 72142.9670553589, 'resolution': 0.00017166137695312505},
  127 + '13': {'scale': 36071.48352767945, 'resolution': 8.583068847656253e-05},
  128 + '14': {'scale': 18035.741763839724, 'resolution': 4.2915344238281264e-05},
  129 + '15': {'scale': 9017.870881919862, 'resolution': 2.1457672119140632e-05},
  130 + '16': {'scale': 4508.935440959931, 'resolution': 1.0728836059570316e-05},
  131 + '17': {'scale': 2254.4677204799655, 'resolution': 5.364418029785158e-06},
  132 + '18': {'scale': 1127.2338602399827, 'resolution': 2.682209014892579e-06},
  133 + '19': {'scale': 563.6169301199914, 'resolution': 1.3411045074462895e-06}}
  134 + #
  135 + # parameter = {'rows': 256.0, 'cols': 256.0, 'x': -180.0, 'y': 90.0, 'dpi': 96.0,
  136 + # '0': {'scale': 590995186.11750006, 'resolution': 1.4062500000000004},
  137 + # '1': {'scale': 295497593.05875003, 'resolution': 0.7031250000000002},
  138 + # '2': {'scale': 147748796.52937502, 'resolution': 0.3515625000000001},
  139 + # '3': {'scale': 73874398.26468751, 'resolution': 0.17578125000000006},
  140 + # '4': {'scale': 36937199.132343754, 'resolution': 0.08789062500000003},
  141 + # '5': {'scale': 18468599.566171877, 'resolution': 0.043945312500000014},
  142 + # '6': {'scale': 9234299.783085939, 'resolution': 0.021972656250000007},
  143 + # '7': {'scale': 4617149.891542969, 'resolution': 0.010986328125000003},
  144 + # '8': {'scale': 2308574.9457714846, 'resolution': 0.005493164062500002},
  145 + # '9': {'scale': 1154287.4728857423, 'resolution': 0.002746582031250001},
  146 + # '10': {'scale': 577143.7364428712, 'resolution': 0.0013732910156250004},
  147 + # '11': {'scale': 288571.8682214356, 'resolution': 0.0006866455078125002},
  148 + # '12': {'scale': 144285.9341107178, 'resolution': 0.0003433227539062501},
  149 + # '13': {'scale': 72142.9670553589, 'resolution': 0.00017166137695312505},
  150 + # '14': {'scale': 36071.48352767945, 'resolution': 8.583068847656253e-05},
  151 + # '15': {'scale': 18035.741763839724, 'resolution': 4.2915344238281264e-05},
  152 + # '16': {'scale': 9017.870881919862, 'resolution': 2.1457672119140632e-05},
  153 + # '17': {'scale': 4508.935440959931, 'resolution': 1.0728836059570316e-05},
  154 + # '18': {'scale': 2254.4677204799655, 'resolution': 5.364418029785158e-06},
  155 + # '19': {'scale': 1127.2338602399827, 'resolution': 2.682209014892579e-06},
  156 + # '20': {'scale': 563.6169301199914, 'resolution': 1.3411045074462895e-06}}
  157 + detaxy = parameter.get(str(zoom)).get("resolution")* parameter.get("cols")
  158 + minx = detaxy*xtile + parameter.get("x")
  159 + maxy = -detaxy*ytile +parameter.get("y")
  160 + maxx = detaxy + minx
  161 + miny = -detaxy + maxy
  162 + return (float('%.8f'%maxy),float('%.8f'%minx))
  163 +
  164 +
  165 +
  166 +# 根据等级行列号获得切片范围
  167 +class Tile:
  168 +
  169 + def __init__(self, x, y, z):
  170 + self.x = x
  171 + self.y = y
  172 + self.z = z
  173 +
  174 + def extent(self):
  175 + lat1, lon1 = num2deg(self.x, self.y, self.z)
  176 + lat2, lon2 = num2deg(self.x + 1, self.y + 1, self.z)
  177 + return [lon1, lat2, lon2, lat1]
  178 +
  179 +
  180 +
  181 +
  182 +class MetaTile:
  183 +
  184 + def __init__(self):
  185 + # list of tuple(row index, column index, Tile)
  186 + self.tiles = []
  187 +
  188 + def add_tile(self, row, column, tile):
  189 + self.tiles.append((row, column, tile))
  190 +
  191 + def rows(self):
  192 + return max([r for r, _, _ in self.tiles]) + 1
  193 +
  194 + def columns(self):
  195 + return max([c for _, c, _ in self.tiles]) + 1
  196 +
  197 + def extent(self):
  198 + _, _, first = self.tiles[0]
  199 + _, _, last = self.tiles[-1]
  200 + lat1, lon1 = num2deg(first.x, first.y, first.z)
  201 + lat2, lon2 = num2deg(last.x + 1, last.y + 1, first.z)
  202 + return [lon1, lat2, lon2, lat1]
  203 +
  204 +mt = MetaTile()
  205 +mt.add_tile(0,0,Tile(0, 0, 1))
  206 +print(Tile(0, 0, 1).extent())
  207 +# print(mt.extent())
  208 +
  209 +
  210 +
  211 +def get_metatiles(extent, zoom, size=4):
  212 + west_edge, south_edge, east_edge, north_edge = extent
  213 +
  214 + left_tile, top_tile = deg2num(north_edge, west_edge, zoom)
  215 +
  216 + right_tile, bottom_tile = deg2num(south_edge, east_edge, zoom)
  217 +
  218 + metatiles = {}
  219 +
  220 + for i, x in enumerate(range(left_tile, right_tile + 1)):
  221 + for j, y in enumerate(range(top_tile, bottom_tile + 1)):
  222 + meta_key = '{}:{}'.format(int(i / size), int(j / size))
  223 + if meta_key not in metatiles:
  224 + metatiles[meta_key] = MetaTile()
  225 + metatile = metatiles[meta_key]
  226 + metatile.add_tile(i % size, j % size, Tile(x, y, zoom))
  227 + print(j % size,i % size, metatile.extent())
  228 +
  229 + return list(metatiles.values())
  230 +
  231 +get_metatiles([-179,-80,179,80], 1, size=4)
  232 +
  233 +
  234 +
  235 +# class TilesXYZAlgorithmBase(QgisAlgorithm):
  236 +# EXTENT = 'EXTENT'
  237 +# ZOOM_MIN = 'ZOOM_MIN'
  238 +# ZOOM_MAX = 'ZOOM_MAX'
  239 +# DPI = 'DPI'
  240 +# BACKGROUND_COLOR = 'BACKGROUND_COLOR'
  241 +# TILE_FORMAT = 'TILE_FORMAT'
  242 +# QUALITY = 'QUALITY'
  243 +# METATILESIZE = 'METATILESIZE'
  244 +#
  245 +# def initAlgorithm(self, config=None):
  246 +# self.addParameter(QgsProcessingParameterExtent(self.EXTENT, self.tr('Extent')))
  247 +# self.addParameter(QgsProcessingParameterNumber(self.ZOOM_MIN,
  248 +# self.tr('Minimum zoom'),
  249 +# minValue=0,
  250 +# maxValue=25,
  251 +# defaultValue=12))
  252 +# self.addParameter(QgsProcessingParameterNumber(self.ZOOM_MAX,
  253 +# self.tr('Maximum zoom'),
  254 +# minValue=0,
  255 +# maxValue=25,
  256 +# defaultValue=12))
  257 +# self.addParameter(QgsProcessingParameterNumber(self.DPI,
  258 +# self.tr('DPI'),
  259 +# minValue=48,
  260 +# maxValue=600,
  261 +# defaultValue=96))
  262 +# self.addParameter(QgsProcessingParameterColor(self.BACKGROUND_COLOR,
  263 +# self.tr('Background color'),
  264 +# defaultValue=QColor(Qt.transparent),
  265 +# optional=True))
  266 +# self.formats = ['PNG', 'JPG']
  267 +# self.addParameter(QgsProcessingParameterEnum(self.TILE_FORMAT,
  268 +# self.tr('Tile format'),
  269 +# self.formats,
  270 +# defaultValue=0))
  271 +# self.addParameter(QgsProcessingParameterNumber(self.QUALITY,
  272 +# self.tr('Quality (JPG only)'),
  273 +# minValue=1,
  274 +# maxValue=100,
  275 +# defaultValue=75))
  276 +# self.addParameter(QgsProcessingParameterNumber(self.METATILESIZE,
  277 +# self.tr('Metatile size'),
  278 +# minValue=1,
  279 +# maxValue=20,
  280 +# defaultValue=4))
  281 +# self.thread_nr_re = re.compile('[0-9]+$') # thread number regex
  282 +#
  283 +# def prepareAlgorithm(self, parameters, context, feedback):
  284 +# project = context.project()
  285 +# visible_layers = [item.layer() for item in project.layerTreeRoot().findLayers() if item.isVisible()]
  286 +# self.layers = [l for l in project.layerTreeRoot().layerOrder() if l in visible_layers]
  287 +# return True
  288 +#
  289 +# def renderSingleMetatile(self, metatile):
  290 +# if self.feedback.isCanceled():
  291 +# return
  292 +# # Haven't found a better way to break than to make all the new threads return instantly
  293 +#
  294 +# if "Dummy" in threading.current_thread().name or len(self.settingsDictionary) == 1: # single thread testing
  295 +# threadSpecificSettings = list(self.settingsDictionary.values())[0]
  296 +# else:
  297 +# thread_nr = self.thread_nr_re.search(threading.current_thread().name)[0] # terminating number only
  298 +# threadSpecificSettings = self.settingsDictionary[thread_nr]
  299 +#
  300 +# size = QSize(self.tile_width * metatile.rows(), self.tile_height * metatile.columns())
  301 +# extent = QgsRectangle(*metatile.extent())
  302 +# threadSpecificSettings.setExtent(self.wgs_to_dest.transformBoundingBox(extent))
  303 +# threadSpecificSettings.setOutputSize(size)
  304 +#
  305 +# #Append MapSettings scope in order to update map variables (e.g @map_scale) with new extent data
  306 +# exp_context = threadSpecificSettings.expressionContext()
  307 +# exp_context.appendScope(QgsExpressionContextUtils.mapSettingsScope(threadSpecificSettings))
  308 +# threadSpecificSettings.setExpressionContext(exp_context)
  309 +#
  310 +# image = QImage(size, QImage.Format_ARGB32_Premultiplied)
  311 +# image.fill(self.color)
  312 +# dpm = threadSpecificSettings.outputDpi() / 25.4 * 1000
  313 +# image.setDotsPerMeterX(dpm)
  314 +# image.setDotsPerMeterY(dpm)
  315 +# painter = QPainter(image)
  316 +# job = QgsMapRendererCustomPainterJob(threadSpecificSettings, painter)
  317 +# job.renderSynchronously()
  318 +# painter.end()
  319 +#
  320 +# ## For analysing metatiles (labels, etc.)
  321 +# ## metatile_dir = os.path.join(output_dir, str(zoom))
  322 +# ## os.makedirs(metatile_dir, exist_ok=True)
  323 +# ## image.save(os.path.join(metatile_dir, 'metatile_%s.png' % i))
  324 +#
  325 +# for r, c, tile in metatile.tiles:
  326 +# tileImage = image.copy(self.tile_width * r, self.tile_height * c, self.tile_width, self.tile_height)
  327 +# self.writer.write_tile(tile, tileImage)
  328 +#
  329 +# # to stop thread sync issues
  330 +# with self.progressThreadLock:
  331 +# self.progress += 1
  332 +# self.feedback.setProgress(100 * (self.progress / self.totalMetatiles))
  333 +#
  334 + # def generate(self, writer, parameters, context, feedback):
  335 + # self.feedback = feedback
  336 + # feedback.setProgress(1)
  337 + #
  338 + # extent = self.parameterAsExtent(parameters, self.EXTENT, context)
  339 + # self.min_zoom = self.parameterAsInt(parameters, self.ZOOM_MIN, context)
  340 + # self.max_zoom = self.parameterAsInt(parameters, self.ZOOM_MAX, context)
  341 + # dpi = self.parameterAsInt(parameters, self.DPI, context)
  342 + # self.color = self.parameterAsColor(parameters, self.BACKGROUND_COLOR, context)
  343 + # self.tile_format = self.formats[self.parameterAsEnum(parameters, self.TILE_FORMAT, context)]
  344 + # self.quality = self.parameterAsInt(parameters, self.QUALITY, context)
  345 + # self.metatilesize = self.parameterAsInt(parameters, self.METATILESIZE, context)
  346 + # self.maxThreads = int(ProcessingConfig.getSetting(ProcessingConfig.MAX_THREADS))
  347 + #
  348 + # try:
  349 + # self.tile_width = self.parameterAsInt(parameters, self.TILE_WIDTH, context)
  350 + # self.tile_height = self.parameterAsInt(parameters, self.TILE_HEIGHT, context)
  351 + #
  352 + # except AttributeError:
  353 + # self.tile_width = 256
  354 + # self.tile_height = 256
  355 + #
  356 + # wgs_crs = QgsCoordinateReferenceSystem('EPSG:4326')
  357 + # dest_crs = QgsCoordinateReferenceSystem('EPSG:3857')
  358 + #
  359 + # project = context.project()
  360 + # self.src_to_wgs = QgsCoordinateTransform(project.crs(), wgs_crs, context.transformContext())
  361 + # self.wgs_to_dest = QgsCoordinateTransform(wgs_crs, dest_crs, context.transformContext())
  362 + # # without re-writing, we need a different settings for each thread to stop async errors
  363 + # # naming doesn't always line up, but the last number does
  364 + # self.settingsDictionary = {str(i): QgsMapSettings() for i in range(self.maxThreads)}
  365 + # for thread in self.settingsDictionary:
  366 + # self.settingsDictionary[thread].setOutputImageFormat(QImage.Format_ARGB32_Premultiplied)
  367 + # self.settingsDictionary[thread].setDestinationCrs(dest_crs)
  368 + # self.settingsDictionary[thread].setLayers(self.layers)
  369 + # self.settingsDictionary[thread].setOutputDpi(dpi)
  370 + # if self.tile_format == 'PNG':
  371 + # self.settingsDictionary[thread].setBackgroundColor(self.color)
  372 + #
  373 + # ## disable partial labels (they would be cut at the edge of tiles)
  374 + # labeling_engine_settings = self.settingsDictionary[thread].labelingEngineSettings()
  375 + # labeling_engine_settings.setFlag(QgsLabelingEngineSettings.UsePartialCandidates, False)
  376 + # self.settingsDictionary[thread].setLabelingEngineSettings(labeling_engine_settings)
  377 + #
  378 + # # Transfer context scopes to MapSettings
  379 + # self.settingsDictionary[thread].setExpressionContext(context.expressionContext())
  380 + #
  381 + # self.wgs_extent = self.src_to_wgs.transformBoundingBox(extent)
  382 + # self.wgs_extent = [self.wgs_extent.xMinimum(), self.wgs_extent.yMinimum(), self.wgs_extent.xMaximum(),
  383 + # self.wgs_extent.yMaximum()]
  384 + #
  385 + # metatiles_by_zoom = {}
  386 + # self.totalMetatiles = 0
  387 + # allMetatiles = []
  388 + # for zoom in range(self.min_zoom, self.max_zoom + 1):
  389 + # metatiles = get_metatiles(self.wgs_extent, zoom, self.metatilesize)
  390 + # metatiles_by_zoom[zoom] = metatiles
  391 + # allMetatiles += metatiles
  392 + # self.totalMetatiles += len(metatiles)
  393 + #
  394 + # lab_buffer_px = 100
  395 + # self.progress = 0
  396 + #
  397 + # tile_params = {
  398 + # 'format': self.tile_format,
  399 + # 'quality': self.quality,
  400 + # 'width': self.tile_width,
  401 + # 'height': self.tile_height,
  402 + # 'min_zoom': self.min_zoom,
  403 + # 'max_zoom': self.max_zoom,
  404 + # 'extent': self.wgs_extent,
  405 + # }
  406 + # writer.set_parameters(tile_params)
  407 + # self.writer = writer
  408 + #
  409 + # self.progressThreadLock = threading.Lock()
  410 + # if self.maxThreads > 1:
  411 + # feedback.pushConsoleInfo(self.tr('Using {max_threads} CPU Threads:').format(max_threads=self.maxThreads))
  412 + # for zoom in range(self.min_zoom, self.max_zoom + 1):
  413 + # feedback.pushConsoleInfo(self.tr('Generating tiles for zoom level: {zoom}').format(zoom=zoom))
  414 + # with ThreadPoolExecutor(max_workers=self.maxThreads) as threadPool:
  415 + # threadPool.map(self.renderSingleMetatile, metatiles_by_zoom[zoom])
  416 + # else:
  417 + # feedback.pushConsoleInfo(self.tr('Using 1 CPU Thread:'))
  418 + # for zoom in range(self.min_zoom, self.max_zoom + 1):
  419 + # feedback.pushConsoleInfo(self.tr('Generating tiles for zoom level: {zoom}').format(zoom=zoom))
  420 + # for i, metatile in enumerate(metatiles_by_zoom[zoom]):
  421 + # self.renderSingleMetatile(metatile)
  422 + #
  423 + # writer.close()
  424 +#
  425 +# def checkParameterValues(self, parameters, context):
  426 +# min_zoom = self.parameterAsInt(parameters, self.ZOOM_MIN, context)
  427 +# max_zoom = self.parameterAsInt(parameters, self.ZOOM_MAX, context)
  428 +# if max_zoom < min_zoom:
  429 +# return False, self.tr('Invalid zoom levels range.')
  430 +#
  431 +# return super().checkParameterValues(parameters, context)
  432 +
  433 +
  434 +########################################################################
  435 +# MBTiles
  436 +########################################################################
  437 +# class MBTilesWriter:
  438 +#
  439 +# def __init__(self, filename):
  440 +# base_dir = os.path.dirname(filename)
  441 +# os.makedirs(base_dir, exist_ok=True)
  442 +# self.filename = filename
  443 +#
  444 +# def set_parameters(self, tile_params):
  445 +# self.extent = tile_params.get('extent')
  446 +# self.tile_width = tile_params.get('width', 256)
  447 +# self.tile_height = tile_params.get('height', 256)
  448 +# self.min_zoom = tile_params.get('min_zoom')
  449 +# self.max_zoom = tile_params.get('max_zoom')
  450 +# tile_format = tile_params['format']
  451 +# options = []
  452 +# if tile_format == 'JPG':
  453 +# tile_format = 'JPEG'
  454 +# options = ['QUALITY=%s' % tile_params.get('quality', 75)]
  455 +# driver = gdal.GetDriverByName('MBTiles')
  456 +# ds = driver.Create(self.filename, 1, 1, 1, options=['TILE_FORMAT=%s' % tile_format] + options)
  457 +# ds = None
  458 +#
  459 +# self._execute_sqlite(
  460 +# "INSERT INTO metadata(name, value) VALUES ('{}', '{}');".format('minzoom', self.min_zoom),
  461 +# "INSERT INTO metadata(name, value) VALUES ('{}', '{}');".format('maxzoom', self.max_zoom),
  462 +# # will be set properly after writing all tiles
  463 +# "INSERT INTO metadata(name, value) VALUES ('{}', '');".format('bounds')
  464 +# )
  465 +# self._zoom = None
  466 +#
  467 +# def _execute_sqlite(self, *commands):
  468 +# conn = sqlite3.connect(self.filename)
  469 +# for cmd in commands:
  470 +# conn.execute(cmd)
  471 +# conn.commit()
  472 +# conn.close()
  473 +#
  474 +# def _init_zoom_layer(self, zoom):
  475 +# self._zoom_ds = None
  476 +# west_edge, south_edge, east_edge, north_edge = self.extent
  477 +# first_tile = Tile(*deg2num(north_edge, west_edge, zoom), zoom)
  478 +# last_tile = Tile(*deg2num(south_edge, east_edge, zoom), zoom)
  479 +#
  480 +# first_tile_extent = first_tile.extent()
  481 +# last_tile_extent = last_tile.extent()
  482 +# zoom_extent = [
  483 +# first_tile_extent[0],
  484 +# last_tile_extent[1],
  485 +# last_tile_extent[2],
  486 +# first_tile_extent[3]
  487 +# ]
  488 +#
  489 +# bounds = ','.join(map(str, zoom_extent))
  490 +# self._execute_sqlite("UPDATE metadata SET value='{}' WHERE name='bounds'".format(bounds))
  491 +#
  492 +# self._zoom_ds = gdal.OpenEx(self.filename, 1, open_options=['ZOOM_LEVEL=%s' % first_tile.z])
  493 +# self._first_tile = first_tile
  494 +# self._zoom = zoom
  495 +#
  496 +# def write_tile(self, tile, image):
  497 +# if tile.z != self._zoom:
  498 +# self._init_zoom_layer(tile.z)
  499 +#
  500 +# data = QByteArray()
  501 +# buff = QBuffer(data)
  502 +# image.save(buff, 'PNG')
  503 +#
  504 +# mmap_name = '/vsimem/' + uuid4().hex
  505 +# gdal.FileFromMemBuffer(mmap_name, data.data())
  506 +# gdal_dataset = gdal.Open(mmap_name)
  507 +# data = gdal_dataset.ReadRaster(0, 0, self.tile_width, self.tile_height)
  508 +# gdal_dataset = None
  509 +# gdal.Unlink(mmap_name)
  510 +#
  511 +# xoff = (tile.x - self._first_tile.x) * self.tile_width
  512 +# yoff = (tile.y - self._first_tile.y) * self.tile_height
  513 +# self._zoom_ds.WriteRaster(xoff, yoff, self.tile_width, self.tile_height, data)
  514 +#
  515 +# def close(self):
  516 +# self._zoom_ds = None
  517 +# bounds = ','.join(map(str, self.extent))
  518 +# self._execute_sqlite("UPDATE metadata SET value='{}' WHERE name='bounds'".format(bounds))
  519 +#
  520 +#
  521 +# class TilesXYZAlgorithmMBTiles(TilesXYZAlgorithmBase):
  522 +# OUTPUT_FILE = 'OUTPUT_FILE'
  523 +#
  524 +# def initAlgorithm(self, config=None):
  525 +# super(TilesXYZAlgorithmMBTiles, self).initAlgorithm()
  526 +# self.addParameter(QgsProcessingParameterFileDestination(self.OUTPUT_FILE,
  527 +# self.tr('Output file (for MBTiles)'),
  528 +# self.tr('MBTiles files (*.mbtiles)'),
  529 +# optional=True))
  530 +#
  531 +# def name(self):
  532 +# return 'tilesxyzmbtiles'
  533 +#
  534 +# def displayName(self):
  535 +# return self.tr('Generate XYZ tiles (MBTiles)')
  536 +#
  537 +# def group(self):
  538 +# return self.tr('Raster tools')
  539 +#
  540 +# def groupId(self):
  541 +# return 'rastertools'
  542 +#
  543 +# def processAlgorithm(self, parameters, context, feedback):
  544 +# output_file = self.parameterAsString(parameters, self.OUTPUT_FILE, context)
  545 +# if not output_file:
  546 +# raise QgsProcessingException(self.tr('You need to specify output filename.'))
  547 +#
  548 +# writer = MBTilesWriter(output_file)
  549 +# self.generate(writer, parameters, context, feedback)
  550 +#
  551 +# results = {'OUTPUT_FILE': output_file}
  552 +# return results
  553 +
  554 +
  555 +########################################################################
  556 +# Directory
  557 +########################################################################
  558 +LEAFLET_TEMPLATE = '''
  559 +<!DOCTYPE html>
  560 +<html>
  561 +<head>
  562 + <title>{tilesetname}</title>
  563 + <meta charset="utf-8" />
  564 + <meta name="viewport" content="width=device-width, initial-scale=1.0">
  565 +
  566 + <link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css"
  567 + integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
  568 + crossorigin=""/>
  569 + <script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"
  570 + integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og=="
  571 + crossorigin=""></script>
  572 + <style type="text/css">
  573 + body {{
  574 + margin: 0;
  575 + padding: 0;
  576 + }}
  577 + html, body, #map{{
  578 + width: 100%;
  579 + height: 100%;
  580 + }}
  581 + </style>
  582 +</head>
  583 +<body>
  584 + <div id="map"></div>
  585 + <script>
  586 + var map = L.map('map').setView([{centery}, {centerx}], {avgzoom});
  587 + L.tileLayer({tilesource}, {{
  588 + minZoom: {minzoom},
  589 + maxZoom: {maxzoom},
  590 + tms: {tms},
  591 + attribution: 'Generated by TilesXYZ'
  592 + }}).addTo(map);
  593 + </script>
  594 +</body>
  595 +</html>
  596 +'''
  597 +
  598 +
  599 +class DirectoryWriter:
  600 +
  601 + def __init__(self, folder, is_tms):
  602 + self.folder = folder
  603 + self.is_tms = is_tms
  604 +
  605 + def set_parameters(self, tile_params):
  606 + self.format = tile_params.get('format', 'PNG')
  607 + self.quality = tile_params.get('quality', -1)
  608 +
  609 + def write_tile(self, tile, image):
  610 + directory = os.path.join(self.folder, str(tile.z), str(tile.x))
  611 + os.makedirs(directory, exist_ok=True)
  612 + ytile = tile.y
  613 + if self.is_tms:
  614 + ytile = tms(ytile, tile.z)
  615 + path = os.path.join(directory, '{}.{}'.format(ytile, self.format.lower()))
  616 + image.save(path, self.format, self.quality)
  617 + return path
  618 +
  619 + def close(self):
  620 + pass
  621 +#
  622 +#
  623 +# class TilesXYZAlgorithmDirectory(TilesXYZAlgorithmBase):
  624 +# TMS_CONVENTION = 'TMS_CONVENTION'
  625 +# OUTPUT_DIRECTORY = 'OUTPUT_DIRECTORY'
  626 +# OUTPUT_HTML = 'OUTPUT_HTML'
  627 +# TILE_WIDTH = 'TILE_WIDTH'
  628 +# TILE_HEIGHT = 'TILE_HEIGHT'
  629 +#
  630 +# def initAlgorithm(self, config=None):
  631 +# super(TilesXYZAlgorithmDirectory, self).initAlgorithm()
  632 +# self.addParameter(QgsProcessingParameterNumber(self.TILE_WIDTH,
  633 +# self.tr('Tile width'),
  634 +# minValue=1,
  635 +# maxValue=4096,
  636 +# defaultValue=256))
  637 +# self.addParameter(QgsProcessingParameterNumber(self.TILE_HEIGHT,
  638 +# self.tr('Tile height'),
  639 +# minValue=1,
  640 +# maxValue=4096,
  641 +# defaultValue=256))
  642 +# self.addParameter(QgsProcessingParameterBoolean(self.TMS_CONVENTION,
  643 +# self.tr('Use inverted tile Y axis (TMS convention)'),
  644 +# defaultValue=False,
  645 +# optional=True))
  646 +# self.addParameter(QgsProcessingParameterFolderDestination(self.OUTPUT_DIRECTORY,
  647 +# self.tr('Output directory'),
  648 +# optional=True))
  649 +# self.addParameter(QgsProcessingParameterFileDestination(self.OUTPUT_HTML,
  650 +# self.tr('Output html (Leaflet)'),
  651 +# self.tr('HTML files (*.html)'),
  652 +# optional=True))
  653 +#
  654 +# def name(self):
  655 +# return 'tilesxyzdirectory'
  656 +#
  657 +# def displayName(self):
  658 +# return self.tr('Generate XYZ tiles (Directory)')
  659 +#
  660 +# def group(self):
  661 +# return self.tr('Raster tools')
  662 +#
  663 +# def groupId(self):
  664 +# return 'rastertools'
  665 +#
  666 +# def processAlgorithm(self, parameters, context, feedback):
  667 +# is_tms = self.parameterAsBoolean(parameters, self.TMS_CONVENTION, context)
  668 +# output_html = self.parameterAsString(parameters, self.OUTPUT_HTML, context)
  669 +# output_dir = self.parameterAsString(parameters, self.OUTPUT_DIRECTORY, context)
  670 +# if not output_dir:
  671 +# raise QgsProcessingException(self.tr('You need to specify output directory.'))
  672 +#
  673 +# writer = DirectoryWriter(output_dir, is_tms)
  674 +# self.generate(writer, parameters, context, feedback)
  675 +#
  676 +# results = {'OUTPUT_DIRECTORY': output_dir}
  677 +#
  678 +# if output_html:
  679 +# output_dir_safe = urllib.parse.quote(output_dir.replace('\\', '/'))
  680 +# html_code = LEAFLET_TEMPLATE.format(
  681 +# tilesetname="Leaflet Preview",
  682 +# centerx=self.wgs_extent[0] + (self.wgs_extent[2] - self.wgs_extent[0]) / 2,
  683 +# centery=self.wgs_extent[1] + (self.wgs_extent[3] - self.wgs_extent[1]) / 2,
  684 +# avgzoom=(self.max_zoom + self.min_zoom) / 2,
  685 +# tilesource="'file:///{}/{{z}}/{{x}}/{{y}}.{}'".format(output_dir_safe, self.tile_format.lower()),
  686 +# minzoom=self.min_zoom,
  687 +# maxzoom=self.max_zoom,
  688 +# tms='true' if is_tms else 'false'
  689 +# )
  690 +# with open(output_html, "w") as fh:
  691 +# fh.write(html_code)
  692 +# results['OUTPUT_HTML'] = output_html
  693 +#
  694 +# return results
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/5/24
  4 +#email: nheweijun@sina.com
  5 +
  6 +import zipfile
  7 +import os
  8 +import uuid
  9 +
  10 +class ZipUtil:
  11 +
  12 + @classmethod
  13 + def unzip(cls,zip_file,create_uuid=False):
  14 + '''
  15 +
  16 + :param zip_file: 待解压文件
  17 + :return: 压缩文件路径
  18 + '''
  19 +
  20 + #处理zip
  21 + #存储路径
  22 + if create_uuid:
  23 + store_path = os.path.join(os.path.dirname(zip_file),uuid.uuid1().__str__())
  24 + else:
  25 + store_path =os.path.dirname(zip_file)
  26 + zip_file = zipfile.ZipFile(zip_file, 'r')
  27 +
  28 + #是否要重命名文件夹,解压中文压缩文件和内嵌中文压缩文件,需要重命名文件夹
  29 + rename_path = False
  30 + rename_path_origin=None
  31 + rename_path_after =None
  32 +
  33 + for names in zip_file.namelist():
  34 + #zipfile解压中文文件会有编码问题,需要解压后重命名,因为zipfile内部使用的是cp437
  35 + try:
  36 + name_t = names.encode('cp437').decode('gbk')
  37 + except:
  38 + name_t = names.encode('utf-8').decode('utf-8')
  39 +
  40 + zip_file.extract(names,store_path)
  41 +
  42 + os.chdir(store_path) # 切换到目标目录
  43 +
  44 +
  45 + if names.__contains__("/"):
  46 + pat = names.split("/")
  47 + pat_t = name_t.split("/")[-1]
  48 + pat[-1] = pat_t
  49 + name_tt = "/".join(pat)
  50 + # 只重命名文件
  51 + os.rename(names, name_tt)
  52 +
  53 + if not names[-1].__eq__("/"):
  54 + rename_path = True
  55 + rename_path_origin = names.split("/")[:-1]
  56 + rename_path_after = name_t.split("/")[:-1]
  57 + else:
  58 +
  59 + os.rename(names, name_t) # 重命名文件
  60 +
  61 + # 重命名文件夹
  62 + if rename_path:
  63 + for i in range(len(rename_path_origin),0,-1):
  64 + origin = "/".join(rename_path_origin[:i])
  65 + rename_path_origin[i-1] = rename_path_after[i-1]
  66 + after = "/".join(rename_path_origin[:i])
  67 + os.rename(origin, after)
  68 +
  69 + os.chdir(os.path.dirname(store_path))
  70 + zip_file.close()
  71 +
  72 + return store_path
  73 +
  74 +
  75 +
  76 +
  77 + @classmethod
  78 + def create_zip(cls,path, file_paths:list):
  79 + """
  80 + 创建ZIP文件 并写入文件 (支持大文件夹)
  81 + :param path: 创建的ZIP文件路径
  82 + :param file_paths:
  83 + :return:
  84 + """
  85 + try:
  86 + with zipfile.ZipFile(path, 'w', zipfile.ZIP_DEFLATED) as zip:
  87 + for file_path in file_paths:
  88 + if os.path.isdir(file_path):
  89 + pre_len = len(os.path.dirname(file_path))
  90 + for parent, dir_names, file_names in os.walk(file_path):
  91 + for filename in file_names:
  92 + path_file = os.path.join(parent, filename)
  93 + if path_file != path: # 避免将新创建的zip写入该zip文件
  94 + arc_name = path_file[pre_len:].strip(os.path.sep) # 相对路径 不进行则会生成目录树
  95 + zip.write(path_file, arc_name)
  96 + elif os.path.isfile(file_path):
  97 + zip.write(file_path, os.path.basename(file_path))
  98 + else:
  99 + print("创建zip文件对象失败!原因:未识别到路径")
  100 + return "创建zip文件对象失败!原因:未识别到路径"
  101 + return True
  102 +
  103 + except Exception as e:
  104 + print("创建zip文件对象失败!原因:%s" % str(e))
  105 + return "创建zip文件对象失败!原因:%s" % str(e)
  106 +
  107 + return path
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/5/17
  4 +#email: nheweijun@sina.com
  1 +[python: **.py]
  2 +[jinja2: **/templates/**.html]
  3 +encoding = utf-8
  1 +# Translations template for PROJECT.
  2 +# Copyright (C) 2015 ORGANIZATION
  3 +# This file is distributed under the same license as the PROJECT project.
  4 +# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
  5 +#
  6 +#, fuzzy
  7 +msgid ""
  8 +msgstr ""
  9 +"Project-Id-Version: PROJECT VERSION\n"
  10 +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
  11 +"POT-Creation-Date: 2015-10-26 13:23+0000\n"
  12 +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
  13 +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
  14 +"Language-Team: LANGUAGE <LL@li.org>\n"
  15 +"MIME-Version: 1.0\n"
  16 +"Content-Type: text/plain; charset=utf-8\n"
  17 +"Content-Transfer-Encoding: 8bit\n"
  18 +"Generated-By: Babel 2.0\n"
  19 +
  20 +#: app/templates/404.html:4
  21 +msgid "Page not found"
  22 +msgstr ""
  23 +
  1 +# coding=utf-8
  2 +
  3 +# 程序部署ip:host
  4 +deploy_ip_host = "172.26.99.160:8840"
  5 +# 系统数据库
  6 +SQLALCHEMY_DATABASE_URI = "postgresql://postgres:chinadci@172.26.99.160:5432/dmap_dms_test"
  7 +
  8 +
  9 +# 部署模式cluster,standalone
  10 +deployment_mode="cluster"
  11 +# 部署模式味cluster时有用,master,slave
  12 +application_name="master"
  13 +
  14 +# 固定配置不需要修改
  15 +swagger_configure={"title":"DMapManager"}
  16 +entry_data_thread = 3
  17 +scan_module = ["app.modules"]# API所在的模块
  1 +# coding=utf-8
  2 +import os
  3 +bind='0.0.0.0:8840'
  4 +workers=1
  5 +backlog=2048
  6 +worker_class="gevent"
  7 +#daemon=True
  8 +threads =8
  9 +pidfile='logs/gunicore.pid'
  10 +loglevel='info'
  11 +accesslog='logs/gunicorn.log'
  12 +errorlog='logs/gunicorn.err.log'
  1 +LoadModule wsgi_module "/usr/lib/apache2/modules/mod_wsgi-py39.cpython-39-x86_64-linux-gnu.so"
  2 + "/usr"
  3 +
  4 + conf.d/*.conf
  5 +<VirtualHost *>
  6 + ServerName dampmanager
  7 + yourapplication user=chinadci group=chinadci threads=5
  8 + /DMapManager /usr/src/DMapManager/run.wsgi
  9 + <Directory /usr/src/>
  10 + yourapplication
  11 + %{GLOBAL}
  12 + Require all granted
  13 + </Directory>
  14 +</VirtualHost>
  15 +
  16 +< *:80>
  17 + ServerName dampmanager
  18 + mlfans threads=5
  19 + / /var/www/mlfans/app.wsgi
  20 +
  21 + < /var/www/mlfans>
  22 + mlfans
  23 + %{GLOBAL}
  24 + On
  25 + Order deny,allow
  26 + Allow from all
  27 + </>
  28 +</>
  29 +
  30 +
  31 +
  32 +
  33 +LoadModule wsgi_module "/usr/lib/apache2/modules/mod_wsgi-py39.cpython-39-x86_64-linux-gnu.so"
  34 + "/usr"
  35 +
  36 + / /usr/DMapManager/run.wsgi
  37 +<Directory /usr/>
  38 + Require all granted
  39 +</Directory>
  1 +# coding=utf-8
  2 +coordinate={
  3 + "WGS84":{"name":"WGS84","proj4":"+proj=longlat +datum=WGS84 +no_defs","srid":4326},
  4 + "BEIJING54":{"name":"BEIJING54","proj4":"+proj=longlat +ellps=krass +towgs84=15.8,-154.4,-82.3,0,0,0,0 +no_defs","srid":2414},
  5 + "XIAN80":{"name":"XIAN80","proj4":"+proj=longlat +a=6378140 +b=6356755.288157528 +no_defs","srid":4610},
  6 + "CGCS2000":{"name":"CGCS2000","proj4":"+proj=longlat +ellps=GRS80 +no_defs","srid":4490},
  7 + "WH2000":{"name":"WH2000","proj4":"proj=tmerc +lat_0=0 +lon_0=114.333333333333 +k=1 +x_0=800000 +y_0=-3000000 +ellps=GRS80 +units=m +no_defs"},
  8 + "BD09":{"name":"BD09"},
  9 + "GCJ02":{"name":"GCJ02"}
  10 +}
  1 +flask==1.1.2
  2 +SQLAlchemy==1.3.17
  3 +Flask-SQLAlchemy==2.4.3
  4 +gevent==20.9.0
  5 +gunicorn==20.0.4
  6 +flask_cors==3.0.8
  7 +flasgger==0.9.5
  8 +GDAL==3.2.1
  9 +psycopg2==2.8.5
  10 +pyDes==2.0.1
  11 +gevent-websocket==0.10.1
  12 +Pillow==8.1.2
  13 +#Rtree==0.9.7
  14 +opencv-python==4.5.1.48
  15 +pstuil==5.8.0
  16 +mod_wsgi==4.8.0
  1 +#! /bin/bash
  2 +docker stop dmapmanager
  3 +docker rm dmapmanager
  4 +curPath=$(readlink -f "$(dirname "$0")")
  5 +#设置端口
  6 +port=""
  7 +if [ ! -n "$1" ] ;then
  8 + port="8840"
  9 + echo "未设置端口,使用默认8840端口..."
  10 +else
  11 + port=$1
  12 + echo "端口设置为$1 ..."
  13 +fi
  14 +docker run -d --name dmapmanager -e TZ="Asia/Shanghai" --restart=always -e ALLOW_IP_RANGE=0.0.0.0/0 -p $port:8840 -v $curPath:/usr/src/app -w /usr/src/app dci/dmapdms:3.0 gunicorn -c gun_conf.py run:app
  15 +# 清除未完成的任务任务
  16 +sleep 5
  17 +curl localhost:$port/release
  1 +# coding=utf-8
  2 +from flask import Flask
  3 +from app import create_app
  4 +app:Flask = create_app()
  5 +if __name__ == '__main__':
  6 + app.run(host="0.0.0.0", port="8840", threaded=True, debug=True)
  7 +
  1 +#! /bin/bash
  2 +docker stop dmapmanager
  3 +docker rm dmapmanager
  4 +curPath=$(readlink -f "$(dirname "$0")")
  5 +#设置端口
  6 +port=""
  7 +if [ ! -n "$1" ] ;then
  8 + port="8840"
  9 + echo "未设置端口,使用默认8840端口..."
  10 +else
  11 + port=$1
  12 + echo "端口设置为$1 ..."
  13 +fi
  14 +
  15 +docker run -d --name dmapmanager -e TZ="Asia/Shanghai" --restart=always -e ALLOW_IP_RANGE=0.0.0.0/0 -p $port:8840 -v $curPath:/usr/src/app -w /usr/src/app dci/dmapdms:3.0 python3 ./run.py
  16 +# 清除未完成的任务任务
  17 +sleep 5
  18 +curl localhost:$port/release
  1 +import sys
  2 +import os
  3 +file_path = os.path.dirname(os.path.realpath(__file__))
  4 +sys.path.insert(0, file_path)
  5 +from run import app as application
  1 +#! /bin/sh
  2 +
  3 +#停止容器
  4 +echo "正在关闭容器..."
  5 +docker stop apache
  6 +docker rm apache
  7 +
  8 +curPath=$(readlink -f $(dirname $0))
  9 +
  10 +#寻找模块
  11 +echo "在modules下寻找模块..."
  12 +map=""
  13 +for mod in $(ls $curPath/modules)
  14 +do
  15 + map="$map -v $curPath/modules/$mod:/usr/src/$mod"
  16 +done
  17 +
  18 +#设置日志权限
  19 +for mod in $(ls $curPath/modules)
  20 +do
  21 + chmod -R 777 $curPath/modules/$mod/logs/*
  22 +done
  23 +
  24 +
  25 +#设置端口
  26 +port=""
  27 +if [ ! -n "$1" ] ;then
  28 + port="8888"
  29 + echo "未设置端口,使用默认8888端口..."
  30 +else
  31 + port=$1
  32 + echo "端口设置为$1 ..."
  33 +fi
  34 +
  35 +#修改httpd.conf
  36 +echo "正在修改httpd.conf..."
  37 +rm $curPath/httpd.conf
  38 +cp $curPath/httpd.conf.sample $curPath/httpd.conf
  39 +echo "<VirtualHost *>" >> $curPath/httpd.conf
  40 +echo " ServerName apacheflask">>$curPath/httpd.conf
  41 +echo " WSGIDaemonProcess yourapplication user=chinadci group=chinadci threads=5">>$curPath/httpd.conf
  42 +
  43 +for mod in $(ls $curPath/modules)
  44 +do
  45 + echo " WSGIScriptAlias /$mod /usr/src/$mod/run.wsgi">>$curPath/httpd.conf
  46 +done
  47 +
  48 +echo " <Directory /usr/src/app>">>$curPath/httpd.conf
  49 +echo " WSGIProcessGroup yourapplication">>$curPath/httpd.conf
  50 +echo " WSGIApplicationGroup %{GLOBAL}">>$curPath/httpd.conf
  51 +echo " Require all granted">>$curPath/httpd.conf
  52 +echo " </Directory>">>$curPath/httpd.conf
  53 +echo "</VirtualHost>">>$curPath/httpd.conf
  54 +
  55 +#启动容器和apache
  56 +echo "正在启动容器..."
  57 +set="--privileged=true -e TZ="Asia/Shanghai" --restart=always -e ALLOW_IP_RANGE=0.0.0.0/0"
  58 +docker run -d --name apache $set -p $port:80 $map -v $curPath/httpd.conf:/etc/httpd/conf/httpd.conf dci/apache:1.0 /usr/sbin/init
  59 +docker exec -d apache systemctl start httpd
  60 +
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/6/11
  4 +#email: nheweijun@sina.com
  5 +import copy
  6 +from osgeo.ogr import *
  7 +from osgeo import gdal,ogr
  8 +import uuid
  9 +import time
  10 +import os
  11 +
  12 +def get_info_from_sqlachemy_uri(uri):
  13 + parts = uri.split(":")
  14 + user = parts[1][2:]
  15 +
  16 + password_list = parts[2].split("@")
  17 + if password_list.__len__() > 2:
  18 + password = "@".join(password_list[:-1])
  19 + else:
  20 + password = parts[2].split("@")[0]
  21 + host = parts[2].split("@")[-1]
  22 + port = parts[3].split("/")[0]
  23 + database = parts[3].split("/")[1]
  24 +
  25 + return user, password, host, port, database
  26 +
  27 +def open_pg_data_source(iswrite, uri):
  28 + """
  29 + # 获取PostGIS数据源
  30 + :return:
  31 + """
  32 + db_conn_tuple = get_info_from_sqlachemy_uri(uri)
  33 + fn = "PG: user=%s password=%s host=%s port=%s dbname=%s " % db_conn_tuple
  34 + driver = ogr.GetDriverByName("PostgreSQL")
  35 + if driver is None:
  36 + raise Exception("打开PostgreSQL驱动失败,可能是当前GDAL未支持PostgreSQL驱动!")
  37 + ds = driver.Open(fn, iswrite)
  38 + if ds is None:
  39 + raise Exception("打开数据源失败!")
  40 + return ds
  41 +
  42 +def move(geo:Geometry,offx,offy):
  43 +
  44 + g = geo.GetGeometryRef(0)
  45 + num = g.GetPointCount()
  46 +
  47 + coor = []
  48 + try:
  49 + for j in range(num):
  50 + point = g.GetPoint(j)
  51 + x = point[0]
  52 + y = point[1]
  53 + x += offx
  54 + y += offy
  55 + coor.append([x, y])
  56 + if num==1:
  57 + point = ogr.Geometry(ogr.wkbPoint)
  58 + point.AddPoint(coor[0][0], coor[0][1])
  59 + return point
  60 + elif coor[0].__eq__(coor[-1]):
  61 + ring = ogr.Geometry(ogr.wkbLinearRing)
  62 + for co in coor:
  63 + ring.AddPoint(co[0], co[1])
  64 + poly = ogr.Geometry(ogr.wkbPolygon)
  65 + poly.AddGeometry(ring)
  66 + return poly
  67 + else :
  68 + line = ogr.Geometry(ogr.wkbLineString)
  69 + for co in coor:
  70 + line.AddPoint(co[0], co[1])
  71 + return line
  72 + except:
  73 + return None
  74 +# work_dir =os.path.dirname(os.path.abspath(__file__))
  75 +work_dir =r"E:\D2\桌面\FSSD_RES_PY_FWM"
  76 +
  77 +data_path=r"E:\D2\桌面\FSSD_RES_PY_FWM\fs4326.shp"
  78 +
  79 +base_name="fs900w"
  80 +
  81 +driver: Driver = ogr.GetDriverByName("ESRI Shapefile")
  82 +ds: DataSource = driver.Open(data_path, 1)
  83 +
  84 +
  85 +
  86 +if not ds:
  87 + raise Exception("打开数据失败!")
  88 +
  89 +layer: Layer = ds.GetLayer(0)
  90 +
  91 +
  92 +
  93 +schema = layer.schema
  94 +schema = [s for s in schema if not s.GetName().lower().__eq__("objectid")]
  95 +for s in schema :
  96 + if s.GetName().lower().__eq__("objectid") and not s.GetTypeName().__eq__("Interger"):
  97 + s.SetType(ogr.OFTInteger)
  98 +
  99 +
  100 +# pg_ds:DataSource= open_pg_data_source(1,"postgresql://postgres:chinadci@172.26.99.173:5433/postgres")
  101 +# pg_layer: Layer = pg_ds.CreateLayer(base_name, layer.GetSpatialRef(), layer.GetGeomType(),["GEOMETRY_NAME=g","OVERWRITE=YES","FID=fid"])
  102 +# pg_layer.CreateFields(schema)
  103 +
  104 +gdb_driver:Driver = ogr.GetDriverByName("FileGDB")
  105 +gdb_ds: DataSource = gdb_driver.CreateDataSource(os.path.join(work_dir,"{}.gdb".format(base_name)))
  106 +gdb_layer:Layer = gdb_ds.CreateLayer(base_name, layer.GetSpatialRef(),layer.GetGeomType())
  107 +
  108 +# gdb_layer.CreateFields(schema)
  109 +
  110 +print(gdb_layer.GetFIDColumn())
  111 +
  112 +extent = layer.GetExtent()
  113 +xxrange=extent[1]-extent[0]
  114 +yrange = extent[3]-extent[2]
  115 +feature_defn: FeatureDefn = layer.GetLayerDefn()
  116 +
  117 +begin = time.time()
  118 +count=0
  119 +work_dir =os.path.dirname(os.path.abspath(__file__))
  120 +
  121 +for f in layer:
  122 +
  123 + if count%10000==0:
  124 + print(count)
  125 + with open(os.path.join(work_dir, "copy.txt"), "w") as fi:
  126 + fi.write("已完成{}".format(count))
  127 + g:Geometry=f.GetGeometryRef()
  128 + new_f:Feature = copy.copy(f)
  129 + for xt in range(3):
  130 + for yt in range(3):
  131 + out_g = move(g,xxrange*xt,yrange*yt)
  132 + new_f.SetGeometry(out_g)
  133 + new_f.SetFID(count)
  134 + dd:FieldDefn=new_f.GetField("OBJECTID")
  135 + # new_f.UnsetField("OBJECTID")
  136 + gdb_layer.CreateFeature(new_f)
  137 + count += 1
  138 +
  139 +print(time.time()-begin)
  140 +
  141 +gdb_ds.Destroy()
  142 +
  143 +
  144 +
  145 +
  146 +
  147 +
  148 +
  149 +
  150 +
  151 +
  152 +
  153 +
  154 +
  155 +
  156 +
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/6/9
  4 +#email: nheweijun@sina.com
  5 +
  6 +from osgeo.ogr import *
  7 +from osgeo.gdal import *
  8 +
  9 +from osgeo import ogr
  10 +import random
  11 +import time
  12 +
  13 +layer_name = "random"
  14 +
  15 +driver:Driver = ogr.GetDriverByName("ESRI Shapefile")
  16 +data_source: DataSource = driver.CreateDataSource(r"E:/Data/bigdata/{}.shp".format(layer_name))
  17 +
  18 +outLayer = data_source.CreateLayer(layer_name, geom_type=ogr.wkbPoint )
  19 +t_point = time.time()
  20 +
  21 +#打开广东边界
  22 +ds: DataSource = driver.Open("E:\Data\广东边界\gdsample.shp", 1)
  23 +if not ds:
  24 + raise Exception("打开数据失败!")
  25 +layer: Layer = ds.GetLayer(0)
  26 +feat :Feature = layer.GetFeature(0)
  27 +geo:Geometry=feat.GetGeometryRef()
  28 +extent = geo.GetEnvelope()
  29 +
  30 +i=0
  31 +while i<100000:
  32 + point = ogr.Geometry(ogr.wkbPoint)
  33 +
  34 + x = (extent[1]-extent[0])*random.random()+extent[0]
  35 + y = (extent[3]-extent[2])*random.random()+extent[2]
  36 + point.AddPoint_2D(x,y)
  37 + # print(geo.Intersect(point))
  38 +
  39 +
  40 + if geo.Intersect(point):
  41 + i+=1
  42 + # print(i)
  43 + featureDefn = outLayer.GetLayerDefn()
  44 + outFeature = ogr.Feature(featureDefn)
  45 + outFeature.SetGeometry(point)
  46 +
  47 + outLayer.CreateFeature(outFeature)
  48 + if i%10000==0:
  49 + print(i)
  50 + print(time.time() - t_point)
  51 + t_point=time.time()
  52 + outFeature=None
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/6/11
  4 +#email: nheweijun@sina.com
  5 +
  6 +from osgeo.ogr import *
  7 +from osgeo import gdal,ogr
  8 +
  9 +
  10 +def get_info_from_sqlachemy_uri(uri):
  11 + parts = uri.split(":")
  12 + user = parts[1][2:]
  13 +
  14 + password_list = parts[2].split("@")
  15 + if password_list.__len__() > 2:
  16 + password = "@".join(password_list[:-1])
  17 + else:
  18 + password = parts[2].split("@")[0]
  19 + host = parts[2].split("@")[-1]
  20 + port = parts[3].split("/")[0]
  21 + database = parts[3].split("/")[1]
  22 +
  23 + return user, password, host, port, database
  24 +
  25 +
  26 +def open_pg_data_source(iswrite, uri):
  27 + """
  28 + # 获取PostGIS数据源
  29 + :return:
  30 + """
  31 + db_conn_tuple = get_info_from_sqlachemy_uri(uri)
  32 + fn = "PG: user=%s password=%s host=%s port=%s dbname=%s " % db_conn_tuple
  33 + driver = ogr.GetDriverByName("PostgreSQL")
  34 + if driver is None:
  35 + raise Exception("打开PostgreSQL驱动失败,可能是当前GDAL未支持PostgreSQL驱动!")
  36 + ds = driver.Open(fn, iswrite)
  37 + if ds is None:
  38 + raise Exception("打开数据源失败!")
  39 + return ds
  40 +
  41 +# data_path=r"E:\Data\voronoi8000w.gdb"
  42 +#
  43 +# driver: Driver = ogr.GetDriverByName("OpenFileGDB")
  44 +# ds: DataSource = driver.Open(data_path, 0)
  45 +# if not ds:
  46 +# raise Exception("打开数据失败!")
  47 +#
  48 +# layer: Layer = ds.GetLayer(0)
  49 +pg_ds:DataSource= open_pg_data_source(1,"postgresql://postgres:chinadci@172.26.99.173:5433/postgres")
  50 +
  51 +pg_layer: Layer = pg_ds.CreateLayer("tg3", None, ogr.wkbUnknown)
  52 +
  53 +feat = ogr.Feature(pg_layer.GetLayerDefn())
  54 +point = ogr.Geometry(ogr.wkbPoint)
  55 +point.AddPoint(1198054.34, 648493.09)
  56 +feat.SetGeometry(point)
  57 +pg_layer.CreateFeature(feat)
  58 +
  59 +
  60 +feat2 = ogr.Feature(pg_layer.GetLayerDefn())
  61 +
  62 +ring = ogr.Geometry(ogr.wkbLinearRing)
  63 +ring.AddPoint(1179091.1646903288, 712782.8838459781)
  64 +ring.AddPoint(1161053.0218226474, 667456.2684348812)
  65 +ring.AddPoint(1214704.933941905, 641092.8288590391)
  66 +ring.AddPoint(1228580.428455506, 682719.3123998424)
  67 +ring.AddPoint(1218405.0658121984, 721108.1805541387)
  68 +ring.AddPoint(1179091.1646903288, 712782.8838459781)
  69 +
  70 +
  71 +
  72 +# Create polygon
  73 +poly = ogr.Geometry(ogr.wkbPolygon)
  74 +poly.AddGeometry(ring)
  75 +
  76 +print(poly.GetEnvelope())
  77 +
  78 +feat2.SetGeometry(poly)
  79 +pg_layer.CreateFeature(feat2)
  80 +
  81 +
  82 +pg_ds.Destroy()
  83 +
  84 +
  85 +
  86 +
  87 +
  88 +
  89 +
  90 +
  91 +
  92 +
  93 +
  94 +
  95 +
  96 +
  97 +
  98 +
  99 +
  100 +
  101 +
  102 +
  103 +
  104 +
  105 +
  106 +
  107 +
  108 +
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2020/6/28
  4 +#email: nheweijun@sina.com
  5 +
  6 +from osgeo import ogr
  7 +from osgeo.ogr import DataSource,Driver,Layer,Feature
  8 +
  9 +
  10 +from osgeo.ogr import *
  11 +from osgeo import gdal,ogr
  12 +import uuid
  13 +import os
  14 +import math
  15 +import time
  16 +
  17 +import threading
  18 +import copy
  19 +def get_info_from_sqlachemy_uri(uri):
  20 + parts = uri.split(":")
  21 + user = parts[1][2:]
  22 +
  23 + password_list = parts[2].split("@")
  24 + if password_list.__len__() > 2:
  25 + password = "@".join(password_list[:-1])
  26 + else:
  27 + password = parts[2].split("@")[0]
  28 + host = parts[2].split("@")[-1]
  29 + port = parts[3].split("/")[0]
  30 + database = parts[3].split("/")[1]
  31 +
  32 + return user, password, host, port, database
  33 +
  34 +
  35 +def open_pg_data_source(iswrite, uri):
  36 + """
  37 + # 获取PostGIS数据源
  38 + :return:
  39 + """
  40 + db_conn_tuple = get_info_from_sqlachemy_uri(uri)
  41 + fn = "PG: user=%s password=%s host=%s port=%s dbname=%s " % db_conn_tuple
  42 + driver = ogr.GetDriverByName("PostgreSQL")
  43 + if driver is None:
  44 + raise Exception("打开PostgreSQL驱动失败,可能是当前GDAL未支持PostgreSQL驱动!")
  45 + ds = driver.Open(fn, iswrite)
  46 + if ds is None:
  47 + raise Exception("打开数据源失败!")
  48 + return ds
  49 +
  50 +
  51 +
  52 +
  53 +def vacuate(extent: tuple, g,max_level,fill_dict,vacuate_layers, vacuate_layers_gridsize):
  54 +
  55 + for level in range(max_level):
  56 +
  57 + center: Geometry = g.Centroid()
  58 +
  59 + this_grid_len = vacuate_layers_gridsize[level]
  60 +
  61 + row = int((center.GetY() - extent[2]) / this_grid_len)
  62 + col = int((center.GetX() - extent[0]) / this_grid_len)
  63 + key = "{}.{}.{}".format(level,row, col)
  64 +
  65 +
  66 + if not fill_dict.get(key):
  67 + fill_dict[key] = 0
  68 + if fill_dict[key] == 0:
  69 + vacuate_layer = vacuate_layers.get(level)
  70 + feat = ogr.Feature(vacuate_layer.GetLayerDefn())
  71 + feat.SetGeometry(g)
  72 + vacuate_layer.CreateFeature(feat)
  73 + # if level==0:
  74 + # vacuate_layer.CreateFeature(feature)
  75 + fill_dict[key] += 1
  76 +
  77 +
  78 +def change_geom_type(raw):
  79 + if raw.__eq__(-2147483646):
  80 + return 5
  81 + if raw.__eq__(-2147483645) or raw.__eq__(-2147483642):
  82 + return 6
  83 + if raw==2 or raw ==3:
  84 + return raw+3
  85 + if raw==4:
  86 + return 1
  87 + return raw
  88 +
  89 +def get_table_type(raw):
  90 + if raw==4 or raw ==5 or raw ==6:
  91 + return raw-3
  92 + return raw
  93 +
  94 +def change_geom(geo:Geometry,geom_type):
  95 + '''
  96 + 转换空间对象的类型,以适应dmap只支持Multi类型
  97 + :param geo:
  98 + :param geom_type:
  99 + :return: 转换后的空间对象
  100 + '''
  101 +
  102 + if geom_type==5 or geom_type.__eq__(-2147483646):
  103 + return ogr.ForceToMultiLineString(geo)
  104 + if geom_type==6 or geom_type.__eq__(-2147483645):
  105 + return ogr.ForceToMultiPolygon(geo)
  106 + if geom_type==1:
  107 + # 多点转单点,会有问题,只拿了第一个点
  108 + xy = geo.GetPoint()
  109 + point = ogr.Geometry(ogr.wkbPoint)
  110 + point.AddPoint(xy[0], xy[1])
  111 + return point
  112 + return geo
  113 +
  114 +
  115 +def insert(data_path,new_layer_name,sqlalchemy_uri,out,num):
  116 +
  117 + work_dir =os.path.dirname(os.path.abspath(__file__))
  118 +
  119 +
  120 + #打开图层
  121 + driver: Driver = ogr.GetDriverByName("OpenFileGDB")
  122 + if data_path.endswith("shp"):
  123 + driver: Driver = ogr.GetDriverByName("ESRI Shapefile")
  124 + ds: DataSource = driver.Open(data_path, 0)
  125 + if not ds:
  126 + raise Exception("打开数据失败!")
  127 + layer: Layer = ds.GetLayer(0)
  128 +
  129 +
  130 + #创建PG图层
  131 + pg_ds:DataSource= open_pg_data_source(1,sqlalchemy_uri)
  132 + geom_type =change_geom_type(layer.GetGeomType())
  133 + print(geom_type)
  134 +
  135 + pg_layer: Layer = pg_ds.CreateLayer(new_layer_name, layer.GetSpatialRef(),geom_type,["GEOMETRY_NAME=g","OVERWRITE=YES"])
  136 + pg_layer.CreateFields(layer.schema)
  137 +
  138 +
  139 +
  140 + #设置抽稀级别
  141 + layer_count = layer.GetFeatureCount()
  142 + max_level = 0
  143 + while layer_count>50000:
  144 + max_level+=1
  145 + layer_count/=2
  146 + print(max_level)
  147 +
  148 + pg_ds_dict={}
  149 + #创建抽稀ds
  150 + for l in range(max_level):
  151 + pg_ds_l: DataSource = open_pg_data_source(1, sqlalchemy_uri)
  152 + pg_ds_dict[l]=pg_ds_l
  153 +
  154 + #建立抽稀图层
  155 + lc = layer.GetFeatureCount()
  156 + extent = layer.GetExtent()
  157 + vacuate_layers = {}
  158 + vacuate_layers_gridsize = {}
  159 +
  160 + density=2
  161 +
  162 + for l in range(max_level):
  163 + pg_ds_l=pg_ds_dict[l]
  164 + vl = pg_ds_l.CreateLayer("{}_vacuate_{}".format(new_layer_name, l), layer.GetSpatialRef(),geom_type, ["GEOMETRY_NAME=g","OVERWRITE=YES"])
  165 + # vl.CreateFields(layer.schema)
  166 + vacuate_layers[l] = vl
  167 + need_object = (lc * density / (2 ** (l + 1)))
  168 + this_grid_ysize = math.sqrt(need_object / ((extent[1] - extent[0]) / (extent[3] - extent[2])))
  169 + this_grid_len = (extent[3] - extent[2]) / this_grid_ysize
  170 + print(this_grid_len)
  171 + vacuate_layers_gridsize[l]=this_grid_len
  172 +
  173 + count=0
  174 + fill_dict = dict()
  175 +
  176 +
  177 + for feature in layer:
  178 + count += 1
  179 + if count==num:
  180 + break
  181 +
  182 + out_feature: Feature = copy.copy(feature)
  183 + out_geom=None
  184 + geo: Geometry = feature.GetGeometryRef()
  185 + # 如果是空对象不录入
  186 + if geo is not None:
  187 + if geo.IsEmpty():
  188 + continue
  189 +
  190 +
  191 + if geo is not None:
  192 + out_geom: Geometry = change_geom(geo, geom_type)
  193 + out_feature.SetGeometry(out_geom)
  194 +
  195 + pg_layer.CreateFeature(out_feature)
  196 +
  197 + if geo is not None:
  198 + vacuate(extent, out_geom, max_level, fill_dict, vacuate_layers, vacuate_layers_gridsize)
  199 +
  200 + if count % 10000 == 0:
  201 + print(count)
  202 + with open(os.path.join(work_dir,out),"w") as fi:
  203 + fi.write("已完成{}".format(count))
  204 +
  205 + pg_ds.Destroy()
  206 + for pg in pg_ds_dict.values():
  207 + pg.Destroy()
  208 + ds.Destroy()
  209 +
  210 +
  211 +if __name__ == '__main__':
  212 + data_path = r"E:\D2\桌面\FSSD_RES_PY_FWM\FSSD_RES_PY_FWM.shp"
  213 + new_layer_name = "fs1"
  214 + sqlalchemy_uri="postgresql://postgres:chinadci@172.26.99.173:5433/postgres"
  215 + out="va.txt"
  216 + begin=time.time()
  217 + num=400
  218 + insert(data_path,new_layer_name,sqlalchemy_uri,out,num)
  219 + print(time.time()-begin)
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/6/9
  4 +#email: nheweijun@sina.com
  5 +
  6 +from osgeo.ogr import *
  7 +from osgeo.gdal import *
  8 +#
  9 +from osgeo import ogr
  10 +import random
  11 +import time
  12 +
  13 +from scipy.spatial import Voronoi,voronoi_plot_2d
  14 +import numpy as np
  15 +import random
  16 +import os
  17 +import time
  18 +
  19 +print(os.path.abspath(__file__))
  20 +begin_time = time.time()
  21 +
  22 +
  23 +create_feature=100000
  24 +
  25 +layer_name="voronoixian"
  26 +work_dir = r"E:/Data/bigdata"
  27 +# work_dir =os.path.dirname(os.path.abspath(__file__))
  28 +
  29 +driver:Driver = ogr.GetDriverByName("ESRI Shapefile")
  30 +
  31 +#打开广东边界
  32 +ds: DataSource = driver.Open("E:\Data\广东边界\gdxian.shp", 1)
  33 +if not ds:
  34 + raise Exception("打开数据失败!")
  35 +layer: Layer = ds.GetLayer(0)
  36 +
  37 +each_piece_features = create_feature*1.0/layer.GetFeatureCount()
  38 +
  39 +data_source=None
  40 +outLayer=None
  41 +
  42 +for feat in layer:
  43 + geo:Geometry=feat.GetGeometryRef()
  44 + extent = geo.GetEnvelope()
  45 + points = []
  46 + i=0
  47 + while i<each_piece_features:
  48 + point = ogr.Geometry(ogr.wkbPoint)
  49 +
  50 + x = (extent[1]-extent[0])*random.random()+extent[0]
  51 + y = (extent[3]-extent[2])*random.random()+extent[2]
  52 + point.AddPoint_2D(x,y)
  53 + # print(geo.Intersect(point))
  54 + if geo.Intersect(point):
  55 + points.append([x,y])
  56 + i+=1
  57 +
  58 +
  59 + array = np.array(points)
  60 +
  61 + # 沃罗诺伊图
  62 + vor = Voronoi(array,furthest_site=False, incremental=True, qhull_options=None)
  63 +
  64 +
  65 + # 泰森多边形的顶点
  66 + vertices = vor.vertices
  67 +
  68 +
  69 + regions = vor.regions
  70 +
  71 +
  72 +
  73 +
  74 +
  75 + if not data_source:
  76 + data_source: DataSource = driver.CreateDataSource(os.path.join(work_dir,"{}.shp".format(layer_name)))
  77 + if not outLayer:
  78 + outLayer = data_source.CreateLayer(layer_name, geom_type=ogr.wkbPolygon )
  79 +
  80 +
  81 + print(time.time()-begin_time)
  82 + print("here")
  83 + vonoi_time = time.time()
  84 +
  85 +
  86 + for index,r in enumerate(regions):
  87 + if len(r) == 0:
  88 + continue
  89 + if -1 in r:
  90 + continue
  91 + angulars = []
  92 + for id in r:
  93 + angulars.append(vertices[id])
  94 + angulars.append(vertices[r[0]])
  95 +
  96 +
  97 + ring = ogr.Geometry(ogr.wkbLinearRing)
  98 + for point in angulars:
  99 + ring.AddPoint(point[0],point[1])
  100 +
  101 +
  102 + # Create polygon
  103 + poly = ogr.Geometry(ogr.wkbPolygon)
  104 + poly.AddGeometry(ring)
  105 +
  106 + poly:Geometry= geo.Intersection(poly)
  107 + if poly:
  108 + if poly.IsEmpty():
  109 + continue
  110 +
  111 + featureDefn = outLayer.GetLayerDefn()
  112 + outFeature = ogr.Feature(featureDefn)
  113 + outFeature.SetGeometry(poly)
  114 +
  115 + outLayer.CreateFeature(outFeature)
  116 + outFeature = None
  117 +
  118 + print(time.time()-vonoi_time)
  119 +data_source.Destroy()
  120 +ds.Destroy()
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/6/9
  4 +#email: nheweijun@sina.com
  5 +
  6 +from osgeo.ogr import *
  7 +from osgeo.gdal import *
  8 +#
  9 +from osgeo import ogr
  10 +import random
  11 +import time
  12 +
  13 +from scipy.spatial import Voronoi,voronoi_plot_2d
  14 +import numpy as np
  15 +import random
  16 +import os
  17 +import time
  18 +
  19 +print(os.path.abspath(__file__))
  20 +begin_time = time.time()
  21 +
  22 +
  23 +
  24 +
  25 +work_dir = r"E:/Data/bigdata"
  26 +
  27 +
  28 +driver:Driver = ogr.GetDriverByName("OpenFileGDB")
  29 +
  30 +
  31 +
  32 +ds: DataSource = driver.Open("", 1)
  33 +if not ds:
  34 + raise Exception("打开数据失败!")
  35 +
  36 +layer: Layer = ds.GetLayer(0)
  37 +feat=layer.GetFeature(0)
  38 +gdsample:Geometry=feat.GetGeometryRef()
  39 +extent = gdsample.GetEnvelope()
  40 +
  41 +
  42 +
  43 +#裁切网格
  44 +grid_list=[]
  45 +
  46 +each_x=(extent[1]-extent[0])/grid_num
  47 +each_y=(extent[3]-extent[2])/grid_num
  48 +
  49 +for xn in range(grid_num+1):
  50 +
  51 + for yn in range(grid_num + 1):
  52 +
  53 + ring = ogr.Geometry(ogr.wkbLinearRing)
  54 +
  55 + ring.AddPoint(extent[0] + xn * each_x, extent[2] + yn * each_y)
  56 + ring.AddPoint(extent[0] + xn * each_x, extent[2] + yn * each_y + each_y)
  57 + ring.AddPoint(extent[0] + xn * each_x + each_x, extent[2] + yn * each_y + each_y)
  58 + ring.AddPoint(extent[0] + xn * each_x + each_x, extent[2] + yn * each_y)
  59 + ring.AddPoint(extent[0] + xn * each_x, extent[2] + yn * each_y)
  60 +
  61 + # Create polygon
  62 + grid = ogr.Geometry(ogr.wkbPolygon)
  63 + grid.AddGeometry(ring)
  64 +
  65 + inter_grid:Geometry = gdsample.Intersection(grid)
  66 +
  67 + if inter_grid:
  68 + if not inter_grid.IsEmpty():
  69 + if inter_grid.Area()/grid.Area()>0.5:
  70 + grid_list.append(inter_grid)
  71 +
  72 +each_piece_features = create_feature*1.0/len(grid_list)
  73 +
  74 +
  75 +
  76 +data_source: DataSource = driver.CreateDataSource(os.path.join(work_dir, "{}.shp".format(layer_name)))
  77 +
  78 +outLayer = data_source.CreateLayer(layer_name, geom_type=ogr.wkbPolygon)
  79 +
  80 +passnum=1
  81 +for geo in grid_list:
  82 + passnum+=1
  83 + if passnum%10==0:
  84 + continue
  85 + extent = geo.GetEnvelope()
  86 + points = []
  87 + i=0
  88 + while i<each_piece_features:
  89 + point = ogr.Geometry(ogr.wkbPoint)
  90 +
  91 + x = (extent[1]-extent[0])*random.random()+extent[0]
  92 + y = (extent[3]-extent[2])*random.random()+extent[2]
  93 + point.AddPoint_2D(x,y)
  94 +
  95 + if geo.Intersect(point):
  96 + points.append([x,y])
  97 + i+=1
  98 +
  99 +
  100 + array = np.array(points)
  101 +
  102 + # 沃罗诺伊图
  103 + vor = Voronoi(array,furthest_site=False, incremental=True, qhull_options=None)
  104 +
  105 +
  106 + # 泰森多边形的顶点
  107 + vertices = vor.vertices
  108 +
  109 +
  110 + regions = vor.regions
  111 +
  112 +
  113 + print(time.time()-begin_time)
  114 + print("here")
  115 + vonoi_time = time.time()
  116 +
  117 + add = True
  118 +
  119 + for index,r in enumerate(regions):
  120 + if len(r) == 0:
  121 + continue
  122 + if -1 in r:
  123 + continue
  124 + angulars = []
  125 + for id in r:
  126 + angulars.append(vertices[id])
  127 + angulars.append(vertices[r[0]])
  128 +
  129 +
  130 + ring = ogr.Geometry(ogr.wkbLinearRing)
  131 + for point in angulars:
  132 + ring.AddPoint(point[0],point[1])
  133 +
  134 +
  135 + # Create polygon
  136 + poly = ogr.Geometry(ogr.wkbPolygon)
  137 + poly.AddGeometry(ring)
  138 +
  139 + poly:Geometry= geo.Intersection(poly)
  140 +
  141 + if add:
  142 + # add =False
  143 + if poly:
  144 + if poly.IsEmpty():
  145 + continue
  146 +
  147 + featureDefn = outLayer.GetLayerDefn()
  148 + outFeature = ogr.Feature(featureDefn)
  149 + outFeature.SetGeometry(poly)
  150 +
  151 + outLayer.CreateFeature(outFeature)
  152 + outFeature = None
  153 + else:
  154 + add=True
  155 +
  156 + print(time.time()-vonoi_time)
  157 +data_source.Destroy()
  158 +ds.Destroy()
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2020/6/29
  4 +#email: nheweijun@sina.com
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2020/10/16
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +
  8 +import numpy as np
  9 +
  10 +
  11 +def bezier_curve(p0, p1, p2, p3, inserted):
  12 + """
  13 + 三阶贝塞尔曲线
  14 +
  15 + p0, p1, p2, p3 - 点坐标,tuple、list或numpy.ndarray类型
  16 + inserted - p0和p3之间插值的数量
  17 + """
  18 + if isinstance(p0, (tuple, list)):
  19 + p0 = np.array(p0)
  20 + if isinstance(p1, (tuple, list)):
  21 + p1 = np.array(p1)
  22 + if isinstance(p2, (tuple, list)):
  23 + p2 = np.array(p2)
  24 + if isinstance(p3, (tuple, list)):
  25 + p3 = np.array(p3)
  26 +
  27 + points = list()
  28 + for t in np.linspace(0, 1, inserted + 2):
  29 + points.append(p0 * np.power((1 - t), 3) + 3 * p1 * t * np.power((1 - t), 2) + 3 * p2 * (1 - t) * np.power(t,
  30 + 2) + p3 * np.power(
  31 + t, 3))
  32 +
  33 + return np.vstack(points)
  34 +
  35 +
  36 +def smoothing_base_bezier(date_x, date_y, k=0.5, inserted=10, closed=False):
  37 + """
  38 + 基于三阶贝塞尔曲线的数据平滑算法
  39 +
  40 + date_x - x维度数据集,list或numpy.ndarray类型
  41 + date_y - y维度数据集,list或numpy.ndarray类型
  42 + k - 调整平滑曲线形状的因子,取值一般在0.2~0.6之间。默认值为0.5
  43 + inserted - 两个原始数据点之间插值的数量。默认值为10
  44 + closed - 曲线是否封闭,如是,则首尾相连。默认曲线不封闭
  45 + """
  46 +
  47 + date_x = np.array(date_x)
  48 + date_y = np.array(date_y)
  49 +
  50 +
  51 + # 第1步:生成原始数据折线中点集
  52 + mid_points = list()
  53 + for i in range(1, date_x.shape[0]):
  54 + mid_points.append({
  55 + 'start': (date_x[i - 1], date_y[i - 1]),
  56 + 'end': (date_x[i], date_y[i]),
  57 + 'mid': ((date_x[i] + date_x[i - 1]) / 2.0, (date_y[i] + date_y[i - 1]) / 2.0)
  58 + })
  59 +
  60 + import uuid
  61 +
  62 + if closed:
  63 + mid_points.append({
  64 + 'start': (date_x[-1], date_y[-1]),
  65 + 'end': (date_x[0], date_y[0]),
  66 + 'mid': ((date_x[0] + date_x[-1]) / 2.0, (date_y[0] + date_y[-1]) / 2.0)
  67 + })
  68 +
  69 + # 第2步:找出中点连线及其分割点
  70 + split_points = list()
  71 + for i in range(len(mid_points)):
  72 + if i < (len(mid_points) - 1):
  73 + j = i + 1
  74 + elif closed:
  75 + j = 0
  76 + else:
  77 + continue
  78 +
  79 + x00, y00 = mid_points[i]['start']
  80 + x01, y01 = mid_points[i]['end']
  81 + x10, y10 = mid_points[j]['start']
  82 + x11, y11 = mid_points[j]['end']
  83 + d0 = np.sqrt(np.power((x00 - x01), 2) + np.power((y00 - y01), 2))
  84 + d1 = np.sqrt(np.power((x10 - x11), 2) + np.power((y10 - y11), 2))
  85 + k_split = 1.0 * d0 / (d0 + d1)
  86 +
  87 + mx0, my0 = mid_points[i]['mid']
  88 + mx1, my1 = mid_points[j]['mid']
  89 +
  90 + split_points.append({
  91 + 'start': (mx0, my0),
  92 + 'end': (mx1, my1),
  93 + 'split': (mx0 + (mx1 - mx0) * k_split, my0 + (my1 - my0) * k_split)
  94 + })
  95 +
  96 + # 第3步:平移中点连线,调整端点,生成控制点
  97 + crt_points = list()
  98 + for i in range(len(split_points)):
  99 + vx, vy = mid_points[i]['end'] # 当前顶点的坐标
  100 + dx = vx - split_points[i]['split'][0] # 平移线段x偏移量
  101 + dy = vy - split_points[i]['split'][1] # 平移线段y偏移量
  102 +
  103 + sx, sy = split_points[i]['start'][0] + dx, split_points[i]['start'][1] + dy # 平移后线段起点坐标
  104 + ex, ey = split_points[i]['end'][0] + dx, split_points[i]['end'][1] + dy # 平移后线段终点坐标
  105 +
  106 + cp0 = sx + (vx - sx) * k, sy + (vy - sy) * k # 控制点坐标
  107 + cp1 = ex + (vx - ex) * k, ey + (vy - ey) * k # 控制点坐标
  108 +
  109 + if crt_points:
  110 + crt_points[-1].insert(2, cp0)
  111 + else:
  112 + crt_points.append([mid_points[0]['start'], cp0, mid_points[0]['end']])
  113 +
  114 + if closed:
  115 + if i < (len(mid_points) - 1):
  116 + crt_points.append([mid_points[i + 1]['start'], cp1, mid_points[i + 1]['end']])
  117 + else:
  118 + crt_points[0].insert(1, cp1)
  119 + else:
  120 + if i < (len(mid_points) - 2):
  121 + crt_points.append([mid_points[i + 1]['start'], cp1, mid_points[i + 1]['end']])
  122 + else:
  123 + crt_points.append([mid_points[i + 1]['start'], cp1, mid_points[i + 1]['end'], mid_points[i + 1]['end']])
  124 + crt_points[0].insert(1, mid_points[0]['start'])
  125 +
  126 + # 第4步:应用贝塞尔曲线方程插值
  127 + out = list()
  128 + for item in crt_points:
  129 + from numpy import ndarray
  130 + group:ndarray = bezier_curve(item[0], item[1], item[2], item[3], inserted)
  131 +
  132 + kk = group.tolist()
  133 +
  134 + out.append(group[:-1])
  135 +
  136 + out.append(group[-1:])
  137 + out = np.vstack(out)
  138 +
  139 + return out.T[0], out.T[1]
  140 +
  141 +
  142 +if __name__ == '__main__':
  143 + import matplotlib.pyplot as plt
  144 +
  145 + x = np.array([2, 4, 4, 3, 2])
  146 + y = np.array([2, 2, 4, 3, 4])
  147 +
  148 + plt.plot(x, y, 'ro')
  149 + x_curve, y_curve = smoothing_base_bezier(x, y, k=0.3, closed=True)
  150 + # print(x_curve)
  151 + # print(y_curve)
  152 + plt.plot(x_curve, y_curve, label='$k=0.3$')
  153 + # x_curve, y_curve = smoothing_base_bezier(x, y, k=0.4, closed=True)
  154 + # plt.plot(x_curve, y_curve, label='$k=0.4$')
  155 + # x_curve, y_curve = smoothing_base_bezier(x, y, k=0.5, closed=True)
  156 + # plt.plot(x_curve, y_curve, label='$k=0.5$')
  157 + # x_curve, y_curve = smoothing_base_bezier(x, y, k=0.6, closed=True)
  158 + # plt.plot(x_curve, y_curve, label='$k=0.6$')
  159 + plt.legend(loc='best')
  160 +
  161 + # plt.show()
  162 + group = [1,2,3,4,5]
  163 + print(group[:-1])
  164 + print(group[-1:])
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2020/10/16
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +
  8 +import numpy as np
  9 +
  10 +
  11 +def bezier_curve(p0, p1, p2, p3, inserted):
  12 + """
  13 + 三阶贝塞尔曲线
  14 +
  15 + p0, p1, p2, p3 - 点坐标,tuple、list或numpy.ndarray类型
  16 + inserted - p0和p3之间插值的数量
  17 + """
  18 +
  19 + assert isinstance(p0, (tuple, list, np.ndarray)), u'点坐标不是期望的元组、列表或numpy数组类型'
  20 + assert isinstance(p0, (tuple, list, np.ndarray)), u'点坐标不是期望的元组、列表或numpy数组类型'
  21 + assert isinstance(p0, (tuple, list, np.ndarray)), u'点坐标不是期望的元组、列表或numpy数组类型'
  22 + assert isinstance(p0, (tuple, list, np.ndarray)), u'点坐标不是期望的元组、列表或numpy数组类型'
  23 +
  24 + if isinstance(p0, (tuple, list)):
  25 + p0 = np.array(p0)
  26 + if isinstance(p1, (tuple, list)):
  27 + p1 = np.array(p1)
  28 + if isinstance(p2, (tuple, list)):
  29 + p2 = np.array(p2)
  30 + if isinstance(p3, (tuple, list)):
  31 + p3 = np.array(p3)
  32 +
  33 + points = list()
  34 + for t in np.linspace(0, 1, inserted + 2):
  35 + points.append(p0 * np.power((1 - t), 3) + 3 * p1 * t * np.power((1 - t), 2) + 3 * p2 * (1 - t) * np.power(t,
  36 + 2) + p3 * np.power(
  37 + t, 3))
  38 +
  39 + return np.vstack(points)
  40 +
  41 +
  42 +def smoothing_base_bezier(date_x, date_y, k=0.5, inserted=10, closed=False):
  43 + """
  44 + 基于三阶贝塞尔曲线的数据平滑算法
  45 +
  46 + date_x - x维度数据集,list或numpy.ndarray类型
  47 + date_y - y维度数据集,list或numpy.ndarray类型
  48 + k - 调整平滑曲线形状的因子,取值一般在0.2~0.6之间。默认值为0.5
  49 + inserted - 两个原始数据点之间插值的数量。默认值为10
  50 + closed - 曲线是否封闭,如是,则首尾相连。默认曲线不封闭
  51 + """
  52 +
  53 + assert isinstance(date_x, (list, np.ndarray)), u'x数据集不是期望的列表或numpy数组类型'
  54 + assert isinstance(date_y, (list, np.ndarray)), u'y数据集不是期望的列表或numpy数组类型'
  55 +
  56 + if isinstance(date_x, list) and isinstance(date_y, list):
  57 + assert len(date_x) == len(date_y), u'x数据集和y数据集长度不匹配'
  58 + date_x = np.array(date_x)
  59 + date_y = np.array(date_y)
  60 + elif isinstance(date_x, np.ndarray) and isinstance(date_y, np.ndarray):
  61 + assert date_x.shape == date_y.shape, u'x数据集和y数据集长度不匹配'
  62 + else:
  63 + raise Exception(u'x数据集或y数据集类型错误')
  64 +
  65 + # 第1步:生成原始数据折线中点集
  66 + mid_points = list()
  67 + for i in range(1, date_x.shape[0]):
  68 + mid_points.append({
  69 + 'start': (date_x[i - 1], date_y[i - 1]),
  70 + 'end': (date_x[i], date_y[i]),
  71 + 'mid': ((date_x[i] + date_x[i - 1]) / 2.0, (date_y[i] + date_y[i - 1]) / 2.0)
  72 + })
  73 +
  74 + if closed:
  75 + mid_points.append({
  76 + 'start': (date_x[-1], date_y[-1]),
  77 + 'end': (date_x[0], date_y[0]),
  78 + 'mid': ((date_x[0] + date_x[-1]) / 2.0, (date_y[0] + date_y[-1]) / 2.0)
  79 + })
  80 +
  81 + # 第2步:找出中点连线及其分割点
  82 + split_points = list()
  83 + for i in range(len(mid_points)):
  84 + if i < (len(mid_points) - 1):
  85 + j = i + 1
  86 + elif closed:
  87 + j = 0
  88 + else:
  89 + continue
  90 +
  91 + x00, y00 = mid_points[i]['start']
  92 + x01, y01 = mid_points[i]['end']
  93 + x10, y10 = mid_points[j]['start']
  94 + x11, y11 = mid_points[j]['end']
  95 + d0 = np.sqrt(np.power((x00 - x01), 2) + np.power((y00 - y01), 2))
  96 + d1 = np.sqrt(np.power((x10 - x11), 2) + np.power((y10 - y11), 2))
  97 + k_split = 1.0 * d0 / (d0 + d1)
  98 +
  99 + mx0, my0 = mid_points[i]['mid']
  100 + mx1, my1 = mid_points[j]['mid']
  101 +
  102 + split_points.append({
  103 + 'start': (mx0, my0),
  104 + 'end': (mx1, my1),
  105 + 'split': (mx0 + (mx1 - mx0) * k_split, my0 + (my1 - my0) * k_split)
  106 + })
  107 +
  108 + # 第3步:平移中点连线,调整端点,生成控制点
  109 + crt_points = list()
  110 + for i in range(len(split_points)):
  111 + vx, vy = mid_points[i]['end'] # 当前顶点的坐标
  112 + dx = vx - split_points[i]['split'][0] # 平移线段x偏移量
  113 + dy = vy - split_points[i]['split'][1] # 平移线段y偏移量
  114 +
  115 + sx, sy = split_points[i]['start'][0] + dx, split_points[i]['start'][1] + dy # 平移后线段起点坐标
  116 + ex, ey = split_points[i]['end'][0] + dx, split_points[i]['end'][1] + dy # 平移后线段终点坐标
  117 +
  118 + cp0 = sx + (vx - sx) * k, sy + (vy - sy) * k # 控制点坐标
  119 + cp1 = ex + (vx - ex) * k, ey + (vy - ey) * k # 控制点坐标
  120 +
  121 + if crt_points:
  122 + crt_points[-1].insert(2, cp0)
  123 + else:
  124 + crt_points.append([mid_points[0]['start'], cp0, mid_points[0]['end']])
  125 +
  126 + if closed:
  127 + if i < (len(mid_points) - 1):
  128 + crt_points.append([mid_points[i + 1]['start'], cp1, mid_points[i + 1]['end']])
  129 + else:
  130 + crt_points[0].insert(1, cp1)
  131 + else:
  132 + if i < (len(mid_points) - 2):
  133 + crt_points.append([mid_points[i + 1]['start'], cp1, mid_points[i + 1]['end']])
  134 + else:
  135 + crt_points.append([mid_points[i + 1]['start'], cp1, mid_points[i + 1]['end'], mid_points[i + 1]['end']])
  136 + crt_points[0].insert(1, mid_points[0]['start'])
  137 +
  138 + # 第4步:应用贝塞尔曲线方程插值
  139 + out = list()
  140 + for item in crt_points:
  141 + group = bezier_curve(item[0], item[1], item[2], item[3], inserted)
  142 + out.append(group[:-1])
  143 +
  144 + out.append(group[-1:])
  145 + out = np.vstack(out)
  146 +
  147 + return out.T[0], out.T[1]
  148 +
  149 +
  150 +if __name__ == '__main__':
  151 + import matplotlib.pyplot as plt
  152 +
  153 + x = np.array([2, 4, 4, 3, 2])
  154 + y = np.array([2, 2, 4, 3, 4])
  155 +
  156 + plt.plot(x, y, 'ro')
  157 + x_curve, y_curve = smoothing_base_bezier(x, y, k=0.3, closed=True)
  158 + print(x_curve)
  159 + print(y_curve)
  160 + plt.plot(x_curve, y_curve, label='$k=0.3$')
  161 + # x_curve, y_curve = smoothing_base_bezier(x, y, k=0.4, closed=True)
  162 + # plt.plot(x_curve, y_curve, label='$k=0.4$')
  163 + # x_curve, y_curve = smoothing_base_bezier(x, y, k=0.5, closed=True)
  164 + # plt.plot(x_curve, y_curve, label='$k=0.5$')
  165 + # x_curve, y_curve = smoothing_base_bezier(x, y, k=0.6, closed=True)
  166 + # plt.plot(x_curve, y_curve, label='$k=0.6$')
  167 + plt.legend(loc='best')
  168 +
  169 + plt.show()
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2020/12/23
  4 +#email: nheweijun@sina.com
  5 +from sqlalchemy import create_engine
  6 +from sqlalchemy.orm import sessionmaker,Session
  7 +from sqlalchemy.engine import ResultProxy
  8 +import multiprocessing
  9 +import threading
  10 +
  11 +import time
  12 +
  13 +
  14 +
  15 +
  16 +# session:Session = get_db_session("postgresql://postgres:chinadci@172.26.99.168:5432/postgres")
  17 +# bbox="113.2470703125 22.840576171875,113.258056640625 22.8515625"
  18 +# # table="fs1kw_vacuate_0_000075"
  19 +# table="fs900w_1"
  20 +# sql ="SELECT geom FROM {} WHERE geom && 'BOX3D({})'::box3d limit 100000".format(table,bbox)
  21 +
  22 +
  23 +def query_thread():
  24 + def get_db_session(db_url, autocommit=False) -> Session:
  25 + engine = create_engine(db_url, pool_size=100)
  26 +
  27 + system_session: Session = sessionmaker(bind=engine, autocommit=autocommit)()
  28 +
  29 + return system_session
  30 +
  31 + ses: Session = get_db_session("postgresql://postgres:chinadci@172.26.99.168:5432/postgres")
  32 + bbox = "113.2470703125 22.840576171875,113.258056640625 {}"
  33 + yy= 22.8515625
  34 +
  35 + table="fs1kw"
  36 +
  37 + left = True
  38 + for i in range(1):
  39 + if left:
  40 + yy+=0.00001
  41 + left=False
  42 +
  43 + else:
  44 + yy-=0.00001
  45 + left=True
  46 + bbox = bbox.format(yy)
  47 + sql = "SELECT geom FROM {} WHERE geom && 'BOX3D({})'::box3d limit 100000".format(table, bbox)
  48 + time1=time.time()
  49 + dd = ses.execute(sql)
  50 + for x in dd:
  51 + dddd = x
  52 + print(multiprocessing.current_process(),time.time()-time1)
  53 + ses.close()
  54 +# query_thread()
  55 +if __name__ == '__main__':
  56 + time1 = time.time()
  57 + ps=[]
  58 + for i in range(20):
  59 + t = multiprocessing.Process(target=query_thread)
  60 + t.start()
  61 + ps.append(t)
  62 + for p in ps:
  63 + p.join()
  64 + print(time.time()-time1)
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/7/15
  4 +#email: nheweijun@sina.com
  5 +
  6 +from pyDes import des,ECB,PAD_PKCS5
  7 +import base64
  8 +
  9 +
  10 +aa = [1,2,3]
  11 +b =[3]
  12 +aa.extend(b)
  13 +print(aa)
  1 +メムヘノ20000
注册登录 后发表评论