예제 #1
0
        public void query_gemini_records()
        {
            IDocumentStore store = new DocumentStore {
                Url = RavenUrl
            }.Initialize();

            RavenUtility.WaitForIndexing(store);

            string peakDistrictBbox = BoundingBoxUtility.ToWkt(new BoundingBox
            {
                North = 53.6m,
                South = 53.0m,
                East  = -1.52m,
                West  = -2.14m
            });

            Stopwatch watch = Stopwatch.StartNew();

            using (IDocumentSession db = store.OpenSession())
            {
                List <Record> results = db.Query <Record, RecordSpatialIndex>()
                                        .Customize(x => x.RelatesToShape(FieldNames.Spatial, peakDistrictBbox, SpatialRelation.Intersects))
                                        .Where(i => i.Gemini.Title.StartsWith("GA"))
                                        //.Take(10)
                                        .ToList();

                //results.Count().Should().Be(10);
                Console.WriteLine(results.Count);
            }

            Console.WriteLine(watch.ElapsedMilliseconds);
        }
예제 #2
0
        public void load_gemini_records()
        {
            string     dir = @"C:\Users\PETMON\Downloads\nbn-gemini2";
            XNamespace gmd = "http://www.isotc211.org/2005/gmd";

            var q = (from f in Directory.GetFiles(dir, "*.xml")
                     where File.ReadLines(f).Any()
                     let xml = XDocument.Load(f)
                               let p = new
            {
                North = (decimal)xml.Descendants(gmd + "northBoundLatitude").Single(),
                South = (decimal)xml.Descendants(gmd + "southBoundLatitude").Single(),
                East = (decimal)xml.Descendants(gmd + "eastBoundLongitude").Single(),
                West = (decimal)xml.Descendants(gmd + "westBoundLongitude").Single(),
            }
                     where p.North < 61 && p.South > 50 && p.East <2 && p.West> -12
                     // ignore bad data
                     select new
            {
                File = Path.GetFileName(f),
                Wkt = BoundingBoxUtility.ToWkt(new BoundingBox
                {
                    North = p.North,
                    South = p.South,
                    East = p.East,
                    West = p.West,
                })
            })
                    .ToList();

            Console.WriteLine(q.Count());
            q.ForEach(Console.WriteLine);


            IDocumentStore store = new DocumentStore {
                Url = RavenUrl
            }.Initialize();

            using (IDocumentSession db = store.OpenSession())
            {
                foreach (var x in q)
                {
                    var item = new Record
                    {
                        Gemini = new Metadata
                        {
                            Title = x.File,
                        },
                        Wkt = x.Wkt,
                    };

                    db.Store(item);
                }

                db.SaveChanges();
            }

            IndexCreation.CreateIndexes(typeof(Record).Assembly, store);
        }
예제 #3
0
 private static void PerformDenormalizations(Record record)
 {
     // we store the bounding box as wkt so we can index it
     if (!BoundingBoxUtility.IsBlank(record.Gemini.BoundingBox))
     {
         record.Wkt = BoundingBoxUtility.ToWkt(record.Gemini.BoundingBox);
     }
 }
예제 #4
0
 void ValidateBoundingBox(Record record, ValidationResult <Record> result)
 {
     if (!BoundingBoxUtility.IsBlank(record.Gemini.BoundingBox))
     {
         if (!BoundingBoxUtility.IsValid(record.Gemini.BoundingBox))
         {
             result.Errors.Add("Invalid bounding box", r => r.Gemini.BoundingBox);
         }
     }
 }
