예제 #1
0
func writeWays(file *os.File, ways []way) error {
	if len(ways) == 0 {
		return nil
	}

	for wayGroupIndex := 0; wayGroupIndex < (len(ways)/8000)+1; wayGroupIndex++ {
		beg := (wayGroupIndex + 0) * 8000
		end := (wayGroupIndex + 1) * 8000
		if len(ways) < end {
			end = len(ways)
		}
		wayGroup := ways[beg:end]

		stringTable := make([][]byte, 1, 1000)
		stringTableIndexes := make(map[string]uint32, 0)

		for _, way := range wayGroup {
			for _, s := range way.keys {
				idx := stringTableIndexes[s]
				if idx == 0 {
					stringTableIndexes[s] = uint32(len(stringTable))
					stringTable = append(stringTable, []byte(s))
				}
			}
			for _, s := range way.values {
				idx := stringTableIndexes[s]
				if idx == 0 {
					stringTableIndexes[s] = uint32(len(stringTable))
					stringTable = append(stringTable, []byte(s))
				}
			}
		}

		osmWays := make([]*OSMPBF.Way, len(wayGroup))

		for idx, way := range wayGroup {
			osmWay := &OSMPBF.Way{}

			var wayId int64 = way.id
			osmWay.Id = &wayId

			// delta-encode the node ids
			nodeRefs := make([]int64, len(way.nodeIds))
			var prevNodeId int64 = 0
			for i, nodeId := range way.nodeIds {
				nodeIdDelta := nodeId - prevNodeId
				prevNodeId = nodeId
				nodeRefs[i] = nodeIdDelta
			}
			osmWay.Refs = nodeRefs

			osmWay.Keys = make([]uint32, len(way.keys))
			for i, s := range way.keys {
				osmWay.Keys[i] = stringTableIndexes[s]
			}
			osmWay.Vals = make([]uint32, len(way.values))
			for i, s := range way.values {
				osmWay.Vals[i] = stringTableIndexes[s]
			}
			osmWays[idx] = osmWay
		}

		group := OSMPBF.PrimitiveGroup{}
		group.Ways = osmWays

		block := OSMPBF.PrimitiveBlock{}
		block.Stringtable = &OSMPBF.StringTable{stringTable, nil}
		block.Primitivegroup = []*OSMPBF.PrimitiveGroup{&group}
		err := WriteBlock(file, &block, "OSMData")
		if err != nil {
			return err
		}
	}

	return nil
}
예제 #2
0
func writeNodes(file *os.File, nodes []node) error {
	if len(nodes) == 0 {
		return nil
	}

	for nodeGroupIndex := 0; nodeGroupIndex < (len(nodes)/8000)+1; nodeGroupIndex++ {
		beg := (nodeGroupIndex + 0) * 8000
		end := (nodeGroupIndex + 1) * 8000
		if len(nodes) < end {
			end = len(nodes)
		}
		nodeGroup := nodes[beg:end]

		stringTable := make([][]byte, 1, 1000)
		stringTableIndexes := make(map[string]uint32, 0)

		for _, node := range nodeGroup {
			for _, s := range node.keys {
				idx := stringTableIndexes[s]
				if idx == 0 {
					stringTableIndexes[s] = uint32(len(stringTable))
					stringTable = append(stringTable, []byte(s))
				}
			}
			for _, s := range node.values {
				idx := stringTableIndexes[s]
				if idx == 0 {
					stringTableIndexes[s] = uint32(len(stringTable))
					stringTable = append(stringTable, []byte(s))
				}
			}
		}

		osmNodes := make([]*OSMPBF.Node, len(nodeGroup))

		for idx, node := range nodeGroup {
			osmNode := &OSMPBF.Node{}

			var nodeId int64 = node.id
			osmNode.Id = &nodeId

			var rawlon int64 = int64(node.lon/.000000001) / 100
			var rawlat int64 = int64(node.lat/.000000001) / 100
			osmNode.Lon = &rawlon
			osmNode.Lat = &rawlat

			osmNode.Keys = make([]uint32, len(node.keys))
			for i, s := range node.keys {
				osmNode.Keys[i] = stringTableIndexes[s]
			}
			osmNode.Vals = make([]uint32, len(node.values))
			for i, s := range node.values {
				osmNode.Vals[i] = stringTableIndexes[s]
			}
			osmNodes[idx] = osmNode
		}

		group := OSMPBF.PrimitiveGroup{}
		group.Nodes = osmNodes

		block := OSMPBF.PrimitiveBlock{}
		block.Stringtable = &OSMPBF.StringTable{stringTable, nil}
		block.Primitivegroup = []*OSMPBF.PrimitiveGroup{&group}
		err := WriteBlock(file, &block, "OSMData")
		if err != nil {
			return err
		}
	}

	return nil
}