diff --git a/server/datacatalog/datacatalogv3/cms.go b/server/datacatalog/datacatalogv3/cms.go index e0bc6d505..78eb307cc 100644 --- a/server/datacatalog/datacatalogv3/cms.go +++ b/server/datacatalog/datacatalogv3/cms.go @@ -51,6 +51,10 @@ func (c *CMS) GetAll(ctx context.Context, project string) (*AllData, error) { return c.GetGenericItems(ctx, project) }) + sampleItemsChan := lo.Async2(func() ([]*GenericItem, error) { + return c.GetSampleItems(ctx, project) + }) + geospatialjpDataItemsChan := lo.Async2(func() ([]*GeospatialjpDataItem, error) { return c.GetGeospatialjpDataItems(ctx, project) }) @@ -83,6 +87,12 @@ func (c *CMS) GetAll(ctx context.Context, project string) (*AllData, error) { all.Generic = res.A } + if res := <-sampleItemsChan; res.B != nil { + return nil, fmt.Errorf("failed to get sample items: %w", res.B) + } else { + all.Sample = res.A + } + if res := <-geospatialjpDataItemsChan; res.B != nil { return nil, fmt.Errorf("failed to get geospatialjp data items: %w", res.B) } else { @@ -134,7 +144,7 @@ func (c *CMS) GetCityItems(ctx context.Context, project string, featureTypes []F } func (c *CMS) GetPlateauItems(ctx context.Context, project, feature string) ([]*PlateauFeatureItem, error) { - items, err := getItemsAndConv[PlateauFeatureItem]( + items, err := getItemsAndConv( c.cms, ctx, project, modelPrefix+feature, func(i cms.Item) *PlateauFeatureItem { return PlateauFeatureItemFrom(&i) @@ -144,7 +154,7 @@ func (c *CMS) GetPlateauItems(ctx context.Context, project, feature string) ([]* } func (c *CMS) GetRelatedItems(ctx context.Context, project string, featureTypes []FeatureType) ([]*RelatedItem, error) { - items, err := getItemsAndConv[RelatedItem]( + items, err := getItemsAndConv( c.cms, ctx, project, modelPrefix+relatedModel, func(i cms.Item) *RelatedItem { return RelatedItemFrom(&i, featureTypes) @@ -154,7 +164,7 @@ func (c *CMS) GetRelatedItems(ctx context.Context, project string, featureTypes } func (c *CMS) GetGenericItems(ctx context.Context, project string) ([]*GenericItem, error) { - items, err := getItemsAndConv[GenericItem]( + items, err := getItemsAndConv( c.cms, ctx, project, modelPrefix+genericModel, func(i cms.Item) *GenericItem { return GenericItemFrom(&i) @@ -170,6 +180,21 @@ func (c *CMS) GetGenericItems(ctx context.Context, project string) ([]*GenericIt return items, err } +func (c *CMS) GetSampleItems(ctx context.Context, project string) ([]*GenericItem, error) { + items, err := getItemsAndConv( + c.cms, ctx, project, modelPrefix+sampleModel, + func(i cms.Item) *GenericItem { + return GenericItemFrom(&i) + }, + ) + + for _, item := range items { + item.Category = "サンプルデータ" + } + + return items, err +} + func (c *CMS) GetGeospatialjpDataItems(ctx context.Context, project string) ([]*GeospatialjpDataItem, error) { items, err := getItemsAndConv[GeospatialjpDataItem]( c.cms, ctx, project, modelPrefix+geospatialjpDataModel, diff --git a/server/datacatalog/datacatalogv3/cms_model.go b/server/datacatalog/datacatalogv3/cms_model.go index a7b5d5db1..105241cab 100644 --- a/server/datacatalog/datacatalogv3/cms_model.go +++ b/server/datacatalog/datacatalogv3/cms_model.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "slices" + "strings" "github.com/eukarya-inc/reearth-plateauview/server/cmsintegration/cmsintegrationcommon" "github.com/eukarya-inc/reearth-plateauview/server/datacatalog/datacatalogcommon" @@ -15,6 +16,7 @@ const modelPrefix = "plateau-" const cityModel = "city" const relatedModel = "related" const genericModel = "generic" +const sampleModel = "sample" const geospatialjpDataModel = "geospatialjp-data" const defaultSpec = "第3.2版" @@ -154,7 +156,12 @@ type PlateauFeatureItem struct { Dic string `json:"dic,omitempty" cms:"dic,textarea"` MaxLOD string `json:"maxlod,omitempty" cms:"maxlod,-"` // metadata - Sample bool `json:"sample,omitempty" cms:"sample,bool,metadata"` + Sample bool `json:"sample,omitempty" cms:"sample,bool,metadata"` + Status *cms.Tag `json:"status,omitempty" cms:"status,select,metadata"` +} + +func (c *PlateauFeatureItem) IsBeta() bool { + return c.Status != nil && c.Status.Name == string(ManagementStatusReady) } func (c PlateauFeatureItem) ReadDic() (d Dic, _ error) { @@ -289,10 +296,13 @@ type GenericItem struct { Items []GenericItemDataset `json:"items,omitempty" cms:"items,group"` OpenDataURL string `json:"open_data_url,omitempty" cms:"open_data_url,url"` Category string `json:"category,omitempty" cms:"category,select"` + // sample + CityGML string `json:"citygml,omitempty" cms:"citygml,asset"` + FeatureType string `json:"feature_type,omitempty" cms:"-"` + MaxLODURL string `json:"maxlodUrl,omitempty" cms:"-"` // metadata Status *cms.Tag `json:"status,omitempty" cms:"status,select,metadata"` Public bool `json:"public,omitempty" cms:"public,bool,metadata"` - UseAR bool `json:"use-ar,omitempty" cms:"use-ar,bool,metadata"` } func (c *GenericItem) Stage() stage { @@ -305,6 +315,16 @@ func (c *GenericItem) Stage() stage { return stageAlpha } +func (c *GenericItem) IsPublic() bool { + stage := c.Stage() + return stage == stageGA +} + +func (c *GenericItem) IsPublicOrBeta() bool { + stage := c.Stage() + return stage == stageGA || stage == stageBeta +} + type GenericItemDataset struct { ID string `json:"id,omitempty" cms:"id"` Name string `json:"name,omitempty" cms:"item_name,text"` @@ -323,6 +343,19 @@ func GenericItemFrom(item *cms.Item) (i *GenericItem) { i.Items[ind].Data = valueToAssetURL(item.FieldByKeyAndGroup("data", d.ID).GetValue()) } + i.MaxLODURL = valueToAssetURL(item.FieldByKey("maxlod").GetValue()) + + // e.g. "建築物モデル(bldg)" -> Name="建築物モデル", FeatureType="bldg" + ft := lo.FromPtr(item.FieldByKey("feature_type").GetValue().String()) + if strings.Contains(ft, "(") && strings.Contains(ft, ")") { + name, s, _ := strings.Cut(ft, "(") + s, _, _ = strings.Cut(s, ")") + i.FeatureType = s + if i.Name == "" { + i.Name = name + } + } + return } diff --git a/server/datacatalog/datacatalogv3/conv.go b/server/datacatalog/datacatalogv3/conv.go index 879dd94d1..d43de26f9 100644 --- a/server/datacatalog/datacatalogv3/conv.go +++ b/server/datacatalog/datacatalogv3/conv.go @@ -72,9 +72,10 @@ func (all *AllData) Into() (res *plateauapi.InMemoryRepoContext, warning []strin res.Datasets.Append(plateauapi.DatasetTypeCategoryRelated, datasets) } - // generic + // generic and sample { - datasets, w := convertGeneric(all.Generic, res.DatasetTypes[plateauapi.DatasetTypeCategoryGeneric], ic) + src := append(all.Generic, all.Sample...) + datasets, w := convertGeneric(src, res.DatasetTypes[plateauapi.DatasetTypeCategoryGeneric], ic) warning = append(warning, w...) res.Datasets.Append(plateauapi.DatasetTypeCategoryGeneric, datasets) } diff --git a/server/datacatalog/datacatalogv3/conv_citygml.go b/server/datacatalog/datacatalogv3/conv_citygml.go index 36d34b8cc..b87c954a0 100644 --- a/server/datacatalog/datacatalogv3/conv_citygml.go +++ b/server/datacatalog/datacatalogv3/conv_citygml.go @@ -1,6 +1,8 @@ package datacatalogv3 import ( + "slices" + "github.com/eukarya-inc/reearth-plateauview/server/datacatalog/plateauapi" ) @@ -50,9 +52,9 @@ func toCityGMLs(all *AllData, regYear int) (map[plateauapi.ID]*plateauapi.CityGM } // add citygml urls for sample data - for _, data := range all.Plateau { + for ft, data := range all.Plateau { for _, d := range data { - if !d.Sample || d.MaxLOD == "" || d.CityGML == "" { + if !d.Sample || d.MaxLOD == "" || d.CityGML == "" /*|| !d.IsBeta()*/ { continue } @@ -66,16 +68,51 @@ func toCityGMLs(all *AllData, regYear int) (map[plateauapi.ID]*plateauapi.CityGM continue } - maxlod := citygml.Admin.(map[string]any)["maxlod"].([]string) - citygmlURL := citygml.Admin.(map[string]any)["citygmlUrl"].([]string) + addCityGML(d.CityGML, d.MaxLOD, ft, citygml) + } + } - maxlod = append(maxlod, d.MaxLOD) - citygmlURL = append(citygmlURL, d.CityGML) + for _, d := range all.Sample { + if d.MaxLODURL == "" || d.CityGML == "" { + continue + } - citygml.Admin.(map[string]any)["maxlod"] = maxlod - citygml.Admin.(map[string]any)["citygmlUrl"] = citygmlURL + citygml := resCity[d.City] + if citygml == nil { + continue } + + city := cityMap[d.City] + if city == nil || !city.SDKPublic { + continue + } + + stage, _ := citygml.Admin.(map[string]any)["stage"].(string) + if stage == string(stageGA) && !d.IsPublic() || stage == string(stageBeta) && !d.IsPublicOrBeta() { + continue + } + + addCityGML(d.CityGML, d.MaxLODURL, d.FeatureType, citygml) } return res, nil } + +func addCityGML(citygmlURL, maxlodURL, featureType string, citygml *plateauapi.CityGMLDataset) { + if citygmlURL == "" || maxlodURL == "" { + return + } + + baseCitygmlURL := citygml.Admin.(map[string]any)["citygmlUrl"].([]string) + baseMaxlod := citygml.Admin.(map[string]any)["maxlod"].([]string) + + baseCitygmlURL = append(baseCitygmlURL, citygmlURL) + baseMaxlod = append(baseMaxlod, maxlodURL) + + citygml.Admin.(map[string]any)["citygmlUrl"] = baseCitygmlURL + citygml.Admin.(map[string]any)["maxlod"] = baseMaxlod + + if featureType != "" && !slices.Contains(citygml.FeatureTypes, featureType) { + citygml.FeatureTypes = append(citygml.FeatureTypes, featureType) + } +} diff --git a/server/datacatalog/datacatalogv3/conv_internal.go b/server/datacatalog/datacatalogv3/conv_internal.go index 1cb96748a..70a67a731 100644 --- a/server/datacatalog/datacatalogv3/conv_internal.go +++ b/server/datacatalog/datacatalogv3/conv_internal.go @@ -87,9 +87,9 @@ func (c *internalContext) SetURL(t, cmsurl, ws, prj, modelID string) { case "plateau": c.plateauCMSURL = url case "related": - c.plateauCMSURL = url + c.relatedCMSURL = url case "generic": - c.plateauCMSURL = url + c.genericCMSURL = url } } diff --git a/server/datacatalog/datacatalogv3/model.go b/server/datacatalog/datacatalogv3/model.go index 2fb00d63f..dc07efd70 100644 --- a/server/datacatalog/datacatalogv3/model.go +++ b/server/datacatalog/datacatalogv3/model.go @@ -10,6 +10,7 @@ type AllData struct { City []*CityItem Related []*RelatedItem Generic []*GenericItem + Sample []*GenericItem Plateau map[string][]*PlateauFeatureItem GeospatialjpDataItems []*GeospatialjpDataItem CMSInfo CMSInfo diff --git a/server/datacatalog/datacatalogv3/repos_test.go b/server/datacatalog/datacatalogv3/repos_test.go index e8abab28b..7f1dbcb70 100644 --- a/server/datacatalog/datacatalogv3/repos_test.go +++ b/server/datacatalog/datacatalogv3/repos_test.go @@ -134,6 +134,10 @@ func mockCMS(t *testing.T) { "GET", "https://example.com/api/projects/prj/models/plateau-generic/items", httpmock.NewJsonResponderOrPanic(200, empty), ) + httpmock.RegisterResponder( + "GET", "https://example.com/api/projects/prj/models/plateau-sample/items", + httpmock.NewJsonResponderOrPanic(200, empty), + ) httpmock.RegisterResponder( "GET", "https://example.com/api/projects/prj/models/plateau-geospatialjp-data/items", httpmock.NewJsonResponderOrPanic(200, empty),