예제 #5
0
        public HttpResponseMessage AddOTBoundingBoxes()
        {
            var query = new RecordQueryInputModel
            {
                F = new FilterOptions {
                    Keywords = new[] { "vocab.jncc.gov.uk/jncc-category/Overseas Territories" }
                },
                P = 0,
                N = 1024,
            };

            var records = _queryer.Query(query).ToList();

            foreach (var record in records)
            {
                // note incorrect 's' in vocabs.jncc!
                var ots = record.Gemini.Keywords.Where(k => k.Vocab == "http://vocabs.jncc.gov.uk/overseas-territories").ToList();

                if (ots.Any())
                {
                    var allBoxes = BoundingBoxes.Groups.Single(g => g.Name == "Overseas Territories").Boxes
                                   .Concat(new[] // currently don't have these so just use 0,0,0,0
                    {
                        new KnownBoundingBox {
                            Name = "Sovereign Base Areas Cyprus", Box = new BoundingBox()
                        },
                        new KnownBoundingBox {
                            Name = "British Antarctic Territory", Box = new BoundingBox()
                        },
                    });

                    var boxes = ots.Select(ot => allBoxes.SingleOrDefault(b => b.Name == ot.Value)).ToList();

                    if (boxes.Any(b => b == null))
                    {
                        throw new Exception("Some box couldn't be looked up for record " + record.Id);
                    }

                    var box = BoundingBoxUtility.MinimumOf(boxes.Select(b => b.Box));
                    record.Gemini.BoundingBox = box;
                }
            }

            db.SaveChanges();

            return(new HttpResponseMessage());
        }
예제 #6
0
        public void should_store_bounding_box_as_wkt()
        {
            var database = Mock.Of <IDocumentSession>();
            var service  = new RecordService(database, ValidatorStub());

            var e      = Library.Example();
            var record = new Record
            {
                Gemini = e,
                Footer = new Footer()
            };

            service.Update(record, TestUser);

            string expectedWkt = BoundingBoxUtility.ToWkt(e.BoundingBox);

            Mock.Get(database).Verify(db => db.Store(It.Is((Record r) => r.Wkt == expectedWkt)));
        }
