Skip to content

Commit 60dc5e9

Browse files
committed
Add style repository commands
1 parent f9af9d5 commit 60dc5e9

File tree

6 files changed

+441
-1
lines changed

6 files changed

+441
-1
lines changed

README.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,16 @@ style raster colormap --raster raster --values "10=red,50=blue,100=wheat,250=whi
287287

288288
style raster palette colormap --min 1 --max 50 --palette MutedTerrain --number 20 --file terrain.sld
289289

290+
style repository save --type h2 --options file=styles_county.db --layerName roads --styleName roads --styleFile examples/roads.sld
291+
292+
style repository get --type nested-directory --options file=examples/county_styles --layerName roads --styleName roads
293+
294+
style repository list --type directory --options file=examples/styles
295+
296+
style repository delete --type directory --options file=examples/styles --layerName parcels --styleName parcels
297+
298+
style repository copy --inputType sqlite --inputOptions file=examples/my-styles.db --outputType h2 --outputOptions file=examples/h2-styles.db
299+
290300
map
291301
---
292302
map open --name state_map

src/main/docs/style.adoc

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,3 +338,126 @@ include::output/style_raster_palette_colormap.sld[]
338338

339339
image::style_raster_palette_colormap.png[]
340340

341+
=== Style Repository Save
342+
343+
include::commands/style_repository_save_description.txt[]
344+
345+
include::output/style_repository_save_1_command.txt[]
346+
347+
include::commands/style_repository_save.txt[]
348+
349+
include::output/style_repository_save_0_command.txt[]
350+
include::output/style_repository_save_0_result.txt[]
351+
352+
include::output/style_repository_save_1_command.txt[]
353+
include::output/style_repository_save_1_result.txt[]
354+
355+
=== Style Repository List
356+
357+
include::commands/style_repository_list_description.txt[]
358+
359+
include::output/style_repository_list_4_command.txt[]
360+
361+
include::commands/style_repository_list.txt[]
362+
363+
include::output/style_repository_list_0_command.txt[]
364+
include::output/style_repository_list_0_result.txt[]
365+
366+
include::output/style_repository_list_1_command.txt[]
367+
include::output/style_repository_list_1_result.txt[]
368+
369+
include::output/style_repository_list_2_command.txt[]
370+
include::output/style_repository_list_2_result.txt[]
371+
372+
include::output/style_repository_list_3_command.txt[]
373+
include::output/style_repository_list_3_result.txt[]
374+
375+
include::output/style_repository_list_4_command.txt[]
376+
include::output/style_repository_list_4_result.txt[]
377+
378+
include::output/style_repository_list_5_command.txt[]
379+
include::output/style_repository_list_5_result.txt[]
380+
381+
=== Style Repository Delete
382+
383+
include::commands/style_repository_delete_description.txt[]
384+
385+
include::output/style_repository_delete_5_command.txt[]
386+
387+
include::commands/style_repository_delete.txt[]
388+
389+
include::output/style_repository_delete_0_command.txt[]
390+
include::output/style_repository_delete_0_result.txt[]
391+
392+
include::output/style_repository_delete_1_command.txt[]
393+
include::output/style_repository_delete_1_result.txt[]
394+
395+
include::output/style_repository_delete_2_command.txt[]
396+
include::output/style_repository_delete_2_result.txt[]
397+
398+
include::output/style_repository_delete_3_command.txt[]
399+
include::output/style_repository_delete_3_result.txt[]
400+
401+
include::output/style_repository_delete_4_command.txt[]
402+
include::output/style_repository_delete_4_result.txt[]
403+
404+
include::output/style_repository_delete_5_command.txt[]
405+
include::output/style_repository_delete_5_result.txt[]
406+
407+
include::output/style_repository_delete_6_command.txt[]
408+
include::output/style_repository_delete_6_result.txt[]
409+
410+
=== Style Repository Get
411+
412+
include::commands/style_repository_get_description.txt[]
413+
414+
include::output/style_repository_get_4_command.txt[]
415+
416+
include::commands/style_repository_get.txt[]
417+
418+
include::output/style_repository_get_0_command.txt[]
419+
include::output/style_repository_get_0_result.txt[]
420+
421+
include::output/style_repository_get_1_command.txt[]
422+
include::output/style_repository_get_1_result.txt[]
423+
424+
include::output/style_repository_get_2_command.txt[]
425+
include::output/style_repository_get_2_result.txt[]
426+
427+
include::output/style_repository_get_3_command.txt[]
428+
include::output/style_repository_get_3_result.txt[]
429+
430+
include::output/style_repository_get_4_command.txt[]
431+
include::output/style_repository_get_4_result.txt[]
432+
433+
include::output/style_repository_get_5_command.txt[]
434+
include::output/style_repository_get_5_result.txt[]
435+
436+
=== Style Repository Copy
437+
438+
include::commands/style_repository_copy_description.txt[]
439+
440+
include::output/style_repository_copy_5_command.txt[]
441+
442+
include::commands/style_repository_copy.txt[]
443+
444+
include::output/style_repository_copy_0_command.txt[]
445+
include::output/style_repository_copy_0_result.txt[]
446+
447+
include::output/style_repository_copy_1_command.txt[]
448+
include::output/style_repository_copy_1_result.txt[]
449+
450+
include::output/style_repository_copy_2_command.txt[]
451+
include::output/style_repository_copy_2_result.txt[]
452+
453+
include::output/style_repository_copy_3_command.txt[]
454+
include::output/style_repository_copy_3_result.txt[]
455+
456+
include::output/style_repository_copy_4_command.txt[]
457+
include::output/style_repository_copy_4_result.txt[]
458+
459+
include::output/style_repository_copy_5_command.txt[]
460+
include::output/style_repository_copy_5_result.txt[]
461+
462+
include::output/style_repository_copy_6_command.txt[]
463+
include::output/style_repository_copy_6_result.txt[]

