Skip to content

Commit 6f5565e

Browse files
authored
Merge pull request #269 from GeoNet/stationxml-1.2b
Stationxml 1.2
2 parents 5f43575 + 27725b3 commit 6f5565e

7 files changed

Lines changed: 275 additions & 203 deletions

File tree

cmd/fdsn-ws/fdsn_event.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ func fdsnEventV1Handler(r *http.Request, h http.Header, b *bytes.Buffer) error {
572572
if l, err := wgs84.ClosestNZ(latitude, longitude); err == nil {
573573
loc = l.Description()
574574
}
575-
s := fmt.Sprintf("%s|%s|%.3f|%.3f|%.1f|GNS|GNS|GNS|%s|%s|%.1f|GNS|%s|%s\n", eventID, tm.Format("2006-01-02T15:04:05"), latitude, longitude, depth, eventID, magType, magnitude, loc, eventType)
575+
s := fmt.Sprintf("%s|%s|%.3f|%.3f|%.1f|GNS|GNS|GNS|%s|%s|%.1f|GNS|%s|%s\n", eventID, tm.UTC().Format(time.RFC3339Nano), latitude, longitude, depth, eventID, magType, magnitude, loc, eventType)
576576
b.WriteString(s)
577577
}
578578

cmd/fdsn-ws/fdsn_event_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func TestTimeParse(t *testing.T) {
118118
t.Error(err)
119119
}
120120

121-
if err := tm.UnmarshalText([]byte("2015-01-12T12:12:12-09:00")); err == nil {
121+
if err := tm.UnmarshalText([]byte("2015-01-12T12:12:12.invalid")); err == nil {
122122
t.Error("expected an error for invalid time string.")
123123
}
124124
}

cmd/fdsn-ws/fdsn_station.go

Lines changed: 51 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@ var (
108108
fdsnStations fdsnStationObj
109109
emptyDateTime = time.Date(9999, 1, 1, 0, 0, 0, 0, time.UTC)
110110
errNotModified = fmt.Errorf("Not modified.")
111-
s3Bucket string
112-
s3Meta string
111+
stationXMLBucket string
112+
stationXMLKey string
113113
)
114114

