write expire tiles; add first tests
parent
bba7d68380
commit
3453b13af2
|
@ -19,6 +19,8 @@ type Config struct {
|
|||
LimitToCacheBuffer float64 `json:"limitto_cache_buffer"`
|
||||
Srid int `json:"srid"`
|
||||
Schemas Schemas `json:"schemas"`
|
||||
ExpireTilesDir string `json:"expire_tiles_dir"`
|
||||
ExpireTilesZoom int `json:"expire_tiles_zoom"`
|
||||
}
|
||||
|
||||
type Schemas struct {
|
||||
|
@ -48,6 +50,8 @@ type _BaseOptions struct {
|
|||
Httpprofile string
|
||||
Quiet bool
|
||||
Schemas Schemas
|
||||
ExpireTilesDir string
|
||||
ExpireTilesZoom int
|
||||
}
|
||||
|
||||
func (o *_BaseOptions) updateFromConfig() error {
|
||||
|
@ -104,6 +108,13 @@ func (o *_BaseOptions) updateFromConfig() error {
|
|||
if o.CacheDir == defaultCacheDir {
|
||||
o.CacheDir = conf.CacheDir
|
||||
}
|
||||
if o.ExpireTilesDir == "" {
|
||||
o.ExpireTilesDir = conf.ExpireTilesDir
|
||||
}
|
||||
if o.ExpireTilesZoom == 0 {
|
||||
o.ExpireTilesZoom = conf.ExpireTilesZoom
|
||||
}
|
||||
|
||||
if o.DiffDir == "" {
|
||||
if conf.DiffDir == "" {
|
||||
// use CacheDir for backwards compatibility
|
||||
|
@ -186,6 +197,9 @@ func init() {
|
|||
ImportFlags.BoolVar(&ImportOptions.RevertDeploy, "revertdeploy", false, "revert deploy to production")
|
||||
ImportFlags.BoolVar(&ImportOptions.RemoveBackup, "removebackup", false, "remove backups from deploy")
|
||||
ImportFlags.DurationVar(&ImportOptions.DiffStateBefore, "diff-state-before", 2*time.Hour, "set initial diff sequence before")
|
||||
|
||||
DiffFlags.StringVar(&BaseOptions.ExpireTilesDir, "expiretiles-dir", "", "write expire tiles into dir")
|
||||
DiffFlags.IntVar(&BaseOptions.ExpireTilesZoom, "expiretiles-zoom", 14, "write expire tiles in this zoom level")
|
||||
}
|
||||
|
||||
func ParseImport(args []string) {
|
||||
|
|
|
@ -125,6 +125,9 @@ func (d *Deleter) deleteRelation(id int64, deleteRefs bool, deleteMembers bool)
|
|||
return err
|
||||
}
|
||||
if d.expireor != nil {
|
||||
if err := d.osmCache.Ways.FillMembers(elem.Members); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, m := range elem.Members {
|
||||
if m.Way == nil {
|
||||
continue
|
||||
|
@ -133,7 +136,7 @@ func (d *Deleter) deleteRelation(id int64, deleteRefs bool, deleteMembers bool)
|
|||
if err != nil {
|
||||
continue
|
||||
}
|
||||
expire.ExpireNodes(d.expireor, m.Way.Nodes, 4326)
|
||||
expire.ExpireProjectedNodes(d.expireor, m.Way.Nodes, 4326, true)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -153,11 +156,13 @@ func (d *Deleter) deleteWay(id int64, deleteRefs bool) error {
|
|||
return nil
|
||||
}
|
||||
deleted := false
|
||||
deletedPolygon := false
|
||||
if matches := d.tmPolygons.MatchWay(elem); len(matches) > 0 {
|
||||
if err := d.delDb.Delete(d.WayId(elem.Id), matches); err != nil {
|
||||
return err
|
||||
}
|
||||
deleted = true
|
||||
deletedPolygon = true
|
||||
}
|
||||
if matches := d.tmLineStrings.MatchWay(elem); len(matches) > 0 {
|
||||
if err := d.delDb.Delete(d.WayId(elem.Id), matches); err != nil {
|
||||
|
@ -177,7 +182,7 @@ func (d *Deleter) deleteWay(id int64, deleteRefs bool) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
expire.ExpireNodes(d.expireor, elem.Nodes, 4326)
|
||||
expire.ExpireProjectedNodes(d.expireor, elem.Nodes, 4326, deletedPolygon)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -56,8 +56,20 @@ func Diff() {
|
|||
log.Fatal("diff cache: ", err)
|
||||
}
|
||||
|
||||
var exp expire.Expireor
|
||||
|
||||
if config.BaseOptions.ExpireTilesDir != "" {
|
||||
tileexpire := expire.NewTileList(config.BaseOptions.ExpireTilesZoom, config.BaseOptions.ExpireTilesDir)
|
||||
exp = tileexpire
|
||||
defer func() {
|
||||
if err := tileexpire.Flush(); err != nil {
|
||||
log.Error("error while writing tile expire file:", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
for _, oscFile := range config.DiffFlags.Args() {
|
||||
err := Update(oscFile, geometryLimiter, nil, osmCache, diffCache, false)
|
||||
err := Update(oscFile, geometryLimiter, exp, osmCache, diffCache, false)
|
||||
if err != nil {
|
||||
osmCache.Close()
|
||||
diffCache.Close()
|
||||
|
|
|
@ -7,17 +7,18 @@ import (
|
|||
|
||||
type Expireor interface {
|
||||
Expire(long, lat float64)
|
||||
ExpireNodes(nodes []element.Node, closed bool)
|
||||
}
|
||||
|
||||
func ExpireNodes(expireor Expireor, nodes []element.Node, srid int) {
|
||||
func ExpireProjectedNodes(expireor Expireor, nodes []element.Node, srid int, closed bool) {
|
||||
if srid == 4326 {
|
||||
for _, nd := range nodes {
|
||||
expireor.Expire(nd.Long, nd.Lat)
|
||||
}
|
||||
} else if srid == 4326 {
|
||||
for _, nd := range nodes {
|
||||
expireor.Expire(proj.MercToWgs(nd.Long, nd.Lat))
|
||||
expireor.ExpireNodes(nodes, closed)
|
||||
} else if srid == 3857 {
|
||||
nds := make([]element.Node, len(nodes))
|
||||
for i, nd := range nodes {
|
||||
nds[i].Long, nds[i].Lat = proj.MercToWgs(nd.Long, nd.Lat)
|
||||
}
|
||||
expireor.ExpireNodes(nds, closed)
|
||||
} else {
|
||||
panic("unsupported srid")
|
||||
}
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
package expire
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/omniscale/imposm3/element"
|
||||
"github.com/omniscale/imposm3/proj"
|
||||
"io"
|
||||
"math"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var mercBbox = [4]float64{
|
||||
-20037508.342789244,
|
||||
-20037508.342789244,
|
||||
20037508.342789244,
|
||||
20037508.342789244,
|
||||
}
|
||||
|
||||
var mercRes [20]float64
|
||||
|
||||
func init() {
|
||||
res := 2 * 20037508.342789244 / 256
|
||||
|
||||
for i, _ := range mercRes {
|
||||
mercRes[i] = res
|
||||
res /= 2
|
||||
}
|
||||
}
|
||||
|
||||
func TileCoord(long, lat float64, zoom uint32) (uint32, uint32) {
|
||||
x, y := proj.WgsToMerc(long, lat)
|
||||
res := mercRes[zoom]
|
||||
x = x - mercBbox[0]
|
||||
y = mercBbox[3] - y
|
||||
tileX := uint32(math.Floor(x / (res * 256)))
|
||||
tileY := uint32(math.Floor(y / (res * 256)))
|
||||
|
||||
return tileX, tileY
|
||||
}
|
||||
|
||||
type TileList struct {
|
||||
mu sync.Mutex
|
||||
tiles map[tileKey]struct{}
|
||||
|
||||
zoom uint32
|
||||
out string
|
||||
}
|
||||
|
||||
type tileKey struct {
|
||||
x uint32
|
||||
y uint32
|
||||
}
|
||||
|
||||
type tile struct {
|
||||
x uint32
|
||||
y uint32
|
||||
z uint32
|
||||
}
|
||||
|
||||
func NewTileList(zoom int, out string) *TileList {
|
||||
return &TileList{
|
||||
tiles: make(map[tileKey]struct{}),
|
||||
zoom: uint32(zoom),
|
||||
mu: sync.Mutex{},
|
||||
out: out,
|
||||
}
|
||||
}
|
||||
|
||||
func (tl *TileList) addCoord(long, lat float64) {
|
||||
tileX, tileY := TileCoord(long, lat, tl.zoom)
|
||||
tl.mu.Lock()
|
||||
tl.tiles[tileKey{tileX, tileY}] = struct{}{}
|
||||
tl.mu.Unlock()
|
||||
}
|
||||
|
||||
func (tl *TileList) Expire(long, lat float64) {
|
||||
tl.addCoord(long, lat)
|
||||
}
|
||||
|
||||
func (tl *TileList) ExpireNodes(nodes []element.Node, closed bool) {
|
||||
for _, nd := range nodes {
|
||||
tl.addCoord(nd.Long, nd.Lat)
|
||||
}
|
||||
}
|
||||
|
||||
func (tl *TileList) writeTiles(w io.Writer) error {
|
||||
for tileKey, _ := range tl.tiles {
|
||||
_, err := fmt.Fprintf(w, "%d/%d/%d\n", tl.zoom, tileKey.x, tileKey.y)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tl *TileList) Flush() error {
|
||||
if len(tl.tiles) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
now := time.Now().UTC()
|
||||
dir := filepath.Join(tl.out, now.Format("20060102"))
|
||||
err := os.MkdirAll(dir, 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fileName := filepath.Join(dir, now.Format("150405.000")+".tiles~")
|
||||
f, err := os.Create(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = tl.writeTiles(f)
|
||||
f.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// wrote to .tiles~ and now atomically move file to .tiles
|
||||
return os.Rename(fileName, fileName[0:len(fileName)-1])
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<osmChange version="0.6" generator="Osmosis 0.41">
|
||||
|
||||
<!-- modify node -->
|
||||
<modify>
|
||||
<node id="10001" version="1" timestamp="2011-11-11T00:11:11Z" lon="1" lat="-1">
|
||||
<tag k="amenity" v="shop"/>
|
||||
</node>
|
||||
</modify>
|
||||
|
||||
<!-- delete node -->
|
||||
<delete>
|
||||
<node id="10002" version="1" timestamp="2011-11-11T00:11:11Z" lon="2" lat="1" />
|
||||
</delete>
|
||||
|
||||
<!-- create node -->
|
||||
<create>
|
||||
<node id="10003" version="1" timestamp="2011-11-11T00:11:11Z" lon="3" lat="1">
|
||||
<tag k="amenity" v="cafe"/>
|
||||
</node>
|
||||
</create>
|
||||
|
||||
<!-- modify node to unmapped -->
|
||||
<modify>
|
||||
<node id="10004" version="1" timestamp="2011-11-11T00:11:11Z" lon="4" lat="-1">
|
||||
<tag k="unmapped" v="node"/>
|
||||
</node>
|
||||
</modify>
|
||||
|
||||
|
||||
<!-- modify way -->
|
||||
<modify>
|
||||
<way id="20151" version="1" timestamp="2011-11-11T00:11:11Z">
|
||||
<nd ref="20101"/>
|
||||
<nd ref="20102"/>
|
||||
<tag k="highway" v="trunk"/>
|
||||
</way>
|
||||
</modify>
|
||||
|
||||
<!-- delete way -->
|
||||
<delete>
|
||||
<way id="20251" version="1" timestamp="2011-11-11T00:11:11Z" />
|
||||
</delete>
|
||||
|
||||
<!-- modify way from node -->
|
||||
<modify>
|
||||
<node id="20301" version="1" timestamp="2011-11-11T00:11:11Z" lon="3.0001" lat="-2" />
|
||||
<node id="20302" version="1" timestamp="2011-11-11T00:11:11Z" lon="3.0002" lat="-2" />
|
||||
</modify>
|
||||
|
||||
<!-- create way -->
|
||||
<node id="20401" version="1" timestamp="2011-11-11T00:11:11Z" lon="4.0001" lat="2" />
|
||||
<node id="20402" version="1" timestamp="2011-11-11T00:11:11Z" lon="4.0002" lat="2" />
|
||||
<way id="20451" version="1" timestamp="2011-11-11T00:11:11Z">
|
||||
<nd ref="20401"/>
|
||||
<nd ref="20402"/>
|
||||
<tag k="highway" v="motorway"/>
|
||||
</way>
|
||||
|
||||
<!-- create long way -->
|
||||
<node id="20501" version="1" timestamp="2011-11-11T00:11:11Z" lon="5.00" lat="2" />
|
||||
<node id="20502" version="1" timestamp="2011-11-11T00:11:11Z" lon="5.05" lat="2" />
|
||||
<way id="20551" version="1" timestamp="2011-11-11T00:11:11Z">
|
||||
<nd ref="20501"/>
|
||||
<nd ref="20502"/>
|
||||
<tag k="highway" v="motorway"/>
|
||||
</way>
|
||||
|
||||
|
||||
|
||||
<!-- modify relation -->
|
||||
<modify>
|
||||
<relation id="30191" version="1" timestamp="2011-11-11T00:11:11Z">
|
||||
<member type="way" ref="30151" role="outer"/>
|
||||
<tag k="building" v="office"/>
|
||||
<tag k="type" v="multipolygon"/>
|
||||
</relation>
|
||||
</modify>
|
||||
|
||||
<!-- delete relation -->
|
||||
<delete>
|
||||
<relation id="30291" version="1" timestamp="2011-11-11T00:11:11Z">
|
||||
<member type="way" ref="30251" role="outer"/>
|
||||
<tag k="building" v="true"/>
|
||||
<tag k="type" v="multipolygon"/>
|
||||
</relation>
|
||||
</delete>
|
||||
|
||||
<!-- modify relation from way -->
|
||||
<modify>
|
||||
<way id="30351" version="1" timestamp="2011-11-11T00:11:11Z">
|
||||
<nd ref="30301"/>
|
||||
<nd ref="30304"/>
|
||||
<nd ref="30303"/>
|
||||
<nd ref="30302"/>
|
||||
<nd ref="30301"/>
|
||||
</way>
|
||||
</modify>
|
||||
|
||||
<!-- modify relation from node -->
|
||||
<modify>
|
||||
<node id="30401" version="1" timestamp="2011-11-11T00:11:11Z" lon="4.0001" lat="-3" />
|
||||
<node id="30402" version="1" timestamp="2011-11-11T00:11:11Z" lon="4.0002" lat="-3" />
|
||||
<node id="30403" version="1" timestamp="2011-11-11T00:11:11Z" lon="4.0002" lat="-3.0001" />
|
||||
<node id="30404" version="1" timestamp="2011-11-11T00:11:11Z" lon="4.0001" lat="-3.0001" />
|
||||
</modify>
|
||||
|
||||
|
||||
|
||||
|
||||
</osmChange>
|
|
@ -0,0 +1,127 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<osm version="0.6" generator="Osmosis SNAPSHOT-r25240">
|
||||
<!-- modify node -->
|
||||
<node id="10001" version="1" timestamp="2011-11-11T00:11:11Z" lon="1" lat="1">
|
||||
<tag k="amenity" v="shop"/>
|
||||
</node>
|
||||
|
||||
<!-- delete node -->
|
||||
<node id="10002" version="1" timestamp="2011-11-11T00:11:11Z" lon="2" lat="1">
|
||||
<tag k="amenity" v="shop"/>
|
||||
</node>
|
||||
|
||||
<!-- create node -->
|
||||
<!-- <node id="10003" ... -->
|
||||
|
||||
<!-- modify node to unmapped -->
|
||||
<node id="10004" version="1" timestamp="2011-11-11T00:11:11Z" lon="4" lat="1">
|
||||
<tag k="amenity" v="shop"/>
|
||||
</node>
|
||||
|
||||
|
||||
<!-- modify way -->
|
||||
<node id="20101" version="1" timestamp="2011-11-11T00:11:11Z" lon="1.0001" lat="2" />
|
||||
<node id="20102" version="1" timestamp="2011-11-11T00:11:11Z" lon="1.0002" lat="2" />
|
||||
<way id="20151" version="1" timestamp="2011-11-11T00:11:11Z">
|
||||
<nd ref="20101"/>
|
||||
<nd ref="20102"/>
|
||||
<tag k="highway" v="motorway"/>
|
||||
</way>
|
||||
|
||||
<!-- delete way -->
|
||||
<node id="20201" version="1" timestamp="2011-11-11T00:11:11Z" lon="2.0001" lat="2" />
|
||||
<node id="20202" version="1" timestamp="2011-11-11T00:11:11Z" lon="2.0002" lat="2" />
|
||||
<way id="20251" version="1" timestamp="2011-11-11T00:11:11Z">
|
||||
<nd ref="20201"/>
|
||||
<nd ref="20202"/>
|
||||
<tag k="highway" v="motorway"/>
|
||||
</way>
|
||||
|
||||
<!-- modify node from way -->
|
||||
<node id="20301" version="1" timestamp="2011-11-11T00:11:11Z" lon="3.0001" lat="2" />
|
||||
<node id="20302" version="1" timestamp="2011-11-11T00:11:11Z" lon="3.0002" lat="2" />
|
||||
<way id="20351" version="1" timestamp="2011-11-11T00:11:11Z">
|
||||
<nd ref="20301"/>
|
||||
<nd ref="20302"/>
|
||||
<tag k="highway" v="motorway"/>
|
||||
</way>
|
||||
|
||||
<!-- create way -->
|
||||
<!-- <way id="20451" ... -->
|
||||
|
||||
<!-- create long way -->
|
||||
<!-- <way id="20551" ... -->
|
||||
|
||||
|
||||
<!-- modify relation -->
|
||||
<node id="30101" version="1" timestamp="2011-11-11T00:11:11Z" lon="1.0001" lat="3" />
|
||||
<node id="30102" version="1" timestamp="2011-11-11T00:11:11Z" lon="1.0002" lat="3" />
|
||||
<node id="30103" version="1" timestamp="2011-11-11T00:11:11Z" lon="1.0002" lat="3.0001" />
|
||||
<node id="30104" version="1" timestamp="2011-11-11T00:11:11Z" lon="1.0001" lat="3.0001" />
|
||||
<way id="30151" version="1" timestamp="2011-11-11T00:11:11Z">
|
||||
<nd ref="30101"/>
|
||||
<nd ref="30102"/>
|
||||
<nd ref="30103"/>
|
||||
<nd ref="30104"/>
|
||||
<nd ref="30101"/>
|
||||
</way>
|
||||
<relation id="30191" version="1" timestamp="2011-11-11T00:11:11Z">
|
||||
<member type="way" ref="30151" role="outer"/>
|
||||
<tag k="building" v="yes"/>
|
||||
<tag k="type" v="multipolygon"/>
|
||||
</relation>
|
||||
|
||||
<!-- delete relation -->
|
||||
<node id="30201" version="1" timestamp="2011-11-11T00:11:11Z" lon="2.0001" lat="3" />
|
||||
<node id="30202" version="1" timestamp="2011-11-11T00:11:11Z" lon="2.0002" lat="3" />
|
||||
<node id="30203" version="1" timestamp="2011-11-11T00:11:11Z" lon="2.0002" lat="3.0001" />
|
||||
<node id="30204" version="1" timestamp="2011-11-11T00:11:11Z" lon="2.0001" lat="3.0001" />
|
||||
<way id="30251" version="1" timestamp="2011-11-11T00:11:11Z">
|
||||
<nd ref="30201"/>
|
||||
<nd ref="30202"/>
|
||||
<nd ref="30203"/>
|
||||
<nd ref="30204"/>
|
||||
<nd ref="30201"/>
|
||||
</way>
|
||||
<relation id="30291" version="1" timestamp="2011-11-11T00:11:11Z">
|
||||
<member type="way" ref="30251" role="outer"/>
|
||||
<tag k="building" v="yes"/>
|
||||
<tag k="type" v="multipolygon"/>
|
||||
</relation>
|
||||
|
||||
<!-- modify way from relation -->
|
||||
<node id="30301" version="1" timestamp="2011-11-11T00:11:11Z" lon="3.0001" lat="3" />
|
||||
<node id="30302" version="1" timestamp="2011-11-11T00:11:11Z" lon="3.0002" lat="3" />
|
||||
<node id="30303" version="1" timestamp="2011-11-11T00:11:11Z" lon="3.0002" lat="3.0001" />
|
||||
<node id="30304" version="1" timestamp="2011-11-11T00:11:11Z" lon="3.0001" lat="3.0001" />
|
||||
<way id="30351" version="1" timestamp="2011-11-11T00:11:11Z">
|
||||
<nd ref="30301"/>
|
||||
<nd ref="30302"/>
|
||||
<nd ref="30303"/>
|
||||
<nd ref="30304"/>
|
||||
<nd ref="30301"/>
|
||||
</way>
|
||||
<relation id="30391" version="1" timestamp="2011-11-11T00:11:11Z">
|
||||
<member type="way" ref="30351" role="outer"/>
|
||||
<tag k="building" v="yes"/>
|
||||
<tag k="type" v="multipolygon"/>
|
||||
</relation>
|
||||
|
||||
<!-- modify node from relation -->
|
||||
<node id="30401" version="1" timestamp="2011-11-11T00:11:11Z" lon="4.0001" lat="3" />
|
||||
<node id="30402" version="1" timestamp="2011-11-11T00:11:11Z" lon="4.0002" lat="3" />
|
||||
<node id="30403" version="1" timestamp="2011-11-11T00:11:11Z" lon="4.0002" lat="3.0001" />
|
||||
<node id="30404" version="1" timestamp="2011-11-11T00:11:11Z" lon="4.0001" lat="3.0001" />
|
||||
<way id="30451" version="1" timestamp="2011-11-11T00:11:11Z">
|
||||
<nd ref="30401"/>
|
||||
<nd ref="30402"/>
|
||||
<nd ref="30403"/>
|
||||
<nd ref="30404"/>
|
||||
<nd ref="30401"/>
|
||||
</way>
|
||||
<relation id="30491" version="1" timestamp="2011-11-11T00:11:11Z">
|
||||
<member type="way" ref="30451" role="outer"/>
|
||||
<tag k="building" v="yes"/>
|
||||
<tag k="type" v="multipolygon"/>
|
||||
</relation>
|
||||
</osm>
|
|
@ -0,0 +1,45 @@
|
|||
tables:
|
||||
roads:
|
||||
type: linestring
|
||||
fields:
|
||||
- name: osm_id
|
||||
type: id
|
||||
- name: type
|
||||
type: mapping_value
|
||||
- name: name
|
||||
type: string
|
||||
key: name
|
||||
- name: geometry
|
||||
type: geometry
|
||||
mapping:
|
||||
highway: [__any__]
|
||||
|
||||
pois:
|
||||
type: point
|
||||
fields:
|
||||
- name: osm_id
|
||||
type: id
|
||||
- name: type
|
||||
type: mapping_value
|
||||
- name: name
|
||||
type: string
|
||||
key: name
|
||||
- name: geometry
|
||||
type: geometry
|
||||
mapping:
|
||||
amenity: [__any__]
|
||||
|
||||
buildings:
|
||||
type: polygon
|
||||
fields:
|
||||
- name: osm_id
|
||||
type: id
|
||||
- name: type
|
||||
type: mapping_value
|
||||
- name: name
|
||||
type: string
|
||||
key: name
|
||||
- name: geometry
|
||||
type: geometry
|
||||
mapping:
|
||||
building: [__any__]
|
|
@ -0,0 +1,162 @@
|
|||
package test
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"database/sql"
|
||||
"github.com/omniscale/imposm3/expire"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"testing"
|
||||
|
||||
"github.com/omniscale/imposm3/geom/geos"
|
||||
)
|
||||
|
||||
func TestExpireTiles_Prepare(t *testing.T) {
|
||||
var err error
|
||||
|
||||
ts.dir, err = ioutil.TempDir("", "imposm3test")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ts.config = importConfig{
|
||||
connection: "postgis://",
|
||||
cacheDir: ts.dir,
|
||||
osmFileName: "build/expire_tiles.pbf",
|
||||
mappingFileName: "expire_tiles_mapping.yml",
|
||||
expireTileDir: filepath.Join(ts.dir, "expiretiles"),
|
||||
}
|
||||
ts.g = geos.NewGeos()
|
||||
|
||||
ts.db, err = sql.Open("postgres", "sslmode=disable")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ts.dropSchemas()
|
||||
}
|
||||
|
||||
func TestExpireTiles_Import(t *testing.T) {
|
||||
if ts.tableExists(t, dbschemaImport, "osm_roads") != false {
|
||||
t.Fatalf("table osm_roads exists in schema %s", dbschemaImport)
|
||||
}
|
||||
ts.importOsm(t)
|
||||
ts.deployOsm(t)
|
||||
if ts.tableExists(t, dbschemaProduction, "osm_roads") != true {
|
||||
t.Fatalf("table osm_roads does not exists in schema %s", dbschemaProduction)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExpireTiles_Elements(t *testing.T) {
|
||||
assertRecords(t, []checkElem{
|
||||
{"osm_roads", 20151, "motorway", nil},
|
||||
{"osm_roads", 20251, "motorway", nil},
|
||||
{"osm_roads", 20351, "motorway", nil},
|
||||
|
||||
{"osm_buildings", -30191, "yes", nil},
|
||||
{"osm_buildings", -30291, "yes", nil},
|
||||
{"osm_buildings", -30391, "yes", nil},
|
||||
{"osm_buildings", -30491, "yes", nil},
|
||||
})
|
||||
}
|
||||
|
||||
func TestExpireTiles_Update(t *testing.T) {
|
||||
ts.updateOsm(t, "build/expire_tiles.osc.gz")
|
||||
}
|
||||
|
||||
func TestExpireTiles_CheckExpireFile(t *testing.T) {
|
||||
files, err := filepath.Glob(filepath.Join(ts.config.expireTileDir, "*", "*.tiles"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(files) != 1 {
|
||||
t.Fatalf("expected one expire tile file, got: %v", files)
|
||||
}
|
||||
tiles, err := parseTileList(files[0])
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
for _, test := range []struct {
|
||||
reason string
|
||||
long float64
|
||||
lat float64
|
||||
expire bool
|
||||
}{
|
||||
{"create node", 3, 1, true},
|
||||
{"modify node (old)", 1, 1, true},
|
||||
{"modify node (new)", 1, -1, true},
|
||||
{"modify node to unmapped (old)", 4, 1, true},
|
||||
{"modify node to unmapped (new)", 4, -1, false},
|
||||
{"delete node", 2, 1, true},
|
||||
|
||||
{"delete way", 2.0001, 2, true},
|
||||
{"modify way", 1.0001, 2, true},
|
||||
{"modify way from node (old)", 3.0001, 2, true},
|
||||
{"modify way from node (new)", 3.0001, -2, true},
|
||||
{"create way", 4.0001, 2, true},
|
||||
|
||||
{"create long way (start)", 5.00, 2, true},
|
||||
{"create long way (mid)", 5.025, 2, false}, // TODO not implemented
|
||||
{"create long way (end)", 5.05, 2, true},
|
||||
|
||||
{"modify relation", 1.0001, 3, true},
|
||||
{"delete relation", 2.0001, 3, true},
|
||||
{"modify relation from way", 3.0001, 3, true},
|
||||
{"modify relation from nodes (old)", 4.0001, 3, true},
|
||||
{"modify relation from nodes (new)", 4.0001, -3, true},
|
||||
} {
|
||||
x, y := expire.TileCoord(test.long, test.lat, 14)
|
||||
if test.expire {
|
||||
if _, ok := tiles[tile{x: int(x), y: int(y), z: 14}]; !ok {
|
||||
t.Errorf("missing expire tile for %s 14/%d/%d for %f %f", test.reason, x, y, test.long, test.lat)
|
||||
} else {
|
||||
delete(tiles, tile{x: int(x), y: int(y), z: 14})
|
||||
}
|
||||
} else {
|
||||
if _, ok := tiles[tile{x: int(x), y: int(y), z: 14}]; ok {
|
||||
t.Errorf("found expire tile for %s 14/%d/%d for %f %f", test.reason, x, y, test.long, test.lat)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for tile, _ := range tiles {
|
||||
t.Errorf("unexpected tile expired: %v", tile)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExpireTiles_Cleanup(t *testing.T) {
|
||||
ts.dropSchemas()
|
||||
if err := os.RemoveAll(ts.dir); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
type tile struct {
|
||||
x, y, z int
|
||||
}
|
||||
|
||||
func parseTileList(filename string) (map[tile]struct{}, error) {
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
tiles := make(map[tile]struct{})
|
||||
for scanner.Scan() {
|
||||
parts := strings.Split(scanner.Text(), "/")
|
||||
z, _ := strconv.ParseInt(parts[0], 10, 32)
|
||||
x, _ := strconv.ParseInt(parts[1], 10, 32)
|
||||
y, _ := strconv.ParseInt(parts[2], 10, 32)
|
||||
tiles[tile{x: int(x), y: int(y), z: int(z)}] = struct{}{}
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return tiles, nil
|
||||
}
|
|
@ -33,6 +33,7 @@ type importConfig struct {
|
|||
mappingFileName string
|
||||
cacheDir string
|
||||
verbose bool
|
||||
expireTileDir string
|
||||
}
|
||||
|
||||
type importTestSuite struct {
|
||||
|
@ -152,8 +153,11 @@ func (s *importTestSuite) updateOsm(t *testing.T, diffFile string) {
|
|||
"-limitto", "clipping.geojson",
|
||||
"-dbschema-production", dbschemaProduction,
|
||||
"-mapping", s.config.mappingFileName,
|
||||
diffFile,
|
||||
}
|
||||
if s.config.expireTileDir != "" {
|
||||
args = append(args, "-expiretiles-dir", s.config.expireTileDir)
|
||||
}
|
||||
args = append(args, diffFile)
|
||||
config.ParseDiffImport(args)
|
||||
diff.Diff()
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ NextRel:
|
|||
if inserted && rw.expireor != nil {
|
||||
for _, m := range allMembers {
|
||||
if m.Way != nil {
|
||||
expire.ExpireNodes(rw.expireor, m.Way.Nodes, rw.srid)
|
||||
expire.ExpireProjectedNodes(rw.expireor, m.Way.Nodes, rw.srid, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,6 +87,7 @@ func (ww *WayWriter) loop() {
|
|||
w.Id = ww.wayId(w.Id)
|
||||
|
||||
inserted := false
|
||||
insertedPolygon := false
|
||||
if matches := ww.lineMatcher.MatchWay(w); len(matches) > 0 {
|
||||
err := ww.buildAndInsert(geos, w, matches, false)
|
||||
if err != nil {
|
||||
|
@ -108,11 +109,12 @@ func (ww *WayWriter) loop() {
|
|||
continue
|
||||
}
|
||||
inserted = true
|
||||
insertedPolygon = true
|
||||
}
|
||||
}
|
||||
|
||||
if inserted && ww.expireor != nil {
|
||||
expire.ExpireNodes(ww.expireor, w.Nodes, ww.srid)
|
||||
expire.ExpireProjectedNodes(ww.expireor, w.Nodes, ww.srid, insertedPolygon)
|
||||
}
|
||||
if ww.diffCache != nil {
|
||||
ww.diffCache.Coords.AddFromWay(w)
|
||||
|
|
Loading…
Reference in New Issue