src/main/groovy/org/geoshell/style/StyleCommands.groovy

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import geoscript.style.ColorMap
77
import geoscript.style.Gradient
88
import geoscript.style.RasterSymbolizer
99
import geoscript.style.Style
10+
import geoscript.style.StyleRepository
1011
import geoscript.style.Symbolizer
1112
import geoscript.style.UniqueValues
1213
import geoscript.style.io.SLDWriter
@@ -218,4 +219,105 @@ class StyleCommands implements CommandMarker {
218219
"Colormap Palette Raster Style written to ${file}!"
219220
}
220221

222+
@CliCommand(value = "style repository save", help = "Save a style to a style repository")
223+
String saveStyleToStyleRepository(
224+
@CliOption(key = "type", mandatory = true, help = "The type of style repository (directory, nested-directory, h2, sqlite, postgres)")
225+
String type,
226+
@CliOption(key = "options", mandatory = true, help = "The style repository options")
227+
String params,
228+
@CliOption(key = "layerName", mandatory = true, help = "The layer name")
229+
String layerName,
230+
@CliOption(key = "styleName", mandatory = true, help = "The style name")
231+
String styleName,
232+
@CliOption(key = "styleFile", mandatory = true, help = "The style file (sld or css)")
233+
File styleFile
234+
) {
235+
StyleRepository styleRepository = StyleRepositoryFactory.getStyleRepository(type, StyleRepositoryFactory.getParameters(params))
236+
styleRepository.save(layerName, styleName, styleFile.text)
237+
"Style ${styleName} for Layer ${layerName} saved to ${type}"
238+
}
239+
240+
@CliCommand(value = "style repository delete", help = "Delete a style from a style repository")
241+
String deleteStyleFromStyleRepository(
242+
@CliOption(key = "type", mandatory = true, help = "The type of style repository (directory, nested-directory, h2, sqlite, postgres)")
243+
String type,
244+
@CliOption(key = "options", mandatory = true, help = "The style repository options")
245+
String params,
246+
@CliOption(key = "layerName", mandatory = true, help = "The layer name")
247+
String layerName,
248+
@CliOption(key = "styleName", mandatory = true, help = "The style name")
249+
String styleName
250+
) {
251+
StyleRepository styleRepository = StyleRepositoryFactory.getStyleRepository(type, StyleRepositoryFactory.getParameters(params))
252+
styleRepository.delete(layerName, styleName)
253+
"Style ${styleName} for Layer ${layerName} deleted from ${type}"
254+
}
255+
256+
@CliCommand(value = "style repository get", help = "Get a style from a style repository")
257+
String getStyleFromStyleRepository(
258+
@CliOption(key = "type", mandatory = true, help = "The type of style repository (directory, nested-directory, h2, sqlite, postgres)")
259+
String type,
260+
@CliOption(key = "options", mandatory = true, help = "The style repository options")
261+
String params,
262+
@CliOption(key = "layerName", mandatory = true, help = "The layer name")
263+
String layerName,
264+
@CliOption(key = "styleName", mandatory = true, help = "The style name")
265+
String styleName,
266+
@CliOption(key = "styleFile", mandatory = false, help = "The style file (sld or css)")
267+
File styleFile
268+
) {
269+
StyleRepository styleRepository = StyleRepositoryFactory.getStyleRepository(type, StyleRepositoryFactory.getParameters(params))
270+
String style = styleRepository.getForLayer(layerName, styleName)
271+
if (styleFile) {
272+
styleFile.text = style
273+
"Style ${styleName} for Layer ${layerName} saved to ${styleFile.name}"
274+
} else {
275+
style
276+
}
277+
}
278+
279+
@CliCommand(value = "style repository list", help = "List styles in a style repository")
280+
String listStylesInStyleRepository(
281+
@CliOption(key = "type", mandatory = true, help = "The type of style repository (directory, nested-directory, h2, sqlite, postgres)")
282+
String type,
283+
@CliOption(key = "options", mandatory = true, help = "The style repository options")
284+
String params,
285+
@CliOption(key = "layerName", mandatory = false, help = "The layer name")
286+
String layerName
287+
) {
288+
StyleRepository styleRepository = StyleRepositoryFactory.getStyleRepository(type, StyleRepositoryFactory.getParameters(params))
289+
List<Map<String,String>> styles = []
290+
if (layerName) {
291+
styles.addAll(styleRepository.getForLayer(layerName))
292+
} else {
293+
styles.addAll(styleRepository.getAll())
294+
}
295+
String NEW_LINE = System.getProperty("line.separator")
296+
StringBuilder str = new StringBuilder()
297+
styles.each { Map<String,String> style ->
298+
str.append(style.layerName + " " + style.styleName).append(NEW_LINE)
299+
}
300+
str.toString()
301+
}
302+
303+
@CliCommand(value = "style repository copy", help = "Copy styles from one repository to another")
304+
String copyStylesInStyleRepository(
305+
@CliOption(key = "inputType", mandatory = true, help = "The type of style repository (directory, nested-directory, h2, sqlite, postgres)")
306+
String inputType,
307+
@CliOption(key = "inputOptions", mandatory = true, help = "The style repository options")
308+
String inputParams,
309+
@CliOption(key = "outputType", mandatory = true, help = "The type of style repository (directory, nested-directory, h2, sqlite, postgres)")
310+
String outputType,
311+
@CliOption(key = "outputOptions", mandatory = true, help = "The style repository options")
312+
String outputParams
313+
) {
314+
StyleRepository inputStyleRepository = StyleRepositoryFactory.getStyleRepository(inputType, StyleRepositoryFactory.getParameters(inputParams))
315+
StyleRepository outputStyleRepository = StyleRepositoryFactory.getStyleRepository(outputType, StyleRepositoryFactory.getParameters(outputParams))
316+
List<Map<String, String>> styles = inputStyleRepository.getAll()
317+
styles.each {Map<String,String> style ->
318+
outputStyleRepository.save(style.layerName, style.styleName, style.style)
319+
}
320+
"Copy styles from ${inputType} to ${outputType}"
321+
}
322+
221323
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package org.geoshell.style
2+
3+
import geoscript.style.DatabaseStyleRepository
4+
import geoscript.style.DirectoryStyleRepository
5+
import geoscript.style.NestedDirectoryStyleRepository
6+
import geoscript.style.StyleRepository
7+
import geoscript.workspace.H2
8+
import groovy.sql.Sql
9+
import org.geotools.util.URLs
10+
11+
class StyleRepositoryFactory {
12+
13+
static StyleRepository getStyleRepository(String type, Map options) {
14+
if (type.equalsIgnoreCase("directory")) {
15+
new DirectoryStyleRepository(getFile(options.file))
16+
} else if (type.equalsIgnoreCase("nested-directory")) {
17+
new NestedDirectoryStyleRepository(getFile(options.file))
18+
} else if (type.equalsIgnoreCase("sqlite")) {
19+
File file = getFile(options.file)
20+
Sql sql = Sql.newInstance("jdbc:sqlite:${file.absolutePath}", "org.sqlite.JDBC")
21+
DatabaseStyleRepository.forSqlite(sql)
22+
} else if (type.equalsIgnoreCase("h2")) {
23+
File file = getFile(options.file)
24+
H2 h2 = new H2(file.name, file)
25+
Sql sql = h2.sql
26+
DatabaseStyleRepository.forH2(sql)
27+
} else if (type.equalsIgnoreCase("postgres")) {
28+
String server = options.server ?: 'localhost'
29+
String database = options.database
30+
String port = options.port ?: '5432'
31+
String userName = options.userName
32+
String password = options.password
33+
Sql sql = Sql.withInstance("jdbc:postgres://${server}:${port}/${database}", userName, password, "org.postgresql.Driver")
34+
DatabaseStyleRepository.forPostgres(sql)
35+
}
36+
}
37+
38+
static Map getParameters(String str) {
39+
Map params = [:]
40+
str.split("[ ]+(?=([^\']*\'[^\']*\')*[^\']*\$)").each {
41+
def parts = it.split("=")
42+
if (parts.size() > 1) {
43+
def key = parts[0].trim()
44+
if ((key.startsWith("'") && key.endsWith("'")) ||
45+
(key.startsWith("\"") && key.endsWith("\""))) {
46+
key = key.substring(1, key.length() - 1)
47+
}
48+
def value = parts[1].trim()
49+
if ((value.startsWith("'") && value.endsWith("'")) ||
50+
(value.startsWith("\"") && value.endsWith("\""))) {
51+
value = value.substring(1, value.length() - 1)
52+
}
53+
params.put(key, value)
54+
}
55+
}
56+
params
57+
}
58+
59+
private static File getFile(Object file) {
60+
if (file instanceof File) {
61+
file
62+
} else {
63+
new File(file.toString())
64+
}
65+
}
66+
67+
}

0 commit comments

Comments
 (0)