115115
func initStationTemplate() {
@@ -134,18 +134,18 @@ func initStationTemplate() {
134134

135135
func initStationXML() {
136136
var err error
137-
s3Bucket = os.Getenv("STATION_XML_BUCKET")
138-
s3Meta = os.Getenv("STATION_XML_META_KEY")
137+
stationXMLBucket = os.Getenv("STATION_XML_BUCKET")
138+
stationXMLKey = os.Getenv("STATION_XML_META_KEY")
139139

140140
// Prepare the data source for station.
141141
// If there's no local file available then we'll have to download first.
142142
by := bytes.NewBuffer(nil)
143143
modified := zeroDateTime
144144
var s os.FileInfo
145-
if s, err = os.Stat("etc/" + s3Meta); err == nil {
146-
log.Println("Loading fdsn station xml file ", "etc/"+s3Meta)
145+
if s, err = os.Stat("etc/" + stationXMLKey); err == nil {
146+
log.Println("Loading fdsn station xml file ", "etc/"+stationXMLKey)
147147
var f *os.File
148-
if f, err = os.Open("etc/" + s3Meta); err == nil {
148+
if f, err = os.Open("etc/" + stationXMLKey); err == nil {
149149

150150
if _, err = io.Copy(by, f); err != nil {
151151
log.Println("Error copying station xml file", err)
@@ -656,7 +656,7 @@ func (r *FDSNStationXML) doFilter(params []fdsnStationV1Search) bool {
656656
// If this node meets at least one criteria, then we pass all the met criterion to next level.
657657

658658
func (n *NetworkType) doFilter(params []fdsnStationV1Search) bool {
659-
n.TotalNumberStations = len(n.Station)
659+
n.TotalNumberStations = CounterType(len(n.Station))
660660
matchedParams := make([]fdsnStationV1Search, 0)
661661
resultStations := make([]StationType, 0)
662662

@@ -699,15 +699,15 @@ func (n *NetworkType) doFilter(params []fdsnStationV1Search) bool {
699699
}
700700
}
701701

702-
n.SelectedNumberStations = len(resultStations)
702+
n.SelectedNumberStations = CounterType(len(resultStations))
703703
n.Station = resultStations
704704

705705
// this node only valid if the children matches any query
706706
return n.SelectedNumberStations > 0
707707
}
708708

709709
func (s *StationType) doFilter(params []fdsnStationV1Search) bool {
710-
s.TotalNumberChannels = len(s.Channel)
710+
s.TotalNumberChannels = CounterType(len(s.Channel))
711711
resultChannels := make([]ChannelType, 0)
712712

713713
matchedParams := make([]fdsnStationV1Search, 0)
@@ -835,39 +835,31 @@ func (v fdsnStationV1Search) validStartEnd(start, end time.Time, level int) bool
835835
return true
836836
}
837837

838-
func (v fdsnStationV1Search) validLatLng(latitude *LatitudeType, longitude *LongitudeType) bool {
839-
if v.MinLatitude != math.MaxFloat64 && (latitude == nil || latitude.Value < v.MinLatitude) {
840-
// request to check latitude:
841-
// 1. this node doesn't have latitude -> check failed
842-
// 2. the value fall outside the range -> check failed
843-
// (similar logics apply for cases below)
838+
func (v fdsnStationV1Search) validLatLng(latitude LatitudeType, longitude LongitudeType) bool {
839+
if v.MinLatitude != math.MaxFloat64 && latitude.Value < v.MinLatitude {
844840
return false
845841
}
846842

847-
if v.MaxLatitude != math.MaxFloat64 && (latitude == nil || latitude.Value > v.MaxLatitude) {
843+
if v.MaxLatitude != math.MaxFloat64 && latitude.Value > v.MaxLatitude {
848844
return false
849845
}
850846

851-
if v.MinLongitude != math.MaxFloat64 && (longitude == nil || longitude.Value < v.MinLongitude) {
847+
if v.MinLongitude != math.MaxFloat64 && longitude.Value < v.MinLongitude {
852848
return false
853849
}
854850

855-
if v.MaxLongitude != math.MaxFloat64 && (longitude == nil || longitude.Value > v.MaxLongitude) {
851+
if v.MaxLongitude != math.MaxFloat64 && longitude.Value > v.MaxLongitude {
856852
return false
857853
}
858854

859855
return true
860856
}
861857

862-
func (v fdsnStationV1Search) validBounding(latitude *LatitudeType, longitude *LongitudeType) bool {
858+
func (v fdsnStationV1Search) validBounding(latitude LatitudeType, longitude LongitudeType) bool {
863859
if v.Latitude == math.MaxFloat64 {
864860
// not using bounding circle
865861
return true
866862
}
867-
if latitude == nil || longitude == nil {
868-
// requested bounding circle, but this node doesn't have lat/lon
869-
return false
870-
}
871863
d, _, err := wgs84.DistanceBearing(v.Latitude, v.Longitude, latitude.Value, longitude.Value)
872864
if err != nil {
873865
log.Printf("Error checking bounding:%s\n", err.Error())
@@ -887,28 +879,43 @@ func (v fdsnStationV1Search) validBounding(latitude *LatitudeType, longitude *Lo
887879

888880
// Download station XML from S3
889881
func downloadStationXML(since time.Time) (by *bytes.Buffer, modified time.Time, err error) {
890-
s3Client, err := s3.NewWithMaxRetries(100)
891-
if err != nil {
892-
return
893-
}
882+
var tp time.Time
883+
by = bytes.NewBuffer(nil)
894884

895-
tp, err := s3Client.LastModified(s3Bucket, s3Meta, "")
896-
if err != nil {
897-
return
898-
}
885+
if stationXMLBucket != "" {
886+
var s3Client s3.S3
887+
s3Client, err = s3.NewWithMaxRetries(100)
888+
if err != nil {
889+
return
890+
}
899891

900-
if !tp.After(since) {
901-
return nil, zeroDateTime, errNotModified
902-
}
892+
tp, err = s3Client.LastModified(stationXMLBucket, stationXMLKey, "")
893+
if err != nil {
894+
return
895+
}
903896

904-
log.Println("Downloading fdsn station xml file from S3: ", s3Bucket+"/"+s3Meta)
897+
if !tp.After(since) {
898+
return nil, zeroDateTime, errNotModified
899+
}
905900

906-
by = bytes.NewBuffer(nil)
907-
err = s3Client.Get(s3Bucket, s3Meta, "", by)
908-
if err != nil {
909-
return
910-
}
901+
log.Println("Downloading fdsn station xml file from S3: ", stationXMLBucket+"/"+stationXMLKey)
911902

903+
err = s3Client.Get(stationXMLBucket, stationXMLKey, "", by)
904+
if err != nil {
905+
return
906+
}
907+
} else {
908+
// load from local to make debugging easier.
909+
// s3Meta be the path to station xml
910+
var f *os.File
911+
f, err = os.Open(stationXMLKey)
912+
if err != nil {
913+
return
914+
}
915+
defer f.Close()
916+
_, err = by.ReadFrom(f)
917+
tp = time.Now()
918+
}
912919
modified = tp
913920
log.Println("Download complete.")
914921
return
@@ -977,7 +984,7 @@ func levelValue(level string) (int, error) {
977984
case "response":
978985
return STATION_LEVEL_RESPONSE, nil
979986
default:
980-
return -1, fmt.Errorf("Invalid level value.")
987+
return -1, fmt.Errorf("invalid level value")
981988
}
982989
}
983990

@@ -1020,14 +1027,13 @@ func (d xsdDateTime) MarshalXMLAttr(name xml.Name) (xml.Attr, error) {
10201027
return xml.Attr{Name: name, Value: string(t)}, nil
10211028
}
10221029

1023-
// For format=text
1030+
// For format=text - now outputs RFC3339Nano with Z timezone
10241031
func (d xsdDateTime) MarshalFormatText() string {
10251032
if time.Time(d).Equal(zeroDateTime) || time.Time(d).Equal(emptyDateTime) {
10261033
return ""
10271034
}
10281035

1029-
b, _ := d.MarshalText()
1030-
return string(b)
1036+
return time.Time(d).UTC().Format(time.RFC3339Nano)
10311037
}
10321038

10331039
func contains(slice []string, value string) bool {

cmd/fdsn-ws/fdsn_station_test.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,9 @@ func TestStartEnd(t *testing.T) {
356356
}
357357

358358
func TestFormatText(t *testing.T) {
359+
setup(t)
360+
defer teardown()
361+
359362
var e fdsnStationV1Search
360363
var err error
361364
var v url.Values = make(map[string][]string)
@@ -373,7 +376,7 @@ func TestFormatText(t *testing.T) {
373376
c.doFilter([]fdsnStationV1Search{e})
374377
b := c.marshalText(STATION_LEVEL_CHANNEL)
375378
exp := `#Network | Station | Location | Channel | Latitude | Longitude | Elevation | Depth | Azimuth | Dip | SensorDescription | Scale | ScaleFreq | ScaleUnits | SampleRate | StartTime | EndTime
376-
NZ|ARAZ|10|EHZ|-38.627690|176.120060|420.000000|0.000000|0.000000|-90.000000|Short Period Seismometer|74574725.120000|15.000000|m/s|100.000000|2011-06-20T04:00:01|
379+
NZ|ARAZ|10|EHZ|-38.627690|176.120060|420.000000|0.000000|0.000000|-90.000000|Short Period Seismometer|74574725.120000|15.000000|m/s|100.000000|2011-06-20T04:00:01Z|
377380
`
378381
if b.String() != exp {
379382
t.Errorf("Incorrect text result.")
@@ -388,7 +391,7 @@ NZ|ARAZ|10|EHZ|-38.627690|176.120060|420.000000|0.000000|0.000000|-90.000000|Sho
388391
c.doFilter([]fdsnStationV1Search{e})
389392
b = c.marshalText(STATION_LEVEL_NETWORK)
390393
exp = `#Network | Description | StartTime | EndTime | TotalStations
391-
NZ|New Zealand National Seismograph Network|1884-02-01T00:00:00||2
394+
NZ|New Zealand National Seismograph Network|1884-02-01T00:00:00Z||2
392395
`
393396
if b.String() != exp {
394397
t.Errorf("Incorrect text result.")
@@ -403,7 +406,7 @@ NZ|New Zealand National Seismograph Network|1884-02-01T00:00:00||2
403406
c.doFilter([]fdsnStationV1Search{e})
404407
b = c.marshalText(STATION_LEVEL_STATION)
405408
exp = `#Network | Station | Latitude | Longitude | Elevation | SiteName | StartTime | EndTime
406-
NZ|ARAZ|-38.627690|176.120060|420.000000|Aratiatia Landcorp Farm|2007-05-20T23:00:00|
409+
NZ|ARAZ|-38.627690|176.120060|420.000000|Aratiatia Landcorp Farm|2007-05-20T23:00:00Z|
407410
`
408411
if b.String() != exp {
409412
t.Errorf("Incorrect text result.")
@@ -457,8 +460,8 @@ NZ ARA* * EHE* 2001-01-01T00:00:00 *
457460
NZ ARH? * EHN* 2001-01-01T00:00:00 *`
458461
expected := strings.TrimSpace(`
459462
#Network | Station | Latitude | Longitude | Elevation | SiteName | StartTime | EndTime
460-
NZ|ARAZ|-38.627690|176.120060|420.000000|Aratiatia Landcorp Farm|2007-05-20T23:00:00|
461-
NZ|ARHZ|-39.263100|176.995900|270.000000|Aropaoanui|2010-03-11T00:00:00|`)
463+
NZ|ARAZ|-38.627690|176.120060|420.000000|Aratiatia Landcorp Farm|2007-05-20T23:00:00Z|
464+
NZ|ARHZ|-39.263100|176.995900|270.000000|Aropaoanui|2010-03-11T00:00:00Z|`)
462465

463466
route := wt.Request{ID: wt.L(), URL: "/fdsnws/station/1/query", Method: "POST", PostBody: []byte(body), Content: "text/plain"}
464467

0 commit comments

Comments
 (0)