Пример #1
0
// writeCheckedMML writes MML from io.ReadCloser to fileName.
// Checks if r is a valid MML before (over)writing file.
func writeCheckedMML(r io.ReadCloser, fileName string) error {
	return writeCheckedFile(r, fileName, func(r io.Reader) error {
		_, err := mml.Parse(r)
		return err
	})
	return nil
}
Пример #2
0
func TestBuilMapFromString(t *testing.T) {
	m := mockMap{}
	f, err := os.Open(filepath.Join("tests", "003-two-layers.mml"))
	if err != nil {
		t.Fatal(err)
	}
	defer f.Close()

	mml, err := mml.Parse(f)
	if err != nil {
		t.Fatal(err)
	}

	mss, err := ioutil.ReadFile(filepath.Join("tests", "003-two-layers.mss"))
	if err != nil {
		t.Fatal(err)
	}

	if err := BuildMapFromString(&m, mml, string(mss)); err != nil {
		t.Fatal(err)
	}
	if len(m.layers) != 2 {
		t.Fatal(m.layers)
	}
}
Пример #3
0
// findProjects searches for .mml files in path and in all sub-directories of
// path, but not any deeper.
func findProjects(path string) ([]project, error) {
	projects := []project{}
	var mmls []string
	if files, err := filepath.Glob(filepath.Join(path, "*.mml")); err != nil {
		return nil, err
	} else {
		mmls = append(mmls, files...)
	}

	if files, err := filepath.Glob(filepath.Join(path, "*", "*.mml")); err != nil {
		return nil, err
	} else {
		mmls = append(mmls, files...)
	}

	for _, mmlFile := range mmls {
		projDir := filepath.Dir(mmlFile)
		projBase, _ := filepath.Rel(path, projDir)

		mssFiles, err := findMSS(projDir)
		if err != nil {
			return nil, err
		}

		r, err := os.Open(mmlFile)
		if err != nil {
			return nil, err
		}
		parsedMML, err := mml.Parse(r)
		r.Close()
		if err != nil {
			return nil, fmt.Errorf("error parsing %s: %v", mmlFile, err)
		}

		lastChange := lastModTime(append([]string{mmlFile}, mssFiles...)...)

		// remove base dir from mml/mss
		mmlFile = filepath.Base(mmlFile)
		for i := range mssFiles {
			mssFiles[i], _ = filepath.Rel(projDir, mssFiles[i])
		}

		name := parsedMML.Name

		projects = append(projects,
			project{
				Name:         name,
				Base:         projBase,
				LastChange:   lastChange,
				MML:          mmlFile,
				MCP:          strings.TrimSuffix(mmlFile, filepath.Ext(mmlFile)) + ".mcp",
				AvailableMSS: mssFiles,
				SelectedMSS:  parsedMML.Stylesheets,
			})
	}

	return projects, nil
}
Пример #4
0
func mssFilesFromMML(mmlFile string) ([]string, error) {
	r, err := os.Open(mmlFile)
	if err != nil {
		return nil, err
	}
	defer r.Close()

	mml, err := mmlparse.Parse(r)
	if err != nil {
		return nil, err
	}
	mssFiles := []string{}
	for _, s := range mml.Stylesheets {
		mssFiles = append(mssFiles, filepath.Join(filepath.Dir(mmlFile), s))
	}
	return mssFiles, nil
}
Пример #5
0
func build(mmlStr string, baseDir string, options C.Opts) (output, error *C.char) {
	conf := config.Magnacarto{}
	locator := conf.Locator()

	builderType := C.GoString(options.builderType)
	if builderType == "" {
		builderType = "mapnik2"
	}
	sqliteDir := C.GoString(options.sqliteDir)
	if sqliteDir != "" {
		conf.Datasources.SQLiteDirs = []string{sqliteDir}
	}
	fontDir := C.GoString(options.fontDir)
	if fontDir != "" {
		conf.Mapnik.FontDirs = []string{fontDir}
	}
	shapeDir := C.GoString(options.shapeDir)
	if shapeDir != "" {
		conf.Datasources.ShapefileDirs = []string{shapeDir}
	}
	imageDir := C.GoString(options.imageDir)
	if imageDir != "" {
		conf.Datasources.ImageDirs = []string{imageDir}
	}
	relPaths := bool(options.relPaths)
	if relPaths {
		locator.UseRelPaths(relPaths)
	}
	msNoMapBlock := bool(options.msNoMapBlock)

	locator.SetBaseDir(baseDir)
	var m builder.MapWriter

	switch builderType {
	case "mapserver":
		mm := mapserver.New(locator)
		mm.SetNoMapBlock(msNoMapBlock)
		m = mm
	case "mapnik2":
		mm := mapnik.New(locator)
		mm.SetMapnik2(true)
		m = mm
	case "mapnik3":
		m = mapnik.New(locator)
	default:
		return nil, C.CString(fmt.Sprint("unknown builder ", builderType))
	}

	r := strings.NewReader(mmlStr)
	mmlData, err := mml.Parse(r)
	if err != nil {
		return nil, C.CString(fmt.Sprint(err))
	}

	var style bytes.Buffer
	for _, s := range mmlData.Stylesheets {
		if strings.HasSuffix(s, ".mss") {
			r, err := os.Open(filepath.Join(baseDir, s))
			if err != nil {
				return nil, C.CString(fmt.Sprint(err))
			}
			content, err := ioutil.ReadAll(r)
			if err != nil {
				return nil, C.CString(fmt.Sprint(err))
			}
			r.Close()
			style.Write(content)
		} else {
			style.WriteString(s)
		}
	}

	builder.BuildMapFromString(m, mmlData, style.String())

	var buf bytes.Buffer
	if err := m.Write(&buf); err != nil {
		return nil, C.CString(fmt.Sprint(err))
	}

	return C.CString(buf.String()), nil
}
Пример #6
0
// Build parses MML, MSS files, builds all rules and adds them to the Map.
func (b *Builder) Build() error {
	layerNames := []string{}
	layers := []mml.Layer{}

	if b.mml != "" {
		r, err := os.Open(b.mml)
		if err != nil {
			return err
		}
		defer r.Close()
		mml, err := mml.Parse(r)
		if err != nil {
			return err
		}
		if len(b.mss) == 0 {
			for _, s := range mml.Stylesheets {
				b.mss = append(b.mss, filepath.Join(filepath.Dir(b.mml), s))
			}
		}

		for _, l := range mml.Layers {
			layers = append(layers, l)
			layerNames = append(layerNames, l.Name)
		}
	}

	carto := mss.New()
	if b.deferEval {
		carto.EnableDeferredEval()
	}

	for _, mss := range b.mss {
		err := carto.ParseFile(mss)
		if err != nil {
			return err
		}
	}

	if err := carto.Evaluate(); err != nil {
		return err
	}

	if b.mml == "" {
		layerNames = carto.MSS().Layers()
		for _, layerName := range layerNames {
			layers = append(layers,
				// XXX assume we only have LineStrings for -mss only export
				mml.Layer{Name: layerName, Type: mml.LineString},
			)
		}
	}

	for _, l := range layers {
		rules := carto.MSS().LayerRules(l.Name, l.Classes...)

		if b.dumpRules != nil {
			for _, r := range rules {
				fmt.Fprintln(b.dumpRules, r.String())
			}
		}
		if len(rules) > 0 {
			b.dstMap.AddLayer(l, rules)
		}
	}

	if m, ok := b.dstMap.(MapOptionsSetter); ok {
		if bgColor, ok := carto.MSS().Map().GetColor("background-color"); ok {
			m.SetBackgroundColor(bgColor)
		}
	}
	return nil
}