예제 #7
0
        void PerformGeminiValidation(Record record, ValidationResult <Record> result)
        {
            // structured to match the gemini doc

            // 1 title is validated at basic level

            // 2 alternative title not used as optional

            // 3 Dataset language, conditional - data resource contains textual information
            // lets assume all data resources contain text
            // data_type is enum so can't be null, will default to eng

            // 4 abstract is mandatory
            if (record.Gemini.Abstract.IsBlank())
            {
                result.Errors.Add("Abstract must be provided" + GeminiSuffix, r => r.Gemini.Abstract);
            }

            // 5 topic_category_must_not_be_blank
            if (record.Gemini.TopicCategory.IsBlank())
            {
                result.Errors.Add(String.Format("Topic Category must be provided" + GeminiSuffix),
                                  r => r.Gemini.TopicCategory);
            }

            // 6 keywords mandatory
            if (record.Gemini.Keywords.Count == 0)
            {
                result.Errors.Add("Keywords must be provided" + GeminiSuffix, r => r.Gemini.Keywords);
            }

            // 7 temporal extent is mandatory - at least Begin must be provided
            if (record.Gemini.TemporalExtent.Begin.IsBlank())
            {
                result.Errors.Add("Temporal Extent must be provided" + GeminiSuffix,
                                  r => r.Gemini.TemporalExtent.Begin);
            }

            // 8 DatasetReferenceDate mandatory
            if (record.Gemini.DatasetReferenceDate.IsBlank())
            {
                result.Errors.Add("Dataset Reference Date must be provided" + GeminiSuffix,
                                  r => r.Gemini.DatasetReferenceDate);
            }

            // 10 Lineage is mandatory
            if (record.Gemini.Lineage.IsBlank())
            {
                result.Errors.Add("Lineage must be provided" + GeminiSuffix, r => r.Gemini.Lineage);
            }

            // 15 extent is optional and not used

            // 16 Vertical extent information is optional and not used

            // 17 Spatial reference system is optional

            // 18 Spatial resolution, where it can be specified it should - so its optional

            // 19 resource location, conditional
            // when online access is availble, should be a valid url
            // when do not yet perform a get request and get a 200 response, the only true way to validate a url
            if (record.Gemini.ResourceLocator.IsNotBlank())
            {
                Uri url;

                if (Uri.TryCreate(record.Gemini.ResourceLocator, UriKind.Absolute, out url))
                {
                    if (url.Scheme != Uri.UriSchemeHttp)
                    {
                        result.Errors.Add("Resource locator must be an http url",
                                          r => r.Gemini.ResourceLocator);
                    }
                }
                else
                {
                    result.Errors.Add("Resource locator must be a valid url",
                                      r => r.Gemini.ResourceLocator);
                }
            }

            // 21 DataFormat optional

            // 23 reponsible Organisation
            if (record.Gemini.ResponsibleOrganisation.Email.IsBlank())
            {
                result.Errors.Add("Email address for responsible organisation must be provided" + GeminiSuffix,
                                  r => r.Gemini.ResponsibleOrganisation.Email);
            }
            if (record.Gemini.ResponsibleOrganisation.Name.IsBlank())
            {
                result.Errors.Add("Name of responsible organisation must be provided" + GeminiSuffix,
                                  r => r.Gemini.ResponsibleOrganisation.Name);
            }
            if (record.Gemini.ResponsibleOrganisation.Role.IsBlank())
            {
                result.Errors.Add("Role of responsible organisation must be provided" + GeminiSuffix,
                                  r => r.Gemini.ResponsibleOrganisation.Role);
            }

            // 24 frequency of update is optional

            // 25 limitations on publci access is mandatory
            if (record.Gemini.LimitationsOnPublicAccess.IsBlank())
            {
                result.Errors.Add("Limitations On Public Access must be provided" + GeminiSuffix,
                                  r => r.Gemini.LimitationsOnPublicAccess);
            }

            // 26 use constraints are mandatory
            if (record.Gemini.UseConstraints.IsBlank())
            {
                result.Errors.Add("Use Constraints must be provided (if there are none, leave as 'no conditions apply')",
                                  r => r.Gemini.UseConstraints);
            }

            // 27 Additional information source is optional

            // 30 metadatadate is mandatory
            if (record.Gemini.MetadataDate.Equals(DateTime.MinValue))
            {
                result.Errors.Add("A metadata reference date must be provided" + GeminiSuffix,
                                  r => r.Gemini.MetadataDate);
            }

            // 33 Metadatalanguage

            // 35 Point of contacts
            // org name and email contact mandatory
            if (record.Gemini.MetadataPointOfContact.Email.IsBlank())
            {
                result.Errors.Add("A metadata point of contact email address must be provided" + GeminiSuffix,
                                  r => r.Gemini.MetadataPointOfContact.Email);
            }
            if (record.Gemini.MetadataPointOfContact.Name.IsBlank())
            {
                result.Errors.Add("A metadata point of contact organisation name must be provided" + GeminiSuffix,
                                  r => r.Gemini.MetadataPointOfContact.Name);
            }
            if (record.Gemini.MetadataPointOfContact.Role != "pointOfContact")
            {
                result.Errors.Add("The metadata point of contact role must be 'pointOfContact'" + GeminiSuffix,
                                  r => r.Gemini.MetadataPointOfContact.Name);
            }

            // 36 Unique resource identifier

            // 39 resource type is mandatory
            if (record.Gemini.ResourceType.IsBlank())
            {
                result.Errors.Add("A resource type must be provided" + GeminiSuffix,
                                  r => r.Gemini.ResourceType);
            }

            // 40 Keywords from controlled vocabularys must be defined, they cannot be added.
            //ValidateControlledKeywords(record, recordValidationResult<Record>);

            // Conformity, required if claiming conformity to INSPIRE
            // not yet implemented

            // Equivalent scale, optional

            // we're going to try to squash gemini and non-geographic iso metadata together in the same validation
            if (record.Gemini.ResourceType != "nonGeographicDataset")
            {
                // BoundingBox
                // mandatory
                // valid todo

                if (BoundingBoxUtility.IsBlank(record.Gemini.BoundingBox))
                {
                    result.Errors.Add("A bounding box must be supplied", r => r.Gemini.BoundingBox);
                }
            }
        }